]> pd.if.org Git - zpackage/blobdiff - src/verify.c
move C source files into src
[zpackage] / src / verify.c
diff --git a/src/verify.c b/src/verify.c
new file mode 100644 (file)
index 0000000..14112c2
--- /dev/null
@@ -0,0 +1,189 @@
+#define _POSIX_C_SOURCE 200112L
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <ctype.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <string.h>
+
+#include "zpm.h"
+#include "t/ctap/ctap.h"
+
+struct config {
+       char *dbfile;
+       int plan;
+       int ran;
+       int failed;
+       int quiet;
+       int failed_only;
+       int tap;
+       int check_owner;
+       int check_group;
+       int check_perms;
+       int check_content; /* ignored for config files */
+       int check_mtime;
+};
+
+static void usage() {
+       printf("usage: zpm foreach-path [-fncC] args ...\n");
+}
+
+static char *column(char *col, int ncols, char **vals, char **cols) {
+       int i = 0;
+       char *val = NULL;
+
+       for (i=0; i < ncols; i++) {
+               if (!strcmp(col, cols[i])) {
+                       val = vals[i];
+                       break;
+               }
+       }
+       return val;
+}
+
+static int count_plan(void *f, int ncols, char **vals, char **cols) {
+       struct config *conf = f;
+
+       int ftype, configfile = 0;
+       char *v;
+
+       v = column("filetype", ncols, vals, cols);
+       ftype = *v;
+       v = column("configuration", ncols, vals, cols);
+       if (*v == '1') {
+               configfile = 1;
+       }
+
+       if (ftype == 'r' && !configfile) {
+               conf->plan++;
+       }
+
+       conf->plan++;
+
+       return 0;
+}
+
+static int verify(void *f, int ncols, char **vals, char **cols) {
+       struct config *conf = f;
+       char *path;
+       struct stat st;
+       int rv;
+       int ftype, configfile = 0;
+       char *v, *hash, ehash[ZPM_HASH_STRLEN+1];
+
+       path = column("path", ncols, vals, cols);
+       hash = column("hash", ncols, vals, cols);
+       v = column("filetype", ncols, vals, cols);
+       ftype = *v;
+       v = column("configuration", ncols, vals, cols);
+       if (*v == '1') {
+               configfile = 1;
+       }
+
+       conf->ran++;
+
+       rv = lstat(path, &st);
+       if (rv == -1) {
+               switch (errno) {
+                       case ENOENT: ok(0, "%s does not exist", path);
+                                    break;
+                       default: ok(0, "cannot stat %s: %s", path, strerror(errno));
+                               conf->failed++;
+                                break;
+               }
+               if (ftype == 'r' && !configfile) {
+                       skip("no hash");
+               }
+               return 0;
+       }
+
+       ok(1, "%s exists", path);
+
+       if (ftype == 'r' && !configfile) {
+               zpm_hash(path, ehash, 0);
+               if (!is_string(ehash, hash, "hash %s", path)) {
+                       conf->failed++;
+               }
+       }
+
+       return 0;
+}
+
+int main(int ac, char **av) {
+       struct zpm pkg;
+       char *s;
+       int opt;
+       char *pkgid;
+
+       struct config conf = { 0 };
+       conf.dbfile = "/var/lib/zpm/local.db";
+
+       if ((s = getenv("ZPMDB"))) {
+               /* TODO does this need to be copied ? */
+               conf.dbfile = s;
+       }
+
+       while ((opt = getopt(ac, av, "f:")) != -1) {
+               switch (opt) {
+                       case 'f': conf.dbfile = optarg;
+                                 break;
+                       default:
+                                 usage();
+                                 exit(EXIT_FAILURE);
+                                 break;
+               }
+       }
+
+       int argn = optind;
+
+       if (!zpm_open(&pkg, conf.dbfile)) {
+               fprintf(stderr, "can't open zpm db %s\n", conf.dbfile);
+               exit(EXIT_FAILURE);
+       }
+       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 */
+
+       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);
+       }
+
+       plan(conf.plan);
+
+       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);
+       }
+
+       zpm_close(&pkg);
+       return conf.failed ? 1 : 0;
+}