|
|
1.1 root 1: /*-
2: * Copyright (c) 1990 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[] = "@(#)verify.c 5.7 (Berkeley) 7/1/90";
22: #endif /* not lint */
23:
24: #include <sys/param.h>
25: #include <sys/stat.h>
26: #include <dirent.h>
27: #include <fts.h>
28: #include <unistd.h>
29: #include <errno.h>
30: #include <stdio.h>
31: #include "mtree.h"
32:
33: extern NODE *root;
34:
35: static char path[MAXPATHLEN];
36:
37: verify()
38: {
39: vwalk();
40: miss(root, path);
41: }
42:
43: vwalk()
44: {
45: extern int ftsoptions, dflag, eflag, rflag;
46: register FTS *t;
47: register FTSENT *p;
48: register NODE *ep, *level;
49: char *argv[2];
50: int ftsdepth = 0, specdepth = 0;
51:
52: argv[0] = ".";
53: argv[1] = (char *)NULL;
54: if (!(t = ftsopen(argv, ftsoptions, (int (*)())NULL))) {
55: (void)fprintf(stderr,
56: "mtree: ftsopen: %s.\n", strerror(errno));
57: exit(1);
58: }
59: level = root;
60: while (p = ftsread(t)) {
61: switch(p->fts_info) {
62: case FTS_D:
63: if (!strcmp(p->fts_name, "."))
64: continue;
65: ftsdepth++;
66: break;
67: case FTS_DC:
68: (void)fprintf(stderr,
69: "mtree: directory cycle: %s.\n", RP(p));
70: continue;
71: case FTS_DNR:
72: case FTS_DNX:
73: (void)fprintf(stderr,
74: "mtree: %s: unable to read or search.\n", RP(p));
75: case FTS_DP:
76: ftsdepth--;
77: if (specdepth > ftsdepth) {
78: for (level = level->parent; level->prev;
79: level = level->prev);
80: specdepth--;
81: }
82: continue;
83: case FTS_ERR:
84: (void)fprintf(stderr, "mtree: %s: %s.\n",
85: RP(p), strerror(errno));
86: continue;
87: case FTS_NS:
88: (void)fprintf(stderr,
89: "mtree: can't stat: %s.\n", RP(p));
90: continue;
91: default:
92: if (dflag)
93: continue;
94: }
95:
96: for (ep = level; ep; ep = ep->next)
97: if (ep->flags & F_MAGIC && fnmatch(ep->name,
98: p->fts_name, FNM_PATHNAME|FNM_QUOTE) ||
99: !strcmp(ep->name, p->fts_name)) {
100: ep->flags |= F_VISIT;
101: if (ep->flags & F_IGN) {
102: (void)ftsset(t, p, FTS_SKIP);
103: continue;
104: }
105: compare(ep->name, ep, p);
106: if (ep->child && ep->type == F_DIR &&
107: p->fts_info == FTS_D) {
108: level = ep->child;
109: specdepth++;
110: }
111: break;
112: }
113:
114: if (ep)
115: continue;
116: if (!eflag) {
117: (void)printf("extra: %s", RP(p));
118: if (rflag) {
119: if (unlink(p->fts_accpath)) {
120: (void)printf(", not removed: %s",
121: strerror(errno));
122: } else
123: (void)printf(", removed");
124: }
125: (void)putchar('\n');
126: }
127: (void)ftsset(t, p, FTS_SKIP);
128: }
129: (void)ftsclose(t);
130: }
131:
132: miss(p, tail)
133: register NODE *p;
134: register char *tail;
135: {
136: extern int dflag, uflag;
137: register int create;
138: register char *tp;
139:
140: for (; p; p = p->next) {
141: if (p->type != F_DIR && (dflag || p->flags & F_VISIT))
142: continue;
143: (void)strcpy(tail, p->name);
144: if (!(p->flags & F_VISIT))
145: (void)printf("missing: %s", path);
146: if (p->type != F_DIR) {
147: putchar('\n');
148: continue;
149: }
150:
151: create = 0;
152: if (!(p->flags & F_VISIT) && uflag)
153: #define MINBITS (F_GROUP|F_MODE|F_OWNER)
154: if ((p->flags & MINBITS) != MINBITS)
155: (void)printf(" (not created -- group, mode or owner not specified)");
156: else if (mkdir(path, S_IRWXU))
157: (void)printf(" (not created: %s)",
158: strerror(errno));
159: else {
160: create = 1;
161: (void)printf(" (created)");
162: }
163:
164: if (!(p->flags & F_VISIT))
165: (void)putchar('\n');
166:
167: for (tp = tail; *tp; ++tp);
168: *tp = '/';
169: miss(p->child, tp + 1);
170: *tp = '\0';
171:
172: if (!create)
173: continue;
174: if (chown(path, p->st_uid, p->st_gid)) {
175: (void)printf("%s: owner/group/mode not modified: %s\n",
176: path, strerror(errno));
177: continue;
178: }
179: if (chmod(path, p->st_mode))
180: (void)printf("%s: permissions not set: %s\n",
181: path, strerror(errno));
182: }
183: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.