View | Details | Raw Unified | Return to bug 143732 | Differences between
and this patch

Collapse All | Expand All

(-)verify.c (-24 / +101 lines)
Lines 47-66 Link Here
47
#include "mtree.h"
47
#include "mtree.h"
48
#include "extern.h"
48
#include "extern.h"
49
49
50
/*
51
 * Error returned when buffer overflows, cannot be 2 as that is reserved for
52
 * MISMATCHEXIT.
53
 */
54
#define BUFFEROVERFLOWEXIT 3
55
50
static NODE *root;
56
static NODE *root;
51
static char path[MAXPATHLEN];
57
static char path[MAXPATHLEN];
52
58
53
static void	miss(NODE *, char *);
59
static int	miss(NODE *, char *, size_t);
60
static int	check(NODE *, char *, size_t);
54
static int	vwalk(void);
61
static int	vwalk(void);
55
62
56
int
63
int
57
mtree_verifyspec(FILE *fi)
64
mtree_verifyspec(FILE *fi)
58
{
65
{
59
	int rval;
66
	int rval = 0;
60
67
61
	root = mtree_readspec(fi);
68
	root = mtree_readspec(fi);
62
	rval = vwalk();
69
	/* No need to walk tree if we are ignoring extra files. */
63
	miss(root, path);
70
	if (!eflag)
71
		rval = vwalk();
72
	*path = '\0';
73
	rval |= miss(root, path, MAXPATHLEN);
74
75
	/* Called here to make sure vwalk() and check() have been called */
76
	if (sflag)
77
		warnx("%s checksum: %lu", fullpath, (unsigned long)crc_total);
78
64
	return (rval);
79
	return (rval);
65
}
80
}
66
81
Lines 135-174 Link Here
135
		if (ep)
150
		if (ep)
136
			continue;
151
			continue;
137
extra:
152
extra:
138
		if (!eflag) {
153
		(void)printf("%s extra", RP(p));
139
			(void)printf("%s extra", RP(p));
154
		if (rflag) {
140
			if (rflag) {
155
			if ((S_ISDIR(p->fts_statp->st_mode)
141
				if ((S_ISDIR(p->fts_statp->st_mode)
156
			    ? rmdir : unlink)(p->fts_accpath)) {
142
				    ? rmdir : unlink)(p->fts_accpath)) {
157
				(void)printf(", not removed: %s",
143
					(void)printf(", not removed: %s",
158
				    strerror(errno));
144
					    strerror(errno));
159
			} else
145
				} else
160
				(void)printf(", removed");
146
					(void)printf(", removed");
147
			}
148
			(void)putchar('\n');
149
		}
161
		}
162
		(void)putchar('\n');
150
		(void)fts_set(t, p, FTS_SKIP);
163
		(void)fts_set(t, p, FTS_SKIP);
151
	}
164
	}
152
	(void)fts_close(t);
165
	(void)fts_close(t);
153
	if (sflag)
154
		warnx("%s checksum: %lu", fullpath, (unsigned long)crc_total);
155
	return (rval);
166
	return (rval);
156
}
167
}
157
168
158
static void
169
static int
159
miss(NODE *p, char *tail)
170
check(NODE *p, char *tail, size_t tail_len)
171
{
172
	FTSENT fts;
173
	struct stat fts_stat;
174
175
	if (strlcpy(tail, p->name, tail_len) >= tail_len)
176
		return (BUFFEROVERFLOWEXIT);
177
178
	/*
179
	 * It is assumed that compare() only requires fts_accpath and fts_statp
180
	 * fields in the FTSENT structure.
181
	 */
182
	fts.fts_accpath = path;
183
	fts.fts_statp = &fts_stat;
184
185
	if (ftsoptions & FTS_LOGICAL) {
186
		if (stat(path, fts.fts_statp) || lstat(path, fts.fts_statp))
187
			return (0);
188
	} else if (lstat(path, fts.fts_statp))
189
		return (0);
190
191
	p->flags |= F_VISIT;
192
	if ((p->flags & F_NOCHANGE) == 0 && compare(p->name, p, &fts))
193
		return (MISMATCHEXIT);
194
	else
195
		return (0);
196
197
	/*
198
	 * tail is not restored to '\0' as the next time tail (or path) is used
199
	 * is with a strlcpy (thus overriding the '\0').
200
	 */
201
}
202
203
static int
204
miss(NODE *p, char *tail, size_t tail_len)
160
{
205
{
161
	int create;
206
	int create;
162
	char *tp;
207
	char *tp;
163
	const char *type, *what;
208
	const char *type, *what;
209
	int rval = 0;
164
	int serr;
210
	int serr;
211
	size_t name_len;
165
212
166
	for (; p; p = p->next) {
213
	for (; p; p = p->next) {
214
		/*
215
		 * if check() needs to be called (eflag set) then directly
216
		 * update nodes if they are not directories and only
217
		 * directories are being checked otherwise check().
218
		 */
219
#if 1
220
		if (tail >= path + MAXPATHLEN)
221
			(void)printf("!!!max path len exceeded!!!");
222
#endif
223
		if (eflag) {
224
			if (dflag && (p->type != F_DIR))
225
				p->flags |= F_VISIT;
226
			else
227
				rval |= check(p, tail, tail_len);
228
		}
229
		/*
230
		 * if check() needs to be called and fails with buffer overflow
231
		 * it is assumed the node cannot be visited as it also cannot
232
		 * exist (due to MAXPATHLEN being exceeded).
233
		 */
167
		if (p->flags & F_OPT && !(p->flags & F_VISIT))
234
		if (p->flags & F_OPT && !(p->flags & F_VISIT))
168
			continue;
235
			continue;
169
		if (p->type != F_DIR && (dflag || p->flags & F_VISIT))
236
		if (p->type != F_DIR && (dflag || p->flags & F_VISIT))
170
			continue;
237
			continue;
171
		(void)strcpy(tail, p->name);
238
		if ((name_len = strlcpy(tail, p->name, tail_len)) >= tail_len) {
239
			(void)printf("%s%s (skipped, buffer overflow)\n", path, p->name);
240
			rval |= BUFFEROVERFLOWEXIT;
241
			continue;
242
		}
172
		if (!(p->flags & F_VISIT)) {
243
		if (!(p->flags & F_VISIT)) {
173
			/* Don't print missing message if file exists as a
244
			/* Don't print missing message if file exists as a
174
			   symbolic link and the -q flag is set. */
245
			   symbolic link and the -q flag is set. */
Lines 228-237 Link Here
228
		if (!(p->flags & F_VISIT))
299
		if (!(p->flags & F_VISIT))
229
			(void)putchar('\n');
300
			(void)putchar('\n');
230
301
231
		for (tp = tail; *tp; ++tp);
302
		if (tail_len - name_len > 1) {
232
		*tp = '/';
303
			tp = tail + name_len;
233
		miss(p->child, tp + 1);
304
			*tp = '/';
234
		*tp = '\0';
305
			rval |= miss(p->child, tp + 1, tail_len - name_len - 1);
306
			*tp = '\0';
307
		} else if (p->child) {
308
			(void)printf("%s (children skipped, buffer overflow)\n", path);
309
			rval |= BUFFEROVERFLOWEXIT;
310
		}
235
311
236
		if (!create)
312
		if (!create)
237
			continue;
313
			continue;
Lines 256-259 Link Here
256
			(void)printf("%s: file flags not set: %s\n",
332
			(void)printf("%s: file flags not set: %s\n",
257
			    path, strerror(errno));
333
			    path, strerror(errno));
258
	}
334
	}
335
	return (rval);
259
}
336
}

Return to bug 143732