From ce38dde467cb64991032812eaaac31deb3c39da5 Mon Sep 17 00:00:00 2001 From: Nathan Wagner Date: Mon, 18 Feb 2019 13:02:01 +0000 Subject: [PATCH] expand verify --- doc/zpm-verify.8 | 16 ++++++-- src/verify.c | 105 ++++++++++++++++++++++++++++++++++++----------- 2 files changed, 94 insertions(+), 27 deletions(-) diff --git a/doc/zpm-verify.8 b/doc/zpm-verify.8 index 80a3dc4..972cc77 100644 --- a/doc/zpm-verify.8 +++ b/doc/zpm-verify.8 @@ -1,4 +1,4 @@ -.TH zpm-verify 8 2019-02-15 "ZPM 0.3" +.TH zpm-verify 8 2019-02-18 "ZPM 0.3" .SH NAME zpm-verify \- verify installed packages .SH SYNOPSIS @@ -6,16 +6,23 @@ zpm-verify \- verify installed packages [ .BI -f " pkgfile" ] +.B -Fe .RI [ package ...] .SH DESCRIPTION \fBzpm-verify\fR -Will check installed files against the metadata recorded in the -local database. For each package given, file size, permissions, -ownership, and content will be checked. +Will check installed files against the metadata recorded in the local database. +For each package given, file content, permissions, and ownership will be +checked. Packages can be partial package ids. .SH OPTIONS .TP .BI \-f path specify the package file to find package metadata in +.TP +.B \-F +Only output failed tests. +.TP +.B \-e +If a package given is not installed, skip it rather than erroring. .SH EXAMPLES .TP .B zpm verify less-543-1 @@ -30,3 +37,4 @@ ZPMDB Nathan Wagner .SH SEE ALSO .BR zpm (8) +.BR zpm-findpkg (8) diff --git a/src/verify.c b/src/verify.c index 14112c2..ec9ca7d 100644 --- a/src/verify.c +++ b/src/verify.c @@ -14,13 +14,16 @@ #include "zpm.h" #include "t/ctap/ctap.h" +#include "lib/jsw/jsw_atree.h" struct config { char *dbfile; + char *pkgid; int plan; int ran; int failed; int quiet; + int skipuninstalled; int failed_only; int tap; int check_owner; @@ -92,8 +95,12 @@ static int verify(void *f, int ncols, char **vals, char **cols) { if (rv == -1) { switch (errno) { case ENOENT: ok(0, "%s does not exist", path); + conf->failed++; break; - default: ok(0, "cannot stat %s: %s", path, strerror(errno)); + default: ok(0, "%s%scannot stat %s: %s", + conf->pkgid ? conf->pkgid : "", + conf->pkgid ? " " : "", + path, strerror(errno)); conf->failed++; break; } @@ -103,25 +110,50 @@ static int verify(void *f, int ncols, char **vals, char **cols) { return 0; } - ok(1, "%s exists", path); + if (!conf->failed_only) { + ok(1, "%s%s%s exists", + conf->pkgid ? conf->pkgid : "", + conf->pkgid ? " " : "", + path); + } + + if (ftype != 'r') { + return 0; + } if (ftype == 'r' && !configfile) { zpm_hash(path, ehash, 0); - if (!is_string(ehash, hash, "hash %s", path)) { + rv = strcmp(ehash, hash); + if (rv != 0) { conf->failed++; } + if (rv != 0 || !conf->failed_only) { + is_string(ehash, hash, "%s%shash %s", + conf->pkgid ? conf->pkgid : "", + conf->pkgid ? " " : "", + path); + } } return 0; } +static int afind_strcmp(const void *a, const void *b) { + return strcmp(a, b); +} + int main(int ac, char **av) { struct zpm pkg; char *s; int opt; char *pkgid; - + jsw_atree_t *pkglist; + jsw_atrav_t *list; + int i, errors = 0; + + pkglist = jsw_anew(afind_strcmp, (dup_f)strdup, (rel_f)free); struct config conf = { 0 }; + conf.dbfile = "/var/lib/zpm/local.db"; if ((s = getenv("ZPMDB"))) { @@ -129,10 +161,11 @@ int main(int ac, char **av) { conf.dbfile = s; } - while ((opt = getopt(ac, av, "f:")) != -1) { + while ((opt = getopt(ac, av, "f:eF")) != -1) { switch (opt) { - case 'f': conf.dbfile = optarg; - break; + case 'f': conf.dbfile = optarg; break; + case 'e': conf.skipuninstalled = 1; break; + case 'F': conf.failed_only = 1; break; default: usage(); exit(EXIT_FAILURE); @@ -149,41 +182,67 @@ int main(int ac, char **av) { char *errmsg = 0; if (argn < ac) { - pkgid = av[argn]; - argn++; } else { fprintf(stderr, "must specify pkgid\n"); usage(); exit(EXIT_FAILURE); } - /* TODO lookup pkgid via zpm-findpkg equivalent */ + for (i = argn; i < ac; i++) { + pkgid = zpm_findpkg(&pkg, av[i], "status = 'installed'"); + if (!pkgid) { + if (conf.skipuninstalled) { + continue; + } + fprintf(stderr, "no installed package: %s\n", av[i]); + errors++; + free(pkgid); + pkgid = 0; + continue; + } - if (!zpm_foreach_path(&pkg, pkgid, 0, count_plan, &conf, &errmsg)) { - if (errmsg) { - fprintf(stderr, "database error: %s\n", errmsg); + if (!zpm_foreach_path(&pkg, pkgid, 0, count_plan, &conf, &errmsg)) { + if (errmsg) { + fprintf(stderr, "database error: %s\n", errmsg); + exit(EXIT_FAILURE); + } + if (pkg.error == 1) { + fprintf(stderr, "unable to allocate memory\n"); + } + fprintf(stderr, "unable to plan\n"); exit(EXIT_FAILURE); } - if (pkg.error == 1) { - fprintf(stderr, "unable to allocate memory\n"); + if (!jsw_ainsert(pkglist, pkgid)) { + fprintf(stderr, "pkglist insert failed\n"); + exit(EXIT_FAILURE); } - fprintf(stderr, "unable to plan\n"); + free(pkgid); + } + if (errors) { exit(EXIT_FAILURE); } plan(conf.plan); - if (!zpm_foreach_path(&pkg, pkgid, 0, verify, &conf, &errmsg)) { - if (errmsg) { - fprintf(stderr, "database error: %s\n", errmsg); + list = jsw_atnew(); + + for (pkgid = jsw_atfirst(list, pkglist); pkgid; pkgid = jsw_atnext(list)) { + conf.pkgid = pkgid; + + if (!zpm_foreach_path(&pkg, pkgid, 0, verify, &conf, &errmsg)) { + if (errmsg) { + fprintf(stderr, "database error: %s\n", errmsg); + exit(EXIT_FAILURE); + } + if (pkg.error == 1) { + fprintf(stderr, "unable to allocate memory\n"); + } exit(EXIT_FAILURE); } - if (pkg.error == 1) { - fprintf(stderr, "unable to allocate memory\n"); - } - exit(EXIT_FAILURE); } + if (pkglist) jsw_adelete(pkglist); + zpm_close(&pkg); return conf.failed ? 1 : 0; } -- 2.40.0