install correct aliases file
[unix-history] / usr / src / bin / chmod / chmod.c
index 4435269..2a25e4f 100644 (file)
-static char *sccsid = "@(#)chmod.c     4.5 %G%";
+/*
+ * Copyright (c) 1980, 1988 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1980, 1988 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)chmod.c    5.7 (Berkeley) %G%";
+#endif /* not lint */
 
 /*
  * chmod options mode files
  * where
 
 /*
  * chmod options mode files
  * where
- *     mode    is [ugoa][+-=][rwxXstugo] or a octal number
- *     options are -R
+ *     mode is [ugoa][+-=][rwxXstugo] or an octal number
+ *     options are -Rf
  */
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/dir.h>
 
  */
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/dir.h>
 
-#define        USER    05700   /* user's bits */
-#define        GROUP   02070   /* group's bits */
-#define        OTHER   00007   /* other's bits */
-#define        ALL     01777   /* all (note absence of setuid, etc) */
+static int     fflag, rflag, retval, um;
+static char    *modestring, *ms;
 
 
-#define        READ    00444   /* read permit */
-#define        WRITE   00222   /* write permit */
-#define        EXEC    00111   /* exec permit */
-#define        SETID   06000   /* set[ug]id */
-#define        STICKY  01000   /* sticky bit */
+main(argc, argv)
+       int argc;
+       char **argv;
+{
+       extern char *optarg;
+       extern int optind, opterr;
+       int ch;
 
 
-char   *modestring, *ms;
-int    um;
-int    status;
-int    rflag, debug;
+       /*
+        * since "-[rwx]" etc. are valid file modes, we don't let getopt(3)
+        * print error messages, and we mess around with optind as necessary.
+        */
+       opterr = 0;
+       while ((ch = getopt(argc, argv, "Rf")) != EOF)
+               switch((char)ch) {
+               case 'R':
+                       rflag++;
+                       break;
+               case 'f':
+                       fflag++;
+                       break;
+               case '?':
+               default:
+                       --optind;
+                       goto done;
+               }
+done:  argv += optind;
+       argc -= optind;
 
 
-main(argc,argv)
-char **argv;
-{
-       register i;
-       register char *p, *flags;
-       struct  stat st;
-
-usage:
-       if (argc < 3) {
-               fprintf(stderr
-                       ,"Usage: chmod [-R] [ugoa][+-=][rwxXstugo] file ...\n");
+       if (argc < 2) {
+               fputs("usage: chmod [-Rf] [ugoa][+-=][rwxXstugo] file ...\n",
+                   stderr);
                exit(-1);
        }
 
                exit(-1);
        }
 
-       argv++, --argc;
-       if (*argv[0] == '-') {
-               for (flags = argv[0]; *flags; ++flags)
-                       switch (*flags) {
-                         case '-':                     break;
-                         case 'R':     rflag++;        break;
-                         default:      argc = 0;       goto usage;
-                       }
-               argv++, argc--;
-       }
-
-       modestring = argv[0];
-
+       modestring = *argv;
        um = umask(0);
        um = umask(0);
-       (void) newmode(0);
-       for (i = 1; i < argc; i++) {
-               p = argv[i];
-               if (stat(p, &st) < 0) {
-                       fprintf(stderr, "chmod: can't access %s\n", p);
-                       ++status;
-                       continue;
-               }
-               if (rflag && st.st_mode & S_IFDIR) {
-                       status += chmodr(p, newmode(st.st_mode));
-               } else if (chmod(p, newmode(st.st_mode)) < 0) {
-                       fprintf(stderr, "chmod: can't change %s\n", p);
-                       ++status;
-                       continue;
-               }
-       }
-       exit(status);
+       (void)newmode((u_short)0);
+
+       while (*++argv)
+               change(*argv);
+       exit(retval);
 }
 
 }
 
