always die, we can't survive some of the compile errors
[unix-history] / usr / src / usr.bin / chflags / chflags.c
CommitLineData
dc986658 1/*
dde011f0 2 * Copyright (c) 1992 The Regents of the University of California.
dc986658
KM
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8#ifndef lint
9char copyright[] =
dde011f0 10"@(#) Copyright (c) 1992 The Regents of the University of California.\n\
dc986658
KM
11 All rights reserved.\n";
12#endif /* not lint */
13
14#ifndef lint
66375d53 15static char sccsid[] = "@(#)chflags.c 5.3 (Berkeley) %G%";
dc986658
KM
16#endif /* not lint */
17
18#include <sys/types.h>
19#include <sys/stat.h>
dde011f0 20#include <errno.h>
dc986658 21#include <fts.h>
dde011f0 22#include <unistd.h>
dc986658 23#include <stdio.h>
dde011f0 24#include <stdlib.h>
dc986658
KM
25#include <string.h>
26
dde011f0
KB
27typedef struct cmdset {
28 long clrbits;
29 long setbits;
30} CMDS;
31CMDS cmds;
dc986658
KM
32int retval;
33
dde011f0
KB
34void err __P((const char *, ...));
35void error __P((char *));
36int getflags __P((CMDS *, int));
37void *setflags __P((char *));
38void usage __P((void));
39
40int
dc986658
KM
41main(argc, argv)
42 int argc;
dde011f0 43 char *argv[];
dc986658 44{
66375d53 45 register FTS *ftsp;
dc986658 46 register FTSENT *p;
dde011f0
KB
47 register long oflags;
48 register int oct;
dc986658 49 register char *flags;
dc986658 50 struct stat sb;
dde011f0 51 void *set;
66375d53 52 int ch, rflag, hflag, Hflag;
dde011f0 53 char *ep;
66375d53 54 int fts_options;
dc986658 55
66375d53
EA
56 rflag = hflag = Hflag = 0;
57 fts_options = FTS_PHYSICAL;
58 while ((ch = getopt(argc, argv, "HRh")) != EOF)
dc986658 59 switch((char)ch) {
66375d53
EA
60 case 'H':
61 Hflag = 1;
62 fts_options |= FTS_COMFOLLOW;
63 break;
dc986658
KM
64 case 'R':
65 rflag = 1;
66 break;
66375d53
EA
67 case 'h':
68 hflag = 1;
69 fts_options &= ~FTS_PHYSICAL;
70 fts_options |= FTS_LOGICAL;
71 break;
72 case '?':
dc986658
KM
73 default:
74 usage();
75 }
76 argv += optind;
77 argc -= optind;
78
79 if (argc < 2)
80 usage();
81
82 flags = *argv;
83 if (*flags >= '0' && *flags <= '7') {
dde011f0
KB
84 oflags = (int)strtol(flags, &ep, 8);
85 if (oflags < 0 || *ep)
86 err("invalid flags: %s", flags);
87 oct = 1;
dc986658 88 } else {
dde011f0
KB
89 if ((set = setflags(flags)) == NULL)
90 err("invalid flags: %s", flags);
dc986658
KM
91 oct = 0;
92 }
93
94 retval = 0;
66375d53
EA
95 if (oct)
96 fts_options |= FTS_NOSTAT;
97 if (!(ftsp = fts_open(++argv, fts_options , 0)))
98 err("%s", strerror(errno));
99 while (p = fts_read(ftsp))
100 switch(p->fts_info) {
101 case FTS_D:
102 if (!rflag)
103 fts_set(ftsp, p, FTS_SKIP);
104 break;
105 case FTS_DNR:
106 case FTS_ERR:
107 case FTS_NS:
108 err("%s: %s", p->fts_path, strerror(errno));
109 default:
110 if (p->fts_info == FTS_SL &&
111 !(hflag ||
112 (Hflag && p->fts_level == FTS_ROOTLEVEL)))
113 continue;
114 if (chflags(p->fts_accpath, oct ? oflags :
115 getflags(set, p->fts_statp->st_flags)))
116 error(p->fts_path);
117 break;
118 }
dc986658
KM
119 exit(retval);
120}
121
dc986658
KM
122/*
123 * These are analogous to the setmode/getmode routines in the C library.
124 */
dc986658
KM
125void *
126setflags(cp)
127 char *cp;
128{
dde011f0 129 register CMDS *fset;
dc986658
KM
130 register char *arg;
131
132 fset = &cmds;
133 fset->clrbits = 0;
134 fset->setbits = 0;
135 while (cp) {
136 while ((arg = strsep(&cp, ",")) != NULL && *arg == '\0')
137 /* void */;
138 if (!strcasecmp(arg, "dump"))
139 fset->clrbits |= NODUMP;
140 else if (!strcasecmp(arg, "nodump"))
141 fset->setbits |= NODUMP;
142 else
143 return (NULL);
144 }
145 return (fset);
146}
147
dde011f0 148int
dc986658 149getflags(fset, oflags)
dde011f0 150 register CMDS *fset;
dc986658
KM
151 register int oflags;
152{
153
154 oflags &= ~fset->clrbits;
155 oflags |= fset->setbits;
156 return (oflags);
157}
dde011f0
KB
158
159#if __STDC__
160#include <stdarg.h>
161#else
162#include <varargs.h>
163#endif
164
165void
166#if __STDC__
167err(const char *fmt, ...)
168#else
169err(fmt, va_alist)
170 char *fmt;
171 va_dcl
172#endif
173{
174 va_list ap;
175#if __STDC__
176 va_start(ap, fmt);
177#else
178 va_start(ap);
179#endif
180 (void)fprintf(stderr, "chflags: ");
181 (void)vfprintf(stderr, fmt, ap);
182 va_end(ap);
183 (void)fprintf(stderr, "\n");
184 exit(1);
185 /* NOTREACHED */
186}
187
188void
189error(name)
190 char *name;
191{
192 (void)fprintf(stderr, "chflags: %s: %s.\n", name, strerror(errno));
193 retval = 1;
194}
195
196void
197usage()
198{
66375d53 199 (void)fprintf(stderr, "usage: chflags [-HRh] flags file ...\n");
dde011f0
KB
200 exit(1);
201}