1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 char copyright[] = 10 "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ 11 All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)chmod.c 5.20 (Berkeley) 12/28/91"; 16 #endif /* not lint */ 17 18 #include <sys/types.h> 19 #include <sys/stat.h> 20 #include <errno.h> 21 #include <fts.h> 22 #include <unistd.h> 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 27 int retval; 28 29 void err __P((const char *, ...)); 30 void error __P((char *)); 31 void usage __P((void)); 32 33 int 34 main(argc, argv) 35 int argc; 36 char *argv[]; 37 { 38 register FTS *fts; 39 register FTSENT *p; 40 register int oct, omode; 41 struct stat sb; 42 mode_t *set; 43 int ch, fflag, rflag; 44 char *ep, *mode; 45 46 fflag = rflag = 0; 47 while ((ch = getopt(argc, argv, "Rfrwx")) != EOF) 48 switch((char)ch) { 49 case 'R': 50 rflag = 1; 51 break; 52 case 'f': /* no longer documented */ 53 fflag = 1; 54 break; 55 case 'r': /* "-[rwx]" are valid file modes */ 56 case 'w': 57 case 'x': 58 --optind; 59 goto done; 60 case '?': 61 default: 62 usage(); 63 } 64 done: argv += optind; 65 argc -= optind; 66 67 if (argc < 2) 68 usage(); 69 70 mode = *argv; 71 if (*mode >= '0' && *mode <= '7') { 72 omode = (int)strtol(mode, &ep, 8); 73 if (omode < 0 || *ep) 74 err("invalid file mode: %s", mode); 75 oct = 1; 76 } else { 77 if (!(set = setmode(mode))) 78 err("invalid file mode: %s", mode); 79 oct = 0; 80 } 81 82 retval = 0; 83 if (rflag) { 84 if ((fts = fts_open(++argv, 85 oct ? FTS_NOSTAT|FTS_PHYSICAL : FTS_PHYSICAL, 0)) == NULL) 86 err("%s", strerror(errno)); 87 while (p = fts_read(fts)) 88 switch(p->fts_info) { 89 case FTS_D: 90 break; 91 case FTS_DNR: 92 case FTS_ERR: 93 case FTS_NS: 94 err("%s: %s", p->fts_path, strerror(errno)); 95 default: 96 if (chmod(p->fts_accpath, oct ? omode : 97 getmode(set, p->fts_statb.st_mode)) && 98 !fflag) 99 error(p->fts_path); 100 break; 101 } 102 exit(retval); 103 } 104 if (oct) { 105 while (*++argv) 106 if (chmod(*argv, omode) && !fflag) 107 error(*argv); 108 } else 109 while (*++argv) 110 if ((lstat(*argv, &sb) || 111 chmod(*argv, getmode(set, sb.st_mode))) && !fflag) 112 error(*argv); 113 exit(retval); 114 } 115 116 void 117 error(name) 118 char *name; 119 { 120 (void)fprintf(stderr, "chmod: %s: %s\n", name, strerror(errno)); 121 retval = 1; 122 } 123 124 void 125 usage() 126 { 127 (void)fprintf(stderr, "usage: chmod [-R] mode file ...\n"); 128 exit(1); 129 } 130 131 #if __STDC__ 132 #include <stdarg.h> 133 #else 134 #include <varargs.h> 135 #endif 136 137 void 138 #if __STDC__ 139 err(const char *fmt, ...) 140 #else 141 err(fmt, va_alist) 142 char *fmt; 143 va_dcl 144 #endif 145 { 146 va_list ap; 147 #if __STDC__ 148 va_start(ap, fmt); 149 #else 150 va_start(ap); 151 #endif 152 (void)fprintf(stderr, "chmod: "); 153 (void)vfprintf(stderr, fmt, ap); 154 va_end(ap); 155 (void)fprintf(stderr, "\n"); 156 exit(1); 157 /* NOTREACHED */ 158 } 159