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.14 (Berkeley) 05/31/90"; 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++; 45 break; 46 case 'f': 47 fflag++; 48 break; 49 /* "-[rwx]" are valid file modes */ 50 case 'r': 51 case 'w': 52 case 'x': 53 --optind; 54 goto done; 55 case '?': 56 default: 57 usage(); 58 } 59 done: argv += optind; 60 argc -= optind; 61 62 if (argc < 2) 63 usage(); 64 65 mode = *argv; 66 if (*mode >= '0' && *mode <= '7') { 67 omode = (int)strtol(mode, (char **)NULL, 8); 68 oct = 1; 69 } else { 70 if (!(set = setmode(mode))) { 71 (void)fprintf(stderr, "chmod: invalid file mode.\n"); 72 exit(1); 73 } 74 oct = 0; 75 } 76 77 retval = 0; 78 if (rflag) { 79 if (!(fts = ftsopen(++argv, 80 (oct ? FTS_NOSTAT : 0)|FTS_MULTIPLE|FTS_PHYSICAL, 0))) { 81 (void)fprintf(stderr, "chmod: %s.\n", strerror(errno)); 82 exit(1); 83 } 84 while (p = ftsread(fts)) { 85 if (p->fts_info == FTS_D) 86 continue; 87 if (p->fts_info == FTS_ERR) { 88 if (!fflag) 89 error(p->fts_path); 90 continue; 91 } 92 if (chmod(p->fts_accpath, oct ? 93 omode : getmode(set, p->fts_statb.st_mode)) && 94 !fflag) 95 error(p->fts_path); 96 } 97 exit(retval); 98 } 99 if (oct) { 100 while (*++argv) 101 if (chmod(*argv, omode) && !fflag) 102 error(*argv); 103 } else 104 while (*++argv) 105 if ((lstat(*argv, &sb) || 106 chmod(*argv, getmode(set, sb.st_mode))) && !fflag) 107 error(*argv); 108 exit(retval); 109 } 110 111 error(name) 112 char *name; 113 { 114 (void)fprintf(stderr, "chmod: %s: %s.\n", name, strerror(errno)); 115 retval = 1; 116 } 117 118 usage() 119 { 120 (void)fprintf(stderr, "chmod: chmod [-fR] mode file ...\n"); 121 exit(1); 122 } 123