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.11 (Berkeley) 04/28/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 extern int errno; 35 int retval; 36 37 main(argc, argv) 38 int argc; 39 char **argv; 40 { 41 extern int optind; 42 register FTS *fts; 43 register FTSENT *p; 44 register int oct, omode; 45 register char *mode; 46 mode_t *set, *setmode(); 47 struct stat sb; 48 int ch, fflag, rflag; 49 50 fflag = rflag = 0; 51 while ((ch = getopt(argc, argv, "Rfrwx")) != EOF) 52 switch((char)ch) { 53 case 'R': 54 rflag++; 55 break; 56 case 'f': 57 fflag++; 58 break; 59 /* "-[rwx]" are valid file modes */ 60 case 'r': 61 case 'w': 62 case 'x': 63 --optind; 64 goto done; 65 case '?': 66 default: 67 usage(); 68 } 69 done: argv += optind; 70 argc -= optind; 71 72 if (argc < 2) 73 usage(); 74 75 mode = *argv; 76 if (*mode >= '0' && *mode <= '7') { 77 omode = (int)strtol(mode, (char **)NULL, 8); 78 oct = 1; 79 } else { 80 if (!(set = setmode(mode))) { 81 (void)fprintf(stderr, "chmod: invalid file mode.\n"); 82 exit(1); 83 } 84 oct = 0; 85 } 86 87 retval = 0; 88 if (rflag) { 89 if (!(fts = ftsopen(++argv, 90 (oct ? FTS_NOSTAT : 0)|FTS_MULTIPLE|FTS_PHYSICAL, 0))) { 91 (void)fprintf(stderr, "chmod: %s.\n", strerror(errno)); 92 exit(1); 93 } 94 while (p = ftsread(fts)) { 95 if (p->info == FTS_D) 96 continue; 97 if (p->info == FTS_ERR) { 98 if (!fflag) 99 error(p->path); 100 continue; 101 } 102 if (chmod(p->accpath, oct ? 103 omode : getmode(set, p->statb.st_mode)) && !fflag) 104 error(p->path); 105 } 106 exit(retval); 107 } 108 if (oct) { 109 while (*++argv) 110 if (chmod(*argv, omode) && !fflag) 111 error(*argv); 112 } else 113 while (*++argv) 114 if ((lstat(*argv, &sb) || 115 chmod(*argv, getmode(set, sb.st_mode))) && !fflag) 116 error(*argv); 117 exit(retval); 118 } 119 120 error(name) 121 char *name; 122 { 123 (void)fprintf(stderr, "chmod: %s: %s.\n", name, strerror(errno)); 124 retval = 1; 125 } 126 127 usage() 128 { 129 (void)fprintf(stderr, "chmod: chmod [-fR] mode file ...\n"); 130 exit(1); 131 } 132