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