add -f flag for install; cleanup -R code
authorSam Leffler <sam@ucbvax.Berkeley.EDU>
Sun, 1 Sep 1985 08:44:44 +0000 (00:44 -0800)
committerSam Leffler <sam@ucbvax.Berkeley.EDU>
Sun, 1 Sep 1985 08:44:44 +0000 (00:44 -0800)
SCCS-vsn: bin/chmod/chmod.c 5.4

usr/src/bin/chmod/chmod.c

index 49811f4..a4aba03 100644 (file)
@@ -5,74 +5,72 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)chmod.c    5.3 (Berkeley) %G%";
-#endif not lint
+static char sccsid[] = "@(#)chmod.c    5.4 (Berkeley) %G%";
+#endif
 
 /*
  * 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) */
-
-#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 */
-
 char   *modestring, *ms;
 int    um;
 int    status;
 char   *modestring, *ms;
 int    um;
 int    status;
-int    rflag, debug;
+int    fflag;
+int    rflag;
 
 
-main(argc,argv)
-char **argv;
+main(argc, argv)
+       char *argv[];
 {
 {
-       register i;
        register char *p, *flags;
        register char *p, *flags;
-       struct  stat st;
+       register int i;
+       struct stat st;
 
 
-usage:
        if (argc < 3) {
        if (argc < 3) {
-               fprintf(stderr
-                       ,"Usage: chmod [-R] [ugoa][+-=][rwxXstugo] file ...\n");
+               fprintf(stderr,
+                   "Usage: chmod [-Rf] [ugoa][+-=][rwxXstugo] file ...\n");
                exit(-1);
        }
                exit(-1);
        }
-
        argv++, --argc;
        argv++, --argc;
-       if (*argv[0] == '-') {
-               if (strcmp(argv[0], "-R") == 0) {
+       while (argc > 0 && argv[0][0] == '-') {
+               for (p = &argv[0][1]; *p; p++) switch (*p) {
+
+               case 'R':
                        rflag++;
                        rflag++;
-                       argv++, argc--;
+                       break;
+
+               case 'f':
+                       fflag++;
+                       break;
+
+               default:
+                       goto done;
                }
                }
+               argc--, argv++;
        }
        }
-
+done:
        modestring = argv[0];
        modestring = argv[0];
-
        um = umask(0);
        (void) newmode(0);
        for (i = 1; i < argc; i++) {
                p = argv[i];
        um = umask(0);
        (void) newmode(0);
        for (i = 1; i < argc; i++) {
                p = argv[i];
+               /* do stat for directory arguments */
                if (stat(p, &st) < 0) {
                if (stat(p, &st) < 0) {
-                       fprintf(stderr, "chmod: can't access %s\n", p);
-                       ++status;
+                       status += error("can't access %s", p);
                        continue;
                }
                        continue;
                }
-               if (rflag && st.st_mode & S_IFDIR) {
+               if (rflag && st.st_mode&S_IFDIR) {
                        status += chmodr(p, newmode(st.st_mode));
                        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;
+               }
+               if (chmod(p, newmode(st.st_mode)) < 0) {
+                       status += error("can't change %s", p);
                        continue;
                }
        }
                        continue;
                }
        }
@@ -80,47 +78,84 @@ usage:
 }
 
 chmodr(dir, mode)
 }
 
 chmodr(dir, mode)
