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