Annotation of src/usr.bin/chflags/chflags.c, Revision 1.3
1.3 ! millert 1: /* $OpenBSD: chflags.c,v 1.2 1996/06/26 05:31:52 deraadt Exp $ */
1.1 deraadt 2: /* $NetBSD: chflags.c,v 1.4 1995/03/26 08:49:20 glass Exp $ */
3:
4: /*
5: * Copyright (c) 1992, 1993, 1994
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by the University of
19: * California, Berkeley and its contributors.
20: * 4. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: */
36:
37: #ifndef lint
38: static char copyright[] =
39: "@(#) Copyright (c) 1992, 1993, 1994\n\
40: The Regents of the University of California. All rights reserved.\n";
41: #endif /* not lint */
42:
43: #ifndef lint
44: #if 0
45: static char sccsid[] = "from: @(#)chflags.c 8.5 (Berkeley) 4/1/94";
46: #else
1.3 ! millert 47: static char rcsid[] = "$OpenBSD: chflags.c,v 1.2 1996/06/26 05:31:52 deraadt Exp $";
1.1 deraadt 48: #endif
49: #endif /* not lint */
50:
51: #include <sys/types.h>
52: #include <sys/stat.h>
53:
54: #include <err.h>
55: #include <errno.h>
1.3 ! millert 56: #include <limits.h>
1.1 deraadt 57: #include <fts.h>
58: #include <stdio.h>
59: #include <stdlib.h>
60: #include <string.h>
61: #include <unistd.h>
62:
1.3 ! millert 63: u_int string_to_flags __P((char **, u_int *, u_int *));
1.1 deraadt 64: void usage __P((void));
65:
66: int
67: main(argc, argv)
68: int argc;
69: char *argv[];
70: {
71: FTS *ftsp;
72: FTSENT *p;
1.3 ! millert 73: u_int clear, set;
! 74: u_long val;
1.1 deraadt 75: int Hflag, Lflag, Pflag, Rflag, ch, fts_options, oct, rval;
76: char *flags, *ep;
77:
78: Hflag = Lflag = Pflag = Rflag = 0;
79: while ((ch = getopt(argc, argv, "HLPR")) != -1)
80: switch (ch) {
81: case 'H':
82: Hflag = 1;
83: Lflag = Pflag = 0;
84: break;
85: case 'L':
86: Lflag = 1;
87: Hflag = Pflag = 0;
88: break;
89: case 'P':
90: Pflag = 1;
91: Hflag = Lflag = 0;
92: break;
93: case 'R':
94: Rflag = 1;
95: break;
96: case '?':
97: default:
98: usage();
99: }
100: argv += optind;
101: argc -= optind;
102:
103: if (argc < 2)
104: usage();
105:
106: fts_options = FTS_PHYSICAL;
107: if (Rflag) {
108: if (Hflag)
109: fts_options |= FTS_COMFOLLOW;
110: if (Lflag) {
111: fts_options &= ~FTS_PHYSICAL;
112: fts_options |= FTS_LOGICAL;
113: }
114: }
115:
116: flags = *argv;
117: if (*flags >= '0' && *flags <= '7') {
118: errno = 0;
1.3 ! millert 119: val = strtoul(flags, &ep, 8);
! 120: if (val > UINT_MAX)
1.1 deraadt 121: errno = ERANGE;
122: if (errno)
123: err(1, "invalid flags: %s", flags);
124: if (*ep)
125: errx(1, "invalid flags: %s", flags);
126: set = val;
127: oct = 1;
128: } else {
129: if (string_to_flags(&flags, &set, &clear))
130: errx(1, "invalid flag: %s", flags);
131: clear = ~clear;
132: oct = 0;
133: }
134:
135: if ((ftsp = fts_open(++argv, fts_options , 0)) == NULL)
136: err(1, NULL);
137:
138: for (rval = 0; (p = fts_read(ftsp)) != NULL;) {
139: switch (p->fts_info) {
140: case FTS_D:
141: if (Rflag) /* Change it at FTS_DP. */
142: continue;
143: fts_set(ftsp, p, FTS_SKIP);
144: break;
145: case FTS_DNR: /* Warn, chflag, continue. */
146: warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
147: rval = 1;
148: break;
149: case FTS_ERR: /* Warn, continue. */
150: case FTS_NS:
151: warnx("%s: %s", p->fts_path, strerror(p->fts_errno));
152: rval = 1;
153: continue;
154: case FTS_SL: /* Ignore. */
155: case FTS_SLNONE:
156: /*
157: * The only symlinks that end up here are ones that
158: * don't point to anything and ones that we found
159: * doing a physical walk.
160: */
161: continue;
162: default:
163: break;
164: }
165: if (oct) {
166: if (!chflags(p->fts_accpath, set))
167: continue;
168: } else {
169: p->fts_statp->st_flags |= set;
170: p->fts_statp->st_flags &= clear;
171: if (!chflags(p->fts_accpath, p->fts_statp->st_flags))
172: continue;
173: }
174: warn("%s", p->fts_path);
175: rval = 1;
176: }
177: if (errno)
178: err(1, "fts_read");
179: exit(rval);
180: }
181:
182: void
183: usage()
184: {
185: (void)fprintf(stderr,
186: "usage: chflags [-R [-H | -L | -P]] flags file ...\n");
187: exit(1);
188: }