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.18 (Berkeley) 03/07/91"; 16 #endif /* not lint */ 17 18 #include <sys/types.h> 19 #include <sys/stat.h> 20 #include <fts.h> 21 #include <stdio.h> 22 #include <string.h> 23 24 extern int errno; 25 int retval; 26 27 main(argc, argv) 28 int argc; 29 char **argv; 30 { 31 extern int optind; 32 register FTS *fts; 33 register FTSENT *p; 34 register int oct, omode; 35 register char *mode; 36 mode_t *set, *setmode(); 37 struct stat sb; 38 int ch, fflag, rflag; 39 40 fflag = rflag = 0; 41 while ((ch = getopt(argc, argv, "Rfrwx")) != EOF) 42 switch((char)ch) { 43 case 'R': 44 rflag = 1; 45 break; 46 case 'f': /* no longer documented */ 47 fflag = 1; 48 break; 49 case 'r': /* "-[rwx]" are valid file modes */ 50 case 'w': 51 case 'x': 52 --optind; 53 goto done; 54 case '?': 55 default: 56 usage(); 57 } 58 done: argv += optind; 59 argc -= optind; 60 61 if (argc < 2) 62 usage(); 63 64 mode = *argv; 65 if (*mode >= '0' && *mode <= '7') { 66 omode = (int)strtol(mode, (char **)NULL, 8); 67 oct = 1; 68 } else { 69 if (!(set = setmode(mode))) { 70 (void)fprintf(stderr, "chmod: invalid file mode.\n"); 71 exit(1); 72 } 73 oct = 0; 74 } 75 76 retval = 0; 77 if (rflag) { 78 if (!(fts = fts_open(++argv, 79 oct ? FTS_NOSTAT|FTS_PHYSICAL : FTS_PHYSICAL, 0))) { 80 (void)fprintf(stderr, "chmod: %s.\n", strerror(errno)); 81 exit(1); 82 } 83 while (p = fts_read(fts)) 84 switch(p->fts_info) { 85 case FTS_DNR: 86 (void)fprintf(stderr, 87 "chmod: %s: unable to read.\n", 88 p->fts_path); 89 break; 90 case FTS_DNX: 91 (void)fprintf(stderr, 92 "chmod: %s: unable to search.\n", 93 p->fts_path); 94 break; 95 case FTS_D: 96 case FTS_DC: 97 break; 98 case FTS_ERR: 99 (void)fprintf(stderr, "chmod: %s: %s.\n", 100 p->fts_path, strerror(errno)); 101 exit(1); 102 case FTS_NS: 103 (void)fprintf(stderr, 104 "chmod: %s: unable to stat.\n", 105 p->fts_path); 106 break; 107 default: 108 if (chmod(p->fts_accpath, oct ? omode : 109 getmode(set, p->fts_statb.st_mode)) && 110 !fflag) 111 error(p->fts_path); 112 break; 113 } 114 exit(retval); 115 } 116 if (oct) { 117 while (*++argv) 118 if (chmod(*argv, omode) && !fflag) 119 error(*argv); 120 } else 121 while (*++argv) 122 if ((lstat(*argv, &sb) || 123 chmod(*argv, getmode(set, sb.st_mode))) && !fflag) 124 error(*argv); 125 exit(retval); 126 } 127 128 error(name) 129 char *name; 130 { 131 (void)fprintf(stderr, "chmod: %s: %s.\n", name, strerror(errno)); 132 retval = 1; 133 } 134 135 usage() 136 { 137 (void)fprintf(stderr, "chmod: chmod [-R] mode file ...\n"); 138 exit(1); 139 } 140