From 2dfe5c6b8bb36d7c23f379e353ee458ff0881d39 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith Date: Fri, 27 May 2011 23:48:07 +0100 Subject: [PATCH] octal-only chmod --- Makefile | 6 +++--- chmod.1 | 24 ++++++++++++++++++++++ chmod.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ chown.c | 1 - 4 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 chmod.1 create mode 100644 chmod.c diff --git a/Makefile b/Makefile index 84b3f40..5f043ca 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,9 @@ HDR = text.h util.h LIB = util/afgets.o util/agetcwd.o util/concat.o util/enmasse.o util/eprintf.o \ util/recurse.o -SRC = basename.c cat.c chown.c date.c dirname.c echo.c false.c grep.c head.c \ - ln.c ls.c mkdir.c mkfifo.c pwd.c rm.c sleep.c tail.c tee.c touch.c \ - true.c wc.c +SRC = basename.c cat.c chmod.c chown.c date.c dirname.c echo.c false.c grep.c \ + head.c ln.c ls.c mkdir.c mkfifo.c pwd.c rm.c sleep.c tail.c tee.c \ + touch.c true.c wc.c OBJ = $(SRC:.c=.o) $(LIB) BIN = $(SRC:.c=) MAN = $(SRC:.c=.1) diff --git a/chmod.1 b/chmod.1 new file mode 100644 index 0000000..8d75296 --- /dev/null +++ b/chmod.1 @@ -0,0 +1,24 @@ +.TH CHMOD 1 sbase\-VERSION +.SH NAME +chmod \- change file mode +.SH SYNOPSIS +.B chmod +.RB [ -Rr ] +.RI mode +.RI [ file ...] +.SH DESCRIPTION +.B chmod +changes the file mode for the given files. The +.I mode +is a four digit octal number derived from its comprising bits. +.P +The first digit defines the setuid (4), setgid (2), and sticky (1) attributes. +The second digit defines the owner's permissions: read (4), write (2), and +execute (1); the third defines permissions for others in the file's group; and +the fourth for all other users. Leading zeroes may be omitted. +.SH OPTIONS +.TP +.B -R, -r +change directory mode recursively. +.SH SEE ALSO +.IR chmod (2) diff --git a/chmod.c b/chmod.c new file mode 100644 index 0000000..1075a29 --- /dev/null +++ b/chmod.c @@ -0,0 +1,61 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include +#include "util.h" + +static void chmodr(const char *); + +static bool rflag = false; +static mode_t mode = 0; + +int +main(int argc, char *argv[]) +{ + char c, *end; + int octal; + + while((c = getopt(argc, argv, "Rr")) != -1) + switch(c) { + case 'R': + case 'r': + rflag = true; + break; + default: + exit(EXIT_FAILURE); + } + if(optind == argc) + eprintf("usage: %s [-Rr] mode [file...]\n", argv[0]); + octal = strtol(argv[optind++], &end, 8); + if(*end != '\0') + eprintf("%s: not an octal number\n", argv[optind-1]); + + /* posix doesn't specify modal bits */ + if(octal & 04000) mode |= S_ISUID; + if(octal & 02000) mode |= S_ISGID; + if(octal & 01000) mode |= S_ISVTX; + if(octal & 00400) mode |= S_IRUSR; + if(octal & 00200) mode |= S_IWUSR; + if(octal & 00100) mode |= S_IXUSR; + if(octal & 00040) mode |= S_IRGRP; + if(octal & 00020) mode |= S_IWGRP; + if(octal & 00010) mode |= S_IXGRP; + if(octal & 00004) mode |= S_IROTH; + if(octal & 00002) mode |= S_IWOTH; + if(octal & 00001) mode |= S_IXOTH; + + for(; optind < argc; optind++) + chmodr(argv[optind]); + return EXIT_SUCCESS; +} + +void +chmodr(const char *path) +{ + if(chmod(path, mode) != 0) + eprintf("chmod %s:", path); + if(rflag) + recurse(path, chmodr); +} diff --git a/chown.c b/chown.c index 68719e9..119711e 100644 --- a/chown.c +++ b/chown.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include