-chmodr(dir, mode)
-       char    *dir;
+change(file)
+       char *file;
 {
 {
-       register DIR            *dirp;
-       register struct direct  *dp;
-       register struct stat    st;
-       char                    savedir[1024];
-
-       if (getwd(savedir) == 0) {
-               fprintf(stderr, "chmod: %s\n", savedir);
-               exit(255);
-       }
+       register DIR *dirp;
+       register struct direct *dp;
+       struct stat buf;
 
 
-       /*
-       ** chmod what we are given before doing it's contents
-       */
-       chmod(dir, newmode(mode));
-       
-       chdir(dir);
-       if ((dirp = opendir(".")) == NULL) {
-               perror(dir);
-               return(1);
+       if (lstat(file, &buf) || chmod(file, newmode(buf.st_mode))) {
+               err(file);
+               return;
        }
        }
-       dp = readdir(dirp);
-       dp = readdir(dirp); /* read "." and ".." */
-       for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
-               if (stat(dp->d_name, &st) < 0) {
-                       fprintf(stderr, "chmod: can't access %s\n", dp->d_name);
-                       return(1);
+       if (rflag && ((buf.st_mode & S_IFMT) == S_IFDIR)) {
+               if (chdir(file) < 0 || !(dirp = opendir("."))) {
+                       err(file);
+                       return;
+               }
+               for (dp = readdir(dirp); dp; dp = readdir(dirp)) {
+                       if (dp->d_name[0] == '.' && (!dp->d_name[1] ||
+                           dp->d_name[1] == '.' && !dp->d_name[2]))
+                               continue;
+                       change(dp->d_name);
+               }
+               closedir(dirp);
+               if (chdir("..")) {
+                       err("..");
+                       exit(fflag ? 0 : -1);
                }
                }
-               chmod(dp->d_name, newmode(st.st_mode));
-               if (st.st_mode & S_IFDIR)
-                       chmodr(dp->d_name, mode);
        }
        }
-       closedir(dirp);
-       chdir(savedir);
-       return(0);
+}
+
+err(s)
+       char *s;
+{
+       if (fflag)
+               return;
+       fputs("chmod: ", stderr);
+       perror(s);
+       retval = -1;
 }
 
 newmode(nm)
 }
 
 newmode(nm)
-unsigned nm;
+       u_short nm;
 {
 {
-       register o, m, b;
-       int savem;
+       register int o, m, b;
 
        ms = modestring;
 
        ms = modestring;
-       savem = nm;
        m = abs();
        m = abs();
-       if (!*ms)
-               return(m);
+       if (*ms == '\0')
+               return (m);
        do {
                m = who();
                while (o = what()) {
        do {
                m = who();
                while (o = what()) {
-                       b = where(nm);
+                       b = where((int)nm);
                        switch (o) {
                        case '+':
                                nm |= b & m;
                        switch (o) {
                        case '+':
                                nm |= b & m;
@@ -143,26 +140,37 @@ unsigned nm;
                }
        } while (*ms++ == ',');
        if (*--ms) {
                }
        } while (*ms++ == ',');
        if (*--ms) {
-               fprintf(stderr, "chmod: invalid mode\n");
-               exit(255);
+               fputs("chmod: invalid mode.\n", stderr);
+               exit(-1);
        }
        }
-       return(nm);
+       return ((int)nm);
 }
 
 abs()
 {
 }
 
 abs()
 {
-       register c, i;
+       register int c, i;
 
        i = 0;
        while ((c = *ms++) >= '0' && c <= '7')
                i = (i << 3) + (c - '0');
        ms--;
 
        i = 0;
        while ((c = *ms++) >= '0' && c <= '7')
                i = (i << 3) + (c - '0');
        ms--;
-       return(i);
+       return (i);
 }
 
 }
 
+#define        USER    05700   /* user's bits */
+#define        GROUP   02070   /* group's bits */
+#define        OTHER   00007   /* other's bits */
+#define        ALL     01777   /* all (note absence of setuid, etc) */
+
+#define        READ    00444   /* read permit */
+#define        WRITE   00222   /* write permit */
+#define        EXEC    00111   /* exec permit */
+#define        SETID   06000   /* set[ug]id */
+#define        STICKY  01000   /* sticky bit */
+
 who()
 {
 who()
 {
-       register m;
+       register int m;
 
        m = 0;
        for (;;) switch (*ms++) {
 
        m = 0;
        for (;;) switch (*ms++) {
@@ -182,26 +190,25 @@ who()
                ms--;
                if (m == 0)
                        m = ALL & ~um;
                ms--;
                if (m == 0)
                        m = ALL & ~um;
-               return m;
+               return (m);
        }
 }
 
 what()
 {
        }
 }
 
 what()
 {
-
        switch (*ms) {
        case '+':
        case '-':
        case '=':
        switch (*ms) {
        case '+':
        case '-':
        case '=':
-               return *ms++;
+               return (*ms++);
        }
        }
-       return(0);
+       return (0);
 }
 
 where(om)
 }
 
 where(om)
-register om;
+       register int om;
 {
 {
-       register m;
+       register int m;
 
        m = 0;
        switch (*ms) {
 
        m = 0;
        switch (*ms) {
@@ -217,7 +224,7 @@ register om;
                m &= (READ|WRITE|EXEC);
                m |= (m << 3) | (m << 6);
                ++ms;
                m &= (READ|WRITE|EXEC);
                m |= (m << 3) | (m << 6);
                ++ms;
-               return m;
+               return (m);
        }
        for (;;) switch (*ms++) {
        case 'r':
        }
        for (;;) switch (*ms++) {
        case 'r':
@@ -241,6 +248,6 @@ register om;
                continue;
        default:
                ms--;
                continue;
        default:
                ms--;
-               return m;
+               return (m);
        }
 }
        }
 }