Branch data Line data Source code
1 : : /*-
2 : : * Copyright (c) 2011-2016 Baptiste Daroussin <bapt@FreeBSD.org>
3 : : * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
4 : : * Copyright (c) 2012 Bryan Drewery <bryan@shatow.net>
5 : : * Copyright (c) 2013 Matthew Seaman <matthew@FreeBSD.org>
6 : : * Copyright (c) 2017 Vsevolod Stakhov <vsevolod@FreeBSD.org>
7 : : * All rights reserved.
8 : : *
9 : : * Redistribution and use in source and binary forms, with or without
10 : : * modification, are permitted provided that the following conditions
11 : : * are met:
12 : : * 1. Redistributions of source code must retain the above copyright
13 : : * notice, this list of conditions and the following disclaimer
14 : : * in this position and unchanged.
15 : : * 2. Redistributions in binary form must reproduce the above copyright
16 : : * notice, this list of conditions and the following disclaimer in the
17 : : * documentation and/or other materials provided with the distribution.
18 : : *
19 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
20 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 : : * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
23 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 : : */
30 : :
31 : : #include <archive.h>
32 : : #include <archive_entry.h>
33 : : #include <assert.h>
34 : : #include <errno.h>
35 : : #include <fcntl.h>
36 : : #include <string.h>
37 : :
38 : : #include "pkg.h"
39 : : #include "private/event.h"
40 : : #include "private/pkg.h"
41 : : #include "private/pkgdb.h"
42 : : #include "private/utils.h"
43 : :
44 : : int
45 : 6949 : pkg_new(struct pkg **pkg, pkg_t type)
46 : : {
47 : 6949 : *pkg = xcalloc(1, sizeof(struct pkg));
48 : 6949 : (*pkg)->type = type;
49 : 6949 : (*pkg)->rootfd = -1;
50 : :
51 : 6949 : return (EPKG_OK);
52 : : }
53 : :
54 : : static void
55 : 544 : pkg_message_free(struct pkg_message *m)
56 : : {
57 : 544 : free(m->str);
58 : 544 : free(m->maximum_version);
59 : 544 : free(m->minimum_version);
60 : 544 : free(m);
61 : 544 : }
62 : :
63 : : void
64 : 10576 : pkg_free(struct pkg *pkg)
65 : : {
66 [ + + ]: 10576 : if (pkg == NULL)
67 : 4295 : return;
68 : :
69 : 6281 : free(pkg->name);
70 : 6281 : free(pkg->origin);
71 : 6281 : free(pkg->old_version);
72 : 6281 : free(pkg->version);
73 : 6281 : free(pkg->maintainer);
74 : 6281 : free(pkg->www);
75 : 6281 : free(pkg->arch);
76 : 6281 : free(pkg->abi);
77 : 6281 : free(pkg->uid);
78 : 6281 : free(pkg->digest);
79 : 6281 : free(pkg->old_digest);
80 : 6281 : free(pkg->prefix);
81 : 6281 : free(pkg->comment);
82 : 6281 : free(pkg->desc);
83 : 6281 : free(pkg->sum);
84 : 6281 : free(pkg->repopath);
85 : 6281 : free(pkg->repourl);
86 : 6281 : free(pkg->reason);
87 : 6281 : free(pkg->dep_formula);
88 : :
89 [ + + ]: 62810 : for (int i = 0; i < PKG_NUM_SCRIPTS; i++)
90 : 56529 : xstring_free(pkg->scripts[i]);
91 : :
92 : 6281 : pkg_list_free(pkg, PKG_DEPS);
93 : 6281 : pkg_list_free(pkg, PKG_RDEPS);
94 : 6281 : pkg_list_free(pkg, PKG_FILES);
95 : 6281 : pkg_list_free(pkg, PKG_DIRS);
96 : 6281 : pkg_list_free(pkg, PKG_OPTIONS);
97 : 6281 : pkg_list_free(pkg, PKG_USERS);
98 : 6281 : pkg_list_free(pkg, PKG_GROUPS);
99 : 6281 : pkg_list_free(pkg, PKG_SHLIBS_REQUIRED);
100 : 6281 : pkg_list_free(pkg, PKG_SHLIBS_PROVIDED);
101 : 6281 : pkg_list_free(pkg, PKG_PROVIDES);
102 : 6281 : pkg_list_free(pkg, PKG_REQUIRES);
103 : 6281 : pkg_list_free(pkg, PKG_CATEGORIES);
104 : 6281 : pkg_list_free(pkg, PKG_LICENSES);
105 : :
106 [ + + + + : 6825 : DL_FREE(pkg->message, pkg_message_free);
+ - + + -
+ # # ]
107 [ + + + + : 10979 : DL_FREE(pkg->annotations, pkg_kv_free);
+ - + + -
+ # # ]
108 : :
109 [ + + ]: 6281 : if (pkg->rootfd != -1)
110 : 1019 : close(pkg->rootfd);
111 : :
112 : 6281 : free(pkg);
113 : 10576 : }
114 : :
115 : : pkg_t
116 : 239 : pkg_type(const struct pkg * restrict pkg)
117 : : {
118 [ + - ]: 239 : assert(pkg != NULL);
119 : :
120 : 239 : return (pkg->type);
121 : : }
122 : :
123 : : int
124 : 3169 : pkg_is_valid(const struct pkg * restrict pkg)
125 : : {
126 [ + - ]: 3169 : if (pkg == NULL) {
127 : 0 : pkg_emit_error("Invalid package: not allocated");
128 : 0 : return (EPKG_FATAL);
129 : : }
130 : :
131 [ + + ]: 3169 : if (pkg->origin == NULL) {
132 : 39 : pkg_emit_error("Invalid package: object has missing property origin");
133 : 39 : return (EPKG_FATAL);
134 : : }
135 : :
136 [ + + ]: 3130 : if (pkg->name == NULL) {
137 : 39 : pkg_emit_error("Invalid package: object has missing property name");
138 : 39 : return (EPKG_FATAL);
139 : : }
140 : :
141 [ + + ]: 3091 : if (pkg->comment == NULL) {
142 : 39 : pkg_emit_error("Invalid package: object has missing property comment");
143 : 39 : return (EPKG_FATAL);
144 : : }
145 : :
146 [ + + ]: 3052 : if (pkg->version == NULL) {
147 : 39 : pkg_emit_error("Invalid package: object has missing property version");
148 : 39 : return (EPKG_FATAL);
149 : : }
150 : :
151 [ + + ]: 3013 : if (pkg->desc == NULL) {
152 : 39 : pkg_emit_error("Invalid package: object has missing property desc");
153 : 39 : return (EPKG_FATAL);
154 : : }
155 : :
156 [ + + ]: 2974 : if (pkg->maintainer == NULL) {
157 : 39 : pkg_emit_error("Invalid package: object has missing property maintainer");
158 : 39 : return (EPKG_FATAL);
159 : : }
160 : :
161 [ + + ]: 2935 : if (pkg->www == NULL) {
162 : 39 : pkg_emit_error("Invalid package: object has missing property www");
163 : 39 : return (EPKG_FATAL);
164 : : }
165 : :
166 [ + + ]: 2896 : if (pkg->prefix == NULL) {
167 : 39 : pkg_emit_error("Invalid package: object has missing property prefix");
168 : 39 : return (EPKG_FATAL);
169 : : }
170 : :
171 : 2857 : return (EPKG_OK);
172 : 3169 : }
173 : :
174 : : static int
175 : 1859 : pkg_vget(const struct pkg * restrict pkg, va_list ap)
176 : : {
177 : : int attr;
178 : :
179 [ + + + + ]: 5459 : while ((attr = va_arg(ap, int)) > 0) {
180 : :
181 [ + - - + ]: 3600 : if (attr >= PKG_NUM_FIELDS || attr <= 0) {
182 : 0 : pkg_emit_error("Bad argument on pkg_get %d", attr);
183 : 0 : return (EPKG_FATAL);
184 : : }
185 : :
186 [ - - + + : 3600 : switch (attr) {
- - - - -
- - - - +
+ - + + -
+ + + + -
+ - - - +
- - - + ]
187 : : case PKG_ORIGIN:
188 [ # # ]: 0 : *va_arg(ap, const char **) = pkg->origin;
189 : 0 : break;
190 : : case PKG_NAME:
191 [ + - ]: 4 : *va_arg(ap, const char **) = pkg->name;
192 : 4 : break;
193 : : case PKG_VERSION:
194 [ + - ]: 288 : *va_arg(ap, const char **) = pkg->version;
195 : 288 : break;
196 : : case PKG_COMMENT:
197 [ # # ]: 0 : *va_arg(ap, const char **) = pkg->comment;
198 : 0 : break;
199 : : case PKG_DESC:
200 [ # # ]: 0 : *va_arg(ap, const char **) = pkg->desc;
201 : 0 : break;
202 : : case PKG_MTREE:
203 [ # # ]: 0 : *va_arg(ap, const char **) = NULL;
204 : 0 : break;
205 : : case PKG_MESSAGE:
206 [ # # # # ]: 0 : *va_arg(ap, const char **) = pkg->message ? pkg->message->str : NULL;
207 : 0 : break;
208 : : case PKG_ARCH:
209 [ # # ]: 0 : *va_arg(ap, const char **) = pkg->arch;
210 : 0 : break;
211 : : case PKG_ABI:
212 [ # # ]: 0 : *va_arg(ap, const char **) = pkg->abi;
213 : 0 : break;
214 : : case PKG_WWW:
215 [ # # ]: 0 : *va_arg(ap, const char **) = pkg->www;
216 : 0 : break;
217 : : case PKG_MAINTAINER:
218 [ # # ]: 0 : *va_arg(ap, const char **) = pkg->maintainer;
219 : 0 : break;
220 : : case PKG_PREFIX:
221 [ # # ]: 0 : *va_arg(ap, const char **) = pkg->prefix;
222 : 0 : break;
223 : : case PKG_REPOPATH:
224 [ - + ]: 521 : *va_arg(ap, const char **) = pkg->repopath;
225 : 521 : break;
226 : : case PKG_CKSUM:
227 [ + - ]: 8 : *va_arg(ap, const char **) = pkg->sum;
228 : 8 : break;
229 : : case PKG_OLD_VERSION:
230 [ # # ]: 0 : *va_arg(ap, const char **) = pkg->old_version;
231 : 0 : break;
232 : : case PKG_REPONAME:
233 [ + - ]: 16 : *va_arg(ap, const char **) = pkg->reponame;
234 : 16 : break;
235 : : case PKG_REPOURL:
236 [ + - ]: 181 : *va_arg(ap, const char **) = pkg->repourl;
237 : 181 : break;
238 : : case PKG_DIGEST:
239 [ # # ]: 0 : *va_arg(ap, const char **) = pkg->digest;
240 : 0 : break;
241 : : case PKG_REASON:
242 [ + - ]: 210 : *va_arg(ap, const char **) = pkg->reason;
243 : 210 : break;
244 : : case PKG_FLATSIZE:
245 [ + - ]: 858 : *va_arg(ap, int64_t *) = pkg->flatsize;
246 : 858 : break;
247 : : case PKG_OLD_FLATSIZE:
248 [ - + ]: 181 : *va_arg(ap, int64_t *) = pkg->old_flatsize;
249 : 181 : break;
250 : : case PKG_PKGSIZE:
251 [ + + ]: 1223 : *va_arg(ap, int64_t *) = pkg->pkgsize;
252 : 1223 : break;
253 : : case PKG_LICENSE_LOGIC:
254 [ # # ]: 0 : *va_arg(ap, lic_t *) = pkg->licenselogic;
255 : 0 : break;
256 : : case PKG_AUTOMATIC:
257 [ + - ]: 46 : *va_arg(ap, bool *) = pkg->automatic;
258 : 46 : break;
259 : : case PKG_LOCKED:
260 [ # # ]: 0 : *va_arg(ap, bool *) = pkg->locked;
261 : 0 : break;
262 : : case PKG_ROWID:
263 [ # # ]: 0 : *va_arg(ap, int64_t *) = pkg->id;
264 : 0 : break;
265 : : case PKG_TIME:
266 [ # # ]: 0 : *va_arg(ap, int64_t *) = pkg->timestamp;
267 : 0 : break;
268 : : case PKG_ANNOTATIONS:
269 [ + - ]: 40 : *va_arg(ap, const struct pkg_kv **) = pkg->annotations;
270 : 40 : break;
271 : : case PKG_UNIQUEID:
272 [ # # ]: 0 : *va_arg(ap, const char **) = pkg->uid;
273 : 0 : break;
274 : : case PKG_OLD_DIGEST:
275 [ # # ]: 0 : *va_arg(ap, const char **) = pkg->old_digest;
276 : 0 : break;
277 : : case PKG_DEP_FORMULA:
278 [ # # ]: 0 : *va_arg(ap, const char **) = pkg->dep_formula;
279 : 0 : break;
280 : : case PKG_VITAL:
281 [ + - ]: 24 : *va_arg(ap, bool *) = pkg->vital;
282 : 24 : break;
283 : : }
284 : : }
285 : :
286 : 1859 : return (EPKG_OK);
287 : 1859 : }
288 : :
289 : : int
290 : 1859 : pkg_get2(const struct pkg * restrict pkg, ...)
291 : : {
292 : 1859 : int ret = EPKG_OK;
293 : : va_list ap;
294 : :
295 [ + - ]: 1859 : assert(pkg != NULL);
296 : :
297 : 1859 : va_start(ap, pkg);
298 : 1859 : ret = pkg_vget(pkg, ap);
299 : 1859 : va_end(ap);
300 : :
301 : 1859 : return (ret);
302 : : }
303 : :
304 : : static int
305 : 388 : pkg_vset(struct pkg *pkg, va_list ap)
306 : : {
307 : : int attr;
308 : : const char *buf;
309 : : ucl_object_t *obj;
310 : : struct pkg_message *msg;
311 : :
312 [ + - + + ]: 776 : while ((attr = va_arg(ap, int)) > 0) {
313 [ + - - + ]: 388 : if (attr >= PKG_NUM_FIELDS || attr <= 0) {
314 : 0 : pkg_emit_error("Bad argument on pkg_set %d", attr);
315 : 0 : return (EPKG_FATAL);
316 : : }
317 : :
318 [ - + + + : 388 : switch (attr) {
+ + - - -
- + + + -
- - - - -
- - - - -
+ - - - -
- ]
319 : : case PKG_NAME:
320 : 39 : free(pkg->name);
321 [ + - ]: 39 : pkg->name = xstrdup(va_arg(ap, const char *));
322 : 39 : free(pkg->uid);
323 : 39 : pkg->uid = xstrdup(pkg->name);
324 : 39 : break;
325 : : case PKG_ORIGIN:
326 : 39 : free(pkg->origin);
327 [ + - ]: 39 : pkg->origin = xstrdup(va_arg(ap, const char *));
328 : 39 : break;
329 : : case PKG_VERSION:
330 : 39 : free(pkg->version);
331 [ + - ]: 39 : pkg->version = xstrdup(va_arg(ap, const char *));
332 : 39 : break;
333 : : case PKG_COMMENT:
334 : 39 : free(pkg->comment);
335 [ + - ]: 39 : pkg->comment = xstrdup(va_arg(ap, const char *));
336 : 39 : break;
337 : : case PKG_DESC:
338 : 39 : free(pkg->desc);
339 [ + - ]: 39 : pkg->desc = xstrdup(va_arg(ap, const char *));
340 : 39 : break;
341 : : case PKG_MTREE:
342 [ # # ]: 0 : (void)va_arg(ap, const char *);
343 : 0 : break;
344 : : case PKG_MESSAGE:
345 [ # # ]: 0 : LL_FOREACH(pkg->message, msg) {
346 : 0 : pkg_message_free(msg);
347 : 0 : }
348 [ # # ]: 0 : buf = va_arg(ap, const char *);
349 [ # # ]: 0 : if (*buf == '[') {
350 : 0 : pkg_message_from_str(pkg, buf, strlen(buf));
351 : 0 : } else {
352 : 0 : obj = ucl_object_fromstring_common(buf, strlen(buf),
353 : : UCL_STRING_RAW|UCL_STRING_TRIM);
354 : 0 : pkg_message_from_ucl(pkg, obj);
355 : 0 : ucl_object_unref(obj);
356 : : }
357 : 0 : break;
358 : : case PKG_ARCH:
359 : 0 : free(pkg->arch);
360 [ # # ]: 0 : pkg->arch = xstrdup(va_arg(ap, const char *));
361 : 0 : break;
362 : : case PKG_ABI:
363 : 0 : free(pkg->abi);
364 [ # # ]: 0 : pkg->abi = xstrdup(va_arg(ap, const char *));
365 : 0 : break;
366 : : case PKG_MAINTAINER:
367 : 39 : free(pkg->maintainer);
368 [ + - ]: 39 : pkg->maintainer = xstrdup(va_arg(ap, const char *));
369 : 39 : break;
370 : : case PKG_WWW:
371 : 39 : free(pkg->www);
372 [ + - ]: 39 : pkg->www = xstrdup(va_arg(ap, const char *));
373 : 39 : break;
374 : : case PKG_PREFIX:
375 : 76 : free(pkg->prefix);
376 [ + - ]: 76 : pkg->prefix = xstrdup(va_arg(ap, const char *));
377 : 76 : break;
378 : : case PKG_REPOPATH:
379 : 0 : free(pkg->repopath);
380 [ # # ]: 0 : pkg->repopath = xstrdup(va_arg(ap, const char *));
381 : 0 : break;
382 : : case PKG_CKSUM:
383 : 0 : free(pkg->sum);
384 [ # # ]: 0 : pkg->sum = xstrdup(va_arg(ap, const char *));
385 : 0 : break;
386 : : case PKG_OLD_VERSION:
387 : 0 : free(pkg->old_version);
388 [ # # ]: 0 : pkg->old_version = xstrdup(va_arg(ap, const char *));
389 : 0 : break;
390 : : case PKG_REPONAME:
391 : 0 : free(pkg->reponame);
392 [ # # ]: 0 : pkg->reponame = xstrdup(va_arg(ap, const char *));
393 : 0 : break;
394 : : case PKG_REPOURL:
395 : 0 : free(pkg->repourl);
396 [ # # ]: 0 : pkg->repourl = xstrdup(va_arg(ap, const char *));
397 : 0 : break;
398 : : case PKG_DIGEST:
399 : 0 : free(pkg->digest);
400 [ # # ]: 0 : pkg->digest = xstrdup(va_arg(ap, const char *));
401 : 0 : break;
402 : : case PKG_REASON:
403 : 0 : free(pkg->reason);
404 [ # # ]: 0 : pkg->reason = xstrdup(va_arg(ap, const char *));
405 : 0 : break;
406 : : case PKG_FLATSIZE:
407 [ # # ]: 0 : pkg->flatsize = va_arg(ap, int64_t);
408 : 0 : break;
409 : : case PKG_OLD_FLATSIZE:
410 [ # # ]: 0 : pkg->old_flatsize = va_arg(ap, int64_t);
411 : 0 : break;
412 : : case PKG_PKGSIZE:
413 [ # # ]: 0 : pkg->pkgsize = va_arg(ap, int64_t);
414 : 0 : break;
415 : : case PKG_LICENSE_LOGIC:
416 [ # # ]: 0 : pkg->licenselogic = (lic_t)va_arg(ap, int);
417 : 0 : break;
418 : : case PKG_AUTOMATIC:
419 [ + - ]: 39 : pkg->automatic = (bool)va_arg(ap, int);
420 : 39 : break;
421 : : case PKG_ROWID:
422 [ # # ]: 0 : pkg->id = va_arg(ap, int64_t);
423 : 0 : break;
424 : : case PKG_LOCKED:
425 [ # # ]: 0 : pkg->locked = (bool)va_arg(ap, int);
426 : 0 : break;
427 : : case PKG_TIME:
428 [ # # ]: 0 : pkg->timestamp = va_arg(ap, int64_t);
429 : 0 : break;
430 : : case PKG_DEP_FORMULA:
431 : 0 : free(pkg->dep_formula);
432 [ # # ]: 0 : pkg->dep_formula = xstrdup(va_arg(ap, const char *));
433 : 0 : break;
434 : : case PKG_VITAL:
435 [ # # ]: 0 : pkg->vital = (bool)va_arg(ap, int);
436 : 0 : break;
437 : : }
438 : : }
439 : :
440 : 388 : return (EPKG_OK);
441 : 388 : }
442 : :
443 : : int
444 : 388 : pkg_set2(struct pkg *pkg, ...)
445 : : {
446 : 388 : int ret = EPKG_OK;
447 : : va_list ap;
448 : :
449 [ + - ]: 388 : assert(pkg != NULL);
450 : :
451 : 388 : va_start(ap, pkg);
452 : 388 : ret = pkg_vset(pkg, ap);
453 : 388 : va_end(ap);
454 : :
455 : 388 : return (ret);
456 : : }
457 : :
458 : : int
459 : 0 : pkg_set_from_fileat(int fd, struct pkg *pkg, pkg_attr attr, const char *path,
460 : : bool trimcr)
461 : : {
462 : 0 : char *buf = NULL;
463 : : char *cp;
464 : 0 : off_t size = 0;
465 : 0 : int ret = EPKG_OK;
466 : :
467 [ # # ]: 0 : assert(pkg != NULL);
468 [ # # ]: 0 : assert(path != NULL);
469 : :
470 [ # # ]: 0 : if ((ret = file_to_bufferat(fd, path, &buf, &size)) != EPKG_OK)
471 : 0 : return (ret);
472 : :
473 [ # # ]: 0 : if (trimcr) {
474 : 0 : cp = buf + strlen(buf) - 1;
475 [ # # # # ]: 0 : while (cp > buf && *cp == '\n') {
476 : 0 : *cp = 0;
477 : 0 : cp--;
478 : : }
479 : 0 : }
480 : :
481 : 0 : ret = pkg_set(pkg, attr, buf);
482 : :
483 : 0 : free(buf);
484 : :
485 : 0 : return (ret);
486 : 0 : }
487 : :
488 : : #define pkg_each(name, type, field) \
489 : : int \
490 : : pkg_##name(const struct pkg *p, type **t) { \
491 : : assert(p != NULL); \
492 : : if ((*t) == NULL) \
493 : : (*t) = p->field; \
494 : : else \
495 : : (*t) = (*t)->next; \
496 : : if ((*t) == NULL) \
497 : : return (EPKG_END); \
498 : : return (EPKG_OK); \
499 : : }
500 : :
501 [ + - + + : 4328 : pkg_each(dirs, struct pkg_dir, dirs);
+ + ]
502 [ + - + + : 14258 : pkg_each(files, struct pkg_file, files);
+ + ]
503 [ + - + + : 8405 : pkg_each(deps, struct pkg_dep, depends);
+ + ]
504 [ + - + + : 2031 : pkg_each(rdeps, struct pkg_dep, rdepends);
+ + ]
505 [ + - + + : 5408 : pkg_each(options, struct pkg_option, options);
+ + ]
506 [ + - + + : 3977 : pkg_each(conflicts, struct pkg_conflict, conflicts);
+ + ]
507 [ + - + + : 2947 : pkg_each(config_files, struct pkg_config_file, config_files);
+ + ]
508 : :
509 : : #define pkg_each_string_hash(name) \
510 : : int \
511 : : pkg_##name(const struct pkg *pkg, char **c) { \
512 : : if ((*c) == NULL) \
513 : : pkghash_loopinit(pkg->name); \
514 : : pkghash_entry *e = pkghash_inext(pkg->name); \
515 : : if (e == NULL) { \
516 : : (*c) = NULL; \
517 : : return (EPKG_END); \
518 : : } \
519 : : (*c) = e->key; \
520 : : return (EPKG_OK); \
521 : : }
522 : :
523 [ # # # # ]: 0 : pkg_each_string_hash(categories);
524 [ # # # # ]: 0 : pkg_each_string_hash(licenses);
525 [ # # # # ]: 0 : pkg_each_string_hash(requires);
526 [ # # # # ]: 0 : pkg_each_string_hash(provides);
527 [ # # # # ]: 0 : pkg_each_string_hash(shlibs_required);
528 [ # # # # ]: 0 : pkg_each_string_hash(shlibs_provided);
529 [ # # # # ]: 0 : pkg_each_string_hash(users);
530 [ # # # # ]: 0 : pkg_each_string_hash(groups);
531 : :
532 : : int
533 : 0 : pkg_adduser(struct pkg *pkg, const char *name)
534 : : {
535 [ # # ]: 0 : assert(pkg != NULL);
536 [ # # ]: 0 : assert(name != NULL && name[0] != '\0');
537 : :
538 [ # # ]: 0 : if (pkghash_get(pkg->users, name) != NULL) {
539 [ # # ]: 0 : if (ctx.developer_mode) {
540 : 0 : pkg_emit_error("duplicate user listing: %s, fatal (developer mode)", name);
541 : 0 : return (EPKG_FATAL);
542 : : } else {
543 : 0 : pkg_emit_error("duplicate user listing: %s, ignoring", name);
544 : 0 : return (EPKG_OK);
545 : : }
546 : : }
547 : :
548 [ # # # # ]: 0 : pkghash_safe_add(pkg->users, name, NULL, NULL);
549 : :
550 : 0 : return (EPKG_OK);
551 : 0 : }
552 : :
553 : : int
554 : 0 : pkg_addgroup(struct pkg *pkg, const char *name)
555 : : {
556 [ # # ]: 0 : assert(pkg != NULL);
557 [ # # ]: 0 : assert(name != NULL && name[0] != '\0');
558 : :
559 [ # # ]: 0 : if (pkghash_get(pkg->groups, name) != NULL) {
560 [ # # ]: 0 : if (ctx.developer_mode) {
561 : 0 : pkg_emit_error("duplicate group listing: %s, fatal (developer mode)", name);
562 : 0 : return (EPKG_FATAL);
563 : : } else {
564 : 0 : pkg_emit_error("duplicate group listing: %s, ignoring", name);
565 : 0 : return (EPKG_OK);
566 : : }
567 : : }
568 : :
569 [ # # # # ]: 0 : pkghash_safe_add(pkg->groups, name, NULL, NULL);
570 : :
571 : 0 : return (EPKG_OK);
572 : 0 : }
573 : :
574 : : int
575 : 1723 : pkg_adddep(struct pkg *pkg, const char *name, const char *origin, const char *version, bool locked)
576 : : {
577 [ - + ]: 1723 : if (pkg_adddep_chain(NULL, pkg, name, origin, version, locked) == NULL) {
578 : 0 : return (EPKG_FATAL);
579 : : }
580 : :
581 : 1723 : return (EPKG_OK);
582 : 1723 : }
583 : :
584 : : struct pkg_dep *
585 : 1723 : pkg_adddep_chain(struct pkg_dep *chain,
586 : : struct pkg *pkg,
587 : : const char *name,
588 : : const char *origin,
589 : : const char *version, bool locked)
590 : : {
591 : 1723 : struct pkg_dep *d = NULL;
592 : :
593 [ + - ]: 1723 : assert(pkg != NULL);
594 [ + - ]: 1723 : assert(name != NULL && name[0] != '\0');
595 [ + - ]: 1723 : assert(origin != NULL && origin[0] != '\0');
596 : :
597 : 1723 : pkg_debug(3, "Pkg: add a new dependency origin: %s, name: %s", origin, name);
598 [ - + ]: 1723 : if (pkghash_get(pkg->depshash, name) != NULL) {
599 : 0 : pkg_emit_error("%s: duplicate dependency listing: %s",
600 : 0 : pkg->name, name);
601 : 0 : return (NULL);
602 : : }
603 : :
604 : 1723 : d = xcalloc(1, sizeof(*d));
605 : 1723 : d->origin = xstrdup(origin);
606 : 1723 : d->name = xstrdup(name);
607 [ + + + - ]: 1723 : if (version != NULL && version[0] != '\0')
608 : 1393 : d->version = xstrdup(version);
609 : 1723 : d->uid = xstrdup(name);
610 : 1723 : d->locked = locked;
611 : :
612 [ + + - + ]: 2045 : pkghash_safe_add(pkg->depshash, d->name, d, NULL);
613 [ - + ]: 1723 : if (chain == NULL) {
614 [ + + ]: 1723 : DL_APPEND(pkg->depends, d);
615 : 1723 : chain = pkg->depends;
616 : 1723 : }
617 : : else {
618 [ # # ]: 0 : DL_APPEND2(chain, d, alt_prev, alt_next);
619 : : }
620 : :
621 : 1723 : return (chain);
622 : 1723 : }
623 : :
624 : : int
625 : 132 : pkg_addrdep(struct pkg *pkg, const char *name, const char *origin, const char *version, bool locked)
626 : : {
627 : : struct pkg_dep *d;
628 : :
629 [ + - ]: 132 : assert(pkg != NULL);
630 [ + - ]: 132 : assert(name != NULL && name[0] != '\0');
631 [ + - ]: 132 : assert(origin != NULL && origin[0] != '\0');
632 : :
633 : 132 : pkg_debug(3, "Pkg: add a new reverse dependency origin: %s, name: %s", origin, name);
634 : :
635 : 132 : d = xcalloc(1, sizeof(*d));
636 : 132 : d->origin = xstrdup(origin);
637 : 132 : d->name = xstrdup(name);
638 [ + - - + ]: 132 : if (version != NULL && version[0] != '\0')
639 : 132 : d->version = xstrdup(version);
640 : 132 : d->uid = xstrdup(name);
641 : 132 : d->locked = locked;
642 : :
643 [ + + - + ]: 156 : pkghash_safe_add(pkg->rdepshash, d->name, d, NULL);
644 : 132 : LL_PREPEND(pkg->rdepends, d);
645 : :
646 : 132 : return (EPKG_OK);
647 : : }
648 : :
649 : : int
650 : 2879 : pkg_addfile(struct pkg *pkg, const char *path, const char *sum, bool check_duplicates)
651 : : {
652 : 2879 : return (pkg_addfile_attr(pkg, path, sum, NULL, NULL, 0, 0, check_duplicates));
653 : : }
654 : :
655 : : int
656 : 3149 : pkg_addfile_attr(struct pkg *pkg, const char *path, const char *sum,
657 : : const char *uname, const char *gname, mode_t perm, u_long fflags,
658 : : bool check_duplicates)
659 : : {
660 : 3149 : struct pkg_file *f = NULL;
661 : : char abspath[MAXPATHLEN];
662 : :
663 [ + - ]: 3149 : assert(pkg != NULL);
664 [ + - ]: 3149 : assert(path != NULL && path[0] != '\0');
665 : :
666 : 3149 : path = pkg_absolutepath(path, abspath, sizeof(abspath), false);
667 : 3149 : pkg_debug(3, "Pkg: add new file '%s'", path);
668 : :
669 [ + + + - ]: 3149 : if (check_duplicates && pkghash_get(pkg->filehash, path) != NULL) {
670 [ # # ]: 0 : if (ctx.developer_mode) {
671 : 0 : pkg_emit_error("duplicate file listing: %s, fatal (developer mode)", path);
672 : 0 : return (EPKG_FATAL);
673 : : } else {
674 : 0 : pkg_emit_error("duplicate file listing: %s, ignoring", path);
675 : 0 : return (EPKG_OK);
676 : : }
677 : : }
678 : :
679 : 3149 : f = xcalloc(1, sizeof(*f));
680 : 3149 : strlcpy(f->path, path, sizeof(f->path));
681 : :
682 [ + + ]: 3149 : if (sum != NULL)
683 : 2199 : f->sum = xstrdup(sum);
684 : :
685 [ + + ]: 3149 : if (uname != NULL)
686 : 258 : strlcpy(f->uname, uname, sizeof(f->uname));
687 : :
688 [ + + ]: 3149 : if (gname != NULL)
689 : 258 : strlcpy(f->gname, gname, sizeof(f->gname));
690 : :
691 [ + + ]: 3149 : if (perm != 0)
692 : 32 : f->perm = perm;
693 : :
694 [ + + ]: 3149 : if (fflags != 0)
695 : 4 : f->fflags = fflags;
696 : :
697 [ + + + - ]: 4350 : pkghash_safe_add(pkg->filehash, f->path, f, NULL);
698 [ + + ]: 3149 : DL_APPEND(pkg->files, f);
699 : :
700 : 3149 : return (EPKG_OK);
701 : 3149 : }
702 : :
703 : : int
704 : 201 : pkg_addconfig_file(struct pkg *pkg, const char *path, const char *content)
705 : : {
706 : 201 : struct pkg_config_file *f = NULL;
707 : : char abspath[MAXPATHLEN];
708 : :
709 : 201 : path = pkg_absolutepath(path, abspath, sizeof(abspath), false);
710 : 201 : pkg_debug(3, "Pkg: add new config file '%s'", path);
711 : :
712 [ + + ]: 201 : if (pkghash_get(pkg->config_files_hash, path) != NULL) {
713 : 16 : pkg_emit_error("duplicate file listing: %s", path);
714 : 16 : return (EPKG_FATAL);
715 : : }
716 : 185 : f = xcalloc(1, sizeof(*f));
717 : 185 : strlcpy(f->path, path, sizeof(f->path));
718 : :
719 [ + + ]: 185 : if (content != NULL)
720 : 70 : f->content = xstrdup(content);
721 : :
722 [ - + # # ]: 185 : pkghash_safe_add(pkg->config_files_hash, f->path, f, NULL);
723 [ - + ]: 185 : DL_APPEND(pkg->config_files, f);
724 : :
725 : 185 : return (EPKG_OK);
726 : 201 : }
727 : :
728 : : int
729 : 3407 : pkg_addstring(pkghash **list, const char *val, const char *title)
730 : : {
731 [ + - ]: 3407 : assert(val != NULL);
732 [ - + ]: 3407 : assert(title != NULL);
733 : :
734 [ - + ]: 3407 : if (pkghash_get(*list, val) != NULL) {
735 [ # # ]: 0 : if (ctx.developer_mode) {
736 : 0 : pkg_emit_error("duplicate %s listing: %s, fatal"
737 : 0 : " (developer mode)", title, val);
738 : 0 : return (EPKG_FATAL);
739 : : } else {
740 : 0 : pkg_emit_error("duplicate %s listing: %s, "
741 : 0 : "ignoring", title, val);
742 : 0 : return (EPKG_OK);
743 : : }
744 : : }
745 : :
746 [ - + # # ]: 3407 : pkghash_safe_add(*list, val, NULL, NULL);
747 : :
748 : 3407 : return (EPKG_OK);
749 : 3407 : }
750 : :
751 : : int
752 : 152 : pkg_adddir(struct pkg *pkg, const char *path, bool check_duplicates)
753 : : {
754 : 152 : return(pkg_adddir_attr(pkg, path, NULL, NULL, 0, 0, check_duplicates));
755 : : }
756 : :
757 : : int
758 : 172 : pkg_adddir_attr(struct pkg *pkg, const char *path, const char *uname,
759 : : const char *gname, mode_t perm, u_long fflags, bool check_duplicates)
760 : : {
761 : 172 : struct pkg_dir *d = NULL;
762 : : char abspath[MAXPATHLEN];
763 : :
764 [ + - ]: 172 : assert(pkg != NULL);
765 [ + - ]: 172 : assert(path != NULL && path[0] != '\0');
766 : :
767 [ + - ]: 172 : if (strcmp(path, "/") == 0) {
768 : 0 : pkg_emit_error("skipping useless directory: '%s'\n", path);
769 : 0 : return (EPKG_OK);
770 : : }
771 : 172 : path = pkg_absolutepath(path, abspath, sizeof(abspath), false);
772 : 172 : pkg_debug(3, "Pkg: add new directory '%s'", path);
773 [ + + + - ]: 172 : if (check_duplicates && pkghash_get(pkg->dirhash, path) != NULL) {
774 [ # # ]: 0 : if (ctx.developer_mode) {
775 : 0 : pkg_emit_error("duplicate directory listing: %s, fatal (developer mode)", path);
776 : 0 : return (EPKG_FATAL);
777 : : } else {
778 : 0 : pkg_emit_error("duplicate directory listing: %s, ignoring", path);
779 : 0 : return (EPKG_OK);
780 : : }
781 : : }
782 : :
783 : 172 : d = xcalloc(1, sizeof(*d));
784 : 172 : strlcpy(d->path, path, sizeof(d->path));
785 : :
786 [ + + ]: 172 : if (uname != NULL)
787 : 20 : strlcpy(d->uname, uname, sizeof(d->uname));
788 : :
789 [ + + ]: 172 : if (gname != NULL)
790 : 20 : strlcpy(d->gname, gname, sizeof(d->gname));
791 : :
792 [ + - ]: 172 : if (perm != 0)
793 : 0 : d->perm = perm;
794 : :
795 [ + - ]: 172 : if (fflags != 0)
796 : 0 : d->fflags = fflags;
797 : :
798 [ + + - + ]: 226 : pkghash_safe_add(pkg->dirhash, d->path, d, NULL);
799 [ + + ]: 172 : DL_APPEND(pkg->dirs, d);
800 : :
801 : 172 : return (EPKG_OK);
802 : 172 : }
803 : :
804 : : int
805 : 699 : pkg_addscript(struct pkg *pkg, const char *data, pkg_script type)
806 : : {
807 : :
808 [ + - ]: 699 : assert(pkg != NULL);
809 [ - + ]: 699 : xstring_renew(pkg->scripts[type]);
810 : 699 : fprintf(pkg->scripts[type]->fp, "%s", data);
811 : :
812 : 699 : return (EPKG_OK);
813 : : }
814 : :
815 : : int
816 : 20 : pkg_add_lua_script(struct pkg *pkg, const char *data, pkg_lua_script type)
817 : : {
818 [ + - ]: 20 : assert(pkg != NULL);
819 : : struct pkg_lua_script *lua;
820 : :
821 [ - + ]: 20 : if (type >= PKG_LUA_UNKNOWN)
822 : 0 : return (EPKG_FATAL);
823 : :
824 : 20 : lua = xcalloc(1, sizeof(*lua));
825 : 20 : lua->script = xstrdup(data);
826 [ + + ]: 20 : DL_APPEND(pkg->lua_scripts[type], lua);
827 : :
828 : 20 : return (EPKG_OK);
829 : 20 : }
830 : :
831 : : int
832 : 0 : pkg_addluascript_fileat(int fd, struct pkg *pkg, const char *filename)
833 : : {
834 : : char *data;
835 : : pkg_lua_script type;
836 : 0 : int ret = EPKG_OK;
837 : 0 : off_t sz = 0;
838 : :
839 [ # # ]: 0 : assert(pkg != NULL);
840 [ # # ]: 0 : assert(filename != NULL);
841 : :
842 : 0 : pkg_debug(1, "Adding script from: '%s'", filename);
843 : :
844 [ # # ]: 0 : if ((ret = file_to_bufferat(fd, filename, &data, &sz)) != EPKG_OK)
845 : 0 : return (ret);
846 : :
847 [ # # ]: 0 : if (strcmp(filename, "pkg-pre-install.lua") == 0) {
848 : 0 : type = PKG_LUA_PRE_INSTALL;
849 [ # # ]: 0 : } else if (strcmp(filename, "pkg-post-install.lua") == 0) {
850 : 0 : type = PKG_LUA_POST_INSTALL;
851 [ # # ]: 0 : } else if (strcmp(filename, "pkg-pre-deinstall") == 0) {
852 : 0 : type = PKG_LUA_PRE_DEINSTALL;
853 [ # # ]: 0 : } else if (strcmp(filename, "pkg-post-deinstall") == 0) {
854 : 0 : type = PKG_LUA_POST_DEINSTALL;
855 : 0 : } else {
856 : 0 : pkg_emit_error("unknown lua script '%s'", filename);
857 : 0 : ret = EPKG_FATAL;
858 : 0 : goto cleanup;
859 : : }
860 : :
861 : 0 : ret = pkg_add_lua_script(pkg, data, type);
862 : : cleanup:
863 : 0 : free(data);
864 : 0 : return (ret);
865 : 0 : }
866 : :
867 : : int
868 : 0 : pkg_addscript_fileat(int fd, struct pkg *pkg, const char *filename)
869 : : {
870 : : char *data;
871 : : pkg_script type;
872 : 0 : int ret = EPKG_OK;
873 : 0 : off_t sz = 0;
874 : :
875 [ # # ]: 0 : assert(pkg != NULL);
876 [ # # ]: 0 : assert(filename != NULL);
877 : :
878 : 0 : pkg_debug(1, "Adding script from: '%s'", filename);
879 : :
880 [ # # ]: 0 : if ((ret = file_to_bufferat(fd, filename, &data, &sz)) != EPKG_OK)
881 : 0 : return (ret);
882 : :
883 [ # # # # ]: 0 : if (strcmp(filename, "pkg-pre-install") == 0 ||
884 : 0 : strcmp(filename, "+PRE_INSTALL") == 0) {
885 : 0 : type = PKG_SCRIPT_PRE_INSTALL;
886 [ # # # # ]: 0 : } else if (strcmp(filename, "pkg-post-install") == 0 ||
887 : 0 : strcmp(filename, "+POST_INSTALL") == 0) {
888 : 0 : type = PKG_SCRIPT_POST_INSTALL;
889 [ # # # # ]: 0 : } else if (strcmp(filename, "pkg-install") == 0 ||
890 : 0 : strcmp(filename, "+INSTALL") == 0) {
891 : 0 : type = PKG_SCRIPT_INSTALL;
892 [ # # # # ]: 0 : } else if (strcmp(filename, "pkg-pre-deinstall") == 0 ||
893 : 0 : strcmp(filename, "+PRE_DEINSTALL") == 0) {
894 : 0 : type = PKG_SCRIPT_PRE_DEINSTALL;
895 [ # # # # ]: 0 : } else if (strcmp(filename, "pkg-post-deinstall") == 0 ||
896 : 0 : strcmp(filename, "+POST_DEINSTALL") == 0) {
897 : 0 : type = PKG_SCRIPT_POST_DEINSTALL;
898 [ # # # # ]: 0 : } else if (strcmp(filename, "pkg-deinstall") == 0 ||
899 : 0 : strcmp(filename, "+DEINSTALL") == 0) {
900 : 0 : type = PKG_SCRIPT_DEINSTALL;
901 : 0 : } else {
902 : 0 : pkg_emit_error("unknown script '%s'", filename);
903 : 0 : ret = EPKG_FATAL;
904 : 0 : goto cleanup;
905 : : }
906 : :
907 : 0 : ret = pkg_addscript(pkg, data, type);
908 : : cleanup:
909 : 0 : free(data);
910 : 0 : return (ret);
911 : 0 : }
912 : :
913 : : int
914 : 12 : pkg_appendscript(struct pkg *pkg, const char *cmd, pkg_script type)
915 : : {
916 : :
917 [ + - ]: 12 : assert(pkg != NULL);
918 [ + - ]: 12 : assert(cmd != NULL && cmd[0] != '\0');
919 : :
920 [ - + ]: 12 : if (pkg->scripts[type] == NULL)
921 : 12 : pkg->scripts[type] = xstring_new();
922 : :
923 : 12 : fprintf(pkg->scripts[type]->fp, "%s", cmd);
924 : :
925 : 12 : return (EPKG_OK);
926 : : }
927 : :
928 : : int
929 : 840 : pkg_addoption(struct pkg *pkg, const char *key, const char *value)
930 : : {
931 : 840 : struct pkg_option *o = NULL;
932 : :
933 [ + - ]: 840 : assert(pkg != NULL);
934 [ + - ]: 840 : assert(key != NULL && key[0] != '\0');
935 [ + - ]: 840 : assert(value != NULL && value[0] != '\0');
936 : :
937 : : /* There might be a default or description for the option
938 : : already, so we only count it as a duplicate if the value
939 : : field is already set. Which implies there could be a
940 : : default value or description for an option but no actual
941 : : value. */
942 : :
943 : 840 : pkg_debug(2,"Pkg> adding options: %s = %s", key, value);
944 [ - + ]: 840 : if (pkghash_get(pkg->optionshash, key) != NULL) {
945 [ # # ]: 0 : if (ctx.developer_mode) {
946 : 0 : pkg_emit_error("duplicate options listing: %s, fatal (developer mode)", key);
947 : 0 : return (EPKG_FATAL);
948 : : } else {
949 : 0 : pkg_emit_error("duplicate options listing: %s, ignoring", key);
950 : 0 : return (EPKG_OK);
951 : : }
952 : : }
953 : 840 : o = xcalloc(1, sizeof(*o));
954 : 840 : o->key = xstrdup(key);
955 : 840 : o->value = xstrdup(value);
956 [ + + - + ]: 1510 : pkghash_safe_add(pkg->optionshash, o->key, o, NULL);
957 [ + + ]: 840 : DL_APPEND(pkg->options, o);
958 : :
959 : 840 : return (EPKG_OK);
960 : 840 : }
961 : :
962 : : int
963 : 0 : pkg_addoption_default(struct pkg *pkg, const char *key,
964 : : const char *default_value)
965 : : {
966 : 0 : struct pkg_option *o = NULL;
967 : :
968 [ # # ]: 0 : assert(pkg != NULL);
969 [ # # ]: 0 : assert(key != NULL && key[0] != '\0');
970 [ # # ]: 0 : assert(default_value != NULL && default_value[0] != '\0');
971 : :
972 : : /* There might be a value or description for the option
973 : : already, so we only count it as a duplicate if the
974 : : default_value field is already set. Which implies there
975 : : could be a default value or description for an option but
976 : : no actual value. */
977 : :
978 [ # # ]: 0 : if (pkghash_get(pkg->optionshash, key) != NULL) {
979 [ # # ]: 0 : if (ctx.developer_mode) {
980 : 0 : pkg_emit_error("duplicate default value for option: %s, fatal (developer mode)", key);
981 : 0 : return (EPKG_FATAL);
982 : : } else {
983 : 0 : pkg_emit_error("duplicate default value for option: %s, ignoring", key);
984 : 0 : return (EPKG_OK);
985 : : }
986 : : }
987 : 0 : o = xcalloc(1, sizeof(*o));
988 : 0 : o->key = xstrdup(key);
989 : 0 : o->default_value = xstrdup(default_value);
990 [ # # # # ]: 0 : pkghash_safe_add(pkg->optionshash, o->key, o, NULL);
991 [ # # ]: 0 : DL_APPEND(pkg->options, o);
992 : :
993 : 0 : return (EPKG_OK);
994 : 0 : }
995 : :
996 : : int
997 : 0 : pkg_addoption_description(struct pkg *pkg, const char *key,
998 : : const char *description)
999 : : {
1000 : 0 : struct pkg_option *o = NULL;
1001 : :
1002 [ # # ]: 0 : assert(pkg != NULL);
1003 [ # # ]: 0 : assert(key != NULL && key[0] != '\0');
1004 [ # # ]: 0 : assert(description != NULL && description[0] != '\0');
1005 : :
1006 : : /* There might be a value or default for the option already,
1007 : : so we only count it as a duplicate if the description field
1008 : : is already set. Which implies there could be a default
1009 : : value or description for an option but no actual value. */
1010 : :
1011 [ # # ]: 0 : if (pkghash_get(pkg->optionshash, key) != NULL) {
1012 [ # # ]: 0 : if (ctx.developer_mode) {
1013 : 0 : pkg_emit_error("duplicate description for option: %s, fatal (developer mode)", key);
1014 : 0 : return (EPKG_FATAL);
1015 : : } else {
1016 : 0 : pkg_emit_error("duplicate description for option: %s, ignoring", key);
1017 : 0 : return (EPKG_OK);
1018 : : }
1019 : : }
1020 : :
1021 : 0 : o = xcalloc(1, sizeof(*o));
1022 : 0 : o->key = xstrdup(key);
1023 : 0 : o->description = xstrdup(description);
1024 [ # # # # ]: 0 : pkghash_safe_add(pkg->optionshash, o->key, o, NULL);
1025 [ # # ]: 0 : DL_APPEND(pkg->options, o);
1026 : :
1027 : 0 : return (EPKG_OK);
1028 : 0 : }
1029 : :
1030 : : int
1031 : 80 : pkg_addshlib_required(struct pkg *pkg, const char *name)
1032 : : {
1033 [ + - ]: 80 : assert(pkg != NULL);
1034 [ + - ]: 80 : assert(name != NULL && name[0] != '\0');
1035 : :
1036 : : /* silently ignore duplicates in case of shlibs */
1037 [ - + ]: 80 : if (pkghash_get(pkg->shlibs_required, name) != NULL)
1038 : 0 : return (EPKG_OK);
1039 : :
1040 [ - + # # ]: 80 : pkghash_safe_add(pkg->shlibs_required, name, NULL, NULL);
1041 : :
1042 : 80 : pkg_debug(3, "added shlib deps for %s on %s", pkg->name, name);
1043 : :
1044 : 80 : return (EPKG_OK);
1045 : 80 : }
1046 : :
1047 : : int
1048 : 166 : pkg_addshlib_provided(struct pkg *pkg, const char *name)
1049 : : {
1050 [ + - ]: 166 : assert(pkg != NULL);
1051 [ + - ]: 166 : assert(name != NULL && name[0] != '\0');
1052 : :
1053 : : /* ignore files which are not starting with lib */
1054 [ - + ]: 166 : if (strncmp(name, "lib", 3) != 0)
1055 : 0 : return (EPKG_OK);
1056 : :
1057 : : /* silently ignore duplicates in case of shlibs */
1058 [ - + ]: 166 : if (pkghash_get(pkg->shlibs_provided, name) != NULL)
1059 : 0 : return (EPKG_OK);
1060 : :
1061 [ + + + - ]: 170 : pkghash_safe_add(pkg->shlibs_provided, name, NULL, NULL);
1062 : :
1063 : 166 : pkg_debug(3, "added shlib provide %s for %s", name, pkg->name);
1064 : :
1065 : 166 : return (EPKG_OK);
1066 : 166 : }
1067 : :
1068 : : int
1069 : 0 : pkg_addconflict(struct pkg *pkg, const char *uniqueid)
1070 : : {
1071 : 0 : struct pkg_conflict *c = NULL;
1072 : :
1073 [ # # ]: 0 : assert(pkg != NULL);
1074 [ # # ]: 0 : assert(uniqueid != NULL && uniqueid[0] != '\0');
1075 : :
1076 [ # # ]: 0 : if (pkghash_get(pkg->conflictshash, uniqueid) != NULL) {
1077 : : /* silently ignore duplicates in case of conflicts */
1078 : 0 : return (EPKG_OK);
1079 : : }
1080 : :
1081 : 0 : c = xcalloc(1, sizeof(*c));
1082 : 0 : c->uid = xstrdup(uniqueid);
1083 : 0 : pkg_debug(3, "Pkg: add a new conflict origin: %s, with %s", pkg->uid, uniqueid);
1084 : :
1085 [ # # # # ]: 0 : pkghash_safe_add(pkg->conflictshash, c->uid, c, NULL);
1086 [ # # ]: 0 : DL_APPEND(pkg->conflicts, c);
1087 : :
1088 : 0 : return (EPKG_OK);
1089 : 0 : }
1090 : :
1091 : : int
1092 : 164 : pkg_addrequire(struct pkg *pkg, const char *name)
1093 : : {
1094 [ + - ]: 164 : assert(pkg != NULL);
1095 [ + - ]: 164 : assert(name != NULL && name[0] != '\0');
1096 : :
1097 : : /* silently ignore duplicates in case of conflicts */
1098 [ - + ]: 164 : if (pkghash_get(pkg->requires, name) != NULL)
1099 : 0 : return (EPKG_OK);
1100 : :
1101 [ - + # # ]: 164 : pkghash_safe_add(pkg->requires, name, NULL, NULL);
1102 : :
1103 : 164 : return (EPKG_OK);
1104 : 164 : }
1105 : :
1106 : : int
1107 : 88 : pkg_addprovide(struct pkg *pkg, const char *name)
1108 : : {
1109 [ + - ]: 88 : assert(pkg != NULL);
1110 [ + - ]: 88 : assert(name != NULL && name[0] != '\0');
1111 : :
1112 : : /* silently ignore duplicates in case of conflicts */
1113 [ - + ]: 88 : if (pkghash_get(pkg->provides, name) != NULL)
1114 : 0 : return (EPKG_OK);
1115 : :
1116 [ - + # # ]: 88 : pkghash_safe_add(pkg->provides, name, NULL, NULL);
1117 : :
1118 : 88 : return (EPKG_OK);
1119 : 88 : }
1120 : :
1121 : : const char *
1122 : 4213 : pkg_kv_get(struct pkg_kv *const *kv, const char *tag)
1123 : : {
1124 : : struct pkg_kv *k;
1125 : :
1126 [ + - ]: 4213 : assert(tag != NULL);
1127 : :
1128 [ + + ]: 7586 : LL_FOREACH(*kv, k) {
1129 [ + + ]: 4024 : if (strcmp(k->key, tag) == 0)
1130 : 651 : return (k->value);
1131 : 3373 : }
1132 : :
1133 : 3562 : return (NULL);
1134 : 4213 : }
1135 : :
1136 : : int
1137 : 5233 : pkg_kv_add(struct pkg_kv **list, const char *key, const char *val, const char *title)
1138 : : {
1139 : : struct pkg_kv *kv;
1140 : :
1141 [ + - ]: 5233 : assert(val != NULL);
1142 [ - + ]: 5233 : assert(title != NULL);
1143 : :
1144 [ + + ]: 6879 : LL_FOREACH(*list, kv) {
1145 [ + - ]: 1646 : if (strcmp(kv->key, key) == 0) {
1146 [ # # ]: 0 : if (ctx.developer_mode) {
1147 : 0 : pkg_emit_error("duplicate %s: %s, fatal"
1148 : 0 : " (developer mode)", title, key);
1149 : 0 : return (EPKG_FATAL);
1150 : : } else {
1151 : 0 : pkg_emit_error("duplicate %s: %s, "
1152 : 0 : "ignoring", title, val);
1153 : 0 : return (EPKG_OK);
1154 : : }
1155 : : }
1156 : 1646 : }
1157 : :
1158 : 5233 : kv = pkg_kv_new(key, val);
1159 [ + + ]: 5233 : DL_APPEND(*list, kv);
1160 : :
1161 : 5233 : return (EPKG_OK);
1162 : 5233 : }
1163 : :
1164 : : int
1165 : 110 : pkg_list_count(const struct pkg *pkg, pkg_list list)
1166 : : {
1167 [ - - - + : 110 : switch (list) {
+ - - - +
+ - + + -
- - ]
1168 : : case PKG_DEPS:
1169 : 0 : return (pkghash_count(pkg->depshash));
1170 : : case PKG_RDEPS:
1171 : 0 : return (pkghash_count(pkg->rdepshash));
1172 : : case PKG_OPTIONS:
1173 : 26 : return (pkghash_count(pkg->optionshash));
1174 : : case PKG_FILES:
1175 : 12 : return (pkghash_count(pkg->filehash));
1176 : : case PKG_DIRS:
1177 : 0 : return (pkghash_count(pkg->dirhash));
1178 : : case PKG_USERS:
1179 : 0 : return (pkghash_count(pkg->users));
1180 : : case PKG_GROUPS:
1181 : 0 : return (pkghash_count(pkg->groups));
1182 : : case PKG_SHLIBS_REQUIRED:
1183 : 18 : return (pkghash_count(pkg->shlibs_required));
1184 : : case PKG_SHLIBS_PROVIDED:
1185 : 18 : return (pkghash_count(pkg->shlibs_provided));
1186 : : case PKG_CONFLICTS:
1187 : 0 : return (pkghash_count(pkg->conflictshash));
1188 : : case PKG_PROVIDES:
1189 : 18 : return (pkghash_count(pkg->provides));
1190 : : case PKG_REQUIRES:
1191 : 18 : return (pkghash_count(pkg->requires));
1192 : : case PKG_CONFIG_FILES:
1193 : 0 : return (pkghash_count(pkg->config_files_hash));
1194 : : case PKG_CATEGORIES:
1195 : 0 : return (pkghash_count(pkg->categories));
1196 : : case PKG_LICENSES:
1197 : 0 : return (pkghash_count(pkg->licenses));
1198 : : }
1199 : :
1200 : 0 : return (0);
1201 : 110 : }
1202 : :
1203 : : void
1204 : 82573 : pkg_list_free(struct pkg *pkg, pkg_list list) {
1205 : : struct pkg_dep *cur;
1206 : :
1207 [ + - + + : 82573 : switch (list) {
+ + + + +
+ - + + +
+ ]
1208 : : case PKG_DEPS:
1209 [ + + ]: 7780 : DL_FOREACH (pkg->depends, cur) {
1210 [ + - ]: 1499 : if (cur->alt_next) {
1211 [ # # # # : 0 : DL_FREE2(cur->alt_next, pkg_dep_free, alt_prev, alt_next);
# # # # #
# # # ]
1212 : 0 : }
1213 : 1499 : }
1214 [ + + + + : 7780 : DL_FREE(pkg->depends, pkg_dep_free);
+ - + + -
+ # # ]
1215 : 6281 : pkghash_destroy(pkg->depshash);
1216 : 6281 : pkg->depshash = NULL;
1217 : 6281 : pkg->flags &= ~PKG_LOAD_DEPS;
1218 : 6281 : break;
1219 : : case PKG_RDEPS:
1220 [ + + + + : 6413 : LL_FREE(pkg->rdepends, pkg_dep_free);
- + # # #
# # # ]
1221 : 6281 : pkghash_destroy(pkg->rdepshash);
1222 : 6281 : pkg->depshash = NULL;
1223 : 6281 : pkg->flags &= ~PKG_LOAD_RDEPS;
1224 : 6281 : break;
1225 : : case PKG_OPTIONS:
1226 [ + + + + : 7089 : DL_FREE(pkg->options, pkg_option_free);
+ - + + -
+ # # ]
1227 : 6281 : pkghash_destroy(pkg->optionshash);
1228 : 6281 : pkg->optionshash = NULL;
1229 : 6281 : pkg->flags &= ~PKG_LOAD_OPTIONS;
1230 : 6281 : break;
1231 : : case PKG_FILES:
1232 : : case PKG_CONFIG_FILES:
1233 [ + + + + : 9878 : DL_FREE(pkg->files, pkg_file_free);
+ - + + -
+ # # ]
1234 : 6741 : pkghash_destroy(pkg->filehash);
1235 : 6741 : pkg->filehash = NULL;
1236 [ + + + + : 6926 : DL_FREE(pkg->config_files, pkg_config_file_free);
+ - - + #
# # # ]
1237 : 6741 : pkghash_destroy(pkg->config_files_hash);
1238 : 6741 : pkg->config_files_hash = NULL;
1239 : 6741 : pkg->flags &= ~PKG_LOAD_FILES;
1240 : 6741 : break;
1241 : : case PKG_DIRS:
1242 [ + + + + : 6913 : DL_FREE(pkg->dirs, free);
+ - + + -
+ # # ]
1243 : 6741 : pkghash_destroy(pkg->dirhash);
1244 : 6741 : pkg->dirhash = NULL;
1245 : 6741 : pkg->flags &= ~PKG_LOAD_DIRS;
1246 : 6741 : break;
1247 : : case PKG_USERS:
1248 : 6281 : pkghash_destroy(pkg->users);
1249 : 6281 : pkg->users = NULL;
1250 : 6281 : pkg->flags &= ~PKG_LOAD_USERS;
1251 : 6281 : break;
1252 : : case PKG_GROUPS:
1253 : 6281 : pkghash_destroy(pkg->groups);
1254 : 6281 : pkg->groups = NULL;
1255 : 6281 : pkg->flags &= ~PKG_LOAD_GROUPS;
1256 : 6281 : break;
1257 : : case PKG_SHLIBS_REQUIRED:
1258 : 6281 : pkghash_destroy(pkg->shlibs_required);
1259 : 6281 : pkg->shlibs_required = NULL;
1260 : 6281 : pkg->flags &= ~PKG_LOAD_SHLIBS_REQUIRED;
1261 : 6281 : break;
1262 : : case PKG_SHLIBS_PROVIDED:
1263 : 6281 : pkghash_destroy(pkg->shlibs_provided);
1264 : 6281 : pkg->shlibs_provided = NULL;
1265 : 6281 : pkg->flags &= ~PKG_LOAD_SHLIBS_PROVIDED;
1266 : 6281 : break;
1267 : : case PKG_CONFLICTS:
1268 [ # # # # : 0 : DL_FREE(pkg->conflicts, pkg_conflict_free);
# # # # #
# # # ]
1269 : 0 : pkghash_destroy(pkg->conflictshash);
1270 : 0 : pkg->conflictshash = NULL;
1271 : 0 : pkg->flags &= ~PKG_LOAD_CONFLICTS;
1272 : 0 : break;
1273 : : case PKG_PROVIDES:
1274 : 6281 : pkghash_destroy(pkg->provides);
1275 : 6281 : pkg->provides = NULL;
1276 : 6281 : pkg->flags &= ~PKG_LOAD_PROVIDES;
1277 : 6281 : break;
1278 : : case PKG_REQUIRES:
1279 : 6281 : pkghash_destroy(pkg->requires);
1280 : 6281 : pkg->requires = NULL;
1281 : 6281 : pkg->flags &= ~PKG_LOAD_REQUIRES;
1282 : 6281 : break;
1283 : : case PKG_CATEGORIES:
1284 : 6281 : pkghash_destroy(pkg->categories);
1285 : 6281 : pkg->categories = NULL;
1286 : 6281 : pkg->flags &= ~PKG_LOAD_CATEGORIES;
1287 : 6281 : break;
1288 : : case PKG_LICENSES:
1289 : 6281 : pkghash_destroy(pkg->licenses);
1290 : 6281 : pkg->licenses = NULL;
1291 : 6281 : pkg->flags &= ~PKG_LOAD_LICENSES;
1292 : 6281 : break;
1293 : : }
1294 : 82573 : }
1295 : :
1296 : : int
1297 : 704 : pkg_open(struct pkg **pkg_p, const char *path, struct pkg_manifest_key *keys, int flags)
1298 : : {
1299 : : struct archive *a;
1300 : : struct archive_entry *ae;
1301 : : int ret;
1302 : :
1303 : 704 : ret = pkg_open2(pkg_p, &a, &ae, path, keys, flags, -1);
1304 : :
1305 [ + + - + ]: 704 : if (ret != EPKG_OK && ret != EPKG_END)
1306 : 0 : return (EPKG_FATAL);
1307 : :
1308 : 704 : archive_read_close(a);
1309 : 704 : archive_read_free(a);
1310 : :
1311 : 704 : return (EPKG_OK);
1312 : 704 : }
1313 : :
1314 : : int
1315 : 49 : pkg_open_fd(struct pkg **pkg_p, int fd, struct pkg_manifest_key *keys, int flags)
1316 : : {
1317 : : struct archive *a;
1318 : : struct archive_entry *ae;
1319 : : int ret;
1320 : :
1321 : 49 : ret = pkg_open2(pkg_p, &a, &ae, NULL, keys, flags, fd);
1322 : :
1323 [ + + - + ]: 49 : if (ret != EPKG_OK && ret != EPKG_END)
1324 : 0 : return (EPKG_FATAL);
1325 : :
1326 : 49 : archive_read_close(a);
1327 : 49 : archive_read_free(a);
1328 : :
1329 : 49 : return (EPKG_OK);
1330 : 49 : }
1331 : :
1332 : : static int
1333 : 1495 : pkg_parse_archive(struct pkg *pkg, struct pkg_manifest_key *keys,
1334 : : struct archive *a, size_t len)
1335 : : {
1336 : : void *buffer;
1337 : : int rc;
1338 : :
1339 : 1495 : buffer = xmalloc(len);
1340 : :
1341 : 1495 : archive_read_data(a, buffer, len);
1342 : 1495 : rc = pkg_parse_manifest(pkg, buffer, len, keys);
1343 : 1495 : free(buffer);
1344 : 1495 : return (rc);
1345 : : }
1346 : :
1347 : : int
1348 : 1495 : pkg_open2(struct pkg **pkg_p, struct archive **a, struct archive_entry **ae,
1349 : : const char *path, struct pkg_manifest_key *keys, int flags, int fd)
1350 : : {
1351 : 1495 : struct pkg *pkg = NULL;
1352 : 1495 : pkg_error_t retcode = EPKG_OK;
1353 : : int ret;
1354 : : const char *fpath;
1355 : 1495 : bool manifest = false;
1356 : 1495 : bool read_from_stdin = 0;
1357 : :
1358 : 1495 : *a = archive_read_new();
1359 : 1495 : archive_read_support_filter_all(*a);
1360 : 1495 : archive_read_support_format_tar(*a);
1361 : :
1362 : : /* archive_read_open_filename() treats a path of NULL as
1363 : : * meaning "read from stdin," but we want this behaviour if
1364 : : * path is exactly "-". In the unlikely event of wanting to
1365 : : * read an on-disk file called "-", just say "./-" or some
1366 : : * other leading path. */
1367 : :
1368 [ + + ]: 1495 : if (fd == -1) {
1369 [ + - ]: 1446 : if (path == NULL) {
1370 : 0 : pkg_emit_error("bad usage of pkg_open2");
1371 : 0 : retcode = EPKG_FATAL;
1372 : 0 : goto cleanup;
1373 : : }
1374 : 1446 : read_from_stdin = (strncmp(path, "-", 2) == 0);
1375 : :
1376 [ - + - + ]: 4338 : if (archive_read_open_filename(*a,
1377 [ + + ]: 1446 : read_from_stdin ? NULL : path, 4096) != ARCHIVE_OK) {
1378 [ # # ]: 0 : if ((flags & PKG_OPEN_TRY) == 0)
1379 : 0 : pkg_emit_error("archive_read_open_filename(%s): %s", path,
1380 : 0 : archive_error_string(*a));
1381 : :
1382 : 0 : retcode = EPKG_FATAL;
1383 : 0 : goto cleanup;
1384 : : }
1385 : 1446 : } else {
1386 [ - + ]: 49 : if (archive_read_open_fd(*a, fd, 4096) != ARCHIVE_OK) {
1387 [ # # ]: 0 : if ((flags & PKG_OPEN_TRY) == 0)
1388 : 0 : pkg_emit_error("archive_read_open_fd: %s",
1389 : 0 : archive_error_string(*a));
1390 : :
1391 : 0 : retcode = EPKG_FATAL;
1392 : 0 : goto cleanup;
1393 : : }
1394 : : }
1395 : :
1396 : 1495 : retcode = pkg_new(pkg_p, PKG_FILE);
1397 [ - + ]: 1495 : if (retcode != EPKG_OK)
1398 : 0 : goto cleanup;
1399 : :
1400 : 1495 : pkg = *pkg_p;
1401 : :
1402 [ + + ]: 4217 : while ((ret = archive_read_next_header(*a, ae)) == ARCHIVE_OK) {
1403 : 3782 : fpath = archive_entry_pathname(*ae);
1404 [ + + ]: 3782 : if (fpath[0] != '+')
1405 : 816 : break;
1406 : :
1407 [ + - - + ]: 2990 : if (!manifest &&
1408 [ + + ]: 2966 : (flags & PKG_OPEN_MANIFEST_COMPACT) &&
1409 : 24 : strcmp(fpath, "+COMPACT_MANIFEST") == 0) {
1410 : 24 : manifest = true;
1411 : :
1412 : 24 : ret = pkg_parse_archive(pkg, keys, *a, archive_entry_size(*ae));
1413 [ + - ]: 24 : if (ret != EPKG_OK) {
1414 : 0 : retcode = EPKG_FATAL;
1415 : 0 : goto cleanup;
1416 : : }
1417 : : /* Do not read anything more */
1418 : 24 : break;
1419 : : }
1420 [ + - + + ]: 2942 : if (!manifest && strcmp(fpath, "+MANIFEST") == 0) {
1421 : 1471 : manifest = true;
1422 : :
1423 : 1471 : ret = pkg_parse_archive(pkg, keys, *a, archive_entry_size(*ae));
1424 [ + - ]: 1471 : if (ret != EPKG_OK) {
1425 [ # # ]: 0 : if ((flags & PKG_OPEN_TRY) == 0)
1426 : 0 : pkg_emit_error("%s is not a valid package: "
1427 : 0 : "Invalid manifest", path);
1428 : :
1429 : 0 : retcode = EPKG_FATAL;
1430 : 0 : goto cleanup;
1431 : : }
1432 : :
1433 [ + + ]: 1471 : if (flags & PKG_OPEN_MANIFEST_ONLY)
1434 : 220 : break;
1435 : 1251 : }
1436 : : }
1437 : :
1438 [ + + + - ]: 1495 : if (ret != ARCHIVE_OK && ret != ARCHIVE_EOF) {
1439 [ # # ]: 0 : if ((flags & PKG_OPEN_TRY) == 0)
1440 : 0 : pkg_emit_error("archive_read_next_header(): %s",
1441 : 0 : archive_error_string(*a));
1442 : :
1443 : 0 : retcode = EPKG_FATAL;
1444 : 0 : }
1445 : :
1446 [ + + ]: 1495 : if (ret == ARCHIVE_EOF)
1447 : 435 : retcode = EPKG_END;
1448 : :
1449 [ + - ]: 1495 : if (!manifest) {
1450 : 0 : retcode = EPKG_FATAL;
1451 [ # # ]: 0 : if ((flags & PKG_OPEN_TRY) == 0)
1452 : 0 : pkg_emit_error("%s is not a valid package: no manifest found", path);
1453 : 0 : }
1454 : :
1455 : : cleanup:
1456 [ + + + - ]: 1495 : if (retcode != EPKG_OK && retcode != EPKG_END) {
1457 [ # # ]: 0 : if (*a != NULL) {
1458 : 0 : archive_read_close(*a);
1459 : 0 : archive_read_free(*a);
1460 : 0 : }
1461 : 0 : free(pkg);
1462 : 0 : *pkg_p = NULL;
1463 : 0 : *a = NULL;
1464 : 0 : *ae = NULL;
1465 : 0 : }
1466 : :
1467 : 1495 : return (retcode);
1468 : : }
1469 : :
1470 : : int
1471 : 1922 : pkg_validate(struct pkg *pkg, struct pkgdb *db)
1472 : : {
1473 [ + - ]: 1922 : assert(pkg != NULL);
1474 : 1922 : unsigned flags = PKG_LOAD_BASIC|PKG_LOAD_OPTIONS|PKG_LOAD_DEPS|
1475 : : PKG_LOAD_REQUIRES|PKG_LOAD_PROVIDES|
1476 : : PKG_LOAD_SHLIBS_REQUIRED|PKG_LOAD_SHLIBS_PROVIDED|
1477 : : PKG_LOAD_ANNOTATIONS|PKG_LOAD_CONFLICTS;
1478 : :
1479 [ + + ]: 1922 : if (pkg->uid == NULL) {
1480 : : /* Keep that part for the day we have to change it */
1481 : : /* Generate uid from name*/
1482 [ + - ]: 212 : if (pkg->name == NULL)
1483 : 0 : return (EPKG_FATAL);
1484 : :
1485 : 212 : pkg->uid = xstrdup(pkg->name);
1486 : 212 : }
1487 : :
1488 [ + + - + : 1922 : if (pkg->digest == NULL || !pkg_checksum_is_valid(pkg->digest,
- + ]
1489 : 1706 : strlen(pkg->digest))) {
1490 : : /* Calculate new digest */
1491 [ + + ]: 216 : if (pkgdb_ensure_loaded(db, pkg, flags)) {
1492 : 212 : return (pkg_checksum_calculate(pkg, db, false, true, false));
1493 : : }
1494 : 4 : return (EPKG_FATAL);
1495 : : }
1496 : :
1497 : 1706 : return (EPKG_OK);
1498 : 1922 : }
1499 : :
1500 : : int
1501 : 0 : pkg_test_filesum(struct pkg *pkg)
1502 : : {
1503 : 0 : struct pkg_file *f = NULL;
1504 : 0 : int rc = EPKG_OK;
1505 : : int ret;
1506 : :
1507 [ # # ]: 0 : assert(pkg != NULL);
1508 : :
1509 [ # # ]: 0 : while (pkg_files(pkg, &f) == EPKG_OK) {
1510 [ # # ]: 0 : if (f->sum != NULL) {
1511 : 0 : ret = pkg_checksum_validate_file(f->path, f->sum);
1512 [ # # ]: 0 : if (ret != 0) {
1513 [ # # ]: 0 : if (ret == ENOENT)
1514 : 0 : pkg_emit_file_missing(pkg, f);
1515 : : else
1516 : 0 : pkg_emit_file_mismatch(pkg, f, f->sum);
1517 : 0 : rc = EPKG_FATAL;
1518 : 0 : }
1519 : 0 : }
1520 : : }
1521 : :
1522 : 0 : return (rc);
1523 : : }
1524 : :
1525 : : int
1526 : 0 : pkg_recompute(struct pkgdb *db, struct pkg *pkg)
1527 : : {
1528 : 0 : struct pkg_file *f = NULL;
1529 : 0 : hardlinks_t *hl = NULL;
1530 : 0 : int64_t flatsize = 0;
1531 : : struct stat st;
1532 : 0 : bool regular = false;
1533 : : char *sum;
1534 : 0 : int rc = EPKG_OK;
1535 : :
1536 : 0 : hl = kh_init_hardlinks();
1537 [ # # ]: 0 : while (pkg_files(pkg, &f) == EPKG_OK) {
1538 [ # # ]: 0 : if (lstat(f->path, &st) != 0)
1539 : 0 : continue;
1540 : 0 : regular = true;
1541 : 0 : sum = pkg_checksum_generate_file(f->path,
1542 : : PKG_HASH_TYPE_SHA256_HEX);
1543 : :
1544 [ # # ]: 0 : if (S_ISLNK(st.st_mode))
1545 : 0 : regular = false;
1546 : :
1547 [ # # ]: 0 : if (sum == NULL) {
1548 : 0 : rc = EPKG_FATAL;
1549 : 0 : break;
1550 : : }
1551 : :
1552 [ # # ]: 0 : if (st.st_nlink > 1)
1553 : 0 : regular = !check_for_hardlink(hl, &st);
1554 : :
1555 [ # # ]: 0 : if (regular)
1556 : 0 : flatsize += st.st_size;
1557 : :
1558 [ # # ]: 0 : if (strcmp(sum, f->sum) != 0)
1559 : 0 : pkgdb_file_set_cksum(db, f, sum);
1560 : 0 : free(sum);
1561 : : }
1562 : 0 : kh_destroy_hardlinks(hl);
1563 : :
1564 [ # # ]: 0 : if (flatsize != pkg->flatsize)
1565 : 0 : pkg->flatsize = flatsize;
1566 : :
1567 : 0 : return (rc);
1568 : : }
1569 : :
1570 : : int
1571 : 688 : pkg_try_installed(struct pkgdb *db, const char *name,
1572 : : struct pkg **pkg, unsigned flags) {
1573 : 688 : struct pkgdb_it *it = NULL;
1574 : 688 : int ret = EPKG_FATAL;
1575 : :
1576 [ - + ]: 688 : if ((it = pkgdb_query(db, name, MATCH_EXACT)) == NULL)
1577 : 0 : return (EPKG_FATAL);
1578 : :
1579 : 688 : ret = pkgdb_it_next(it, pkg, flags);
1580 : 688 : pkgdb_it_free(it);
1581 : :
1582 : 688 : return (ret);
1583 : 688 : }
1584 : :
1585 : : int
1586 : 485 : pkg_is_installed(struct pkgdb *db, const char *name)
1587 : : {
1588 : 485 : struct pkg *pkg = NULL;
1589 : 485 : int ret = EPKG_FATAL;
1590 : :
1591 : 485 : ret = pkg_try_installed(db, name, &pkg, PKG_LOAD_BASIC);
1592 : 485 : pkg_free(pkg);
1593 : :
1594 : 485 : return (ret);
1595 : : }
1596 : :
1597 : : bool
1598 : 24 : pkg_has_message(struct pkg *p)
1599 : : {
1600 : 24 : return (p->message != NULL);
1601 : : }
1602 : :
1603 : : bool
1604 : 1303 : pkg_is_locked(const struct pkg * restrict p)
1605 : : {
1606 [ + - ]: 1303 : assert(p != NULL);
1607 : :
1608 : 1303 : return (p->locked);
1609 : : }
1610 : :
1611 : : bool
1612 : 22 : pkg_is_config_file(struct pkg *p, const char *path,
1613 : : const struct pkg_file **file,
1614 : : struct pkg_config_file **cfile)
1615 : : {
1616 : 22 : *file = NULL;
1617 : 22 : *cfile = NULL;
1618 : :
1619 [ + + ]: 22 : if (pkghash_count(p->config_files_hash) == 0)
1620 : 10 : return (false);
1621 : :
1622 : 12 : *file = pkghash_get_value(p->filehash, path);
1623 [ + - ]: 12 : if (*file == NULL)
1624 : 0 : return (false);
1625 : 12 : *cfile = pkghash_get_value(p->config_files_hash, path);
1626 [ - + ]: 12 : if (*cfile == NULL) {
1627 : 0 : *file = NULL;
1628 : 0 : return (false);
1629 : : }
1630 : :
1631 : 12 : return (true);
1632 : 22 : }
1633 : :
1634 : : struct pkg_dir *
1635 : 24 : pkg_get_dir(struct pkg *p, const char *path)
1636 : : {
1637 : 24 : return (pkghash_get_value(p->dirhash, path));
1638 : : }
1639 : :
1640 : : struct pkg_file *
1641 : 522 : pkg_get_file(struct pkg *p, const char *path)
1642 : : {
1643 : 522 : return (pkghash_get_value(p->filehash, path));
1644 : : }
1645 : :
1646 : : bool
1647 : 388 : pkg_has_file(struct pkg *p, const char *path)
1648 : : {
1649 : 388 : return (pkghash_get(p->filehash, path) != NULL);
1650 : : }
1651 : :
1652 : : bool
1653 : 56 : pkg_has_dir(struct pkg *p, const char *path)
1654 : : {
1655 : 56 : return (pkghash_get(p->dirhash, path) != NULL);
1656 : : }
1657 : :
1658 : : int
1659 : 1197 : pkg_open_root_fd(struct pkg *pkg)
1660 : : {
1661 : : const char *path;
1662 : :
1663 [ + + ]: 1197 : if (pkg->rootfd != -1)
1664 : 170 : return (EPKG_OK);
1665 : :
1666 : 1027 : path = pkg_kv_get(&pkg->annotations, "relocated");
1667 [ - + ]: 1027 : if (path == NULL) {
1668 [ - + ]: 1027 : if ((pkg->rootfd = dup(ctx.rootfd)) == -1) {
1669 : 0 : pkg_emit_errno("dup2", "rootfd");
1670 : 0 : return (EPKG_FATAL);
1671 : : }
1672 : 1027 : return (EPKG_OK);
1673 : : }
1674 : :
1675 : 0 : pkg_absolutepath(path, pkg->rootpath, sizeof(pkg->rootpath), false);
1676 : :
1677 [ # # ]: 0 : if ((pkg->rootfd = openat(ctx.rootfd, pkg->rootpath + 1, O_DIRECTORY)) >= 0 )
1678 : 0 : return (EPKG_OK);
1679 : :
1680 : 0 : pkg->rootpath[0] = '\0';
1681 : 0 : pkg_emit_errno("open", path);
1682 : :
1683 : 0 : return (EPKG_FATAL);
1684 : 1197 : }
1685 : :
1686 : : int
1687 : 160 : pkg_message_from_ucl(struct pkg *pkg, const ucl_object_t *obj)
1688 : : {
1689 : 160 : struct pkg_message *msg = NULL;
1690 : : const ucl_object_t *elt, *cur;
1691 : 160 : ucl_object_iter_t it = NULL;
1692 : :
1693 [ + + ]: 160 : if (ucl_object_type(obj) == UCL_STRING) {
1694 : 12 : msg = xcalloc(1, sizeof(*msg));
1695 : 12 : msg->str = xstrdup(ucl_object_tostring(obj));
1696 : 12 : msg->type = PKG_MESSAGE_ALWAYS;
1697 [ - + ]: 12 : DL_APPEND(pkg->message, msg);
1698 : 12 : return (EPKG_OK);
1699 : : }
1700 : :
1701 : : /* New format of pkg message */
1702 [ + - ]: 148 : if (ucl_object_type(obj) != UCL_ARRAY)
1703 : 0 : pkg_emit_error("package message badly formatted, an array was"
1704 : : " expected");
1705 : :
1706 [ + + ]: 668 : while ((cur = ucl_iterate_object(obj, &it, true))) {
1707 : 520 : elt = ucl_object_find_key(cur, "message");
1708 : :
1709 [ + - - + ]: 520 : if (elt == NULL || ucl_object_type(elt) != UCL_STRING) {
1710 : 0 : pkg_emit_error("package message lacks 'message' key"
1711 : : " that is required");
1712 : :
1713 : 0 : return (EPKG_FATAL);
1714 : : }
1715 : :
1716 : 520 : msg = xcalloc(1, sizeof(*msg));
1717 : :
1718 : 520 : msg->str = xstrdup(ucl_object_tostring(elt));
1719 : 520 : msg->type = PKG_MESSAGE_ALWAYS;
1720 : 520 : elt = ucl_object_find_key(cur, "type");
1721 [ + + - + ]: 520 : if (elt != NULL && ucl_object_type(elt) == UCL_STRING) {
1722 [ + + ]: 368 : if (strcasecmp(ucl_object_tostring(elt), "install") == 0)
1723 : 68 : msg->type = PKG_MESSAGE_INSTALL;
1724 [ + + ]: 300 : else if (strcasecmp(ucl_object_tostring(elt), "remove") == 0)
1725 : 64 : msg->type = PKG_MESSAGE_REMOVE;
1726 [ - + ]: 236 : else if (strcasecmp(ucl_object_tostring(elt), "upgrade") == 0)
1727 : 236 : msg->type = PKG_MESSAGE_UPGRADE;
1728 : : else
1729 : 0 : pkg_emit_error("Unknown message type,"
1730 : : " message will always be printed");
1731 : 368 : }
1732 [ + + ]: 520 : if (msg->type != PKG_MESSAGE_UPGRADE) {
1733 [ + + ]: 284 : DL_APPEND(pkg->message, msg);
1734 : 284 : continue;
1735 : : }
1736 : :
1737 : 236 : elt = ucl_object_find_key(cur, "minimum_version");
1738 [ + + - + ]: 236 : if (elt != NULL && ucl_object_type(elt) == UCL_STRING) {
1739 : 112 : msg->minimum_version = xstrdup(ucl_object_tostring(elt));
1740 : 112 : }
1741 : :
1742 : 236 : elt = ucl_object_find_key(cur, "maximum_version");
1743 [ + + - + ]: 236 : if (elt != NULL && ucl_object_type(elt) == UCL_STRING) {
1744 : 112 : msg->maximum_version = xstrdup(ucl_object_tostring(elt));
1745 : 112 : }
1746 : :
1747 [ + - ]: 236 : DL_APPEND(pkg->message, msg);
1748 : : }
1749 : :
1750 : 148 : return (EPKG_OK);
1751 : 160 : }
1752 : :
1753 : : int
1754 : 68 : pkg_message_from_str(struct pkg *pkg, const char *str, size_t len)
1755 : : {
1756 : : struct ucl_parser *parser;
1757 : : ucl_object_t *obj;
1758 : 68 : int ret = EPKG_FATAL;
1759 : :
1760 [ + - ]: 68 : assert(str != NULL);
1761 : :
1762 [ + + ]: 68 : if (len == 0) {
1763 : 60 : len = strlen(str);
1764 : 60 : }
1765 : :
1766 : 68 : parser = ucl_parser_new(UCL_PARSER_NO_FILEVARS);
1767 [ + + ]: 68 : if (pkg->prefix != NULL) {
1768 : 8 : ucl_parser_register_variable(parser, "PREFIX", pkg->prefix);
1769 : 8 : }
1770 [ - + ]: 68 : if (pkg->name != NULL) {
1771 : 68 : ucl_parser_register_variable(parser, "PKGNAME", pkg->name);
1772 : 68 : }
1773 [ - + ]: 68 : if (pkg->origin != NULL) {
1774 : 68 : ucl_parser_register_variable(parser, "PKGORIGIN", pkg->origin);
1775 : 68 : }
1776 [ + + ]: 68 : if (pkg->maintainer != NULL) {
1777 : 8 : ucl_parser_register_variable(parser, "MAINTAINER", pkg->origin);
1778 : 8 : }
1779 : :
1780 [ + - ]: 68 : if (ucl_parser_add_chunk(parser, (const unsigned char*)str, len)) {
1781 : 68 : obj = ucl_parser_get_object(parser);
1782 : 68 : ucl_parser_free(parser);
1783 : :
1784 : 68 : ret = pkg_message_from_ucl(pkg, obj);
1785 : 68 : ucl_object_unref(obj);
1786 : :
1787 : 68 : return (ret);
1788 : : }
1789 : :
1790 : 0 : ucl_parser_free (parser);
1791 : :
1792 : 0 : return (ret);
1793 : 68 : }
1794 : :
1795 : : ucl_object_t*
1796 : 88 : pkg_message_to_ucl(const struct pkg *pkg)
1797 : : {
1798 : : struct pkg_message *msg;
1799 : : ucl_object_t *array;
1800 : : ucl_object_t *obj;
1801 : :
1802 : 88 : array = ucl_object_typed_new(UCL_ARRAY);
1803 [ + + ]: 360 : LL_FOREACH(pkg->message, msg) {
1804 : 272 : obj = ucl_object_typed_new (UCL_OBJECT);
1805 : :
1806 : 544 : ucl_object_insert_key(obj,
1807 : 272 : ucl_object_fromstring_common(msg->str, 0,
1808 : : UCL_STRING_RAW|UCL_STRING_TRIM),
1809 : : "message", 0, false);
1810 : :
1811 [ - + + + : 272 : switch (msg->type) {
+ ]
1812 : : case PKG_MESSAGE_ALWAYS:
1813 : 96 : break;
1814 : : case PKG_MESSAGE_INSTALL:
1815 : 72 : ucl_object_insert_key(obj,
1816 : 36 : ucl_object_fromstring("install"),
1817 : : "type", 0, false);
1818 : 36 : break;
1819 : : case PKG_MESSAGE_UPGRADE:
1820 : 224 : ucl_object_insert_key(obj,
1821 : 112 : ucl_object_fromstring("upgrade"),
1822 : : "type", 0, false);
1823 : 112 : break;
1824 : : case PKG_MESSAGE_REMOVE:
1825 : 56 : ucl_object_insert_key(obj,
1826 : 28 : ucl_object_fromstring("remove"),
1827 : : "type", 0, false);
1828 : 28 : break;
1829 : : }
1830 [ + + ]: 272 : if (msg->maximum_version) {
1831 : 96 : ucl_object_insert_key(obj,
1832 : 48 : ucl_object_fromstring(msg->maximum_version),
1833 : : "maximum_version", 0, false);
1834 : 48 : }
1835 [ + + ]: 272 : if (msg->minimum_version) {
1836 : 96 : ucl_object_insert_key(obj,
1837 : 48 : ucl_object_fromstring(msg->minimum_version),
1838 : : "minimum_version", 0, false);
1839 : 48 : }
1840 : 272 : ucl_array_append(array, obj);
1841 : 272 : }
1842 : :
1843 : 88 : return (array);
1844 : : }
1845 : :
1846 : : char*
1847 : 1080 : pkg_message_to_str(struct pkg *pkg)
1848 : : {
1849 : : ucl_object_t *obj;
1850 : 1080 : char *ret = NULL;
1851 : :
1852 [ + + ]: 1080 : if (pkg->message == NULL) {
1853 : 1024 : return (NULL);
1854 : : }
1855 : :
1856 : 56 : obj = pkg_message_to_ucl(pkg);
1857 : 56 : ret = ucl_object_emit(obj, UCL_EMIT_JSON_COMPACT);
1858 : 56 : ucl_object_unref(obj);
1859 : :
1860 : 56 : return (ret);
1861 : 1080 : }
|