Commit | Line | Data |
---|---|---|
bcf1365c | 1 | /* |
6aa2c2f8 KB |
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. | |
bcf1365c DF |
16 | */ |
17 | ||
18 | #ifndef lint | |
8cc66a82 | 19 | char copyright[] = |
6aa2c2f8 | 20 | "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ |
8cc66a82 KB |
21 | All rights reserved.\n"; |
22 | #endif /* not lint */ | |
23 | ||
24 | #ifndef lint | |
0f3ab199 | 25 | static char sccsid[] = "@(#)chmod.c 5.13 (Berkeley) %G%"; |
8cc66a82 | 26 | #endif /* not lint */ |
473911a1 | 27 | |
473911a1 KL |
28 | #include <sys/types.h> |
29 | #include <sys/stat.h> | |
6aa2c2f8 KB |
30 | #include <fts.h> |
31 | #include <stdio.h> | |
6ebcb998 | 32 | #include <string.h> |
473911a1 | 33 | |
3600788a | 34 | extern int errno; |
6aa2c2f8 | 35 | int retval; |
473911a1 | 36 | |
3d6dbb93 | 37 | main(argc, argv) |
8cc66a82 KB |
38 | int argc; |
39 | char **argv; | |
473911a1 | 40 | { |
3600788a | 41 | extern int optind; |
6aa2c2f8 KB |
42 | register FTS *fts; |
43 | register FTSENT *p; | |
44 | register int oct, omode; | |
45 | register char *mode; | |
34353049 | 46 | mode_t *set, *setmode(); |
6aa2c2f8 KB |
47 | struct stat sb; |
48 | int ch, fflag, rflag; | |
6aa2c2f8 KB |
49 | |
50 | fflag = rflag = 0; | |
51 | while ((ch = getopt(argc, argv, "Rfrwx")) != EOF) | |
8cc66a82 | 52 | switch((char)ch) { |
3d6dbb93 | 53 | case 'R': |
fe196551 | 54 | rflag++; |
3d6dbb93 | 55 | break; |
3d6dbb93 SL |
56 | case 'f': |
57 | fflag++; | |
58 | break; | |
6aa2c2f8 KB |
59 | /* "-[rwx]" are valid file modes */ |
60 | case 'r': | |
61 | case 'w': | |
62 | case 'x': | |
8cc66a82 | 63 | --optind; |
3d6dbb93 | 64 | goto done; |
6aa2c2f8 KB |
65 | case '?': |
66 | default: | |
67 | usage(); | |
fe196551 | 68 | } |
8cc66a82 KB |
69 | done: argv += optind; |
70 | argc -= optind; | |
71 | ||
6aa2c2f8 KB |
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 { | |
34353049 | 80 | if (!(set = setmode(mode))) { |
6aa2c2f8 KB |
81 | (void)fprintf(stderr, "chmod: invalid file mode.\n"); |
82 | exit(1); | |
83 | } | |
84 | oct = 0; | |
473911a1 | 85 | } |
8cc66a82 | 86 | |
6aa2c2f8 KB |
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); | |
3d6dbb93 | 93 | } |
6aa2c2f8 | 94 | while (p = ftsread(fts)) { |
0f3ab199 | 95 | if (p->fts_info == FTS_D) |
6aa2c2f8 | 96 | continue; |
0f3ab199 | 97 | if (p->fts_info == FTS_ERR) { |
6aa2c2f8 | 98 | if (!fflag) |
0f3ab199 | 99 | error(p->fts_path); |
8cc66a82 | 100 | continue; |
473911a1 | 101 | } |
0f3ab199 KB |
102 | if (chmod(p->fts_accpath, oct ? |
103 | omode : getmode(set, p->fts_statb.st_mode)) && | |
104 | !fflag) | |
105 | error(p->fts_path); | |
473911a1 | 106 | } |
6aa2c2f8 | 107 | exit(retval); |
473911a1 | 108 | } |
6aa2c2f8 KB |
109 | if (oct) { |
110 | while (*++argv) | |
111 | if (chmod(*argv, omode) && !fflag) | |
112 | error(*argv); | |
113 | } else | |
114 | while (*++argv) | |
3600788a | 115 | if ((lstat(*argv, &sb) || |
34353049 | 116 | chmod(*argv, getmode(set, sb.st_mode))) && !fflag) |
6aa2c2f8 KB |
117 | error(*argv); |
118 | exit(retval); | |
473911a1 KL |
119 | } |
120 | ||
6aa2c2f8 KB |
121 | error(name) |
122 | char *name; | |
473911a1 | 123 | { |
6aa2c2f8 KB |
124 | (void)fprintf(stderr, "chmod: %s: %s.\n", name, strerror(errno)); |
125 | retval = 1; | |
473911a1 KL |
126 | } |
127 | ||
6aa2c2f8 | 128 | usage() |
473911a1 | 129 | { |
6aa2c2f8 KB |
130 | (void)fprintf(stderr, "chmod: chmod [-fR] mode file ...\n"); |
131 | exit(1); | |
473911a1 | 132 | } |