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