* [gentoo-commits] gentoo-projects commit in portage-utils: qcheck.c
@ 2012-11-10 0:08 Mike Frysinger (vapier)
0 siblings, 0 replies; 6+ messages in thread
From: Mike Frysinger (vapier) @ 2012-11-10 0:08 UTC (permalink / raw
To: gentoo-commits
vapier 12/11/10 00:08:46
Modified: qcheck.c
Log:
qcheck: fix ROOT handling when hashing files
Revision Changes Path
1.57 portage-utils/qcheck.c
file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?rev=1.57&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?rev=1.57&content-type=text/plain
diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?r1=1.56&r2=1.57
Index: qcheck.c
===================================================================
RCS file: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -r1.56 -r1.57
--- qcheck.c 28 Oct 2012 04:52:56 -0000 1.56
+++ qcheck.c 10 Nov 2012 00:08:46 -0000 1.57
@@ -1,7 +1,7 @@
/*
* Copyright 2005-2011 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
- * $Header: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v 1.56 2012/10/28 04:52:56 vapier Exp $
+ * $Header: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v 1.57 2012/11/10 00:08:46 vapier Exp $
*
* Copyright 2005-2010 Ned Ludd - <solar@gentoo.org>
* Copyright 2005-2011 Mike Frysinger - <vapier@gentoo.org>
@@ -36,7 +36,7 @@
"Undo prelink when calculating checksums",
COMMON_OPTS_HELP
};
-static const char qcheck_rcsid[] = "$Id: qcheck.c,v 1.56 2012/10/28 04:52:56 vapier Exp $";
+static const char qcheck_rcsid[] = "$Id: qcheck.c,v 1.57 2012/11/10 00:08:46 vapier Exp $";
#define qcheck_usage(ret) usage(ret, QCHECK_FLAGS, qcheck_long_opts, qcheck_opts_help, lookup_applet_idx("qcheck"))
#define qcprintf(fmt, args...) if (!state->bad_only) printf(_(fmt), ## args)
@@ -173,7 +173,7 @@
}
continue;
}
- hashed_file = (char*)hash_file_cb(e->name, hash_algo, hash_cb);
+ hashed_file = (char *)hash_file_at_cb(pkg_ctx->cat_ctx->ctx->portroot_fd, e->name + 1, hash_algo, hash_cb);
if (!hashed_file) {
++num_files_unknown;
free(hashed_file);
^ permalink raw reply [flat|nested] 6+ messages in thread
* [gentoo-commits] gentoo-projects commit in portage-utils: qcheck.c
@ 2012-10-28 4:52 Mike Frysinger (vapier)
0 siblings, 0 replies; 6+ messages in thread
From: Mike Frysinger (vapier) @ 2012-10-28 4:52 UTC (permalink / raw
To: gentoo-commits
vapier 12/10/28 04:52:56
Modified: qcheck.c
Log:
support skipping checking of CONFIG_PROTECT-ed files #330537 by Michał Górny
Revision Changes Path
1.56 portage-utils/qcheck.c
file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?rev=1.56&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?rev=1.56&content-type=text/plain
diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?r1=1.55&r2=1.56
Index: qcheck.c
===================================================================
RCS file: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -r1.55 -r1.56
--- qcheck.c 19 Dec 2011 04:23:18 -0000 1.55
+++ qcheck.c 28 Oct 2012 04:52:56 -0000 1.56
@@ -1,7 +1,7 @@
/*
* Copyright 2005-2011 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
- * $Header: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v 1.55 2011/12/19 04:23:18 vapier Exp $
+ * $Header: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v 1.56 2012/10/28 04:52:56 vapier Exp $
*
* Copyright 2005-2010 Ned Ludd - <solar@gentoo.org>
* Copyright 2005-2011 Mike Frysinger - <vapier@gentoo.org>
@@ -11,15 +11,16 @@
#define QCHECK_FLAGS "aes:uABHTp" COMMON_FLAGS
static struct option const qcheck_long_opts[] = {
- {"all", no_argument, NULL, 'a'},
- {"exact", no_argument, NULL, 'e'},
- {"skip", a_argument, NULL, 's'},
- {"update", no_argument, NULL, 'u'},
- {"noafk", no_argument, NULL, 'A'},
- {"badonly", no_argument, NULL, 'B'},
- {"nohash", no_argument, NULL, 'H'},
- {"nomtime", no_argument, NULL, 'T'},
- {"prelink", no_argument, NULL, 'p'},
+ {"all", no_argument, NULL, 'a'},
+ {"exact", no_argument, NULL, 'e'},
+ {"skip", a_argument, NULL, 's'},
+ {"update", no_argument, NULL, 'u'},
+ {"noafk", no_argument, NULL, 'A'},
+ {"badonly", no_argument, NULL, 'B'},
+ {"nohash", no_argument, NULL, 'H'},
+ {"nomtime", no_argument, NULL, 'T'},
+ {"skip-protected", no_argument, NULL, 128},
+ {"prelink", no_argument, NULL, 'p'},
COMMON_LONG_OPTS
};
static const char * const qcheck_opts_help[] = {
@@ -31,10 +32,11 @@
"Only print pkgs containing bad files",
"Ignore differing/unknown file chksums",
"Ignore differing file mtimes",
+ "Ignore files in CONFIG_PROTECT-ed paths",
"Undo prelink when calculating checksums",
COMMON_OPTS_HELP
};
-static const char qcheck_rcsid[] = "$Id: qcheck.c,v 1.55 2011/12/19 04:23:18 vapier Exp $";
+static const char qcheck_rcsid[] = "$Id: qcheck.c,v 1.56 2012/10/28 04:52:56 vapier Exp $";
#define qcheck_usage(ret) usage(ret, QCHECK_FLAGS, qcheck_long_opts, qcheck_opts_help, lookup_applet_idx("qcheck"))
#define qcprintf(fmt, args...) if (!state->bad_only) printf(_(fmt), ## args)
@@ -49,6 +51,7 @@
bool chk_afk;
bool chk_hash;
bool chk_mtime;
+ bool chk_config_protect;
bool undo_prelink;
bool exact;
};
@@ -63,6 +66,8 @@
char *buffer, *line;
size_t linelen;
struct stat st, cst;
+ int cp_argc, cpm_argc;
+ char **cp_argv, **cpm_argv;
fpx = NULL;
@@ -91,6 +96,11 @@
}
}
+ if (!state->chk_config_protect) {
+ makeargv(config_protect, &cp_argc, &cp_argv);
+ makeargv(config_protect_mask, &cpm_argc, &cpm_argv);
+ }
+
buffer = line = NULL;
while (getline(&line, &linelen, fp) != -1) {
contents_entry *e;
@@ -127,6 +137,21 @@
continue;
}
if (e->digest && S_ISREG(st.st_mode)) {
+ if (!state->chk_config_protect) {
+ /* handle CONFIG_PROTECT-ed files */
+ int i;
+ /* if it's in CONFIG_PROTECT_MASK, check it like normal */
+ for (i = 1; i < cpm_argc; ++i)
+ if (strncmp(cpm_argv[i], e->name, strlen(cpm_argv[i])) == 0)
+ break;
+ if (i == cpm_argc) {
+ /* not explicitly masked, so if it's protected */
+ for (i = 1; i < cp_argc; ++i)
+ if (strncmp(cp_argv[i], e->name, strlen(cp_argv[i])) == 0)
+ goto cfg_protected;
+ }
+ }
+
/* validate digest (handles MD5 / SHA1) */
uint8_t hash_algo;
char *hashed_file;
@@ -225,12 +250,18 @@
if (state->qc_update)
fputs(buffer, fpx);
}
+ cfg_protected:
++num_files_ok;
}
free(line);
free(buffer);
fclose(fp);
+ if (!state->chk_config_protect) {
+ freeargv(cp_argc, cp_argv);
+ freeargv(cpm_argc, cpm_argv);
+ }
+
if (state->qc_update) {
if (fchown(fd, cst.st_uid, cst.st_gid)) {
/* meh */;
@@ -338,6 +369,7 @@
.chk_afk = true,
.chk_hash = true,
.chk_mtime = true,
+ .chk_config_protect = true,
.undo_prelink = false,
.exact = false,
};
@@ -361,6 +393,7 @@
case 'B': state.bad_only = true; break;
case 'H': state.chk_hash = false; break;
case 'T': state.chk_mtime = false; break;
+ case 128: state.chk_config_protect = false; break;
case 'p': state.undo_prelink = prelink_available(); break;
}
}
^ permalink raw reply [flat|nested] 6+ messages in thread
* [gentoo-commits] gentoo-projects commit in portage-utils: qcheck.c
@ 2011-12-18 7:58 Mike Frysinger (vapier)
0 siblings, 0 replies; 6+ messages in thread
From: Mike Frysinger (vapier) @ 2011-12-18 7:58 UTC (permalink / raw
To: gentoo-commits
vapier 11/12/18 07:58:40
Modified: qcheck.c
Log:
push down "exact" from global scope to per-applet state
Revision Changes Path
1.53 portage-utils/qcheck.c
file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?rev=1.53&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?rev=1.53&content-type=text/plain
diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?r1=1.52&r2=1.53
Index: qcheck.c
===================================================================
RCS file: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -r1.52 -r1.53
--- qcheck.c 18 Dec 2011 01:17:14 -0000 1.52
+++ qcheck.c 18 Dec 2011 07:58:40 -0000 1.53
@@ -1,7 +1,7 @@
/*
* Copyright 2005-2011 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
- * $Header: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v 1.52 2011/12/18 01:17:14 vapier Exp $
+ * $Header: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v 1.53 2011/12/18 07:58:40 vapier Exp $
*
* Copyright 2005-2010 Ned Ludd - <solar@gentoo.org>
* Copyright 2005-2011 Mike Frysinger - <vapier@gentoo.org>
@@ -34,7 +34,7 @@
"Undo prelink when calculating checksums",
COMMON_OPTS_HELP
};
-static const char qcheck_rcsid[] = "$Id: qcheck.c,v 1.52 2011/12/18 01:17:14 vapier Exp $";
+static const char qcheck_rcsid[] = "$Id: qcheck.c,v 1.53 2011/12/18 07:58:40 vapier Exp $";
#define qcheck_usage(ret) usage(ret, QCHECK_FLAGS, qcheck_long_opts, qcheck_opts_help, lookup_applet_idx("qcheck"))
#define qcprintf(fmt, args...) if (!state->bad_only) printf(_(fmt), ## args)
@@ -50,6 +50,7 @@
bool chk_hash;
bool chk_mtime;
bool undo_prelink;
+ bool exact;
};
static int qcheck_process_contents(q_vdb_pkg_ctx *pkg_ctx, struct qcheck_opt_state *state)
@@ -290,7 +291,7 @@
for (i = optind; i < state->argc; ++i) {
free(buf);
xasprintf(&buf, "%s/%s", catname, pkgname);
- if (!exact) {
+ if (!state->exact) {
if (rematch(state->argv[i], buf, REG_EXTENDED) == 0)
break;
if (rematch(state->argv[i], pkgname, REG_EXTENDED) == 0)
@@ -336,6 +337,7 @@
.chk_hash = true,
.chk_mtime = true,
.undo_prelink = false,
+ .exact = false,
};
DBG("argc=%d argv[0]=%s argv[1]=%s",
@@ -345,7 +347,7 @@
switch (i) {
COMMON_GETOPTS_CASES(qcheck)
case 'a': state.search_all = true; break;
- case 'e': exact = 1; break;
+ case 'e': state.exact = true; break;
case 's': {
regex_t regex;
xregcomp(®ex, optarg, REG_EXTENDED|REG_NOSUB);
^ permalink raw reply [flat|nested] 6+ messages in thread
* [gentoo-commits] gentoo-projects commit in portage-utils: qcheck.c
@ 2011-10-03 3:18 Mike Frysinger (vapier)
0 siblings, 0 replies; 6+ messages in thread
From: Mike Frysinger (vapier) @ 2011-10-03 3:18 UTC (permalink / raw
To: gentoo-commits
vapier 11/10/03 03:18:11
Modified: qcheck.c
Log:
rewrite qcheck to use *at style funcs
Revision Changes Path
1.50 portage-utils/qcheck.c
file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?rev=1.50&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?rev=1.50&content-type=text/plain
diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?r1=1.49&r2=1.50
Index: qcheck.c
===================================================================
RCS file: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -r1.49 -r1.50
--- qcheck.c 3 Oct 2011 01:25:54 -0000 1.49
+++ qcheck.c 3 Oct 2011 03:18:10 -0000 1.50
@@ -1,7 +1,7 @@
/*
* Copyright 2005-2010 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
- * $Header: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v 1.49 2011/10/03 01:25:54 vapier Exp $
+ * $Header: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v 1.50 2011/10/03 03:18:10 vapier Exp $
*
* Copyright 2005-2010 Ned Ludd - <solar@gentoo.org>
* Copyright 2005-2010 Mike Frysinger - <vapier@gentoo.org>
@@ -34,11 +34,11 @@
"Undo prelink when calculating checksums",
COMMON_OPTS_HELP
};
-static const char qcheck_rcsid[] = "$Id: qcheck.c,v 1.49 2011/10/03 01:25:54 vapier Exp $";
+static const char qcheck_rcsid[] = "$Id: qcheck.c,v 1.50 2011/10/03 03:18:10 vapier Exp $";
#define qcheck_usage(ret) usage(ret, QCHECK_FLAGS, qcheck_long_opts, qcheck_opts_help, lookup_applet_idx("qcheck"))
-short bad_only = 0;
-#define qcprintf(fmt, args...) if (!bad_only) printf( _( fmt ), ## args)
+static bool bad_only = false;
+#define qcprintf(fmt, args...) if (!bad_only) printf(_(fmt), ## args)
static void qcheck_cleanup(regex_t **regex_head, const size_t regex_count)
{
@@ -54,21 +54,242 @@
free(regex_head);
}
+static int qcheck_process_contents(int portroot_fd, int pkg_fd,
+ const char *catname, const char *pkgname, regex_t **regex_head,
+ size_t regex_count, bool qc_update, bool chk_afk,
+ bool chk_hash, bool chk_mtime, bool undo_prelink)
+{
+ int fd;
+ FILE *fp, *fpx;
+ size_t num_files, num_files_ok, num_files_unknown, num_files_ignored;
+ char *buffer, *line;
+ size_t linelen;
+ struct stat st, cst;
+
+ fpx = NULL;
+
+ fd = openat(pkg_fd, "CONTENTS", O_RDONLY|O_CLOEXEC);
+ if (fd == -1)
+ return EXIT_SUCCESS;
+ if (fstat(fd, &cst)) {
+ close(fd);
+ return EXIT_SUCCESS;
+ }
+ if ((fp = fdopen(fd, "r")) == NULL) {
+ close(fd);
+ return EXIT_SUCCESS;
+ }
+
+ num_files = num_files_ok = num_files_unknown = num_files_ignored = 0;
+ qcprintf("%sing %s%s/%s%s ...\n",
+ (qc_update ? "Updat" : "Check"),
+ GREEN, catname, pkgname, NORM);
+ if (qc_update) {
+ fd = openat(pkg_fd, "CONTENTS~", O_RDWR|O_CLOEXEC|O_CREAT|O_TRUNC, 0644);
+ if (fd == -1 || (fpx = fdopen(fd, "w")) == NULL) {
+ fclose(fp);
+ warnp("unable to fopen(%s/%s, w)", pkgname, "CONTENTS~");
+ return EXIT_FAILURE;
+ }
+ }
+
+ buffer = line = NULL;
+ while (getline(&line, &linelen, fp) != -1) {
+ contents_entry *e;
+ free(buffer);
+ buffer = xstrdup(line);
+ e = contents_parse_line(line);
+ if (!e)
+ continue;
+
+ /* run our little checks */
+ ++num_files;
+ if (regex_count) {
+ size_t j;
+ for (j = 0; j < regex_count; ++j)
+ if (!regexec(regex_head[j], e->name, 0, NULL, 0))
+ break;
+ if (j < regex_count) {
+ --num_files;
+ ++num_files_ignored;
+ continue;
+ }
+ }
+ if (fstatat(portroot_fd, e->name + 1, &st, AT_SYMLINK_NOFOLLOW)) {
+ /* make sure file exists */
+ if (chk_afk) {
+ qcprintf(" %sAFK%s: %s\n", RED, NORM, e->name);
+ } else {
+ --num_files;
+ ++num_files_ignored;
+ if (qc_update)
+ fputs(buffer, fpx);
+ }
+ continue;
+ }
+ if (e->digest && S_ISREG(st.st_mode)) {
+ /* validate digest (handles MD5 / SHA1) */
+ uint8_t hash_algo;
+ char *hashed_file;
+ hash_cb_t hash_cb = undo_prelink ? hash_cb_prelink_undo : hash_cb_default;
+ switch (strlen(e->digest)) {
+ case 32: hash_algo = HASH_MD5; break;
+ case 40: hash_algo = HASH_SHA1; break;
+ default: hash_algo = 0; break;
+ }
+ if (!hash_algo) {
+ if (chk_hash) {
+ qcprintf(" %sUNKNOWN DIGEST%s: '%s' for '%s'\n", RED, NORM, e->digest, e->name);
+ ++num_files_unknown;
+ } else {
+ --num_files;
+ ++num_files_ignored;
+ if (qc_update)
+ fputs(buffer, fpx);
+ }
+ continue;
+ }
+ hashed_file = (char*)hash_file_cb(e->name, hash_algo, hash_cb);
+ if (!hashed_file) {
+ ++num_files_unknown;
+ free(hashed_file);
+ if (qc_update) {
+ fputs(buffer, fpx);
+ if (!verbose)
+ continue;
+ }
+ qcprintf(" %sPERM %4o%s: %s\n", RED, (unsigned int)(st.st_mode & 07777), NORM, e->name);
+ continue;
+ } else if (strcmp(e->digest, hashed_file)) {
+ if (chk_hash) {
+ const char *digest_disp;
+ if (qc_update)
+ fprintf(fpx, "obj %s %s %lu\n", e->name, hashed_file, st.st_mtime);
+ switch (hash_algo) {
+ case HASH_MD5: digest_disp = "MD5"; break;
+ case HASH_SHA1: digest_disp = "SHA1"; break;
+ default: digest_disp = "UNK"; break;
+ }
+ qcprintf(" %s%s-DIGEST%s: %s", RED, digest_disp, NORM, e->name);
+ if (verbose)
+ qcprintf(" (recorded '%s' != actual '%s')", e->digest, hashed_file);
+ qcprintf("\n");
+ } else {
+ --num_files;
+ ++num_files_ignored;
+ if (qc_update)
+ fputs(buffer, fpx);
+ }
+ free(hashed_file);
+ continue;
+ } else if (e->mtime && e->mtime != st.st_mtime) {
+ if (chk_mtime) {
+ qcprintf(" %sMTIME%s: %s", RED, NORM, e->name);
+ if (verbose)
+ qcprintf(" (recorded '%lu' != actual '%lu')", e->mtime, (unsigned long)st.st_mtime);
+ qcprintf("\n");
+
+ /* This can only be an obj, dir and sym have no digest */
+ if (qc_update)
+ fprintf(fpx, "obj %s %s %lu\n", e->name, e->digest, st.st_mtime);
+ } else {
+ --num_files;
+ ++num_files_ignored;
+ if (qc_update)
+ fputs(buffer, fpx);
+ }
+ free(hashed_file);
+ continue;
+ } else {
+ if (qc_update)
+ fputs(buffer, fpx);
+ free(hashed_file);
+ }
+ } else if (e->mtime && e->mtime != st.st_mtime) {
+ if (chk_mtime) {
+ qcprintf(" %sMTIME%s: %s", RED, NORM, e->name);
+ if (verbose)
+ qcprintf(" (recorded '%lu' != actual '%lu')", e->mtime, (unsigned long)st.st_mtime);
+ qcprintf("\n");
+
+ /* This can only be a sym */
+ if (qc_update)
+ fprintf(fpx, "sym %s -> %s %lu\n", e->name, e->sym_target, st.st_mtime);
+ } else {
+ --num_files;
+ ++num_files_ignored;
+ if (qc_update)
+ fputs(buffer, fpx);
+ }
+ continue;
+ } else {
+ if (qc_update)
+ fputs(buffer, fpx);
+ }
+ ++num_files_ok;
+ }
+ free(line);
+ free(buffer);
+ fclose(fp);
+
+ if (qc_update) {
+ if (fchown(fd, cst.st_uid, cst.st_gid))
+ /* meh */;
+ if (fchmod(fd, cst.st_mode))
+ /* meh */;
+ fclose(fpx);
+ if (renameat(pkg_fd, "CONTENTS~", pkg_fd, "CONTENTS"))
+ unlinkat(pkg_fd, "CONTENTS~", 0);
+ if (!verbose)
+ return EXIT_SUCCESS;
+ }
+ if (bad_only && num_files_ok != num_files) {
+ if (verbose)
+ printf("%s/%s\n", catname, pkgname);
+ else {
+ depend_atom *atom = NULL;
+ char *buf;
+ xasprintf(&buf, "%s/%s", catname, pkgname);
+ if ((atom = atom_explode(buf)) != NULL) {
+ printf("%s/%s\n", catname, atom->PN);
+ atom_implode(atom);
+ } else {
+ printf("%s/%s\n", catname, pkgname);
+ }
+ free(buf);
+ }
+ }
+ qcprintf(" %2$s*%1$s %3$s%4$zu%1$s out of %3$s%5$zu%1$s file%6$s are good",
+ NORM, BOLD, BLUE, num_files_ok, num_files,
+ (num_files > 1 ? "s" : ""));
+ if (num_files_unknown)
+ qcprintf(" (Unable to digest %2$s%3$zu%1$s file%4$s)",
+ NORM, BLUE, num_files_unknown,
+ (num_files_unknown > 1 ? "s" : ""));
+ if (num_files_ignored)
+ qcprintf(" (%2$s%3$zu%1$s file%4$s ignored)",
+ NORM, BLUE, num_files_ignored,
+ (num_files_ignored > 1 ? "s were" : " was"));
+ qcprintf("\n");
+
+ if (num_files_ok != num_files)
+ return EXIT_FAILURE;
+ else
+ return EXIT_SUCCESS;
+}
+
int qcheck_main(int argc, char **argv)
{
DIR *dir, *dirp;
int i, ret;
+ int portroot_fd, vdb_fd, cat_fd, pkg_fd;
struct dirent *dentry, *de;
- char search_all = 0;
- char qc_update = 0;
- char chk_afk = 1;
- char chk_hash = 1;
- char chk_mtime = 1;
+ bool search_all = 0;
+ bool qc_update = false;
+ bool chk_afk = true;
+ bool chk_hash = true;
+ bool chk_mtime = true;
bool undo_prelink = false;
- struct stat st;
- size_t num_files, num_files_ok, num_files_unknown, num_files_ignored;
- char buf[_Q_PATH_MAX], filename[_Q_PATH_MAX];
- char buffer[_Q_PATH_MAX];
regex_t **regex_head = NULL;
size_t regex_count = 0;
@@ -78,7 +299,7 @@
while ((i = GETOPT_LONG(QCHECK, qcheck, "")) != -1) {
switch (i) {
COMMON_GETOPTS_CASES(qcheck)
- case 'a': search_all = 1; break;
+ case 'a': search_all = true; break;
case 'e': exact = 1; break;
case 's': {
regex_head = xrealloc(regex_head, (regex_count + 1) * sizeof(*regex_head));
@@ -87,42 +308,47 @@
++regex_count;
}
break;
- case 'u': qc_update = 1; break;
- case 'A': chk_afk = 0; break;
- case 'B': bad_only = 1; break;
- case 'H': chk_hash = 0; break;
- case 'T': chk_mtime = 0; break;
+ case 'u': qc_update = true; break;
+ case 'A': chk_afk = false; break;
+ case 'B': bad_only = true; break;
+ case 'H': chk_hash = false; break;
+ case 'T': chk_mtime = false; break;
case 'p': undo_prelink = prelink_available(); break;
}
}
if ((argc == optind) && !search_all)
qcheck_usage(EXIT_FAILURE);
- snprintf(buf, sizeof(buf), "%s/%s", portroot, portvdb);
- xchdir(buf);
- if ((dir = opendir(".")) == NULL)
- errp("unable to read '.' !?");
+ portroot_fd = open(portroot, O_RDONLY|O_CLOEXEC);
+ if (portroot_fd == -1)
+ errp("unable to read %s !?", portroot);
+ vdb_fd = openat(portroot_fd, portvdb + 1, O_RDONLY|O_CLOEXEC);
+ if (vdb_fd == -1 || (dir = fdopendir(vdb_fd)) == NULL)
+ errp("unable to read %s !?", portvdb);
ret = EXIT_SUCCESS;
/* open /var/db/pkg */
while ((dentry = q_vdb_get_next_dir(dir))) {
- if (chdir(dentry->d_name) != 0)
+ cat_fd = openat(vdb_fd, dentry->d_name, O_RDONLY|O_CLOEXEC);
+ if (cat_fd == -1)
continue;
- if ((dirp = opendir(".")) == NULL)
+ if ((dirp = fdopendir(cat_fd)) == NULL) {
+ close(cat_fd);
continue;
+ }
/* open the cateogry */
while ((de = readdir(dirp)) != NULL) {
- FILE *fp, *fpx;
if (*de->d_name == '.')
continue;
- fp = fpx = NULL;
/* see if this cat/pkg is requested */
if (!search_all) {
+ char *buf = NULL;
for (i = optind; i < argc; ++i) {
- snprintf(buf, sizeof(buf), "%s/%s", dentry->d_name, de->d_name);
+ free(buf);
+ xasprintf(&buf, "%s/%s", dentry->d_name, de->d_name);
if (!exact) {
if (rematch(argv[i], buf, REG_EXTENDED) == 0)
break;
@@ -141,211 +367,27 @@
break;
if ((strcmp(argv[i], strstr(swap, "/") + 1) == 0) || (strcmp(argv[i], strstr(buf, "/") + 1) == 0))
break;
- }
+ }
}
+ free(buf);
if (i == argc)
continue;
}
- snprintf(buf, sizeof(buf), "%s%s/%s/%s/CONTENTS", portroot, portvdb, dentry->d_name, de->d_name);
- if ((fp = fopen(buf, "re")) == NULL)
+ pkg_fd = openat(cat_fd, de->d_name, O_RDONLY|O_CLOEXEC);
+ if (pkg_fd == -1)
continue;
- strncat(buf, "~", sizeof(buf)-strlen(buf)-1);
- num_files = num_files_ok = num_files_unknown = num_files_ignored = 0;
- qcprintf("%sing %s%s/%s%s ...\n",
- (qc_update ? "Updat" : "Check"),
- GREEN, dentry->d_name, de->d_name, NORM);
- if (qc_update) {
- if ((fpx = fopen(buf, "we")) == NULL) {
- fclose(fp);
- warnp("unable to fopen(%s, w)", buf);
- continue;
- }
- }
- while ((fgets(buf, sizeof(buf), fp)) != NULL) {
- contents_entry *e;
- /* safe. buf and buffer are the same size.. */
- strcpy(buffer, buf);
- e = contents_parse_line(buf);
- if (!e)
- continue;
- if (strcmp(portroot, "/") != 0) {
- snprintf(filename, sizeof(filename), "%s%s", portroot, e->name);
- e->name = filename;
- }
-
- /* run our little checks */
- ++num_files;
- if (regex_count) {
- size_t j;
- for (j = 0; j < regex_count; ++j)
- if (!regexec(regex_head[j], e->name, 0, NULL, 0))
- break;
- if (j < regex_count) {
- --num_files;
- ++num_files_ignored;
- continue;
- }
- }
- if (lstat(e->name, &st)) {
- /* make sure file exists */
- if (chk_afk) {
- qcprintf(" %sAFK%s: %s\n", RED, NORM, e->name);
- } else {
- --num_files;
- ++num_files_ignored;
- if (qc_update)
- fputs(buffer, fpx);
- }
- continue;
- }
- if (e->digest && S_ISREG(st.st_mode)) {
- /* validate digest (handles MD5 / SHA1) */
- uint8_t hash_algo;
- char *hashed_file;
- hash_cb_t hash_cb = undo_prelink ? hash_cb_prelink_undo : hash_cb_default;
- switch (strlen(e->digest)) {
- case 32: hash_algo = HASH_MD5; break;
- case 40: hash_algo = HASH_SHA1; break;
- default: hash_algo = 0; break;
- }
- if (!hash_algo) {
- if (chk_hash) {
- qcprintf(" %sUNKNOWN DIGEST%s: '%s' for '%s'\n", RED, NORM, e->digest, e->name);
- ++num_files_unknown;
- } else {
- --num_files;
- ++num_files_ignored;
- if (qc_update)
- fputs(buffer, fpx);
- }
- continue;
- }
- hashed_file = (char*)hash_file_cb(e->name, hash_algo, hash_cb);
- if (!hashed_file) {
- ++num_files_unknown;
- free(hashed_file);
- if (qc_update) {
- fputs(buffer, fpx);
- if (!verbose)
- continue;
- }
- qcprintf(" %sPERM %4o%s: %s\n", RED, (unsigned int)(st.st_mode & 07777), NORM, e->name);
- continue;
- } else if (strcmp(e->digest, hashed_file)) {
- if (chk_hash) {
- const char *digest_disp;
- if (qc_update)
- fprintf(fpx, "obj %s %s %lu\n", e->name, hashed_file, st.st_mtime);
- switch (hash_algo) {
- case HASH_MD5: digest_disp = "MD5"; break;
- case HASH_SHA1: digest_disp = "SHA1"; break;
- default: digest_disp = "UNK"; break;
- }
- qcprintf(" %s%s-DIGEST%s: %s", RED, digest_disp, NORM, e->name);
- if (verbose)
- qcprintf(" (recorded '%s' != actual '%s')", e->digest, hashed_file);
- qcprintf("\n");
- } else {
- --num_files;
- ++num_files_ignored;
- if (qc_update)
- fputs(buffer, fpx);
- }
- free(hashed_file);
- continue;
- } else if (e->mtime && e->mtime != st.st_mtime) {
- if (chk_mtime) {
- qcprintf(" %sMTIME%s: %s", RED, NORM, e->name);
- if (verbose)
- qcprintf(" (recorded '%lu' != actual '%lu')", e->mtime, (unsigned long)st.st_mtime);
- qcprintf("\n");
-
- /* This can only be an obj, dir and sym have no digest */
- if (qc_update)
- fprintf(fpx, "obj %s %s %lu\n", e->name, e->digest, st.st_mtime);
- } else {
- --num_files;
- ++num_files_ignored;
- if (qc_update)
- fputs(buffer, fpx);
- }
- free(hashed_file);
- continue;
- } else {
- if (qc_update)
- fputs(buffer, fpx);
- free(hashed_file);
- }
- } else if (e->mtime && e->mtime != st.st_mtime) {
- if (chk_mtime) {
- qcprintf(" %sMTIME%s: %s", RED, NORM, e->name);
- if (verbose)
- qcprintf(" (recorded '%lu' != actual '%lu')", e->mtime, (unsigned long)st.st_mtime);
- qcprintf("\n");
-
- /* This can only be a sym */
- if (qc_update)
- fprintf(fpx, "sym %s -> %s %lu\n", e->name, e->sym_target, st.st_mtime);
- } else {
- --num_files;
- ++num_files_ignored;
- if (qc_update)
- fputs(buffer, fpx);
- }
- continue;
- } else {
- if (qc_update)
- fputs(buffer, fpx);
- }
- ++num_files_ok;
- }
- fclose(fp);
- if (qc_update) {
- fclose(fpx);
- snprintf(buf, sizeof(buf), "%s%s/%s/%s/CONTENTS", portroot, portvdb,
- dentry->d_name, de->d_name);
- strcpy(buffer, buf);
- strncat(buffer, "~", sizeof(buffer)-strlen(buf)-1);
- rename(buffer, buf);
- if (!verbose)
- continue;
- }
- if (bad_only && num_files_ok != num_files) {
- if (verbose)
- printf("%s/%s\n", dentry->d_name, de->d_name);
- else {
- depend_atom *atom = NULL;
- snprintf(buf, sizeof(buf), "%s/%s", dentry->d_name, de->d_name);
- if ((atom = atom_explode(buf)) != NULL) {
- printf("%s/%s\n", dentry->d_name, atom->PN);
- atom_implode(atom);
- } else {
- printf("%s/%s\n", dentry->d_name, de->d_name);
- }
- }
- }
- qcprintf(" %2$s*%1$s %3$s%4$zu%1$s out of %3$s%5$zu%1$s file%6$s are good",
- NORM, BOLD, BLUE, num_files_ok, num_files,
- (num_files > 1 ? "s" : ""));
- if (num_files_unknown)
- qcprintf(" (Unable to digest %2$s%3$zu%1$s file%4$s)",
- NORM, BLUE, num_files_unknown,
- (num_files_unknown > 1 ? "s" : ""));
- if (num_files_ignored)
- qcprintf(" (%2$s%3$zu%1$s file%4$s ignored)",
- NORM, BLUE, num_files_ignored,
- (num_files_ignored > 1 ? "s were" : " was"));
- qcprintf("\n");
- if (num_files_ok != num_files)
- ret = EXIT_FAILURE;
+ ret = qcheck_process_contents(portroot_fd, pkg_fd,
+ dentry->d_name, de->d_name, regex_head, regex_count,
+ qc_update, chk_afk, chk_hash, chk_mtime, undo_prelink);
+ close(pkg_fd);
}
closedir(dirp);
- xchdir("..");
}
qcheck_cleanup(regex_head, regex_count);
+ close(portroot_fd);
return ret;
}
^ permalink raw reply [flat|nested] 6+ messages in thread
* [gentoo-commits] gentoo-projects commit in portage-utils: qcheck.c
@ 2010-06-08 5:38 Mike Frysinger (vapier)
0 siblings, 0 replies; 6+ messages in thread
From: Mike Frysinger (vapier) @ 2010-06-08 5:38 UTC (permalink / raw
To: gentoo-commits
vapier 10/06/08 05:38:17
Modified: qcheck.c
Log:
qcheck: exit(0) only when all files are good to aid in scripting as suggested by Elias Probst #282647
Revision Changes Path
1.45 portage-utils/qcheck.c
file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?rev=1.45&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?rev=1.45&content-type=text/plain
diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?r1=1.44&r2=1.45
Index: qcheck.c
===================================================================
RCS file: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v
retrieving revision 1.44
retrieving revision 1.45
diff -u -r1.44 -r1.45
--- qcheck.c 8 Jun 2010 05:24:14 -0000 1.44
+++ qcheck.c 8 Jun 2010 05:38:17 -0000 1.45
@@ -1,7 +1,7 @@
/*
* Copyright 2005-2010 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
- * $Header: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v 1.44 2010/06/08 05:24:14 vapier Exp $
+ * $Header: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v 1.45 2010/06/08 05:38:17 vapier Exp $
*
* Copyright 2005-2010 Ned Ludd - <solar@gentoo.org>
* Copyright 2005-2010 Mike Frysinger - <vapier@gentoo.org>
@@ -32,7 +32,7 @@
"Ignore differing file mtimes",
COMMON_OPTS_HELP
};
-static const char qcheck_rcsid[] = "$Id: qcheck.c,v 1.44 2010/06/08 05:24:14 vapier Exp $";
+static const char qcheck_rcsid[] = "$Id: qcheck.c,v 1.45 2010/06/08 05:38:17 vapier Exp $";
#define qcheck_usage(ret) usage(ret, QCHECK_FLAGS, qcheck_long_opts, qcheck_opts_help, lookup_applet_idx("qcheck"))
short bad_only = 0;
@@ -55,7 +55,7 @@
int qcheck_main(int argc, char **argv)
{
DIR *dir, *dirp;
- int i;
+ int i, ret;
struct dirent *dentry, *de;
char search_all = 0;
char qc_update = 0;
@@ -103,7 +103,9 @@
xchdir(portroot);
xchdir(portvdb);
if ((dir = opendir(".")) == NULL)
- return EXIT_FAILURE;
+ errp("unable to read '.' !?");
+
+ ret = EXIT_SUCCESS;
/* open /var/db/pkg */
while ((dentry = q_vdb_get_next_dir(dir))) {
@@ -336,13 +338,16 @@
NORM, BLUE, num_files_ignored,
(num_files_ignored > 1 ? "s were" : " was"));
qcprintf("\n");
+
+ if (num_files_ok != num_files)
+ ret = EXIT_FAILURE;
}
closedir(dirp);
xchdir("..");
}
qcheck_cleanup(regex_head, regex_count);
- return EXIT_SUCCESS;
+ return ret;
}
#else
^ permalink raw reply [flat|nested] 6+ messages in thread
* [gentoo-commits] gentoo-projects commit in portage-utils: qcheck.c
@ 2010-06-08 5:24 Mike Frysinger (vapier)
0 siblings, 0 replies; 6+ messages in thread
From: Mike Frysinger (vapier) @ 2010-06-08 5:24 UTC (permalink / raw
To: gentoo-commits
vapier 10/06/08 05:24:14
Modified: qcheck.c
Log:
qcheck: add support by Darren Smith for ignoring files via regex #301360
Revision Changes Path
1.44 portage-utils/qcheck.c
file : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?rev=1.44&view=markup
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?rev=1.44&content-type=text/plain
diff : http://sources.gentoo.org/viewvc.cgi/gentoo-projects/portage-utils/qcheck.c?r1=1.43&r2=1.44
Index: qcheck.c
===================================================================
RCS file: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -r1.43 -r1.44
--- qcheck.c 7 Apr 2010 05:58:16 -0000 1.43
+++ qcheck.c 8 Jun 2010 05:24:14 -0000 1.44
@@ -1,7 +1,7 @@
/*
* Copyright 2005-2010 Gentoo Foundation
* Distributed under the terms of the GNU General Public License v2
- * $Header: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v 1.43 2010/04/07 05:58:16 solar Exp $
+ * $Header: /var/cvsroot/gentoo-projects/portage-utils/qcheck.c,v 1.44 2010/06/08 05:24:14 vapier Exp $
*
* Copyright 2005-2010 Ned Ludd - <solar@gentoo.org>
* Copyright 2005-2010 Mike Frysinger - <vapier@gentoo.org>
@@ -9,33 +9,49 @@
#ifdef APPLET_qcheck
-#define QCHECK_FLAGS "eauAHTB" COMMON_FLAGS
+#define QCHECK_FLAGS "aes:uABHT" COMMON_FLAGS
static struct option const qcheck_long_opts[] = {
- {"exact", no_argument, NULL, 'e'},
{"all", no_argument, NULL, 'a'},
+ {"exact", no_argument, NULL, 'e'},
+ {"skip", a_argument, NULL, 's'},
{"update", no_argument, NULL, 'u'},
{"noafk", no_argument, NULL, 'A'},
+ {"badonly", no_argument, NULL, 'B'},
{"nohash", no_argument, NULL, 'H'},
{"nomtime", no_argument, NULL, 'T'},
- {"badonly", no_argument, NULL, 'B'},
COMMON_LONG_OPTS
};
static const char *qcheck_opts_help[] = {
- "Exact match (only CAT/PN or PN without PV)",
"List all packages",
+ "Exact match (only CAT/PN or PN without PV)",
+ "Ignore files matching the regular expression <arg>",
"Update missing files, chksum and mtimes for packages",
"Ignore missing files",
+ "Only print pkgs containing bad files",
"Ignore differing/unknown file chksums",
"Ignore differing file mtimes",
- "Only print pkgs containing bad files excluding /etc.",
COMMON_OPTS_HELP
};
-static const char qcheck_rcsid[] = "$Id: qcheck.c,v 1.43 2010/04/07 05:58:16 solar Exp $";
+static const char qcheck_rcsid[] = "$Id: qcheck.c,v 1.44 2010/06/08 05:24:14 vapier Exp $";
#define qcheck_usage(ret) usage(ret, QCHECK_FLAGS, qcheck_long_opts, qcheck_opts_help, lookup_applet_idx("qcheck"))
short bad_only = 0;
#define qcprintf(fmt, args...) if (!bad_only) printf( _( fmt ), ## args)
+static void qcheck_cleanup(regex_t **regex_head, const size_t regex_count)
+{
+ size_t i;
+
+ if (regex_head == NULL)
+ return;
+
+ for (i = 0; i < regex_count; ++i) {
+ regfree(regex_head[i]);
+ free(regex_head[i]);
+ }
+ free(regex_head);
+}
+
int qcheck_main(int argc, char **argv)
{
DIR *dir, *dirp;
@@ -50,6 +66,8 @@
size_t num_files, num_files_ok, num_files_unknown, num_files_ignored;
char buf[_Q_PATH_MAX], filename[_Q_PATH_MAX];
char buffer[_Q_PATH_MAX];
+ regex_t **regex_head = NULL;
+ size_t regex_count = 0;
DBG("argc=%d argv[0]=%s argv[1]=%s",
argc, argv[0], argc > 1 ? argv[1] : "NULL?");
@@ -57,13 +75,26 @@
while ((i = GETOPT_LONG(QCHECK, qcheck, "")) != -1) {
switch (i) {
COMMON_GETOPTS_CASES(qcheck)
- case 'e': exact = 1; break;
case 'a': search_all = 1; break;
+ case 'e': exact = 1; break;
+ case 's': {
+ int regex_val;
+ regex_head = xrealloc(regex_head, (regex_count + 1) * sizeof(*regex_head));
+ regex_head[regex_count] = xmalloc(sizeof(*regex_head[0]));
+ regex_val = regcomp(regex_head[regex_count], optarg, REG_EXTENDED|REG_NOSUB);
+ if (regex_val != 0) {
+ char errbuf[256];
+ regerror(regex_val, regex_head[regex_count], errbuf, sizeof(errbuf));
+ err("Invalid regexp: %s -- %s\n", optarg, errbuf);
+ }
+ ++regex_count;
+ }
+ break;
case 'u': qc_update = 1; break;
case 'A': chk_afk = 0; break;
+ case 'B': bad_only = 1; break;
case 'H': chk_hash = 0; break;
case 'T': chk_mtime = 0; break;
- case 'B': bad_only = 1; break;
}
}
if ((argc == optind) && !search_all)
@@ -138,9 +169,6 @@
e = contents_parse_line(buf);
if (!e)
continue;
- if (bad_only && strncmp(e->name, "/etc", 4) == 0) {
- continue;
- }
if (strcmp(portroot, "/") != 0) {
snprintf(filename, sizeof(filename), "%s%s", portroot, e->name);
e->name = filename;
@@ -148,6 +176,17 @@
/* run our little checks */
++num_files;
+ if (regex_count) {
+ size_t j;
+ for (j = 0; j < regex_count; ++j)
+ if (!regexec(regex_head[j], e->name, 0, NULL, 0))
+ break;
+ if (j < regex_count) {
+ --num_files;
+ ++num_files_ignored;
+ continue;
+ }
+ }
if (lstat(e->name, &st)) {
/* make sure file exists */
if (chk_afk) {
@@ -302,6 +341,7 @@
xchdir("..");
}
+ qcheck_cleanup(regex_head, regex_count);
return EXIT_SUCCESS;
}
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2012-11-10 0:08 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-10 0:08 [gentoo-commits] gentoo-projects commit in portage-utils: qcheck.c Mike Frysinger (vapier)
-- strict thread matches above, loose matches on Subject: below --
2012-10-28 4:52 Mike Frysinger (vapier)
2011-12-18 7:58 Mike Frysinger (vapier)
2011-10-03 3:18 Mike Frysinger (vapier)
2010-06-08 5:38 Mike Frysinger (vapier)
2010-06-08 5:24 Mike Frysinger (vapier)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox