sbase

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

commit 3a04302c6608c9a10a7ab1b905590c1b1a873be0
parent 8f436abde68108f78d2c9346858fb85e8332253c
Author: FRIGN <dev@frign.de>
Date:   Mon Mar  9 00:37:34 +0100

Audit chown(1)

Similar to the chgrp(1)-audit:
1) Refactor manpage so it's actually fun to read
2) BUGFIX: Call (l)chown properly when the H-flag is specified
   (only when depth > 0)
3) BUGFIX: Call (l)chown properly when the h-flag is specified
   (only when depth = 0).
4) BUGFIX: Only recurse() in chgrp() when the initial chownf()
   succeeds.
5) Style fixes, argv-basing.
6) Rename status to ret for consistency.
7) Add blank line before return.

Diffstat:
README | 2+-
chown.1 | 33+++++++++++++++++++++------------
chown.c | 60++++++++++++++++++++++++++++++------------------------------
3 files changed, 52 insertions(+), 43 deletions(-)
diff --git a/README b/README @@ -14,7 +14,7 @@ The following tools are implemented ('*' == finished, '#' == UTF-8 support, =*| cat yes none =*| chgrp yes none =*| chmod yes none -=* chown yes none +=*| chown yes none =*| chroot non-posix none =* cksum yes none =* cmp yes none diff --git a/chown.1 b/chown.1 @@ -1,4 +1,4 @@ -.Dd February 17, 2015 +.Dd March 9, 2015 .Dt CHOWN 1 .Os sbase .Sh NAME @@ -15,26 +15,35 @@ .Op Ar file ... .Sh DESCRIPTION .Nm -changes the user or group ownership for the given -.Ar files . +sets the user or group id of each +.Ar file +to the uid of +.Ar owner +or the gid of +.Ar group +respectively. .Sh OPTIONS .Bl -tag -width Ds .It Fl h -Change the user ID and/or group ID of the symlink itself. This flag cannot be used -with -.Op Fl R . +Preserve +.Ar file +if it is a symbolic link. .It Fl R -Change directory ownership recursively. +Change file ownerships 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 chown 2 +.Xr chmod 1 , +.Xr chown 2 , +.Xr getgrnam 3 , +.Xr getpwnam 3 .Sh STANDARDS The .Nm diff --git a/chown.c b/chown.c @@ -1,6 +1,7 @@ /* See LICENSE file for copyright and license details. */ #include <errno.h> #include <grp.h> +#include <limits.h> #include <pwd.h> #include <stdlib.h> #include <string.h> @@ -8,45 +9,54 @@ #include "util.h" -static int rflag = 0; -static uid_t uid = -1; -static gid_t gid = -1; -static int ret = 0; -static char *chownf_name = "chown"; -static int (*chownf)(const char *, uid_t, gid_t) = chown; +static int hflag = 0; +static int Rflag = 0; +static uid_t uid = -1; +static gid_t gid = -1; +static int ret = 0; static void chownpwgr(const char *path, int depth) { + char *chownf_name; + int (*chownf)(const char *, uid_t, gid_t); + + if (recurse_follow == 'P' || (recurse_follow == 'H' && depth) || (hflag && !depth)) { + chownf_name = "lchown"; + chownf = lchown; + } else { + chownf_name = "chown"; + chownf = chown; + } + if (chownf(path, uid, gid) < 0) { weprintf("%s %s:", chownf_name, path); ret = 1; - } - if (rflag) + } else if (Rflag) { recurse(path, chownpwgr, depth); + } } static void usage(void) { - eprintf("usage: %s [-h] [-R [-H | -L | -P]] [owner][:[group]] file...\n", argv0); + eprintf("usage: %s [-h] [-R [-H | -L | -P]] [owner][:[group]] file ...\n", argv0); } int main(int argc, char *argv[]) { - char *owner, *group, *end; struct passwd *pw; struct group *gr; + char *owner, *group; ARGBEGIN { case 'h': - chownf_name = "lchown"; - chownf = lchown; + hflag = 1; break; case 'r': case 'R': - rflag = 1; + Rflag = 1; break; case 'H': case 'L': @@ -57,16 +67,10 @@ main(int argc, char *argv[]) usage(); } ARGEND; - if (argc == 0) + if (argc < 2) usage(); - if (recurse_follow == 'P') { - chownf_name = "lchown"; - chownf = lchown; - } owner = argv[0]; - argv++; - argc--; if ((group = strchr(owner, ':'))) *group++ = '\0'; @@ -76,11 +80,9 @@ main(int argc, char *argv[]) if (pw) { uid = pw->pw_uid; } else { - if (errno != 0) + if (errno) eprintf("getpwnam %s:", owner); - uid = strtoul(owner, &end, 10); - if (*end != '\0') - eprintf("getpwnam %s: no such user\n", owner); + uid = estrtonum(owner, 0, UINT_MAX); } } if (group && *group) { @@ -89,15 +91,13 @@ main(int argc, char *argv[]) if (gr) { gid = gr->gr_gid; } else { - if (errno != 0) + if (errno) eprintf("getgrnam %s:", group); - gid = strtoul(group, &end, 10); - if (*end != '\0') - eprintf("getgrnam %s: no such group\n", group); + gid = estrtonum(group, 0, UINT_MAX); } } - for (; argc > 0; argc--, argv++) - chownpwgr(argv[0], 0); + for (argc--, argv++; *argv; argc--, argv++) + chownpwgr(*argv, 0); return ret; }