summaryrefslogtreecommitdiff
path: root/bin/chmod/chmod.c
diff options
context:
space:
mode:
authorMichael Shalayeff <mickey@cvs.openbsd.org>2000-06-09 16:26:52 +0000
committerMichael Shalayeff <mickey@cvs.openbsd.org>2000-06-09 16:26:52 +0000
commit2c4dd839b221ff29c42a444c4642510a244b2331 (patch)
treea092f43ea852d22d05b62a6a07bafc0bdcf2293e /bin/chmod/chmod.c
parent35abe9a53cf6ed748ead5fcca7758417cabc17b3 (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.c151
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);
}