diff --git a/README b/README index d6d6b3f..d4ecd58 100644 --- a/README +++ b/README @@ -13,7 +13,7 @@ The following tools are implemented ('*' == finished, '#' == UTF-8 support, =* cal yes none =*| cat yes none =* chgrp yes none -=* chmod yes none +=*| chmod yes none =* chown yes none =*| chroot non-posix none =* cksum yes none diff --git a/chmod.1 b/chmod.1 index 08ad958..52a2da5 100644 --- a/chmod.1 +++ b/chmod.1 @@ -1,9 +1,9 @@ -.Dd January 17, 2015 +.Dd March 5, 2015 .Dt CHMOD 1 .Os sbase .Sh NAME .Nm chmod -.Nd change file mode +.Nd change file modes .Sh SYNOPSIS .Nm .Oo @@ -14,8 +14,10 @@ .Ar file ... .Sh DESCRIPTION .Nm -changes the file mode of the given -.Ar files . +changes the file mode of each +.Ar file +to +.Ar mode . .Pp If .Ar mode @@ -59,12 +61,13 @@ read | write | execute | setuid and setgid | sticky .It Fl R Change modes recursively. .It Fl H -Only dereference symbolic links that are passed as command line arguments when -recursively traversing directories. +Dereference +.Ar file +if it is a symbolic link. .It Fl L -Always dereference symbolic links while recursively traversing directories. +Dereference all symbolic links. .It Fl P -Don't dereference symbolic links (default). +Preserve symbolic links. This is the default. .El .Sh SEE ALSO .Xr chgrp 1 , diff --git a/chmod.c b/chmod.c index a29b04a..2436721 100644 --- a/chmod.c +++ b/chmod.c @@ -24,8 +24,7 @@ chmodr(const char *path, int depth) if (chmod(path, m) < 0) { weprintf("chmod %s:", path); ret = 1; - } - if (Rflag) + } else if (Rflag) recurse(path, chmodr, depth); } @@ -40,37 +39,48 @@ main(int argc, char *argv[]) { size_t i; - argv0 = argv[0]; - for (i = 1; i < argc && argv[i][0] == '-'; i++) { - switch (argv[i][1]) { - case 'R': - Rflag = 1; - break; - case 'H': - case 'L': - case 'P': - recurse_follow = argv[i][1]; - break; - case 'r': case 'w': case 'x': case 's': case 't': - /* - * -[rwxst] are valid modes so do not interpret - * them as options - in any case we are done if - * we hit this case - */ - goto done; - default: + argv0 = *(argv++); + argc--; + for (; *argv && (*argv)[0] == '-'; argc--, argv++) { + if (!(*argv)[1]) usage(); + for (i = 1; (*argv)[i]; i++) { + switch ((*argv)[i]) { + case 'R': + Rflag = 1; + break; + case 'H': + case 'L': + case 'P': + recurse_follow = (*argv)[i]; + break; + case 'r': case 'w': case 'x': case 's': case 't': + /* -[rwxst] are valid modes, so we're done */ + if (i == 1) + goto done; + /* fallthrough */ + case '-': + /* -- terminator */ + if (i == 1 && !(*argv)[i + 1]) { + argv++; + argc--; + goto done; + } + /* fallthrough */ + default: + usage(); + } } } done: mask = getumask(); - modestr = argv[i]; + modestr = *argv; - if (argc - i - 1 < 1) + if (argc < 2) usage(); - for (++i; i < argc; i++) - chmodr(argv[i], 0); + for (--argc, ++argv; *argv; argc--, argv++) + chmodr(*argv, 0); return ret; }