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 |
} |