diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2000-06-09 16:26:52 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2000-06-09 16:26:52 +0000 |
commit | 2c4dd839b221ff29c42a444c4642510a244b2331 (patch) | |
tree | a092f43ea852d22d05b62a6a07bafc0bdcf2293e /bin/chmod/chmod.c | |
parent | 35abe9a53cf6ed748ead5fcca7758417cabc17b3 (diff) |
merge chown/chgrp into chmod.
provide symlinks from old location for the time being.
Diffstat (limited to 'bin/chmod/chmod.c')
-rw-r--r-- | bin/chmod/chmod.c | 151 |
1 files changed, 123 insertions, 28 deletions
diff --git a/bin/chmod/chmod.c b/bin/chmod/chmod.c index 7d4aae83668..aa4009bf0a7 100644 --- a/bin/chmod/chmod.c +++ b/bin/chmod/chmod.c @@ -1,4 +1,4 @@ -/* $OpenBSD: chmod.c,v 1.7 1997/11/08 23:26:39 todd Exp $ */ +/* $OpenBSD: chmod.c,v 1.8 2000/06/09 16:26:51 mickey Exp $ */ /* $NetBSD: chmod.c,v 1.12 1995/03/21 09:02:09 cgd Exp $ */ /* @@ -44,16 +44,18 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)chmod.c 8.8 (Berkeley) 4/1/94"; #else -static char rcsid[] = "$OpenBSD: chmod.c,v 1.7 1997/11/08 23:26:39 todd Exp $"; +static char rcsid[] = "$OpenBSD: chmod.c,v 1.8 2000/06/09 16:26:51 mickey Exp $"; #endif #endif /* not lint */ -#include <sys/types.h> +#include <sys/param.h> #include <sys/stat.h> #include <err.h> #include <errno.h> #include <fts.h> +#include <pwd.h> +#include <grp.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -61,6 +63,11 @@ static char rcsid[] = "$OpenBSD: chmod.c,v 1.7 1997/11/08 23:26:39 todd Exp $"; #include <limits.h> #include <locale.h> +int ischown, ischgrp, ischmod; +extern char *__progname; + +gid_t a_gid __P((const char *)); +uid_t a_uid __P((const char *)); void usage __P((void)); int @@ -74,14 +81,22 @@ main(argc, argv) long val; int oct, omode; int Hflag, Lflag, Pflag, Rflag, ch, fflag, fts_options, hflag, rval; - char *ep, *mode; + uid_t uid; + gid_t gid; + char *ep, *mode, *cp; #ifdef lint set = NULL; - omode = 0; + oct = omode = 0; #endif setlocale(LC_ALL, ""); + ischown = __progname[2] == 'o'; + ischgrp = __progname[2] == 'g'; + ischmod = __progname[2] == 'm'; + + uid = -1; + gid = -1; Hflag = Lflag = Pflag = Rflag = fflag = hflag = 0; while ((ch = getopt(argc, argv, "HLPRXfgorstuwx")) != -1) switch (ch) { @@ -121,6 +136,8 @@ main(argc, argv) */ case 'g': case 'o': case 'r': case 's': case 't': case 'u': case 'w': case 'X': case 'x': + if (!ischmod) + usage(); if (argv[optind - 1][0] == '-' && argv[optind - 1][1] == ch && argv[optind - 1][2] == '\0') @@ -148,23 +165,38 @@ done: argv += optind; } } - mode = *argv; - if (*mode >= '0' && *mode <= '7') { - errno = 0; - val = strtol(mode, &ep, 8); - if (val > INT_MAX || val < 0) - errno = ERANGE; - if (errno) - err(1, "invalid file mode: %s", mode); - if (*ep) - errx(1, "invalid file mode: %s", mode); - omode = val; - oct = 1; - } else { - if ((set = setmode(mode)) == NULL) - errx(1, "invalid file mode: %s", mode); - oct = 0; - } + if (ischmod) { + mode = *argv; + if (*mode >= '0' && *mode <= '7') { + errno = 0; + val = strtol(mode, &ep, 8); + if (val > INT_MAX || val < 0) + errno = ERANGE; + if (errno) + err(1, "invalid file mode: %s", mode); + if (*ep) + errx(1, "invalid file mode: %s", mode); + omode = val; + oct = 1; + } else { + if ((set = setmode(mode)) == NULL) + errx(1, "invalid file mode: %s", mode); + oct = 0; + } + } else if (ischown) { + if ((cp = strchr(*argv, ':')) != NULL) { + *cp++ = '\0'; + gid = a_gid(cp); + } +#ifdef SUPPORT_DOT + else if ((cp = strchr(*argv, '.')) != NULL) { + *cp++ = '\0'; + gid = a_gid(cp); + } +#endif + uid = a_uid(*argv); + } else + gid = a_gid(*argv); if ((ftsp = fts_open(++argv, fts_options, 0)) == NULL) err(1, NULL); @@ -173,13 +205,19 @@ done: argv += optind; case FTS_D: if (!Rflag) fts_set(ftsp, p, FTS_SKIP); - break; + if (ischmod) + break; + else + continue; case FTS_DNR: /* Warn, chmod, continue. */ warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); rval = 1; break; case FTS_DP: /* Already changed at FTS_D. */ - continue; + if (ischmod) + continue; + else + break; case FTS_ERR: /* Warn, continue. */ case FTS_NS: warnx("%s: %s", p->fts_path, strerror(p->fts_errno)); @@ -192,14 +230,20 @@ done: argv += optind; * don't point to anything and ones that we found * doing a physical walk. */ - continue; + if (chmod || !hflag) + continue; default: break; } - if (chmod(p->fts_accpath, oct ? omode : + if (ischmod && chmod(p->fts_accpath, oct ? omode : getmode(set, p->fts_statp->st_mode)) && !fflag) { warn(p->fts_path); rval = 1; + } else if (!ischmod && + (hflag ? lchown(p->fts_accpath, uid, gid) : + chown(p->fts_accpath, uid, gid)) && !fflag) { + warn("%s", p->fts_path); + rval = 1; } } if (errno) @@ -207,10 +251,61 @@ done: argv += optind; exit(rval); } +uid_t +a_uid(s) + const char *s; +{ + struct passwd *pw; + char *ep; + u_long ul; + + if (*s == '\0') /* Argument was "gid[:.]". */ + return -1; + + if ((pw = getpwnam(s)) != NULL) { + return pw->pw_uid; + } else { + if ((ul = strtoul(s, &ep, 10)) == ULONG_MAX) + err(1, "%s", s); + if (*ep != '\0') + errx(1, "%s: invalid user name", s); + return (uid_t)ul; + } +} + +gid_t +a_gid(s) + const char *s; +{ + struct group *gr; + char *ep; + u_long ul; + + if (*s == '\0') /* Argument was "gid[:.]". */ + return -1; + + if ((gr = getgrnam(s)) != NULL) { + return gr->gr_gid; + } else { + if ((ul = strtoul(s, &ep, 10)) == ULONG_MAX) + err(1, "%s", s); + if (*ep != '\0') + errx(1, "%s: invalid group name", s); + return (gid_t)ul; + } +} + void usage() { - (void)fprintf(stderr, - "usage: chmod [-R [-H | -L | -P]] mode file ...\n"); + if (ischmod) + fprintf(stderr, + "usage: %s [-R [-H | -L | -P]] mode file ...\n", + __progname); + else + fprintf(stderr, + "usage: %s [-R [-H | -L | -P]] [-f] [-h] %s file ...\n", + __progname, ischown ? "[owner][:group]" : "group"); + exit(1); } |