|
|
1.1 root 1: /*-
2: * Copyright (c) 1989 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted provided
6: * that: (1) source distributions retain this entire copyright notice and
7: * comment, and (2) distributions including binaries display the following
8: * acknowledgement: ``This product includes software developed by the
9: * University of California, Berkeley and its contributors'' in the
10: * documentation or other materials provided with the distribution and in
11: * all advertising materials mentioning features or use of this software.
12: * Neither the name of the University nor the names of its contributors may
13: * be used to endorse or promote products derived from this software without
14: * specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: static char sccsid[] = "@(#)spec.c 5.12 (Berkeley) 5/25/90";
22: #endif /* not lint */
23:
24: #include <sys/types.h>
25: #include <pwd.h>
26: #include <grp.h>
27: #include <stdio.h>
28: #include <errno.h>
29: #include <ctype.h>
30: #include "mtree.h"
31:
32: extern NODE *root; /* root of the tree */
33:
34: static int lineno; /* current spec line number */
35:
36: spec()
37: {
38: register NODE *centry, *last;
39: register char *p;
40: NODE ginfo, *emalloc();
41: char buf[2048];
42:
43: bzero((void *)&ginfo, sizeof(ginfo));
44: for (lineno = 1; fgets(buf, sizeof(buf), stdin); ++lineno) {
45: if (!(p = index(buf, '\n'))) {
46: (void)fprintf(stderr,
47: "mtree: line %d too long, ignored.\n", lineno);
48: exit(1);
49: }
50: *p = '\0';
51: for (p = buf; *p && isspace(*p); ++p);
52: if (!*p || *p == '#')
53: continue;
54:
55: /* grab file name, "$", "set", or "unset" */
56: if (!(p = strtok(p, "\n\t ")))
57: specerr();
58:
59: if (p[0] == '/')
60: switch(p[1]) {
61: case 's':
62: if (strcmp(p + 1, "set"))
63: break;
64: set(&ginfo);
65: continue;
66: case 'u':
67: if (strncmp(p + 1, "unset"))
68: break;
69: unset(&ginfo);
70: continue;
71: }
72:
73: if (index(p, '/')) {
74: (void)fprintf(stderr,
75: "mtree: file names may not contain slashes.\n");
76: specerr();
77: }
78:
79: if (!strcmp(p, "..")) {
80: /* don't go up, if haven't gone down */
81: if (!root)
82: noparent();
83: if (last->type != F_DIR || last->flags & F_DONE) {
84: if (last == root)
85: noparent();
86: last = last->parent;
87: }
88: last->flags |= F_DONE;
89: continue;
90: }
91:
92: centry = emalloc(sizeof(NODE) + strlen(p));
93: *centry = ginfo;
94: (void)strcpy(centry->name, p);
95: #define MAGIC "?*["
96: if (strpbrk(p, MAGIC))
97: centry->flags |= F_MAGIC;
98: set(centry);
99:
100: if (!root) {
101: last = root = centry;
102: root->parent = root;
103: } else if (last->type == F_DIR && !(last->flags & F_DONE)) {
104: centry->parent = last;
105: last = last->child = centry;
106: } else {
107: centry->parent = last->parent;
108: centry->prev = last;
109: last = last->next = centry;
110: }
111: }
112: }
113:
114: set(ip)
115: register NODE *ip;
116: {
117: register int type;
118: register char *kw, *val;
119: gid_t getgroup();
120: uid_t getowner();
121: long atol(), strtol();
122:
123: while (kw = strtok((char *)NULL, "= \t\n")) {
124: ip->flags |= type = key(kw);
125: val = strtok((char *)NULL, " \t\n");
126: if (!val)
127: specerr();
128: switch(type) {
129: case F_CKSUM:
130: ip->cksum = atol(val);
131: break;
132: case F_GROUP:
133: ip->st_gid = getgroup(val);
134: break;
135: case F_IGN:
136: /* just set flag bit */
137: break;
138: case F_MODE: {
139: mode_t *m, *setmode();
140:
141: if (!(m = setmode(val))) {
142: (void)fprintf(stderr,
143: "mtree: invalid file mode %s.\n", val);
144: specerr();
145: }
146: ip->st_mode = getmode(m, 0);
147: break;
148: }
149: case F_NLINK:
150: ip->st_nlink = atoi(val);
151: break;
152: case F_OWNER:
153: ip->st_uid = getowner(val);
154: break;
155: case F_SIZE:
156: ip->st_size = atol(val);
157: break;
158: case F_SLINK:
159: if (!(ip->slink = strdup(val)))
160: nomem();
161: break;
162: case F_TIME:
163: ip->st_mtime = atol(val);
164: break;
165: case F_TYPE:
166: switch(*val) {
167: case 'b':
168: if (!strcmp(val, "block"))
169: ip->type = F_BLOCK;
170: break;
171: case 'c':
172: if (!strcmp(val, "char"))
173: ip->type = F_CHAR;
174: break;
175: case 'd':
176: if (!strcmp(val, "dir"))
177: ip->type = F_DIR;
178: break;
179: case 'f':
180: if (!strcmp(val, "file"))
181: ip->type = F_FILE;
182: if (!strcmp(val, "fifo"))
183: ip->type = F_FIFO;
184: break;
185: case 'l':
186: if (!strcmp(val, "link"))
187: ip->type = F_LINK;
188: break;
189: case 's':
190: if (!strcmp(val, "socket"))
191: ip->type = F_SOCK;
192: break;
193: default:
194: (void)fprintf(stderr,
195: "mtree: unknown file type %s.\n", val);
196: specerr();
197: }
198: break;
199: }
200: }
201: }
202:
203: unset(ip)
204: register NODE *ip;
205: {
206: register char *p;
207:
208: while (p = strtok((char *)NULL, "\n\t "))
209: ip->flags &= ~key(p);
210: }
211:
212: key(p)
213: char *p;
214: {
215: switch(*p) {
216: case 'c':
217: if (!strcmp(p, "cksum"))
218: return(F_CKSUM);
219: break;
220: case 'g':
221: if (!strcmp(p, "group"))
222: return(F_GROUP);
223: break;
224: case 'i':
225: if (!strcmp(p, "ignore"))
226: return(F_IGN);
227: break;
228: case 'l':
229: if (!strcmp(p, "link"))
230: return(F_SLINK);
231: break;
232: case 'm':
233: if (!strcmp(p, "mode"))
234: return(F_MODE);
235: break;
236: case 'n':
237: if (!strcmp(p, "nlink"))
238: return(F_NLINK);
239: break;
240: case 'o':
241: if (!strcmp(p, "owner"))
242: return(F_OWNER);
243: break;
244: case 's':
245: if (!strcmp(p, "size"))
246: return(F_SIZE);
247: break;
248: case 't':
249: if (!strcmp(p, "type"))
250: return(F_TYPE);
251: if (!strcmp(p, "time"))
252: return(F_TIME);
253: break;
254: }
255: (void)fprintf(stderr, "mtree: unknown keyword %s.\n", p);
256: specerr();
257: /* NOTREACHED */
258: }
259:
260:
261: uid_t
262: getowner(p)
263: register char *p;
264: {
265: struct passwd *pw;
266: int val;
267:
268: if (isdigit(*p)) {
269: if ((val = atoi(p)) >= 0)
270: return((uid_t)val);
271: (void)fprintf(stderr, "mtree: illegal uid value %s.\n", p);
272: } else if (pw = getpwnam(p))
273: return(pw->pw_uid);
274: else
275: (void)fprintf(stderr, "mtree: unknown user %s.\n", p);
276: specerr();
277: /* NOTREACHED */
278: }
279:
280: gid_t
281: getgroup(p)
282: register char *p;
283: {
284: struct group *gr;
285: int val;
286:
287: if (isdigit(*p)) {
288: if ((val = atoi(p)) >= 0)
289: return((gid_t)val);
290: (void)fprintf(stderr, "mtree: illegal gid value %s.\n", p);
291: } else if (gr = getgrnam(p))
292: return(gr->gr_gid);
293: else
294: (void)fprintf(stderr, "mtree: unknown group %s.\n", p);
295: specerr();
296: /* NOTREACHED */
297: }
298:
299: noparent()
300: {
301: (void)fprintf(stderr, "mtree: no parent node.\n");
302: specerr();
303: }
304:
305: specerr()
306: {
307: (void)fprintf(stderr,
308: "mtree: line %d of the specification is incorrect.\n", lineno);
309: exit(1);
310: }
311:
312: NODE *
313: emalloc(size)
314: int size;
315: {
316: void *p;
317:
318: /* NOSTRICT */
319: if (!(p = malloc((u_int)size)))
320: nomem();
321: bzero(p, size);
322: return((NODE *)p);
323: }
324:
325: nomem()
326: {
327: (void)fprintf(stderr, "mtree: %s.\n", strerror(ENOMEM));
328: exit(1);
329: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.