Commit | Line | Data |
---|---|---|
bcf1365c | 1 | /* |
6aa2c2f8 KB |
2 | * Copyright (c) 1989 The Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
27c71911 | 5 | * %sccs.include.redist.c% |
bcf1365c DF |
6 | */ |
7 | ||
8 | #ifndef lint | |
8cc66a82 | 9 | char copyright[] = |
6aa2c2f8 | 10 | "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ |
8cc66a82 KB |
11 | All rights reserved.\n"; |
12 | #endif /* not lint */ | |
13 | ||
14 | #ifndef lint | |
834beb60 | 15 | static char sccsid[] = "@(#)chmod.c 5.21 (Berkeley) %G%"; |
8cc66a82 | 16 | #endif /* not lint */ |
473911a1 | 17 | |
473911a1 KL |
18 | #include <sys/types.h> |
19 | #include <sys/stat.h> | |
a22be226 | 20 | #include <errno.h> |
6aa2c2f8 | 21 | #include <fts.h> |
a22be226 | 22 | #include <unistd.h> |
6aa2c2f8 | 23 | #include <stdio.h> |
a22be226 | 24 | #include <stdlib.h> |
6ebcb998 | 25 | #include <string.h> |
473911a1 | 26 | |
6aa2c2f8 | 27 | int retval; |
473911a1 | 28 | |
a22be226 KB |
29 | void err __P((const char *, ...)); |
30 | void error __P((char *)); | |
31 | void usage __P((void)); | |
32 | ||
33 | int | |
3d6dbb93 | 34 | main(argc, argv) |
8cc66a82 | 35 | int argc; |
a22be226 | 36 | char *argv[]; |
473911a1 | 37 | { |
6aa2c2f8 KB |
38 | register FTS *fts; |
39 | register FTSENT *p; | |
40 | register int oct, omode; | |
6aa2c2f8 | 41 | struct stat sb; |
a22be226 | 42 | mode_t *set; |
6aa2c2f8 | 43 | int ch, fflag, rflag; |
a22be226 | 44 | char *ep, *mode; |
6aa2c2f8 KB |
45 | |
46 | fflag = rflag = 0; | |
47 | while ((ch = getopt(argc, argv, "Rfrwx")) != EOF) | |
8cc66a82 | 48 | switch((char)ch) { |
3d6dbb93 | 49 | case 'R': |
36c26652 | 50 | rflag = 1; |
3d6dbb93 | 51 | break; |
36c26652 KB |
52 | case 'f': /* no longer documented */ |
53 | fflag = 1; | |
3d6dbb93 | 54 | break; |
36c26652 | 55 | case 'r': /* "-[rwx]" are valid file modes */ |
6aa2c2f8 KB |
56 | case 'w': |
57 | case 'x': | |
8cc66a82 | 58 | --optind; |
3d6dbb93 | 59 | goto done; |
6aa2c2f8 KB |
60 | case '?': |
61 | default: | |
62 | usage(); | |
fe196551 | 63 | } |
8cc66a82 KB |
64 | done: argv += optind; |
65 | argc -= optind; | |
66 | ||
6aa2c2f8 KB |
67 | if (argc < 2) |
68 | usage(); | |
69 | ||
70 | mode = *argv; | |
71 | if (*mode >= '0' && *mode <= '7') { | |
a22be226 KB |
72 | omode = (int)strtol(mode, &ep, 8); |
73 | if (omode < 0 || *ep) | |
74 | err("invalid file mode: %s", mode); | |
6aa2c2f8 KB |
75 | oct = 1; |
76 | } else { | |
a22be226 KB |
77 | if (!(set = setmode(mode))) |
78 | err("invalid file mode: %s", mode); | |
6aa2c2f8 | 79 | oct = 0; |
473911a1 | 80 | } |
8cc66a82 | 81 | |
6aa2c2f8 KB |
82 | retval = 0; |
83 | if (rflag) { | |
a22be226 KB |
84 | if ((fts = fts_open(++argv, |
85 | oct ? FTS_NOSTAT|FTS_PHYSICAL : FTS_PHYSICAL, 0)) == NULL) | |
86 | err("%s", strerror(errno)); | |
c19052a5 KB |
87 | while (p = fts_read(fts)) |
88 | switch(p->fts_info) { | |
c19052a5 | 89 | case FTS_D: |
c19052a5 | 90 | break; |
28234b31 | 91 | case FTS_DNR: |
c19052a5 | 92 | case FTS_ERR: |
28234b31 | 93 | case FTS_NS: |
a22be226 | 94 | err("%s: %s", p->fts_path, strerror(errno)); |
c19052a5 KB |
95 | default: |
96 | if (chmod(p->fts_accpath, oct ? omode : | |
834beb60 | 97 | getmode(set, p->fts_statp->st_mode)) && |
c19052a5 | 98 | !fflag) |
0f3ab199 | 99 | error(p->fts_path); |
c19052a5 | 100 | break; |
473911a1 | 101 | } |
6aa2c2f8 | 102 | exit(retval); |
473911a1 | 103 | } |
6aa2c2f8 KB |
104 | if (oct) { |
105 | while (*++argv) | |
106 | if (chmod(*argv, omode) && !fflag) | |
107 | error(*argv); | |
108 | } else | |
109 | while (*++argv) | |
3600788a | 110 | if ((lstat(*argv, &sb) || |
34353049 | 111 | chmod(*argv, getmode(set, sb.st_mode))) && !fflag) |
6aa2c2f8 KB |
112 | error(*argv); |
113 | exit(retval); | |
473911a1 KL |
114 | } |
115 | ||
a22be226 | 116 | void |
6aa2c2f8 KB |
117 | error(name) |
118 | char *name; | |
473911a1 | 119 | { |
a22be226 | 120 | (void)fprintf(stderr, "chmod: %s: %s\n", name, strerror(errno)); |
6aa2c2f8 | 121 | retval = 1; |
473911a1 KL |
122 | } |
123 | ||
a22be226 | 124 | void |
6aa2c2f8 | 125 | usage() |
473911a1 | 126 | { |
a22be226 KB |
127 | (void)fprintf(stderr, "usage: chmod [-R] mode file ...\n"); |
128 | exit(1); | |
129 | } | |
130 | ||
131 | #if __STDC__ | |
132 | #include <stdarg.h> | |
133 | #else | |
134 | #include <varargs.h> | |
135 | #endif | |
136 | ||
137 | void | |
138 | #if __STDC__ | |
139 | err(const char *fmt, ...) | |
140 | #else | |
141 | err(fmt, va_alist) | |
142 | char *fmt; | |
143 | va_dcl | |
144 | #endif | |
145 | { | |
146 | va_list ap; | |
147 | #if __STDC__ | |
148 | va_start(ap, fmt); | |
149 | #else | |
150 | va_start(ap); | |
151 | #endif | |
152 | (void)fprintf(stderr, "chmod: "); | |
153 | (void)vfprintf(stderr, fmt, ap); | |
154 | va_end(ap); | |
155 | (void)fprintf(stderr, "\n"); | |
6aa2c2f8 | 156 | exit(1); |
a22be226 | 157 | /* NOTREACHED */ |
473911a1 | 158 | } |