1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 char copyright[] = 20 "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ 21 All rights reserved.\n"; 22 #endif /* not lint */ 23 24 #ifndef lint 25 static char sccsid[] = "@(#)chmod.c 5.8 (Berkeley) 01/01/90"; 26 #endif /* not lint */ 27 28 #include <sys/types.h> 29 #include <sys/stat.h> 30 #include <fts.h> 31 #include <stdio.h> 32 #include <strings.h> 33 34 int retval; 35 36 main(argc, argv) 37 int argc; 38 char **argv; 39 { 40 extern int errno, optind; 41 register FTS *fts; 42 register FTSENT *p; 43 register int oct, omode; 44 register char *mode; 45 struct stat sb; 46 int ch, fflag, rflag; 47 mode_t setmode(); 48 49 fflag = rflag = 0; 50 while ((ch = getopt(argc, argv, "Rfrwx")) != EOF) 51 switch((char)ch) { 52 case 'R': 53 rflag++; 54 break; 55 case 'f': 56 fflag++; 57 break; 58 /* "-[rwx]" are valid file modes */ 59 case 'r': 60 case 'w': 61 case 'x': 62 --optind; 63 goto done; 64 case '?': 65 default: 66 usage(); 67 } 68 done: argv += optind; 69 argc -= optind; 70 71 if (argc < 2) 72 usage(); 73 74 mode = *argv; 75 if (*mode >= '0' && *mode <= '7') { 76 omode = (int)strtol(mode, (char **)NULL, 8); 77 oct = 1; 78 } else { 79 if (setmode(mode, 0, 0) == (mode_t)-1) { 80 (void)fprintf(stderr, "chmod: invalid file mode.\n"); 81 exit(1); 82 } 83 oct = 0; 84 } 85 86 retval = 0; 87 if (rflag) { 88 if (!(fts = ftsopen(++argv, 89 (oct ? FTS_NOSTAT : 0)|FTS_MULTIPLE|FTS_PHYSICAL, 0))) { 90 (void)fprintf(stderr, "chmod: %s.\n", strerror(errno)); 91 exit(1); 92 } 93 while (p = ftsread(fts)) { 94 if (p->info == FTS_D) 95 continue; 96 if (p->info == FTS_ERR) { 97 if (!fflag) 98 error(p->path); 99 continue; 100 } 101 if (chmod(p->accpath, oct ? omode : 102 (int)setmode(mode, p->statb.st_mode, 0)) && !fflag) 103 error(p->path); 104 } 105 exit(retval); 106 } 107 if (oct) { 108 while (*++argv) 109 if (chmod(*argv, omode) && !fflag) 110 error(*argv); 111 } else 112 while (*++argv) 113 if ((lstat(*argv, &sb) || chmod(*argv, 114 (int)setmode(mode, sb.st_mode, 0))) && !fflag) 115 error(*argv); 116 exit(retval); 117 } 118 119 error(name) 120 char *name; 121 { 122 (void)fprintf(stderr, "chmod: %s: %s.\n", name, strerror(errno)); 123 retval = 1; 124 } 125 126 usage() 127 { 128 (void)fprintf(stderr, "chmod: chmod [-fR] mode file ...\n"); 129 exit(1); 130 } 131