Commit | Line | Data |
---|---|---|
dc986658 | 1 | /* |
f49acbb1 | 2 | * Copyright (c) 1992, 1993, 1994 |
13de2e6a | 3 | * The Regents of the University of California. All rights reserved. |
dc986658 KM |
4 | * |
5 | * %sccs.include.redist.c% | |
6 | */ | |
7 | ||
8 | #ifndef lint | |
13de2e6a | 9 | static char copyright[] = |
f49acbb1 | 10 | "@(#) Copyright (c) 1992, 1993, 1994\n\ |
13de2e6a | 11 | The Regents of the University of California. All rights reserved.\n"; |
dc986658 KM |
12 | #endif /* not lint */ |
13 | ||
14 | #ifndef lint | |
77d21b9b | 15 | static char sccsid[] = "@(#)chflags.c 8.4 (Berkeley) %G%"; |
dc986658 KM |
16 | #endif /* not lint */ |
17 | ||
18 | #include <sys/types.h> | |
19 | #include <sys/stat.h> | |
8a499f2f KB |
20 | |
21 | #include <err.h> | |
f49acbb1 | 22 | #include <errno.h> |
dc986658 KM |
23 | #include <fts.h> |
24 | #include <stdio.h> | |
dde011f0 | 25 | #include <stdlib.h> |
dc986658 | 26 | #include <string.h> |
8a499f2f | 27 | #include <unistd.h> |
dc986658 | 28 | |
8a499f2f KB |
29 | u_long string_to_flags __P((char **, u_long *, u_long *)); |
30 | void usage __P((void)); | |
dde011f0 KB |
31 | |
32 | int | |
dc986658 KM |
33 | main(argc, argv) |
34 | int argc; | |
dde011f0 | 35 | char *argv[]; |
dc986658 | 36 | { |
f49acbb1 KB |
37 | FTS *ftsp; |
38 | FTSENT *p; | |
8a499f2f | 39 | u_long clear, set; |
f49acbb1 KB |
40 | long val; |
41 | int Hflag, Lflag, Pflag, Rflag, ch, fts_options, oct, rval; | |
8a499f2f | 42 | char *flags, *ep; |
dc986658 | 43 | |
f49acbb1 KB |
44 | Hflag = Lflag = Pflag = Rflag = 0; |
45 | while ((ch = getopt(argc, argv, "HLPR")) != EOF) | |
46 | switch (ch) { | |
66375d53 EA |
47 | case 'H': |
48 | Hflag = 1; | |
f49acbb1 | 49 | Lflag = Pflag = 0; |
66375d53 | 50 | break; |
f49acbb1 KB |
51 | case 'L': |
52 | Lflag = 1; | |
53 | Hflag = Pflag = 0; | |
dc986658 | 54 | break; |
f49acbb1 KB |
55 | case 'P': |
56 | Pflag = 1; | |
57 | Hflag = Lflag = 0; | |
58 | break; | |
59 | case 'R': | |
60 | Rflag = 1; | |
66375d53 | 61 | break; |
f49acbb1 | 62 | case '?': |
dc986658 KM |
63 | default: |
64 | usage(); | |
65 | } | |
66 | argv += optind; | |
67 | argc -= optind; | |
68 | ||
69 | if (argc < 2) | |
70 | usage(); | |
71 | ||
f49acbb1 KB |
72 | fts_options = FTS_PHYSICAL; |
73 | if (Rflag) { | |
74 | if (Hflag) | |
75 | fts_options |= FTS_COMFOLLOW; | |
76 | if (Lflag) { | |
77 | fts_options &= ~FTS_PHYSICAL; | |
78 | fts_options |= FTS_LOGICAL; | |
79 | } | |
80 | } | |
81 | ||
dc986658 KM |
82 | flags = *argv; |
83 | if (*flags >= '0' && *flags <= '7') { | |
f49acbb1 KB |
84 | errno = 0; |
85 | val = strtol(flags, &ep, 8); | |
86 | if (val < 0) | |
87 | errno = ERANGE; | |
88 | if (errno) | |
89 | err(1, "invalid flags: %s", flags); | |
90 | if (*ep) | |
8a499f2f | 91 | errx(1, "invalid flags: %s", flags); |
f49acbb1 | 92 | set = val; |
dde011f0 | 93 | oct = 1; |
dc986658 | 94 | } else { |
8a499f2f KB |
95 | if (string_to_flags(&flags, &set, &clear)) |
96 | errx(1, "invalid flag: %s", flags); | |
97 | clear = ~clear; | |
dc986658 KM |
98 | oct = 0; |
99 | } | |
100 | ||
8a499f2f | 101 | if ((ftsp = fts_open(++argv, fts_options , 0)) == NULL) |
f49acbb1 | 102 | err(1, NULL); |
8a499f2f | 103 | |
f49acbb1 KB |
104 | for (rval = 0; (p = fts_read(ftsp)) != NULL;) { |
105 | switch (p->fts_info) { | |
66375d53 | 106 | case FTS_D: |
f49acbb1 KB |
107 | if (Rflag) /* Change it at FTS_DP. */ |
108 | continue; | |
109 | fts_set(ftsp, p, FTS_SKIP); | |
66375d53 | 110 | break; |
f49acbb1 KB |
111 | case FTS_DNR: /* Warn, chflag, continue. */ |
112 | errno = p->fts_errno; | |
113 | warn("%s", p->fts_path); | |
114 | rval = 1; | |
115 | break; | |
116 | case FTS_ERR: /* Warn, continue. */ | |
66375d53 | 117 | case FTS_NS: |
f49acbb1 | 118 | errno = p->fts_errno; |
8a499f2f | 119 | warn("%s", p->fts_path); |
f49acbb1 KB |
120 | rval = 1; |
121 | continue; | |
122 | case FTS_SL: /* Ignore. */ | |
123 | case FTS_SLNONE: | |
124 | /* | |
125 | * The only symlinks that end up here are ones that | |
126 | * don't point to anything and ones that we found | |
127 | * doing a physical walk. | |
128 | */ | |
129 | continue; | |
130 | default: | |
66375d53 EA |
131 | break; |
132 | } | |
f49acbb1 KB |
133 | if (oct) { |
134 | if (!chflags(p->fts_accpath, set)) | |
135 | continue; | |
136 | } else { | |
137 | p->fts_statp->st_flags |= set; | |
138 | p->fts_statp->st_flags &= clear; | |
139 | if (!chflags(p->fts_accpath, p->fts_statp->st_flags)) | |
140 | continue; | |
141 | } | |
142 | warn("%s", p->fts_path); | |
143 | rval = 1; | |
144 | } | |
d30ff6d9 KB |
145 | if (errno) |
146 | err(1, "fts_read"); | |
f49acbb1 | 147 | exit(rval); |
dc986658 KM |
148 | } |
149 | ||
dde011f0 KB |
150 | void |
151 | usage() | |
152 | { | |
f49acbb1 KB |
153 | (void)fprintf(stderr, |
154 | "usage: chflags [-R [-H | -L | -P]] flags file ...\n"); | |
dde011f0 KB |
155 | exit(1); |
156 | } |