]> pd.if.org Git - zpackage/blob - zpm-verify.c
add support for notes
[zpackage] / zpm-verify.c
1 #define _POSIX_C_SOURCE 200112L
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <errno.h>
7 #include <ctype.h>
8 #include <limits.h>
9 #include <unistd.h>
10 #include <sys/types.h>
11 #include <sys/wait.h>
12
13 #include <string.h>
14
15 #include "sqlite3.h"
16 #include "zpm.h"
17 #include "t/ctap/ctap.h"
18
19 struct config {
20         char *dbfile;
21         int plan;
22         int ran;
23         int failed;
24         int quiet;
25         int failed_only;
26         int tap;
27         int check_owner;
28         int check_group;
29         int check_perms;
30         int check_content; /* ignored for config files */
31         int check_mtime;
32 };
33
34 static void usage() {
35         printf("usage: zpm foreach-path [-fncC] args ...\n");
36 }
37
38 static char *column(char *col, int ncols, char **vals, char **cols) {
39         int i = 0;
40         char *val = NULL;
41
42         for (i=0; i < ncols; i++) {
43                 if (!strcmp(col, cols[i])) {
44                         val = vals[i];
45                         break;
46                 }
47         }
48         return val;
49 }
50
51 static int count_plan(void *f, int ncols, char **vals, char **cols) {
52         struct config *conf = f;
53
54         int ftype, configfile = 0;
55         char *v;
56
57         v = column("filetype", ncols, vals, cols);
58         ftype = *v;
59         v = column("configuration", ncols, vals, cols);
60         if (*v == '1') {
61                 configfile = 1;
62         }
63
64         if (ftype == 'r' && !configfile) {
65                 conf->plan++;
66         }
67
68         conf->plan++;
69
70         return 0;
71 }
72
73 static int verify(void *f, int ncols, char **vals, char **cols) {
74         struct config *conf = f;
75         char *path;
76         struct stat st;
77         int rv;
78         int ftype, configfile = 0;
79         char *v, *hash, ehash[ZPM_HASH_STRLEN+1];
80
81         path = column("path", ncols, vals, cols);
82         hash = column("hash", ncols, vals, cols);
83         v = column("filetype", ncols, vals, cols);
84         ftype = *v;
85         v = column("configuration", ncols, vals, cols);
86         if (*v == '1') {
87                 configfile = 1;
88         }
89
90         conf->ran++;
91
92         rv = lstat(path, &st);
93         if (rv == -1) {
94                 switch (errno) {
95                         case ENOENT: ok(0, "%s does not exist", path);
96                                      break;
97                         default: ok(0, "cannot stat %s: %s", path, strerror(errno));
98                                 conf->failed++;
99                                  break;
100                 }
101                 if (ftype == 'r' && !configfile) {
102                         skip("no hash");
103                 }
104                 return 0;
105         }
106
107         ok(1, "%s exists", path);
108
109         if (ftype == 'r' && !configfile) {
110                 zpm_hash(path, ehash, 0);
111                 if (!is_string(ehash, hash, "hash %s", path)) {
112                         conf->failed++;
113                 }
114         }
115
116         return 0;
117 }
118
119 int main(int ac, char **av) {
120         struct zpm pkg;
121         char *s;
122         int opt;
123         char *pkgid;
124
125         struct config conf = { 0 };
126         conf.dbfile = "/var/lib/zpm/local.db";
127
128         if ((s = getenv("ZPMDB"))) {
129                 /* TODO does this need to be copied ? */
130                 conf.dbfile = s;
131         }
132
133         while ((opt = getopt(ac, av, "f:")) != -1) {
134                 switch (opt) {
135                         case 'f': conf.dbfile = optarg;
136                                   break;
137                         default:
138                                   usage();
139                                   exit(EXIT_FAILURE);
140                                   break;
141                 }
142         }
143
144         int argn = optind;
145
146         if (!zpm_open(&pkg, conf.dbfile)) {
147                 fprintf(stderr, "can't open zpm db %s\n", conf.dbfile);
148                 exit(EXIT_FAILURE);
149         }
150         char *errmsg = 0;
151
152         if (argn < ac) {
153                 pkgid = av[argn];
154                 argn++;
155         } else {
156                 fprintf(stderr, "must specify pkgid\n");
157                 usage();
158                 exit(EXIT_FAILURE);
159         }
160
161         /* TODO lookup pkgid via zpm-findpkg equivalent */
162
163         if (!zpm_foreach_path(&pkg, pkgid, 0, count_plan, &conf, &errmsg)) {
164                 if (errmsg) {
165                         fprintf(stderr, "database error: %s\n", errmsg);
166                         exit(EXIT_FAILURE);
167                 }
168                 if (pkg.error == 1) {
169                         fprintf(stderr, "unable to allocate memory\n");
170                 }
171                 fprintf(stderr, "unable to plan\n");
172                 exit(EXIT_FAILURE);
173         }
174
175         plan(conf.plan);
176
177         if (!zpm_foreach_path(&pkg, pkgid, 0, verify, &conf, &errmsg)) {
178                 if (errmsg) {
179                         fprintf(stderr, "database error: %s\n", errmsg);
180                         exit(EXIT_FAILURE);
181                 }
182                 if (pkg.error == 1) {
183                         fprintf(stderr, "unable to allocate memory\n");
184                 }
185                 exit(EXIT_FAILURE);
186         }
187
188         zpm_close(&pkg);
189         return conf.failed ? 1 : 0;
190 }