1: /*
2: * Program Name: symcompact.c
3: * Date: December 3, 1994
4: * Author: S.M. Schultz
5: *
6: * ----------------- Modification History ---------------
7: * Version Date Reason For Modification
8: * 1.0 03Dec94 1. Initial release into the public domain.
9: */
10:
11: #include <stdio.h>
12: #include <varargs.h>
13: #include <sys/types.h>
14: #include <fcntl.h>
15: #include <sys/stat.h>
16: #include <sys/dir.h>
17:
18: static char *fmsg = "Can't fchdir() back to starting directory";
19: static int oct, status, fflag, rflag;
20: static u_short set, clear;
21: static struct stat st;
22: static void usage();
23:
24: extern long strtol();
25: extern int optind, errno;
26: extern u_short string_to_flags(); /* from ../ls */
27:
28: main(argc, argv)
29: int argc;
30: char *argv[];
31: {
32: register char *p;
33: char *flags, *ep;
34: int ch, fcurdir;
35: long tmp;
36:
37: while ((ch = getopt(argc, argv, "Rf")) != EOF)
38: {
39: switch (ch)
40: {
41: case 'R':
42: rflag++;
43: break;
44: case 'f':
45: fflag++;
46: break;
47: case '?':
48: default:
49: usage();
50: }
51: }
52: argv += optind;
53: argc += optind;
54: if (argc < 2)
55: usage();
56:
57: flags = *argv++;
58: if (*flags >= '0' && *flags <= '7')
59: {
60: tmp = strtol(flags, &ep, 8);
61: if (tmp < 0 || tmp >= 64L*1024*1024 || *ep)
62: die("invalid flags: %s", flags);
63: oct = 1;
64: set = tmp;
65: }
66: else
67: {
68: if (string_to_flags(&flags, &set, &clear))
69: die("invalid flag: %s", flags);
70: clear = ~clear;
71: oct = 0;
72: }
73:
74: if (rflag)
75: {
76: fcurdir = open(".", O_RDONLY);
77: if (fcurdir < 0)
78: die("Can't open .");
79: }
80:
81: while (p = *argv++)
82: {
83: if (lstat(p, &st) < 0)
84: {
85: status |= warning(p);
86: continue;
87: }
88: if (rflag && (st.st_mode&S_IFMT) == S_IFDIR)
89: {
90: status |= recurse(p, fcurdir);
91: continue;
92: }
93: if ((st.st_mode&S_IFMT) == S_IFLNK && stat(p, &st) < 0)
94: {
95: status |= warning(p);
96: continue;
97: }
98: if (chflags(p, newflags(st.st_flags)) < 0)
99: {
100: status |= warning(p);
101: continue;
102: }
103: }
104: close(fcurdir);
105: exit(status);
106: }
107:
108: recurse(dir, savedir)
109: char *dir;
110: int savedir;
111: {
112: register DIR *dirp;
113: register struct direct *dp;
114: int ecode;
115:
116: if (chdir(dir) < 0)
117: {
118: warning(dir);
119: return(1);
120: }
121: if ((dirp = opendir(".")) == NULL)
122: {
123: warning(dir);
124: return(1);
125: }
126: dp = readdir(dirp);
127: dp = readdir(dirp); /* read "." and ".." */
128: ecode = 0;
129: for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp))
130: {
131: if (lstat(dp->d_name, &st) < 0)
132: {
133: ecode = warning(dp->d_name);
134: if (ecode)
135: break;
136: continue;
137: }
138: if ((st.st_mode&S_IFMT) == S_IFDIR)
139: {
140: ecode = recurse(dp->d_name, dirfd(dirp));
141: if (ecode)
142: break;
143: continue;
144: }
145: if ((st.st_mode&S_IFMT) == S_IFLNK)
146: continue;
147: if (chflags(dp->d_name, newflags(st.st_flags)) < 0 &&
148: (ecode = warning(dp->d_name)))
149: break;
150: }
151: /*
152: * Lastly change the flags on the directory we are in before returning to
153: * the previous level.
154: */
155: if (fstat(dirfd(dirp), &st) < 0)
156: die("can't fstat .");
157: if (fchflags(dirfd(dirp), newflags(st.st_flags)) < 0)
158: ecode = warning(dir);
159: if (fchdir(savedir) < 0)
160: die(fmsg);
161: closedir(dirp);
162: return(ecode);
163: }
164:
165: /* VARARGS1 */
166: die(fmt, va_alist)
167: char *fmt;
168: va_dcl
169: {
170: va_list ap;
171:
172: va_start(ap);
173: vfprintf(stderr, fmt, ap);
174: fputc('\n', stderr);
175: va_end(ap);
176: exit(1);
177: }
178:
179: warning(msg)
180: char *msg;
181: {
182:
183: if (!fflag)
184: fprintf(stderr, "chflags: %s: %s\n", msg, strerror(errno));
185: return(!fflag);
186: }
187:
188: newflags(flags)
189: u_short flags;
190: {
191:
192: if (oct)
193: flags = set;
194: else
195: {
196: flags |= set;
197: flags &= clear;
198: }
199: return(flags);
200: }
201:
202: static void
203: usage()
204: {
205: fputs("usage: chflags [-Rf] flags file ...\n", stderr);
206: exit(1);
207: }
Defined functions
die
defined in line
166; used 5 times
main
defined in line
28;
never used
Defined variables
clear
defined in line
20; used 4 times
fflag
defined in line
19; used 3 times
fmsg
defined in line
18; used 1 times
oct
defined in line
19; used 3 times
rflag
defined in line
19; used 3 times
set
defined in line
20; used 4 times
st
defined in line
21; used 11 times