sbase

suckless unix tools
git clone git://git.2f30.org/sbase
Log | Files | Refs | README | LICENSE

commit 2dfe5c6b8bb36d7c23f379e353ee458ff0881d39
parent 73c2898e91eb7466402858831ee38c754cb42480
Author: Connor Lane Smith <cls@lubutu.com>
Date:   Fri, 27 May 2011 23:48:07 +0100

octal-only chmod
Diffstat:
MMakefile | 6+++---
Achmod.1 | 24++++++++++++++++++++++++
Achmod.c | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mchown.c | 1-
4 files changed, 88 insertions(+), 4 deletions(-)

diff --git 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 @@ -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 @@ -0,0 +1,61 @@ +/* See LICENSE file for copyright and license details. */ +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#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 @@ -3,7 +3,6 @@ #include <grp.h> #include <pwd.h> #include <stdbool.h> -#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h>