-       char    *dir;
+       char *dir;
 {
 {
-       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;
+       register struct stat st;
+       char savedir[1024];
+       int ecode;
 
 
+       if (getwd(savedir) == 0)
+               fatal(255, "%s", savedir);
        /*
        /*
-       ** chmod what we are given before doing it's contents
-       */
-       chmod(dir, newmode(mode));
-       
-       chdir(dir);
-       if ((dirp = opendir(".")) == NULL) {
-               perror(dir);
-               return(1);
-       }
+        * Change what we are given before doing it's contents
+        */
+       if (chmod(dir, newmode(mode)) < 0 && error("can't change %s", dir))
+               return (1);
+       if (chdir(dir) < 0)
+               return (Perror(dir));
+       if ((dirp = opendir(".")) == NULL)
+               return (Perror(dir));
        dp = readdir(dirp);
        dp = readdir(dirp); /* read "." and ".." */
        dp = readdir(dirp);
        dp = readdir(dirp); /* read "." and ".." */
+       ecode = 0;
        for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
        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 (lstat(dp->d_name, &st) < 0) {
+                       ecode = error("can't access %s", dp->d_name);
+                       if (ecode)
+                               break;
+                       continue;
+               }
+               if (st.st_mode&S_IFDIR) {
+                       ecode = chmodr(dp->d_name, newmode(st.st_mode));
+                       if (ecode)
+                               break;
+                       continue;
                }
                }
-               if (st.st_mode & S_IFDIR)
-                       chmodr(dp->d_name, newmode(st.st_mode));
-               else
-                       chmod(dp->d_name, newmode(st.st_mode));
+               if (chmod(dp->d_name, newmode(st.st_mode)) < 0 &&
+                   (ecode = error("can't change %s", dp->d_name)))
+                       break;
        }
        closedir(dirp);
        }
        closedir(dirp);
-       chdir(savedir);
-       return(0);
+       if (chdir(savedir) < 0)
+               fatal(255, "can't change back to %s", savedir);
+       return (ecode);
+}
+
+error(fmt, a)
+       char *fmt, *a;
+{
+
+       if (!fflag) {
+               fprintf(stderr, "chmod: ");
+               fprintf(stderr, fmt, a);
+               putc('\n', stderr);
+       }
+       return (!fflag);
+}
+
+fatal(status, fmt, a)
+       int status;
+       char *fmt, *a;
+{
+
+       fflag = 0;
+       (void) error(fmt, a);
+       exit(status);
+}
+
+Perror(s)
+       char *s;
+{
+
+       fprintf(stderr, "chmod: ");
+       perror(s);
+       return (1);
 }
 
 newmode(nm)
 }
 
 newmode(nm)
-unsigned nm;
+       unsigned nm;
 {
        register o, m, b;
        int savem;
 {
        register o, m, b;
        int savem;
@@ -128,8 +163,8 @@ unsigned nm;
        ms = modestring;
        savem = nm;
        m = abs();
        ms = modestring;
        savem = nm;
        m = abs();
-       if (!*ms)
-               return(m);
+       if (*ms == '\0')
+               return (m);
        do {
                m = who();
                while (o = what()) {
        do {
                m = who();
                while (o = what()) {
@@ -148,11 +183,9 @@ unsigned nm;
                        }
                }
        } while (*ms++ == ',');
                        }
                }
        } while (*ms++ == ',');
-       if (*--ms) {
-               fprintf(stderr, "chmod: invalid mode\n");
-               exit(255);
-       }
-       return(nm);
+       if (*--ms)
+               fatal(255, "invalid mode");
+       return (nm);
 }
 
 abs()
 }
 
 abs()
@@ -163,9 +196,20 @@ abs()
        while ((c = *ms++) >= '0' && c <= '7')
                i = (i << 3) + (c - '0');
        ms--;
        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()
 {
        register m;
 who()
 {
        register m;
@@ -188,7 +232,7 @@ who()
                ms--;
                if (m == 0)
                        m = ALL & ~um;
                ms--;
                if (m == 0)
                        m = ALL & ~um;
-               return m;
+               return (m);
        }
 }
 
        }
 }
 
@@ -199,13 +243,13 @@ what()
        case '+':
        case '-':
        case '=':
        case '+':
        case '-':
        case '=':
-               return *ms++;
+               return (*ms++);
        }
        }
-       return(0);
+       return (0);
 }
 
 where(om)
 }
 
 where(om)
-register om;
+       register om;
 {
        register m;
 
 {
        register m;
 
@@ -223,7 +267,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':
@@ -247,6 +291,6 @@ register om;
                continue;
        default:
                ms--;
                continue;
        default:
                ms--;
-               return m;
+               return (m);
        }
 }
        }
 }