lint
[unix-history] / usr / src / usr.sbin / mtree / verify.c
CommitLineData
0a578b0d
KB
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8#ifndef lint
7e5e86d9 9static char sccsid[] = "@(#)verify.c 5.3 (Berkeley) %G%";
0a578b0d
KB
10#endif /* not lint */
11
cdae27a7 12#include <sys/param.h>
0a578b0d 13#include <sys/stat.h>
0a578b0d 14#include <dirent.h>
cdae27a7 15#include <fts.h>
7e5e86d9 16#include <unistd.h>
cdae27a7 17#include <errno.h>
0a578b0d
KB
18#include <stdio.h>
19#include "mtree.h"
20
21extern ENTRY *root;
0a578b0d 22
cdae27a7 23static char path[MAXPATHLEN];
0a578b0d
KB
24
25verify()
26{
cdae27a7
KB
27 vwalk();
28 miss(root, path);
0a578b0d
KB
29}
30
cdae27a7 31vwalk()
0a578b0d 32{
cdae27a7
KB
33 extern int ftsoptions, dflag, eflag, rflag;
34 register FTS *t;
35 register FTSENT *p;
36 register ENTRY *ep, *level;
0a578b0d 37
cdae27a7
KB
38 if (!(t = ftsopen(".", ftsoptions, (int (*)())NULL))) {
39 (void)fprintf(stderr,
40 "mtree: ftsopen: %s.\n", strerror(errno));
0a578b0d
KB
41 exit(1);
42 }
cdae27a7
KB
43 level = root;
44 while (p = ftsread(t)) {
45 switch(p->fts_info) {
46 case FTS_D:
47 if (!strcmp(p->fts_name, "."))
48 continue;
49 break;
50 case FTS_DC:
51 (void)fprintf(stderr,
52 "mtree: directory cycle: %s.\n", RP(p));
0a578b0d 53 continue;
cdae27a7
KB
54 case FTS_DNR:
55 (void)fprintf(stderr,
56 "mtree: %s: unable to read.\n", RP(p));
0a578b0d 57 continue;
cdae27a7
KB
58 case FTS_DNX:
59 (void)fprintf(stderr,
60 "mtree: %s: unable to search.\n", RP(p));
61 continue;
62 case FTS_DP:
63 for (level = level->parent; level->prev;
64 level = level->prev);
65 continue;
66 case FTS_ERR:
67 (void)fprintf(stderr, "mtree: %s: %s.\n",
68 RP(p), strerror(errno));
69 continue;
70 case FTS_NS:
71 (void)fprintf(stderr,
72 "mtree: can't stat: %s.\n", RP(p));
73 continue;
74 default:
75 if (dflag)
76 continue;
0a578b0d 77 }
cdae27a7
KB
78
79 for (ep = level; ep; ep = ep->next)
7e5e86d9
KB
80 if (ep->flags & F_MAGIC && fnmatch(ep->name,
81 p->fts_name, FNM_PATHNAME|FNM_QUOTE) ||
82 !strcmp(ep->name, p->fts_name)) {
0a578b0d 83 ep->flags |= F_VISIT;
cdae27a7
KB
84 if (ep->info.flags&F_IGN) {
85 (void)ftsset(t, p, FTS_SKIP);
86 continue;
87 }
88 compare(ep->name, &ep->info, p);
89 if (ep->child && ep->info.type == F_DIR &&
90 p->fts_info == FTS_D)
91 level = ep->child;
92 break;
0a578b0d 93 }
cdae27a7
KB
94 if (ep)
95 continue;
96 if (!eflag) {
97 (void)printf("extra: %s", RP(p));
98 if (rflag) {
99 if (unlink(p->fts_accpath)) {
100 (void)printf(", not removed: %s",
101 strerror(errno));
102 } else
103 (void)printf(", removed");
0a578b0d 104 }
cdae27a7 105 (void)putchar('\n');
0a578b0d 106 }
cdae27a7 107 (void)ftsset(t, p, FTS_SKIP);
0a578b0d 108 }
0a578b0d
KB
109}
110
cdae27a7
KB
111miss(p, tail)
112 register ENTRY *p;
0a578b0d
KB
113 register char *tail;
114{
115 extern int dflag, uflag;
116 register int create;
cdae27a7 117 register char *tp;
0a578b0d 118
cdae27a7
KB
119 for (; p; p = p->next) {
120 if (p->info.type != F_DIR && (dflag || p->flags&F_VISIT))
121 continue;
122 (void)strcpy(tail, p->name);
123 if (!(p->flags&F_VISIT))
124 (void)printf("missing: %s", path);
125 if (p->info.type != F_DIR) {
126 putchar('\n');
0a578b0d 127 continue;
cdae27a7
KB
128 }
129
0a578b0d 130 create = 0;
cdae27a7
KB
131 if (!(p->flags&F_VISIT) && uflag)
132#define MINBITS (F_GROUP|F_MODE|F_OWNER)
133 if ((p->info.flags & MINBITS) != MINBITS)
134 (void)printf(" (not created -- group, mode or owner not specified)");
135 else if (mkdir(path, S_IRWXU))
136 (void)printf(" (not created: %s)",
0a578b0d
KB
137 strerror(errno));
138 else {
139 create = 1;
cdae27a7 140 (void)printf(" (created)");
0a578b0d 141 }
0a578b0d 142
cdae27a7
KB
143 if (!(p->flags&F_VISIT))
144 (void)putchar('\n');
0a578b0d 145
cdae27a7
KB
146 for (tp = tail; *tp; ++tp);
147 *tp = '/';
148 miss(p->child, tp + 1);
149 *tp = '\0';
0a578b0d 150
cdae27a7
KB
151 if (!create)
152 continue;
153 if (chown(path, p->info.st_uid, p->info.st_gid)) {
154 (void)printf("%s: owner/group/mode not modified: %s\n",
155 path, strerror(errno));
156 continue;
157 }
158 if (chmod(path, p->info.st_mode))
159 (void)printf("%s: permissions not set: %s\n",
160 path, strerror(errno));
161 }
0a578b0d 162}