1 |
vapier 11/10/03 03:18:11 |
2 |
|
3 |
Modified: qcheck.c |
4 |
Log: |
5 |
rewrite qcheck to use *at style funcs |
6 |
|
7 |
Revision Changes Path |
8 |
1.50 portage-utils/qcheck.c |
9 |
|
10 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?rev=1.50&view=markup |
11 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?rev=1.50&content-type=text/plain |
12 |
diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?r1=1.49&r2=1.50 |
13 |
|
14 |
Index: qcheck.c |
15 |
=================================================================== |
16 |
RCS file: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v |
17 |
retrieving revision 1.49 |
18 |
retrieving revision 1.50 |
19 |
diff -u -r1.49 -r1.50 |
20 |
--- qcheck.c 3 Oct 2011 01:25:54 -0000 1.49 |
21 |
+++ qcheck.c 3 Oct 2011 03:18:10 -0000 1.50 |
22 |
@@ -1,7 +1,7 @@ |
23 |
/* |
24 |
* Copyright 2005-2010 Gentoo Foundation |
25 |
* Distributed under the terms of the GNU General Public License v2 |
26 |
- * $Header: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v 1.49 2011/10/03 01:25:54 vapier Exp $ |
27 |
+ * $Header: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v 1.50 2011/10/03 03:18:10 vapier Exp $ |
28 |
* |
29 |
* Copyright 2005-2010 Ned Ludd - <solar@g.o> |
30 |
* Copyright 2005-2010 Mike Frysinger - <vapier@g.o> |
31 |
@@ -34,11 +34,11 @@ |
32 |
"Undo prelink when calculating checksums", |
33 |
COMMON_OPTS_HELP |
34 |
}; |
35 |
-static const char qcheck_rcsid[] = "$Id: qcheck.c,v 1.49 2011/10/03 01:25:54 vapier Exp $"; |
36 |
+static const char qcheck_rcsid[] = "$Id: qcheck.c,v 1.50 2011/10/03 03:18:10 vapier Exp $"; |
37 |
#define qcheck_usage(ret) usage(ret, QCHECK_FLAGS, qcheck_long_opts, qcheck_opts_help, lookup_applet_idx("qcheck")) |
38 |
|
39 |
-short bad_only = 0; |
40 |
-#define qcprintf(fmt, args...) if (!bad_only) printf( _( fmt ), ## args) |
41 |
+static bool bad_only = false; |
42 |
+#define qcprintf(fmt, args...) if (!bad_only) printf(_(fmt), ## args) |
43 |
|
44 |
static void qcheck_cleanup(regex_t **regex_head, const size_t regex_count) |
45 |
{ |
46 |
@@ -54,21 +54,242 @@ |
47 |
free(regex_head); |
48 |
} |
49 |
|
50 |
+static int qcheck_process_contents(int portroot_fd, int pkg_fd, |
51 |
+ const char *catname, const char *pkgname, regex_t **regex_head, |
52 |
+ size_t regex_count, bool qc_update, bool chk_afk, |
53 |
+ bool chk_hash, bool chk_mtime, bool undo_prelink) |
54 |
+{ |
55 |
+ int fd; |
56 |
+ FILE *fp, *fpx; |
57 |
+ size_t num_files, num_files_ok, num_files_unknown, num_files_ignored; |
58 |
+ char *buffer, *line; |
59 |
+ size_t linelen; |
60 |
+ struct stat st, cst; |
61 |
+ |
62 |
+ fpx = NULL; |
63 |
+ |
64 |
+ fd = openat(pkg_fd, "CONTENTS", O_RDONLY|O_CLOEXEC); |
65 |
+ if (fd == -1) |
66 |
+ return EXIT_SUCCESS; |
67 |
+ if (fstat(fd, &cst)) { |
68 |
+ close(fd); |
69 |
+ return EXIT_SUCCESS; |
70 |
+ } |
71 |
+ if ((fp = fdopen(fd, "r")) == NULL) { |
72 |
+ close(fd); |
73 |
+ return EXIT_SUCCESS; |
74 |
+ } |
75 |
+ |
76 |
+ num_files = num_files_ok = num_files_unknown = num_files_ignored = 0; |
77 |
+ qcprintf("%sing %s%s/%s%s ...\n", |
78 |
+ (qc_update ? "Updat" : "Check"), |
79 |
+ GREEN, catname, pkgname, NORM); |
80 |
+ if (qc_update) { |
81 |
+ fd = openat(pkg_fd, "CONTENTS~", O_RDWR|O_CLOEXEC|O_CREAT|O_TRUNC, 0644); |
82 |
+ if (fd == -1 || (fpx = fdopen(fd, "w")) == NULL) { |
83 |
+ fclose(fp); |
84 |
+ warnp("unable to fopen(%s/%s, w)", pkgname, "CONTENTS~"); |
85 |
+ return EXIT_FAILURE; |
86 |
+ } |
87 |
+ } |
88 |
+ |
89 |
+ buffer = line = NULL; |
90 |
+ while (getline(&line, &linelen, fp) != -1) { |
91 |
+ contents_entry *e; |
92 |
+ free(buffer); |
93 |
+ buffer = xstrdup(line); |
94 |
+ e = contents_parse_line(line); |
95 |
+ if (!e) |
96 |
+ continue; |
97 |
+ |
98 |
+ /* run our little checks */ |
99 |
+ ++num_files; |
100 |
+ if (regex_count) { |
101 |
+ size_t j; |
102 |
+ for (j = 0; j < regex_count; ++j) |
103 |
+ if (!regexec(regex_head[j], e->name, 0, NULL, 0)) |
104 |
+ break; |
105 |
+ if (j < regex_count) { |
106 |
+ --num_files; |
107 |
+ ++num_files_ignored; |
108 |
+ continue; |
109 |
+ } |
110 |
+ } |
111 |
+ if (fstatat(portroot_fd, e->name + 1, &st, AT_SYMLINK_NOFOLLOW)) { |
112 |
+ /* make sure file exists */ |
113 |
+ if (chk_afk) { |
114 |
+ qcprintf(" %sAFK%s: %s\n", RED, NORM, e->name); |
115 |
+ } else { |
116 |
+ --num_files; |
117 |
+ ++num_files_ignored; |
118 |
+ if (qc_update) |
119 |
+ fputs(buffer, fpx); |
120 |
+ } |
121 |
+ continue; |
122 |
+ } |
123 |
+ if (e->digest && S_ISREG(st.st_mode)) { |
124 |
+ /* validate digest (handles MD5 / SHA1) */ |
125 |
+ uint8_t hash_algo; |
126 |
+ char *hashed_file; |
127 |
+ hash_cb_t hash_cb = undo_prelink ? hash_cb_prelink_undo : hash_cb_default; |
128 |
+ switch (strlen(e->digest)) { |
129 |
+ case 32: hash_algo = HASH_MD5; break; |
130 |
+ case 40: hash_algo = HASH_SHA1; break; |
131 |
+ default: hash_algo = 0; break; |
132 |
+ } |
133 |
+ if (!hash_algo) { |
134 |
+ if (chk_hash) { |
135 |
+ qcprintf(" %sUNKNOWN DIGEST%s: '%s' for '%s'\n", RED, NORM, e->digest, e->name); |
136 |
+ ++num_files_unknown; |
137 |
+ } else { |
138 |
+ --num_files; |
139 |
+ ++num_files_ignored; |
140 |
+ if (qc_update) |
141 |
+ fputs(buffer, fpx); |
142 |
+ } |
143 |
+ continue; |
144 |
+ } |
145 |
+ hashed_file = (char*)hash_file_cb(e->name, hash_algo, hash_cb); |
146 |
+ if (!hashed_file) { |
147 |
+ ++num_files_unknown; |
148 |
+ free(hashed_file); |
149 |
+ if (qc_update) { |
150 |
+ fputs(buffer, fpx); |
151 |
+ if (!verbose) |
152 |
+ continue; |
153 |
+ } |
154 |
+ qcprintf(" %sPERM %4o%s: %s\n", RED, (unsigned int)(st.st_mode & 07777), NORM, e->name); |
155 |
+ continue; |
156 |
+ } else if (strcmp(e->digest, hashed_file)) { |
157 |
+ if (chk_hash) { |
158 |
+ const char *digest_disp; |
159 |
+ if (qc_update) |
160 |
+ fprintf(fpx, "obj %s %s %lu\n", e->name, hashed_file, st.st_mtime); |
161 |
+ switch (hash_algo) { |
162 |
+ case HASH_MD5: digest_disp = "MD5"; break; |
163 |
+ case HASH_SHA1: digest_disp = "SHA1"; break; |
164 |
+ default: digest_disp = "UNK"; break; |
165 |
+ } |
166 |
+ qcprintf(" %s%s-DIGEST%s: %s", RED, digest_disp, NORM, e->name); |
167 |
+ if (verbose) |
168 |
+ qcprintf(" (recorded '%s' != actual '%s')", e->digest, hashed_file); |
169 |
+ qcprintf("\n"); |
170 |
+ } else { |
171 |
+ --num_files; |
172 |
+ ++num_files_ignored; |
173 |
+ if (qc_update) |
174 |
+ fputs(buffer, fpx); |
175 |
+ } |
176 |
+ free(hashed_file); |
177 |
+ continue; |
178 |
+ } else if (e->mtime && e->mtime != st.st_mtime) { |
179 |
+ if (chk_mtime) { |
180 |
+ qcprintf(" %sMTIME%s: %s", RED, NORM, e->name); |
181 |
+ if (verbose) |
182 |
+ qcprintf(" (recorded '%lu' != actual '%lu')", e->mtime, (unsigned long)st.st_mtime); |
183 |
+ qcprintf("\n"); |
184 |
+ |
185 |
+ /* This can only be an obj, dir and sym have no digest */ |
186 |
+ if (qc_update) |
187 |
+ fprintf(fpx, "obj %s %s %lu\n", e->name, e->digest, st.st_mtime); |
188 |
+ } else { |
189 |
+ --num_files; |
190 |
+ ++num_files_ignored; |
191 |
+ if (qc_update) |
192 |
+ fputs(buffer, fpx); |
193 |
+ } |
194 |
+ free(hashed_file); |
195 |
+ continue; |
196 |
+ } else { |
197 |
+ if (qc_update) |
198 |
+ fputs(buffer, fpx); |
199 |
+ free(hashed_file); |
200 |
+ } |
201 |
+ } else if (e->mtime && e->mtime != st.st_mtime) { |
202 |
+ if (chk_mtime) { |
203 |
+ qcprintf(" %sMTIME%s: %s", RED, NORM, e->name); |
204 |
+ if (verbose) |
205 |
+ qcprintf(" (recorded '%lu' != actual '%lu')", e->mtime, (unsigned long)st.st_mtime); |
206 |
+ qcprintf("\n"); |
207 |
+ |
208 |
+ /* This can only be a sym */ |
209 |
+ if (qc_update) |
210 |
+ fprintf(fpx, "sym %s -> %s %lu\n", e->name, e->sym_target, st.st_mtime); |
211 |
+ } else { |
212 |
+ --num_files; |
213 |
+ ++num_files_ignored; |
214 |
+ if (qc_update) |
215 |
+ fputs(buffer, fpx); |
216 |
+ } |
217 |
+ continue; |
218 |
+ } else { |
219 |
+ if (qc_update) |
220 |
+ fputs(buffer, fpx); |
221 |
+ } |
222 |
+ ++num_files_ok; |
223 |
+ } |
224 |
+ free(line); |
225 |
+ free(buffer); |
226 |
+ fclose(fp); |
227 |
+ |
228 |
+ if (qc_update) { |
229 |
+ if (fchown(fd, cst.st_uid, cst.st_gid)) |
230 |
+ /* meh */; |
231 |
+ if (fchmod(fd, cst.st_mode)) |
232 |
+ /* meh */; |
233 |
+ fclose(fpx); |
234 |
+ if (renameat(pkg_fd, "CONTENTS~", pkg_fd, "CONTENTS")) |
235 |
+ unlinkat(pkg_fd, "CONTENTS~", 0); |
236 |
+ if (!verbose) |
237 |
+ return EXIT_SUCCESS; |
238 |
+ } |
239 |
+ if (bad_only && num_files_ok != num_files) { |
240 |
+ if (verbose) |
241 |
+ printf("%s/%s\n", catname, pkgname); |
242 |
+ else { |
243 |
+ depend_atom *atom = NULL; |
244 |
+ char *buf; |
245 |
+ xasprintf(&buf, "%s/%s", catname, pkgname); |
246 |
+ if ((atom = atom_explode(buf)) != NULL) { |
247 |
+ printf("%s/%s\n", catname, atom->PN); |
248 |
+ atom_implode(atom); |
249 |
+ } else { |
250 |
+ printf("%s/%s\n", catname, pkgname); |
251 |
+ } |
252 |
+ free(buf); |
253 |
+ } |
254 |
+ } |
255 |
+ qcprintf(" %2$s*%1$s %3$s%4$zu%1$s out of %3$s%5$zu%1$s file%6$s are good", |
256 |
+ NORM, BOLD, BLUE, num_files_ok, num_files, |
257 |
+ (num_files > 1 ? "s" : "")); |
258 |
+ if (num_files_unknown) |
259 |
+ qcprintf(" (Unable to digest %2$s%3$zu%1$s file%4$s)", |
260 |
+ NORM, BLUE, num_files_unknown, |
261 |
+ (num_files_unknown > 1 ? "s" : "")); |
262 |
+ if (num_files_ignored) |
263 |
+ qcprintf(" (%2$s%3$zu%1$s file%4$s ignored)", |
264 |
+ NORM, BLUE, num_files_ignored, |
265 |
+ (num_files_ignored > 1 ? "s were" : " was")); |
266 |
+ qcprintf("\n"); |
267 |
+ |
268 |
+ if (num_files_ok != num_files) |
269 |
+ return EXIT_FAILURE; |
270 |
+ else |
271 |
+ return EXIT_SUCCESS; |
272 |
+} |
273 |
+ |
274 |
int qcheck_main(int argc, char **argv) |
275 |
{ |
276 |
DIR *dir, *dirp; |
277 |
int i, ret; |
278 |
+ int portroot_fd, vdb_fd, cat_fd, pkg_fd; |
279 |
struct dirent *dentry, *de; |
280 |
- char search_all = 0; |
281 |
- char qc_update = 0; |
282 |
- char chk_afk = 1; |
283 |
- char chk_hash = 1; |
284 |
- char chk_mtime = 1; |
285 |
+ bool search_all = 0; |
286 |
+ bool qc_update = false; |
287 |
+ bool chk_afk = true; |
288 |
+ bool chk_hash = true; |
289 |
+ bool chk_mtime = true; |
290 |
bool undo_prelink = false; |
291 |
- struct stat st; |
292 |
- size_t num_files, num_files_ok, num_files_unknown, num_files_ignored; |
293 |
- char buf[_Q_PATH_MAX], filename[_Q_PATH_MAX]; |
294 |
- char buffer[_Q_PATH_MAX]; |
295 |
regex_t **regex_head = NULL; |
296 |
size_t regex_count = 0; |
297 |
|
298 |
@@ -78,7 +299,7 @@ |
299 |
while ((i = GETOPT_LONG(QCHECK, qcheck, "")) != -1) { |
300 |
switch (i) { |
301 |
COMMON_GETOPTS_CASES(qcheck) |
302 |
- case 'a': search_all = 1; break; |
303 |
+ case 'a': search_all = true; break; |
304 |
case 'e': exact = 1; break; |
305 |
case 's': { |
306 |
regex_head = xrealloc(regex_head, (regex_count + 1) * sizeof(*regex_head)); |
307 |
@@ -87,42 +308,47 @@ |
308 |
++regex_count; |
309 |
} |
310 |
break; |
311 |
- case 'u': qc_update = 1; break; |
312 |
- case 'A': chk_afk = 0; break; |
313 |
- case 'B': bad_only = 1; break; |
314 |
- case 'H': chk_hash = 0; break; |
315 |
- case 'T': chk_mtime = 0; break; |
316 |
+ case 'u': qc_update = true; break; |
317 |
+ case 'A': chk_afk = false; break; |
318 |
+ case 'B': bad_only = true; break; |
319 |
+ case 'H': chk_hash = false; break; |
320 |
+ case 'T': chk_mtime = false; break; |
321 |
case 'p': undo_prelink = prelink_available(); break; |
322 |
} |
323 |
} |
324 |
if ((argc == optind) && !search_all) |
325 |
qcheck_usage(EXIT_FAILURE); |
326 |
|
327 |
- snprintf(buf, sizeof(buf), "%s/%s", portroot, portvdb); |
328 |
- xchdir(buf); |
329 |
- if ((dir = opendir(".")) == NULL) |
330 |
- errp("unable to read '.' !?"); |
331 |
+ portroot_fd = open(portroot, O_RDONLY|O_CLOEXEC); |
332 |
+ if (portroot_fd == -1) |
333 |
+ errp("unable to read %s !?", portroot); |
334 |
+ vdb_fd = openat(portroot_fd, portvdb + 1, O_RDONLY|O_CLOEXEC); |
335 |
+ if (vdb_fd == -1 || (dir = fdopendir(vdb_fd)) == NULL) |
336 |
+ errp("unable to read %s !?", portvdb); |
337 |
|
338 |
ret = EXIT_SUCCESS; |
339 |
|
340 |
/* open /var/db/pkg */ |
341 |
while ((dentry = q_vdb_get_next_dir(dir))) { |
342 |
- if (chdir(dentry->d_name) != 0) |
343 |
+ cat_fd = openat(vdb_fd, dentry->d_name, O_RDONLY|O_CLOEXEC); |
344 |
+ if (cat_fd == -1) |
345 |
continue; |
346 |
- if ((dirp = opendir(".")) == NULL) |
347 |
+ if ((dirp = fdopendir(cat_fd)) == NULL) { |
348 |
+ close(cat_fd); |
349 |
continue; |
350 |
+ } |
351 |
|
352 |
/* open the cateogry */ |
353 |
while ((de = readdir(dirp)) != NULL) { |
354 |
- FILE *fp, *fpx; |
355 |
if (*de->d_name == '.') |
356 |
continue; |
357 |
- fp = fpx = NULL; |
358 |
|
359 |
/* see if this cat/pkg is requested */ |
360 |
if (!search_all) { |
361 |
+ char *buf = NULL; |
362 |
for (i = optind; i < argc; ++i) { |
363 |
- snprintf(buf, sizeof(buf), "%s/%s", dentry->d_name, de->d_name); |
364 |
+ free(buf); |
365 |
+ xasprintf(&buf, "%s/%s", dentry->d_name, de->d_name); |
366 |
if (!exact) { |
367 |
if (rematch(argv[i], buf, REG_EXTENDED) == 0) |
368 |
break; |
369 |
@@ -141,211 +367,27 @@ |
370 |
break; |
371 |
if ((strcmp(argv[i], strstr(swap, "/") + 1) == 0) || (strcmp(argv[i], strstr(buf, "/") + 1) == 0)) |
372 |
break; |
373 |
- } |
374 |
+ } |
375 |
} |
376 |
+ free(buf); |
377 |
if (i == argc) |
378 |
continue; |
379 |
} |
380 |
|
381 |
- snprintf(buf, sizeof(buf), "%s%s/%s/%s/CONTENTS", portroot, portvdb, dentry->d_name, de->d_name); |
382 |
- if ((fp = fopen(buf, "re")) == NULL) |
383 |
+ pkg_fd = openat(cat_fd, de->d_name, O_RDONLY|O_CLOEXEC); |
384 |
+ if (pkg_fd == -1) |
385 |
continue; |
386 |
- strncat(buf, "~", sizeof(buf)-strlen(buf)-1); |
387 |
- num_files = num_files_ok = num_files_unknown = num_files_ignored = 0; |
388 |
- qcprintf("%sing %s%s/%s%s ...\n", |
389 |
- (qc_update ? "Updat" : "Check"), |
390 |
- GREEN, dentry->d_name, de->d_name, NORM); |
391 |
- if (qc_update) { |
392 |
- if ((fpx = fopen(buf, "we")) == NULL) { |
393 |
- fclose(fp); |
394 |
- warnp("unable to fopen(%s, w)", buf); |
395 |
- continue; |
396 |
- } |
397 |
- } |
398 |
- while ((fgets(buf, sizeof(buf), fp)) != NULL) { |
399 |
- contents_entry *e; |
400 |
- /* safe. buf and buffer are the same size.. */ |
401 |
- strcpy(buffer, buf); |
402 |
- e = contents_parse_line(buf); |
403 |
- if (!e) |
404 |
- continue; |
405 |
- if (strcmp(portroot, "/") != 0) { |
406 |
- snprintf(filename, sizeof(filename), "%s%s", portroot, e->name); |
407 |
- e->name = filename; |
408 |
- } |
409 |
- |
410 |
- /* run our little checks */ |
411 |
- ++num_files; |
412 |
- if (regex_count) { |
413 |
- size_t j; |
414 |
- for (j = 0; j < regex_count; ++j) |
415 |
- if (!regexec(regex_head[j], e->name, 0, NULL, 0)) |
416 |
- break; |
417 |
- if (j < regex_count) { |
418 |
- --num_files; |
419 |
- ++num_files_ignored; |
420 |
- continue; |
421 |
- } |
422 |
- } |
423 |
- if (lstat(e->name, &st)) { |
424 |
- /* make sure file exists */ |
425 |
- if (chk_afk) { |
426 |
- qcprintf(" %sAFK%s: %s\n", RED, NORM, e->name); |
427 |
- } else { |
428 |
- --num_files; |
429 |
- ++num_files_ignored; |
430 |
- if (qc_update) |
431 |
- fputs(buffer, fpx); |
432 |
- } |
433 |
- continue; |
434 |
- } |
435 |
- if (e->digest && S_ISREG(st.st_mode)) { |
436 |
- /* validate digest (handles MD5 / SHA1) */ |
437 |
- uint8_t hash_algo; |
438 |
- char *hashed_file; |
439 |
- hash_cb_t hash_cb = undo_prelink ? hash_cb_prelink_undo : hash_cb_default; |
440 |
- switch (strlen(e->digest)) { |
441 |
- case 32: hash_algo = HASH_MD5; break; |
442 |
- case 40: hash_algo = HASH_SHA1; break; |
443 |
- default: hash_algo = 0; break; |
444 |
- } |
445 |
- if (!hash_algo) { |
446 |
- if (chk_hash) { |
447 |
- qcprintf(" %sUNKNOWN DIGEST%s: '%s' for '%s'\n", RED, NORM, e->digest, e->name); |
448 |
- ++num_files_unknown; |
449 |
- } else { |
450 |
- --num_files; |
451 |
- ++num_files_ignored; |
452 |
- if (qc_update) |
453 |
- fputs(buffer, fpx); |
454 |
- } |
455 |
- continue; |
456 |
- } |
457 |
- hashed_file = (char*)hash_file_cb(e->name, hash_algo, hash_cb); |
458 |
- if (!hashed_file) { |
459 |
- ++num_files_unknown; |
460 |
- free(hashed_file); |
461 |
- if (qc_update) { |
462 |
- fputs(buffer, fpx); |
463 |
- if (!verbose) |
464 |
- continue; |
465 |
- } |
466 |
- qcprintf(" %sPERM %4o%s: %s\n", RED, (unsigned int)(st.st_mode & 07777), NORM, e->name); |
467 |
- continue; |
468 |
- } else if (strcmp(e->digest, hashed_file)) { |
469 |
- if (chk_hash) { |
470 |
- const char *digest_disp; |
471 |
- if (qc_update) |
472 |
- fprintf(fpx, "obj %s %s %lu\n", e->name, hashed_file, st.st_mtime); |
473 |
- switch (hash_algo) { |
474 |
- case HASH_MD5: digest_disp = "MD5"; break; |
475 |
- case HASH_SHA1: digest_disp = "SHA1"; break; |
476 |
- default: digest_disp = "UNK"; break; |
477 |
- } |
478 |
- qcprintf(" %s%s-DIGEST%s: %s", RED, digest_disp, NORM, e->name); |
479 |
- if (verbose) |
480 |
- qcprintf(" (recorded '%s' != actual '%s')", e->digest, hashed_file); |
481 |
- qcprintf("\n"); |
482 |
- } else { |
483 |
- --num_files; |
484 |
- ++num_files_ignored; |
485 |
- if (qc_update) |
486 |
- fputs(buffer, fpx); |
487 |
- } |
488 |
- free(hashed_file); |
489 |
- continue; |
490 |
- } else if (e->mtime && e->mtime != st.st_mtime) { |
491 |
- if (chk_mtime) { |
492 |
- qcprintf(" %sMTIME%s: %s", RED, NORM, e->name); |
493 |
- if (verbose) |
494 |
- qcprintf(" (recorded '%lu' != actual '%lu')", e->mtime, (unsigned long)st.st_mtime); |
495 |
- qcprintf("\n"); |
496 |
- |
497 |
- /* This can only be an obj, dir and sym have no digest */ |
498 |
- if (qc_update) |
499 |
- fprintf(fpx, "obj %s %s %lu\n", e->name, e->digest, st.st_mtime); |
500 |
- } else { |
501 |
- --num_files; |
502 |
- ++num_files_ignored; |
503 |
- if (qc_update) |
504 |
- fputs(buffer, fpx); |
505 |
- } |
506 |
- free(hashed_file); |
507 |
- continue; |
508 |
- } else { |
509 |
- if (qc_update) |
510 |
- fputs(buffer, fpx); |
511 |
- free(hashed_file); |
512 |
- } |
513 |
- } else if (e->mtime && e->mtime != st.st_mtime) { |
514 |
- if (chk_mtime) { |
515 |
- qcprintf(" %sMTIME%s: %s", RED, NORM, e->name); |
516 |
- if (verbose) |
517 |
- qcprintf(" (recorded '%lu' != actual '%lu')", e->mtime, (unsigned long)st.st_mtime); |
518 |
- qcprintf("\n"); |
519 |
- |
520 |
- /* This can only be a sym */ |
521 |
- if (qc_update) |
522 |
- fprintf(fpx, "sym %s -> %s %lu\n", e->name, e->sym_target, st.st_mtime); |
523 |
- } else { |
524 |
- --num_files; |
525 |
- ++num_files_ignored; |
526 |
- if (qc_update) |
527 |
- fputs(buffer, fpx); |
528 |
- } |
529 |
- continue; |
530 |
- } else { |
531 |
- if (qc_update) |
532 |
- fputs(buffer, fpx); |
533 |
- } |
534 |
- ++num_files_ok; |
535 |
- } |
536 |
- fclose(fp); |
537 |
- if (qc_update) { |
538 |
- fclose(fpx); |
539 |
- snprintf(buf, sizeof(buf), "%s%s/%s/%s/CONTENTS", portroot, portvdb, |
540 |
- dentry->d_name, de->d_name); |
541 |
- strcpy(buffer, buf); |
542 |
- strncat(buffer, "~", sizeof(buffer)-strlen(buf)-1); |
543 |
- rename(buffer, buf); |
544 |
- if (!verbose) |
545 |
- continue; |
546 |
- } |
547 |
- if (bad_only && num_files_ok != num_files) { |
548 |
- if (verbose) |
549 |
- printf("%s/%s\n", dentry->d_name, de->d_name); |
550 |
- else { |
551 |
- depend_atom *atom = NULL; |
552 |
- snprintf(buf, sizeof(buf), "%s/%s", dentry->d_name, de->d_name); |
553 |
- if ((atom = atom_explode(buf)) != NULL) { |
554 |
- printf("%s/%s\n", dentry->d_name, atom->PN); |
555 |
- atom_implode(atom); |
556 |
- } else { |
557 |
- printf("%s/%s\n", dentry->d_name, de->d_name); |
558 |
- } |
559 |
- } |
560 |
- } |
561 |
- qcprintf(" %2$s*%1$s %3$s%4$zu%1$s out of %3$s%5$zu%1$s file%6$s are good", |
562 |
- NORM, BOLD, BLUE, num_files_ok, num_files, |
563 |
- (num_files > 1 ? "s" : "")); |
564 |
- if (num_files_unknown) |
565 |
- qcprintf(" (Unable to digest %2$s%3$zu%1$s file%4$s)", |
566 |
- NORM, BLUE, num_files_unknown, |
567 |
- (num_files_unknown > 1 ? "s" : "")); |
568 |
- if (num_files_ignored) |
569 |
- qcprintf(" (%2$s%3$zu%1$s file%4$s ignored)", |
570 |
- NORM, BLUE, num_files_ignored, |
571 |
- (num_files_ignored > 1 ? "s were" : " was")); |
572 |
- qcprintf("\n"); |
573 |
|
574 |
- if (num_files_ok != num_files) |
575 |
- ret = EXIT_FAILURE; |
576 |
+ ret = qcheck_process_contents(portroot_fd, pkg_fd, |
577 |
+ dentry->d_name, de->d_name, regex_head, regex_count, |
578 |
+ qc_update, chk_afk, chk_hash, chk_mtime, undo_prelink); |
579 |
+ close(pkg_fd); |
580 |
} |
581 |
closedir(dirp); |
582 |
- xchdir(".."); |
583 |
} |
584 |
|
585 |
qcheck_cleanup(regex_head, regex_count); |
586 |
+ close(portroot_fd); |
587 |
return ret; |
588 |
} |