diff -ru portage-utils-0.3.1.orig/qcheck.c portage-utils-0.3.1/qcheck.c --- portage-utils-0.3.1.orig/qcheck.c 2010-01-16 18:26:29.000000000 -0600 +++ portage-utils-0.3.1/qcheck.c 2010-01-22 19:33:12.569895805 -0600 @@ -9,15 +9,16 @@ #ifdef APPLET_qcheck -#define QCHECK_FLAGS "eauAHTB" COMMON_FLAGS +#define QCHECK_FLAGS "eauAHTBs:" COMMON_FLAGS static struct option const qcheck_long_opts[] = { - {"exact", no_argument, NULL, 'e'}, - {"all", no_argument, NULL, 'a'}, - {"update", no_argument, NULL, 'u'}, - {"noafk", no_argument, NULL, 'A'}, - {"nohash", no_argument, NULL, 'H'}, - {"nomtime", no_argument, NULL, 'T'}, - {"badonly", no_argument, NULL, 'B'}, + {"exact", no_argument, NULL, 'e'}, + {"all", no_argument, NULL, 'a'}, + {"update", no_argument, NULL, 'u'}, + {"noafk", no_argument, NULL, 'A'}, + {"nohash", no_argument, NULL, 'H'}, + {"nomtime", no_argument, NULL, 'T'}, + {"badonly", no_argument, NULL, 'B'}, + {"skip", required_argument, NULL, 's'}, COMMON_LONG_OPTS }; static const char *qcheck_opts_help[] = { @@ -27,7 +28,8 @@ "Ignore missing files", "Ignore differing/unknown file chksums", "Ignore differing file mtimes", - "Only print pkgs containing bad files excluding /etc.", + "Only print pkgs containing bad files", + "Ignore files matching the regular expression ", COMMON_OPTS_HELP }; static const char qcheck_rcsid[] = "$Id: qcheck.c,v 1.42 2010/01/13 18:17:23 vapier Exp $"; @@ -36,6 +38,8 @@ short bad_only = 0; #define qcprintf(fmt, args...) if (!bad_only) printf( _( fmt ), ## args) +void qcheck_cleanup(regex_t **regex_head, int regex_count); + int qcheck_main(int argc, char **argv) { DIR *dir, *dirp; @@ -50,6 +54,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; + int regex_count = 0; DBG("argc=%d argv[0]=%s argv[1]=%s", argc, argv[0], argc > 1 ? argv[1] : "NULL?"); @@ -64,15 +70,49 @@ case 'H': chk_hash = 0; break; case 'T': chk_mtime = 0; break; case 'B': bad_only = 1; break; + case 's': { + int regval; + regex_t **tmp = realloc(regex_head, + (regex_count+1) * sizeof(regex_t *)); + if (tmp == NULL) { + warn("Could not allocate memory."); + continue; + } + regex_head = tmp; + regex_head[regex_count] = (regex_t *) malloc(sizeof(regex_t)); + if (regex_head[regex_count] == NULL) { + warn("Could not allocate memory."); + continue; + } + regval = regcomp(regex_head[regex_count], optarg, + REG_EXTENDED|REG_NOSUB); + if (regval != 0) { + char errbuf[256]; + if (regerror(regval, regex_head[regex_count], errbuf, + sizeof(errbuf))) + warn("Invalid regexp: %s -- %s\n", optarg, errbuf); + else + warn("Invalid regexp: %s\n", optarg); + regfree(regex_head[regex_count]); + free(regex_head[regex_count]); + continue; + } + regex_count++; + } + break; } } - if ((argc == optind) && !search_all) + if ((argc == optind) && !search_all) { + qcheck_cleanup(regex_head, regex_count); qcheck_usage(EXIT_FAILURE); + } xchdir(portroot); xchdir(portvdb); - if ((dir = opendir(".")) == NULL) + if ((dir = opendir(".")) == NULL) { + qcheck_cleanup(regex_head, regex_count); return EXIT_FAILURE; + } /* open /var/db/pkg */ while ((dentry = q_vdb_get_next_dir(dir))) { @@ -138,9 +178,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 +185,20 @@ /* run our little checks */ ++num_files; + if (regex_count) { + int match = 0; + for (int j = 0; j < regex_count; j++) { + if (regexec(regex_head[j], e->name, 0, NULL, 0) == 0) { + match = 1; + break; + } + } + if (match == 1) { + --num_files; + ++num_files_ignored; + continue; + } + } if (lstat(e->name, &st)) { /* make sure file exists */ if (chk_afk) { @@ -302,9 +353,22 @@ xchdir(".."); } + qcheck_cleanup(regex_head, regex_count); return EXIT_SUCCESS; } +void qcheck_cleanup(regex_t **regex_head, int regex_count) +{ + if (regex_head == NULL) { + return; + } + for (int i = 0; i < regex_count; i++) { + regfree(regex_head[i]); + free(regex_head[i]); + } + free(regex_head); +} + #else DEFINE_APPLET_STUB(qcheck) #endif