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