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