Added -Hh flags documentation.
[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
dde011f0 15static char sccsid[] = "@(#)chflags.c 5.2 (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{
dc986658
KM
45 register FTS *fts;
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
KB
51 void *set;
52 int ch, rflag;
53 char *ep;
dc986658 54
dde011f0
KB
55 rflag = 0;
56 while ((ch = getopt(argc, argv, "R")) != EOF)
dc986658
KM
57 switch((char)ch) {
58 case 'R':
59 rflag = 1;
60 break;
dc986658
KM
61 case '?':
62 default:
63 usage();
64 }
65 argv += optind;
66 argc -= optind;
67
68 if (argc < 2)
69 usage();
70
71 flags = *argv;
72 if (*flags >= '0' && *flags <= '7') {
dde011f0
KB
73 oflags = (int)strtol(flags, &ep, 8);
74 if (oflags < 0 || *ep)
75 err("invalid flags: %s", flags);
76 oct = 1;
dc986658 77 } else {
dde011f0
KB
78 if ((set = setflags(flags)) == NULL)
79 err("invalid flags: %s", flags);
dc986658
KM
80 oct = 0;
81 }
82
83 retval = 0;
84 if (rflag) {
85 if (!(fts = fts_open(++argv,
dde011f0
KB
86 oct ? FTS_NOSTAT|FTS_PHYSICAL : FTS_PHYSICAL, 0)))
87 err("%s", strerror(errno));
dc986658
KM
88 while (p = fts_read(fts))
89 switch(p->fts_info) {
90 case FTS_D:
91 break;
92 case FTS_DNR:
93 case FTS_ERR:
94 case FTS_NS:
dde011f0 95 err("%s: %s", p->fts_path, strerror(errno));
dc986658
KM
96 default:
97 if (chflags(p->fts_accpath, oct ? oflags :
dde011f0 98 getflags(set, p->fts_statp->st_flags)))
dc986658
KM
99 error(p->fts_path);
100 break;
101 }
102 exit(retval);
103 }
104 if (oct) {
105 while (*++argv)
dde011f0 106 if (chflags(*argv, oflags))
dc986658
KM
107 error(*argv);
108 } else
109 while (*++argv)
dde011f0
KB
110 if (lstat(*argv, &sb) ||
111 chflags(*argv, getflags(set, sb.st_flags)))
dc986658
KM
112 error(*argv);
113 exit(retval);
114}
115
dc986658
KM
116/*
117 * These are analogous to the setmode/getmode routines in the C library.
118 */
dc986658
KM
119void *
120setflags(cp)
121 char *cp;
122{
dde011f0 123 register CMDS *fset;
dc986658
KM
124 register char *arg;
125
126 fset = &cmds;
127 fset->clrbits = 0;
128 fset->setbits = 0;
129 while (cp) {
130 while ((arg = strsep(&cp, ",")) != NULL && *arg == '\0')
131 /* void */;
132 if (!strcasecmp(arg, "dump"))
133 fset->clrbits |= NODUMP;
134 else if (!strcasecmp(arg, "nodump"))
135 fset->setbits |= NODUMP;
136 else
137 return (NULL);
138 }
139 return (fset);
140}
141
dde011f0 142int
dc986658 143getflags(fset, oflags)
dde011f0 144 register CMDS *fset;
dc986658
KM
145 register int oflags;
146{
147
148 oflags &= ~fset->clrbits;
149 oflags |= fset->setbits;
150 return (oflags);
151}
dde011f0
KB
152
153#if __STDC__
154#include <stdarg.h>
155#else
156#include <varargs.h>
157#endif
158
159void
160#if __STDC__
161err(const char *fmt, ...)
162#else
163err(fmt, va_alist)
164 char *fmt;
165 va_dcl
166#endif
167{
168 va_list ap;
169#if __STDC__
170 va_start(ap, fmt);
171#else
172 va_start(ap);
173#endif
174 (void)fprintf(stderr, "chflags: ");
175 (void)vfprintf(stderr, fmt, ap);
176 va_end(ap);
177 (void)fprintf(stderr, "\n");
178 exit(1);
179 /* NOTREACHED */
180}
181
182void
183error(name)
184 char *name;
185{
186 (void)fprintf(stderr, "chflags: %s: %s.\n", name, strerror(errno));
187 retval = 1;
188}
189
190void
191usage()
192{
193 (void)fprintf(stderr, "usage: chflags [-R] flags file ...\n");
194 exit(1);
195}