etc/services - sync with NetBSD-8
[minix.git] / external / bsd / pkg_install / dist / add / perform.c
blob7a9cbbbc26d501c22f0f1d7d62e125ee7579d1f3
1 /* $NetBSD: perform.c,v 1.4 2013/04/20 15:29:22 wiz Exp $ */
2 #if HAVE_CONFIG_H
3 #include "config.h"
4 #endif
5 #include <nbcompat.h>
6 #if HAVE_SYS_CDEFS_H
7 #include <sys/cdefs.h>
8 #endif
9 __RCSID("$NetBSD: perform.c,v 1.4 2013/04/20 15:29:22 wiz Exp $");
11 /*-
12 * Copyright (c) 2003 Grant Beattie <grant@NetBSD.org>
13 * Copyright (c) 2005 Dieter Baron <dillo@NetBSD.org>
14 * Copyright (c) 2007 Roland Illig <rillig@NetBSD.org>
15 * Copyright (c) 2008, 2009 Joerg Sonnenberger <joerg@NetBSD.org>
16 * Copyright (c) 2010 Thomas Klausner <wiz@NetBSD.org>
17 * All rights reserved.
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in
27 * the documentation and/or other materials provided with the
28 * distribution.
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
31 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
34 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
35 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
36 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
38 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
39 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
40 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
41 * SUCH DAMAGE.
44 #include <sys/utsname.h>
45 #include <sys/stat.h>
46 #if HAVE_ERR_H
47 #include <err.h>
48 #endif
49 #include <errno.h>
50 #if HAVE_FCNTL_H
51 #include <fcntl.h>
52 #endif
53 #include <stdlib.h>
54 #include <string.h>
55 #include <unistd.h>
57 #include <archive.h>
58 #include <archive_entry.h>
60 #include "lib.h"
61 #include "add.h"
62 #include "version.h"
64 struct pkg_meta {
65 char *meta_contents;
66 char *meta_comment;
67 char *meta_desc;
68 char *meta_mtree;
69 char *meta_build_version;
70 char *meta_build_info;
71 char *meta_size_pkg;
72 char *meta_size_all;
73 char *meta_required_by;
74 char *meta_display;
75 char *meta_install;
76 char *meta_deinstall;
77 char *meta_preserve;
78 char *meta_views;
79 char *meta_installed_info;
82 struct pkg_task {
83 char *pkgname;
85 const char *prefix;
86 char *install_prefix;
88 char *logdir;
89 char *install_logdir;
90 char *install_logdir_real;
91 char *other_version;
93 package_t plist;
95 struct pkg_meta meta_data;
97 struct archive *archive;
98 struct archive_entry *entry;
100 char *buildinfo[BI_ENUM_COUNT];
102 size_t dep_length, dep_allocated;
103 char **dependencies;
106 static const struct pkg_meta_desc {
107 size_t entry_offset;
108 const char *entry_filename;
109 int required_file;
110 mode_t perm;
111 } pkg_meta_descriptors[] = {
112 { offsetof(struct pkg_meta, meta_contents), CONTENTS_FNAME, 1, 0644 },
113 { offsetof(struct pkg_meta, meta_comment), COMMENT_FNAME, 1, 0444},
114 { offsetof(struct pkg_meta, meta_desc), DESC_FNAME, 1, 0444},
115 { offsetof(struct pkg_meta, meta_install), INSTALL_FNAME, 0, 0555 },
116 { offsetof(struct pkg_meta, meta_deinstall), DEINSTALL_FNAME, 0, 0555 },
117 { offsetof(struct pkg_meta, meta_display), DISPLAY_FNAME, 0, 0444 },
118 { offsetof(struct pkg_meta, meta_mtree), MTREE_FNAME, 0, 0444 },
119 { offsetof(struct pkg_meta, meta_build_version), BUILD_VERSION_FNAME, 0, 0444 },
120 { offsetof(struct pkg_meta, meta_build_info), BUILD_INFO_FNAME, 0, 0444 },
121 { offsetof(struct pkg_meta, meta_size_pkg), SIZE_PKG_FNAME, 0, 0444 },
122 { offsetof(struct pkg_meta, meta_size_all), SIZE_ALL_FNAME, 0, 0444 },
123 { offsetof(struct pkg_meta, meta_preserve), PRESERVE_FNAME, 0, 0444 },
124 { offsetof(struct pkg_meta, meta_views), VIEWS_FNAME, 0, 0444 },
125 { offsetof(struct pkg_meta, meta_required_by), REQUIRED_BY_FNAME, 0, 0644 },
126 { offsetof(struct pkg_meta, meta_installed_info), INSTALLED_INFO_FNAME, 0, 0644 },
127 { 0, NULL, 0, 0 },
130 static int pkg_do(const char *, int, int);
132 static int
133 end_of_version(const char *opsys, const char *version_end)
135 if (*version_end == '\0')
136 return 1;
138 if (strcmp(opsys, "NetBSD") == 0) {
139 if (strncmp(version_end, "_ALPHA", 6) == 0
140 || strncmp(version_end, "_BETA", 5) == 0
141 || strncmp(version_end, "_RC", 3) == 0
142 || strncmp(version_end, "_STABLE", 7) == 0
143 || strncmp(version_end, "_PATCH", 6) == 0)
144 return 1;
147 return 0;
150 static int
151 compatible_platform(const char *opsys, const char *host, const char *package)
153 int i = 0;
155 /* returns 1 if host and package operating system match */
156 if (strcmp(host, package) == 0)
157 return 1;
159 /* accept, if host version is a minor release of package version */
160 if (strncmp(host, package, strlen(package)) == 0)
161 return 1;
163 /* find offset of first difference */
164 for (i=0; (host[i] != '\0') && (host[i] == package[i]);)
165 i++;
167 if (end_of_version(opsys, host+i) && end_of_version(opsys, package+i))
168 return 1;
170 return 0;
173 static int
174 mkdir_p(const char *path)
176 char *p, *cur_end;
177 int done, saved_errno;
178 struct stat sb;
181 * Handle the easy case of direct success or
182 * pre-existing directory first.
184 if (mkdir(path, 0777) == 0)
185 return 0;
186 if (stat(path, &sb) == 0) {
187 if (S_ISDIR(sb.st_mode))
188 return 0;
189 errno = ENOTDIR;
190 return -1;
193 cur_end = p = xstrdup(path);
195 for (;;) {
197 * First skip leading slashes either from / or
198 * from the last iteration.
200 cur_end += strspn(cur_end, "/");
201 /* Find end of actual directory name. */
202 cur_end += strcspn(cur_end, "/");
205 * Remember if this is the last component and
206 * overwrite / if needed.
208 done = (*cur_end == '\0');
209 *cur_end = '\0';
211 if (mkdir(p, 0777) == -1) {
212 saved_errno = errno;
213 if (stat(p, &sb) == 0) {
214 if (S_ISDIR(sb.st_mode))
215 goto pass;
216 errno = ENOTDIR;
217 } else {
218 errno = saved_errno;
220 free(p);
221 return -1;
223 pass:
224 if (done)
225 break;
226 *cur_end = '/';
229 free(p);
230 return 0;
234 * Read meta data from archive.
235 * Bail out if a required entry is missing or entries are in the wrong order.
237 static int
238 read_meta_data(struct pkg_task *pkg)
240 const struct pkg_meta_desc *descr, *last_descr;
241 const char *fname;
242 char **target;
243 int64_t size;
244 int r, found_required;
246 found_required = 0;
248 r = ARCHIVE_OK;
249 last_descr = 0;
251 if (pkg->entry != NULL)
252 goto skip_header;
254 for (;;) {
255 r = archive_read_next_header(pkg->archive, &pkg->entry);
256 if (r != ARCHIVE_OK)
257 break;
258 skip_header:
259 fname = archive_entry_pathname(pkg->entry);
261 for (descr = pkg_meta_descriptors; descr->entry_filename;
262 ++descr) {
263 if (strcmp(descr->entry_filename, fname) == 0)
264 break;
266 if (descr->entry_filename == NULL)
267 break;
269 if (descr->required_file)
270 ++found_required;
272 target = (char **)((char *)&pkg->meta_data +
273 descr->entry_offset);
274 if (*target) {
275 warnx("duplicate entry, package corrupt");
276 return -1;
278 if (descr < last_descr) {
279 warnx("misordered package");
280 return -1;
282 last_descr = descr;
284 size = archive_entry_size(pkg->entry);
285 if (size > SSIZE_MAX - 1) {
286 warnx("package meta data too large to process");
287 return -1;
289 *target = xmalloc(size + 1);
290 if (archive_read_data(pkg->archive, *target, size) != size) {
291 warnx("cannot read package meta data");
292 return -1;
294 (*target)[size] = '\0';
297 if (r != ARCHIVE_OK)
298 pkg->entry = NULL;
299 if (r == ARCHIVE_EOF)
300 r = ARCHIVE_OK;
302 for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) {
303 if (descr->required_file)
304 --found_required;
307 return !found_required && r == ARCHIVE_OK ? 0 : -1;
311 * Free meta data.
313 static void
314 free_meta_data(struct pkg_task *pkg)
316 const struct pkg_meta_desc *descr;
317 char **target;
319 for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) {
320 target = (char **)((char *)&pkg->meta_data +
321 descr->entry_offset);
322 free(*target);
323 *target = NULL;
328 * Parse PLIST and populate pkg.
330 static int
331 pkg_parse_plist(struct pkg_task *pkg)
333 plist_t *p;
335 parse_plist(&pkg->plist, pkg->meta_data.meta_contents);
336 if ((p = find_plist(&pkg->plist, PLIST_NAME)) == NULL) {
337 warnx("Invalid PLIST: missing @name");
338 return -1;
340 if (pkg->pkgname == NULL)
341 pkg->pkgname = xstrdup(p->name);
342 else if (strcmp(pkg->pkgname, p->name) != 0) {
343 warnx("Signature and PLIST differ on package name");
344 return -1;
346 if ((p = find_plist(&pkg->plist, PLIST_CWD)) == NULL) {
347 warnx("Invalid PLIST: missing @cwd");
348 return -1;
351 if (Prefix != NULL &&
352 strcmp(p->name, Prefix) != 0) {
353 size_t len;
355 delete_plist(&pkg->plist, FALSE, PLIST_CWD, NULL);
356 add_plist_top(&pkg->plist, PLIST_CWD, Prefix);
357 free(pkg->meta_data.meta_contents);
358 stringify_plist(&pkg->plist, &pkg->meta_data.meta_contents, &len,
359 Prefix);
360 pkg->prefix = Prefix;
361 } else
362 pkg->prefix = p->name;
364 if (Destdir != NULL)
365 pkg->install_prefix = xasprintf("%s/%s", Destdir, pkg->prefix);
366 else
367 pkg->install_prefix = xstrdup(pkg->prefix);
369 return 0;
373 * Helper function to extract value from a string of the
374 * form key=value ending at eol.
376 static char *
377 dup_value(const char *line, const char *eol)
379 const char *key;
380 char *val;
382 key = strchr(line, '=');
383 val = xmalloc(eol - key);
384 memcpy(val, key + 1, eol - key - 1);
385 val[eol - key - 1] = '\0';
386 return val;
389 static int
390 check_already_installed(struct pkg_task *pkg)
392 char *filename;
393 int fd;
395 filename = pkgdb_pkg_file(pkg->pkgname, CONTENTS_FNAME);
396 fd = open(filename, O_RDONLY);
397 free(filename);
398 if (fd == -1)
399 return 1;
400 close(fd);
402 if (ReplaceSame) {
403 struct stat sb;
405 pkg->install_logdir_real = pkg->install_logdir;
406 pkg->install_logdir = xasprintf("%s.xxxxxx", pkg->install_logdir);
407 if (stat(pkg->install_logdir, &sb) == 0) {
408 warnx("package `%s' already has a temporary update "
409 "directory `%s', remove it manually",
410 pkg->pkgname, pkg->install_logdir);
411 return -1;
413 return 1;
416 if (Force)
417 return 1;
419 /* We can only arrive here for explicitly requested packages. */
420 if (!Automatic && is_automatic_installed(pkg->pkgname)) {
421 if (Fake ||
422 mark_as_automatic_installed(pkg->pkgname, 0) == 0)
423 warnx("package `%s' was already installed as "
424 "dependency, now marked as installed "
425 "manually", pkg->pkgname);
426 } else {
427 warnx("package `%s' already recorded as installed",
428 pkg->pkgname);
430 return 0;
434 static int
435 check_other_installed(struct pkg_task *pkg)
437 FILE *f, *f_pkg;
438 size_t len;
439 char *pkgbase, *iter, *filename;
440 package_t plist;
441 plist_t *p;
442 int status;
444 if (pkg->install_logdir_real) {
445 pkg->other_version = xstrdup(pkg->pkgname);
446 return 0;
449 pkgbase = xstrdup(pkg->pkgname);
451 if ((iter = strrchr(pkgbase, '-')) == NULL) {
452 free(pkgbase);
453 warnx("Invalid package name %s", pkg->pkgname);
454 return -1;
456 *iter = '\0';
457 pkg->other_version = find_best_matching_installed_pkg(pkgbase);
458 free(pkgbase);
459 if (pkg->other_version == NULL)
460 return 0;
462 if (!Replace) {
463 /* XXX This is redundant to the implicit conflict check. */
464 warnx("A different version of %s is already installed: %s",
465 pkg->pkgname, pkg->other_version);
466 return -1;
469 filename = pkgdb_pkg_file(pkg->other_version, REQUIRED_BY_FNAME);
470 errno = 0;
471 f = fopen(filename, "r");
472 free(filename);
473 if (f == NULL) {
474 if (errno == ENOENT) {
475 /* No packages depend on this, so everything is well. */
476 return 0;
478 warnx("Can't open +REQUIRED_BY of %s", pkg->other_version);
479 return -1;
482 status = 0;
484 while ((iter = fgetln(f, &len)) != NULL) {
485 if (iter[len - 1] == '\n')
486 iter[len - 1] = '\0';
487 filename = pkgdb_pkg_file(iter, CONTENTS_FNAME);
488 if ((f_pkg = fopen(filename, "r")) == NULL) {
489 warnx("Can't open +CONTENTS of depending package %s",
490 iter);
491 fclose(f);
492 return -1;
494 read_plist(&plist, f_pkg);
495 fclose(f_pkg);
496 for (p = plist.head; p != NULL; p = p->next) {
497 if (p->type == PLIST_IGNORE) {
498 p = p->next;
499 continue;
500 } else if (p->type != PLIST_PKGDEP)
501 continue;
503 * XXX This is stricter than necessary.
504 * XXX One pattern might be fulfilled by
505 * XXX a different package and still need this
506 * XXX one for a different pattern.
508 if (pkg_match(p->name, pkg->other_version) == 0)
509 continue;
510 if (pkg_match(p->name, pkg->pkgname) == 1)
511 continue; /* Both match, ok. */
512 warnx("Dependency of %s fulfilled by %s, but not by %s",
513 iter, pkg->other_version, pkg->pkgname);
514 if (!ForceDepending)
515 status = -1;
516 break;
518 free_plist(&plist);
521 fclose(f);
523 return status;
527 * Read package build information from meta data.
529 static int
530 read_buildinfo(struct pkg_task *pkg)
532 const char *data, *eol, *next_line;
534 data = pkg->meta_data.meta_build_info;
536 for (; data != NULL && *data != '\0'; data = next_line) {
537 if ((eol = strchr(data, '\n')) == NULL) {
538 eol = data + strlen(data);
539 next_line = eol;
540 } else
541 next_line = eol + 1;
543 if (strncmp(data, "OPSYS=", 6) == 0)
544 pkg->buildinfo[BI_OPSYS] = dup_value(data, eol);
545 else if (strncmp(data, "OS_VERSION=", 11) == 0)
546 pkg->buildinfo[BI_OS_VERSION] = dup_value(data, eol);
547 else if (strncmp(data, "MACHINE_ARCH=", 13) == 0)
548 pkg->buildinfo[BI_MACHINE_ARCH] = dup_value(data, eol);
549 else if (strncmp(data, "IGNORE_RECOMMENDED=", 19) == 0)
550 pkg->buildinfo[BI_IGNORE_RECOMMENDED] = dup_value(data,
551 eol);
552 else if (strncmp(data, "USE_ABI_DEPENDS=", 16) == 0)
553 pkg->buildinfo[BI_USE_ABI_DEPENDS] = dup_value(data,
554 eol);
555 else if (strncmp(data, "LICENSE=", 8) == 0)
556 pkg->buildinfo[BI_LICENSE] = dup_value(data, eol);
557 else if (strncmp(data, "PKGTOOLS_VERSION=", 17) == 0)
558 pkg->buildinfo[BI_PKGTOOLS_VERSION] = dup_value(data,
559 eol);
561 if (pkg->buildinfo[BI_OPSYS] == NULL ||
562 pkg->buildinfo[BI_OS_VERSION] == NULL ||
563 pkg->buildinfo[BI_MACHINE_ARCH] == NULL) {
564 warnx("Not all required build information are present.");
565 return -1;
568 if ((pkg->buildinfo[BI_USE_ABI_DEPENDS] != NULL &&
569 strcasecmp(pkg->buildinfo[BI_USE_ABI_DEPENDS], "YES") != 0) ||
570 (pkg->buildinfo[BI_IGNORE_RECOMMENDED] != NULL &&
571 strcasecmp(pkg->buildinfo[BI_IGNORE_RECOMMENDED], "NO") != 0)) {
572 warnx("%s was built to ignore ABI dependencies", pkg->pkgname);
575 return 0;
579 * Free buildinfo.
581 static void
582 free_buildinfo(struct pkg_task *pkg)
584 size_t i;
586 for (i = 0; i < BI_ENUM_COUNT; ++i) {
587 free(pkg->buildinfo[i]);
588 pkg->buildinfo[i] = NULL;
593 * Write meta data files to pkgdb after creating the directory.
595 static int
596 write_meta_data(struct pkg_task *pkg)
598 const struct pkg_meta_desc *descr;
599 char *filename, **target;
600 size_t len;
601 ssize_t ret;
602 int fd;
604 if (Fake)
605 return 0;
607 if (mkdir_p(pkg->install_logdir)) {
608 warn("Can't create pkgdb entry: %s", pkg->install_logdir);
609 return -1;
612 for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) {
613 target = (char **)((char *)&pkg->meta_data +
614 descr->entry_offset);
615 if (*target == NULL)
616 continue;
617 filename = xasprintf("%s/%s", pkg->install_logdir,
618 descr->entry_filename);
619 (void)unlink(filename);
620 fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, descr->perm);
621 if (fd == -1) {
622 warn("Can't open meta data file: %s", filename);
623 return -1;
625 len = strlen(*target);
626 do {
627 ret = write(fd, *target, len);
628 if (ret == -1) {
629 warn("Can't write meta data file: %s",
630 filename);
631 free(filename);
632 close(fd);
633 return -1;
635 len -= ret;
636 } while (ret > 0);
637 if (close(fd) == -1) {
638 warn("Can't close meta data file: %s", filename);
639 free(filename);
640 return -1;
642 free(filename);
645 return 0;
649 * Helper function for extract_files.
651 static int
652 copy_data_to_disk(struct archive *reader, struct archive *writer,
653 const char *filename)
655 int r;
656 const void *buff;
657 size_t size;
658 off_t offset;
660 for (;;) {
661 r = archive_read_data_block(reader, &buff, &size, &offset);
662 if (r == ARCHIVE_EOF)
663 return 0;
664 if (r != ARCHIVE_OK) {
665 warnx("Read error for %s: %s", filename,
666 archive_error_string(reader));
667 return -1;
669 r = archive_write_data_block(writer, buff, size, offset);
670 if (r != ARCHIVE_OK) {
671 warnx("Write error for %s: %s", filename,
672 archive_error_string(writer));
673 return -1;
679 * Extract package.
680 * Any misordered, missing or unlisted file in the package is an error.
683 static const int extract_flags = ARCHIVE_EXTRACT_OWNER |
684 ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_UNLINK |
685 ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR;
687 static int
688 extract_files(struct pkg_task *pkg)
690 char cmd[MaxPathSize];
691 const char *owner, *group, *permissions;
692 struct archive *writer;
693 int r;
694 plist_t *p;
695 const char *last_file;
696 char *fullpath;
698 if (Fake)
699 return 0;
701 if (mkdir_p(pkg->install_prefix)) {
702 warn("Can't create prefix: %s", pkg->install_prefix);
703 return -1;
706 if (!NoRecord && !pkgdb_open(ReadWrite)) {
707 warn("Can't open pkgdb for writing");
708 return -1;
711 if (chdir(pkg->install_prefix) == -1) {
712 warn("Can't change into prefix: %s", pkg->install_prefix);
713 return -1;
716 writer = archive_write_disk_new();
717 archive_write_disk_set_options(writer, extract_flags);
718 archive_write_disk_set_standard_lookup(writer);
720 owner = NULL;
721 group = NULL;
722 permissions = NULL;
723 last_file = NULL;
725 r = -1;
727 for (p = pkg->plist.head; p != NULL; p = p->next) {
728 switch (p->type) {
729 case PLIST_FILE:
730 last_file = p->name;
731 if (pkg->entry == NULL) {
732 warnx("PLIST entry not in package (%s)",
733 archive_entry_pathname(pkg->entry));
734 goto out;
736 if (strcmp(p->name, archive_entry_pathname(pkg->entry))) {
737 warnx("PLIST entry and package don't match (%s vs %s)",
738 p->name, archive_entry_pathname(pkg->entry));
739 goto out;
741 fullpath = xasprintf("%s/%s", pkg->prefix, p->name);
742 pkgdb_store(fullpath, pkg->pkgname);
743 free(fullpath);
744 if (Verbose)
745 printf("%s", p->name);
746 break;
748 case PLIST_PKGDIR:
749 fullpath = xasprintf("%s/%s", pkg->prefix, p->name);
750 mkdir_p(fullpath);
751 free(fullpath);
752 add_pkgdir(pkg->pkgname, pkg->prefix, p->name);
753 continue;
755 case PLIST_CMD:
756 if (format_cmd(cmd, sizeof(cmd), p->name, pkg->prefix, last_file))
757 return -1;
758 printf("Executing '%s'\n", cmd);
759 if (!Fake && system(cmd))
760 warnx("command '%s' failed", cmd); /* XXX bail out? */
761 continue;
763 case PLIST_CHMOD:
764 permissions = p->name;
765 continue;
767 case PLIST_CHOWN:
768 owner = p->name;
769 continue;
771 case PLIST_CHGRP:
772 group = p->name;
773 continue;
775 case PLIST_IGNORE:
776 p = p->next;
777 continue;
779 default:
780 continue;
783 r = archive_write_header(writer, pkg->entry);
784 if (r != ARCHIVE_OK) {
785 warnx("Failed to write %s for %s: %s",
786 archive_entry_pathname(pkg->entry),
787 pkg->pkgname,
788 archive_error_string(writer));
789 goto out;
792 if (owner != NULL)
793 archive_entry_set_uname(pkg->entry, owner);
794 if (group != NULL)
795 archive_entry_set_uname(pkg->entry, group);
796 if (permissions != NULL) {
797 mode_t mode;
799 mode = archive_entry_mode(pkg->entry);
800 mode = getmode(setmode(permissions), mode);
801 archive_entry_set_mode(pkg->entry, mode);
804 r = copy_data_to_disk(pkg->archive, writer,
805 archive_entry_pathname(pkg->entry));
806 if (r)
807 goto out;
808 if (Verbose)
809 printf("\n");
811 r = archive_read_next_header(pkg->archive, &pkg->entry);
812 if (r == ARCHIVE_EOF) {
813 pkg->entry = NULL;
814 continue;
816 if (r != ARCHIVE_OK) {
817 warnx("Failed to read from archive for %s: %s",
818 pkg->pkgname,
819 archive_error_string(pkg->archive));
820 goto out;
824 if (pkg->entry != NULL) {
825 warnx("Package contains entries not in PLIST: %s",
826 archive_entry_pathname(pkg->entry));
827 goto out;
830 r = 0;
832 out:
833 if (!NoRecord)
834 pkgdb_close();
835 archive_write_close(writer);
836 archive_write_finish(writer);
838 return r;
842 * Register dependencies after sucessfully installing the package.
844 static void
845 pkg_register_depends(struct pkg_task *pkg)
847 int fd;
848 size_t text_len, i;
849 char *required_by, *text;
851 if (Fake)
852 return;
854 text = xasprintf("%s\n", pkg->pkgname);
855 text_len = strlen(text);
857 for (i = 0; i < pkg->dep_length; ++i) {
858 required_by = pkgdb_pkg_file(pkg->dependencies[i], REQUIRED_BY_FNAME);
860 fd = open(required_by, O_WRONLY | O_APPEND | O_CREAT, 0644);
861 if (fd == -1) {
862 warn("can't open dependency file '%s',"
863 "registration is incomplete!", required_by);
864 } else if (write(fd, text, text_len) != (ssize_t)text_len) {
865 warn("can't write to dependency file `%s'", required_by);
866 close(fd);
867 } else if (close(fd) == -1)
868 warn("cannot close file %s", required_by);
870 free(required_by);
873 free(text);
877 * Reduce the result from uname(3) to a canonical form.
879 static void
880 normalise_platform(struct utsname *host_name)
882 #ifdef NUMERIC_VERSION_ONLY
883 size_t span;
885 span = strspn(host_name->release, "0123456789.");
886 host_name->release[span] = '\0';
887 #endif
891 * Check build platform of the package against local host.
893 static int
894 check_platform(struct pkg_task *pkg)
896 struct utsname host_uname;
897 const char *effective_arch;
898 int fatal;
900 if (uname(&host_uname) < 0) {
901 if (Force) {
902 warnx("uname() failed, continuing.");
903 return 0;
904 } else {
905 warnx("uname() failed, aborting.");
906 return -1;
910 normalise_platform(&host_uname);
912 if (OverrideMachine != NULL)
913 effective_arch = OverrideMachine;
914 else
915 effective_arch = MACHINE_ARCH;
917 /* If either the OS or arch are different, bomb */
918 if (strcmp(OPSYS_NAME, pkg->buildinfo[BI_OPSYS]) ||
919 strcmp(effective_arch, pkg->buildinfo[BI_MACHINE_ARCH]) != 0)
920 fatal = 1;
921 else
922 fatal = 0;
924 if (fatal ||
925 compatible_platform(OPSYS_NAME, host_uname.release,
926 pkg->buildinfo[BI_OS_VERSION]) != 1) {
927 warnx("Warning: package `%s' was built for a platform:",
928 pkg->pkgname);
929 warnx("%s/%s %s (pkg) vs. %s/%s %s (this host)",
930 pkg->buildinfo[BI_OPSYS],
931 pkg->buildinfo[BI_MACHINE_ARCH],
932 pkg->buildinfo[BI_OS_VERSION],
933 OPSYS_NAME,
934 effective_arch,
935 host_uname.release);
936 if (!Force && fatal)
937 return -1;
939 return 0;
942 static int
943 check_pkgtools_version(struct pkg_task *pkg)
945 const char *val = pkg->buildinfo[BI_PKGTOOLS_VERSION];
946 int version;
948 if (val == NULL) {
949 warnx("Warning: package `%s' lacks pkg_install version data",
950 pkg->pkgname);
951 return 0;
954 if (strlen(val) != 8 || strspn(val, "0123456789") != 8) {
955 warnx("Warning: package `%s' contains an invalid pkg_install version",
956 pkg->pkgname);
957 return Force ? 0 : -1;
959 version = atoi(val);
960 if (version > PKGTOOLS_VERSION) {
961 warnx("%s: package `%s' was built with a newer pkg_install version",
962 Force ? "Warning" : "Error", pkg->pkgname);
963 return Force ? 0 : -1;
965 return 0;
969 * Run the install script.
971 static int
972 run_install_script(struct pkg_task *pkg, const char *argument)
974 int ret;
975 char *filename;
977 if (pkg->meta_data.meta_install == NULL || NoInstall)
978 return 0;
980 if (Destdir != NULL)
981 setenv(PKG_DESTDIR_VNAME, Destdir, 1);
982 setenv(PKG_PREFIX_VNAME, pkg->prefix, 1);
983 setenv(PKG_METADATA_DIR_VNAME, pkg->logdir, 1);
984 setenv(PKG_REFCOUNT_DBDIR_VNAME, config_pkg_refcount_dbdir, 1);
986 if (Verbose)
987 printf("Running install with PRE-INSTALL for %s.\n", pkg->pkgname);
988 if (Fake)
989 return 0;
991 filename = pkgdb_pkg_file(pkg->pkgname, INSTALL_FNAME);
993 ret = 0;
994 errno = 0;
995 if (fcexec(pkg->install_logdir, filename, pkg->pkgname, argument,
996 (void *)NULL)) {
997 if (errno != 0)
998 warn("exec of install script failed");
999 else
1000 warnx("install script returned error status");
1001 ret = -1;
1003 free(filename);
1005 return ret;
1008 struct find_conflict_data {
1009 const char *pkg;
1010 const char *old_pkg;
1011 const char *pattern;
1014 static int
1015 check_explicit_conflict_iter(const char *cur_pkg, void *cookie)
1017 struct find_conflict_data *data = cookie;
1019 if (data->old_pkg && strcmp(data->old_pkg, cur_pkg) == 0)
1020 return 0;
1022 warnx("Package `%s' conflicts with `%s', and `%s' is installed.",
1023 data->pkg, data->pattern, cur_pkg);
1025 return 1;
1028 static int
1029 check_explicit_conflict(struct pkg_task *pkg)
1031 struct find_conflict_data data;
1032 char *installed, *installed_pattern;
1033 plist_t *p;
1034 int status;
1036 status = 0;
1038 for (p = pkg->plist.head; p != NULL; p = p->next) {
1039 if (p->type == PLIST_IGNORE) {
1040 p = p->next;
1041 continue;
1043 if (p->type != PLIST_PKGCFL)
1044 continue;
1045 data.pkg = pkg->pkgname;
1046 data.old_pkg = pkg->other_version;
1047 data.pattern = p->name;
1048 status |= match_installed_pkgs(p->name,
1049 check_explicit_conflict_iter, &data);
1052 if (some_installed_package_conflicts_with(pkg->pkgname,
1053 pkg->other_version, &installed, &installed_pattern)) {
1054 warnx("Installed package `%s' conflicts with `%s' when trying to install `%s'.",
1055 installed, installed_pattern, pkg->pkgname);
1056 free(installed);
1057 free(installed_pattern);
1058 status |= -1;
1061 return status;
1064 static int
1065 check_implicit_conflict(struct pkg_task *pkg)
1067 plist_t *p;
1068 char *fullpath, *existing;
1069 int status;
1071 if (!pkgdb_open(ReadOnly)) {
1072 #if notyet /* XXX empty pkgdb without database? */
1073 warn("Can't open pkgdb for reading");
1074 return -1;
1075 #else
1076 return 0;
1077 #endif
1080 status = 0;
1082 for (p = pkg->plist.head; p != NULL; p = p->next) {
1083 if (p->type == PLIST_IGNORE) {
1084 p = p->next;
1085 continue;
1086 } else if (p->type != PLIST_FILE)
1087 continue;
1089 fullpath = xasprintf("%s/%s", pkg->prefix, p->name);
1090 existing = pkgdb_retrieve(fullpath);
1091 free(fullpath);
1092 if (existing == NULL)
1093 continue;
1094 if (pkg->other_version != NULL &&
1095 strcmp(pkg->other_version, existing) == 0)
1096 continue;
1098 warnx("Conflicting PLIST with %s: %s", existing, p->name);
1099 if (!Force) {
1100 status = -1;
1101 if (!Verbose)
1102 break;
1106 pkgdb_close();
1107 return status;
1110 static int
1111 check_dependencies(struct pkg_task *pkg)
1113 plist_t *p;
1114 char *best_installed;
1115 int status;
1116 size_t i;
1118 status = 0;
1120 for (p = pkg->plist.head; p != NULL; p = p->next) {
1121 if (p->type == PLIST_IGNORE) {
1122 p = p->next;
1123 continue;
1124 } else if (p->type != PLIST_PKGDEP)
1125 continue;
1127 best_installed = find_best_matching_installed_pkg(p->name);
1129 if (best_installed == NULL) {
1130 /* XXX check cyclic dependencies? */
1131 if (Fake || NoRecord) {
1132 if (!Force) {
1133 warnx("Missing dependency %s\n",
1134 p->name);
1135 status = -1;
1136 break;
1138 warnx("Missing dependency %s, continuing",
1139 p->name);
1140 continue;
1142 if (pkg_do(p->name, 1, 0)) {
1143 if (ForceDepends) {
1144 warnx("Can't install dependency %s, "
1145 "continuing", p->name);
1146 continue;
1147 } else {
1148 warnx("Can't install dependency %s",
1149 p->name);
1150 status = -1;
1151 break;
1154 best_installed = find_best_matching_installed_pkg(p->name);
1155 if (best_installed == NULL && ForceDepends) {
1156 warnx("Missing dependency %s ignored", p->name);
1157 continue;
1158 } else if (best_installed == NULL) {
1159 warnx("Just installed dependency %s disappeared", p->name);
1160 status = -1;
1161 break;
1164 for (i = 0; i < pkg->dep_length; ++i) {
1165 if (strcmp(best_installed, pkg->dependencies[i]) == 0)
1166 break;
1168 if (i < pkg->dep_length) {
1169 /* Already used as dependency, so skip it. */
1170 free(best_installed);
1171 continue;
1173 if (pkg->dep_length + 1 >= pkg->dep_allocated) {
1174 char **tmp;
1175 pkg->dep_allocated = 2 * pkg->dep_allocated + 1;
1176 pkg->dependencies = xrealloc(pkg->dependencies,
1177 pkg->dep_allocated * sizeof(*tmp));
1179 pkg->dependencies[pkg->dep_length++] = best_installed;
1182 return status;
1186 * If this package uses pkg_views, register it in the default view.
1188 static void
1189 pkg_register_views(struct pkg_task *pkg)
1191 if (Fake || NoView || pkg->meta_data.meta_views == NULL)
1192 return;
1194 if (Verbose) {
1195 printf("%s/pkg_view -d %s %s%s %s%s %sadd %s\n",
1196 BINDIR, pkgdb_get_dir(),
1197 View ? "-w " : "", View ? View : "",
1198 Viewbase ? "-W " : "", Viewbase ? Viewbase : "",
1199 Verbose ? "-v " : "", pkg->pkgname);
1202 fexec_skipempty(BINDIR "/pkg_view", "-d", pkgdb_get_dir(),
1203 View ? "-w " : "", View ? View : "",
1204 Viewbase ? "-W " : "", Viewbase ? Viewbase : "",
1205 Verbose ? "-v " : "", "add", pkg->pkgname,
1206 (void *)NULL);
1209 static int
1210 preserve_meta_data_file(struct pkg_task *pkg, const char *name)
1212 char *old_file, *new_file;
1213 int rv;
1215 if (Fake)
1216 return 0;
1218 old_file = pkgdb_pkg_file(pkg->other_version, name);
1219 new_file = xasprintf("%s/%s", pkg->install_logdir, name);
1220 rv = 0;
1221 if (rename(old_file, new_file) == -1 && errno != ENOENT) {
1222 warn("Can't move %s from %s to %s", name, old_file, new_file);
1223 rv = -1;
1225 free(old_file);
1226 free(new_file);
1227 return rv;
1230 static int
1231 start_replacing(struct pkg_task *pkg)
1233 if (preserve_meta_data_file(pkg, REQUIRED_BY_FNAME))
1234 return -1;
1236 if (preserve_meta_data_file(pkg, PRESERVE_FNAME))
1237 return -1;
1239 if (pkg->meta_data.meta_installed_info == NULL &&
1240 preserve_meta_data_file(pkg, INSTALLED_INFO_FNAME))
1241 return -1;
1243 if (Verbose || Fake) {
1244 printf("%s/pkg_delete -K %s -p %s%s%s '%s'\n",
1245 BINDIR, pkgdb_get_dir(), pkg->prefix,
1246 Destdir ? " -P ": "", Destdir ? Destdir : "",
1247 pkg->other_version);
1249 if (!Fake)
1250 fexec_skipempty(BINDIR "/pkg_delete", "-K", pkgdb_get_dir(),
1251 "-p", pkg->prefix,
1252 Destdir ? "-P": "", Destdir ? Destdir : "",
1253 pkg->other_version, NULL);
1255 /* XXX Check return value and do what? */
1256 return 0;
1259 static int check_input(const char *line, size_t len)
1261 if (line == NULL || len == 0)
1262 return 1;
1263 switch (*line) {
1264 case 'Y':
1265 case 'y':
1266 case 'T':
1267 case 't':
1268 case '1':
1269 return 0;
1270 default:
1271 return 1;
1275 static int
1276 check_signature(struct pkg_task *pkg, int invalid_sig)
1278 char *line;
1279 size_t len;
1281 if (strcasecmp(verified_installation, "never") == 0)
1282 return 0;
1283 if (strcasecmp(verified_installation, "always") == 0) {
1284 if (invalid_sig)
1285 warnx("No valid signature found, rejected");
1286 return invalid_sig;
1288 if (strcasecmp(verified_installation, "trusted") == 0) {
1289 if (!invalid_sig)
1290 return 0;
1291 fprintf(stderr, "No valid signature found for %s.\n",
1292 pkg->pkgname);
1293 fprintf(stderr,
1294 "Do you want to proceed with the installation [y/n]?\n");
1295 line = fgetln(stdin, &len);
1296 if (check_input(line, len)) {
1297 fprintf(stderr, "Cancelling installation\n");
1298 return 1;
1300 return 0;
1302 if (strcasecmp(verified_installation, "interactive") == 0) {
1303 fprintf(stderr, "Do you want to proceed with "
1304 "the installation of %s [y/n]?\n", pkg->pkgname);
1305 line = fgetln(stdin, &len);
1306 if (check_input(line, len)) {
1307 fprintf(stderr, "Cancelling installation\n");
1308 return 1;
1310 return 0;
1312 warnx("Unknown value of configuration variable VERIFIED_INSTALLATION");
1313 return 1;
1316 static int
1317 check_vulnerable(struct pkg_task *pkg)
1319 static struct pkg_vulnerabilities *pv;
1320 int require_check;
1321 char *line;
1322 size_t len;
1324 if (strcasecmp(check_vulnerabilities, "never") == 0)
1325 return 0;
1326 else if (strcasecmp(check_vulnerabilities, "always") == 0)
1327 require_check = 1;
1328 else if (strcasecmp(check_vulnerabilities, "interactive") == 0)
1329 require_check = 0;
1330 else {
1331 warnx("Unknown value of the configuration variable"
1332 "CHECK_VULNERABILITIES");
1333 return 1;
1336 if (pv == NULL) {
1337 pv = read_pkg_vulnerabilities_file(pkg_vulnerabilities_file,
1338 require_check, 0);
1339 if (pv == NULL)
1340 return require_check;
1343 if (!audit_package(pv, pkg->pkgname, NULL, 2))
1344 return 0;
1346 if (require_check)
1347 return 1;
1349 fprintf(stderr, "Do you want to proceed with the installation of %s"
1350 " [y/n]?\n", pkg->pkgname);
1351 line = fgetln(stdin, &len);
1352 if (check_input(line, len)) {
1353 fprintf(stderr, "Cancelling installation\n");
1354 return 1;
1356 return 0;
1359 static int
1360 check_license(struct pkg_task *pkg)
1362 if (LicenseCheck == 0)
1363 return 0;
1365 if ((pkg->buildinfo[BI_LICENSE] == NULL ||
1366 *pkg->buildinfo[BI_LICENSE] == '\0')) {
1368 if (LicenseCheck == 1)
1369 return 0;
1370 warnx("No LICENSE set for package `%s'", pkg->pkgname);
1371 return 1;
1374 switch (acceptable_license(pkg->buildinfo[BI_LICENSE])) {
1375 case 0:
1376 warnx("License `%s' of package `%s' is not acceptable",
1377 pkg->buildinfo[BI_LICENSE], pkg->pkgname);
1378 return 1;
1379 case 1:
1380 return 0;
1381 default:
1382 warnx("Invalid LICENSE for package `%s'", pkg->pkgname);
1383 return 1;
1388 * Install a single package.
1390 static int
1391 pkg_do(const char *pkgpath, int mark_automatic, int top_level)
1393 char *archive_name;
1394 int status, invalid_sig;
1395 struct pkg_task *pkg;
1397 pkg = xcalloc(1, sizeof(*pkg));
1399 status = -1;
1401 pkg->archive = find_archive(pkgpath, top_level, &archive_name);
1402 if (pkg->archive == NULL) {
1403 warnx("no pkg found for '%s', sorry.", pkgpath);
1404 goto clean_find_archive;
1407 invalid_sig = pkg_verify_signature(archive_name, &pkg->archive, &pkg->entry,
1408 &pkg->pkgname);
1409 free(archive_name);
1411 if (pkg->archive == NULL)
1412 goto clean_memory;
1414 if (read_meta_data(pkg))
1415 goto clean_memory;
1417 /* Parse PLIST early, so that messages can use real package name. */
1418 if (pkg_parse_plist(pkg))
1419 goto clean_memory;
1421 if (check_signature(pkg, invalid_sig))
1422 goto clean_memory;
1424 if (read_buildinfo(pkg))
1425 goto clean_memory;
1427 if (check_pkgtools_version(pkg))
1428 goto clean_memory;
1430 if (check_vulnerable(pkg))
1431 goto clean_memory;
1433 if (check_license(pkg))
1434 goto clean_memory;
1436 if (pkg->meta_data.meta_mtree != NULL)
1437 warnx("mtree specification in pkg `%s' ignored", pkg->pkgname);
1439 if (pkg->meta_data.meta_views != NULL) {
1440 pkg->logdir = xstrdup(pkg->prefix);
1441 pkgdb_set_dir(dirname_of(pkg->logdir), 4);
1442 } else {
1443 pkg->logdir = xasprintf("%s/%s", config_pkg_dbdir, pkg->pkgname);
1446 if (Destdir != NULL)
1447 pkg->install_logdir = xasprintf("%s/%s", Destdir, pkg->logdir);
1448 else
1449 pkg->install_logdir = xstrdup(pkg->logdir);
1451 if (NoRecord && !Fake) {
1452 const char *tmpdir;
1454 tmpdir = getenv("TMPDIR");
1455 if (tmpdir == NULL)
1456 tmpdir = "/tmp";
1458 free(pkg->install_logdir);
1459 pkg->install_logdir = xasprintf("%s/pkg_install.XXXXXX", tmpdir);
1460 /* XXX pkg_add -u... */
1461 if (mkdtemp(pkg->install_logdir) == NULL) {
1462 warn("mkdtemp failed");
1463 goto clean_memory;
1467 switch (check_already_installed(pkg)) {
1468 case 0:
1469 status = 0;
1470 goto clean_memory;
1471 case 1:
1472 break;
1473 case -1:
1474 goto clean_memory;
1477 if (check_platform(pkg))
1478 goto clean_memory;
1480 if (check_other_installed(pkg))
1481 goto clean_memory;
1483 if (check_explicit_conflict(pkg))
1484 goto clean_memory;
1486 if (check_implicit_conflict(pkg))
1487 goto clean_memory;
1489 if (pkg->other_version != NULL) {
1491 * Replacing an existing package.
1492 * Write meta-data, get rid of the old version,
1493 * install/update dependencies and finally extract.
1495 if (write_meta_data(pkg))
1496 goto nuke_pkgdb;
1498 if (start_replacing(pkg))
1499 goto nuke_pkgdb;
1501 if (pkg->install_logdir_real) {
1502 rename(pkg->install_logdir, pkg->install_logdir_real);
1503 free(pkg->install_logdir);
1504 pkg->install_logdir = pkg->install_logdir_real;
1505 pkg->install_logdir_real = NULL;
1508 if (check_dependencies(pkg))
1509 goto nuke_pkgdb;
1510 } else {
1512 * Normal installation.
1513 * Install/update dependencies first and
1514 * write the current package to disk afterwards.
1516 if (check_dependencies(pkg))
1517 goto clean_memory;
1519 if (write_meta_data(pkg))
1520 goto nuke_pkgdb;
1523 if (run_install_script(pkg, "PRE-INSTALL"))
1524 goto nuke_pkgdb;
1526 if (extract_files(pkg))
1527 goto nuke_pkg;
1529 if (run_install_script(pkg, "POST-INSTALL"))
1530 goto nuke_pkgdb;
1532 /* XXX keep +INSTALL_INFO for updates? */
1533 /* XXX keep +PRESERVE for updates? */
1534 if (mark_automatic)
1535 mark_as_automatic_installed(pkg->pkgname, 1);
1537 pkg_register_depends(pkg);
1539 if (Verbose)
1540 printf("Package %s registered in %s\n", pkg->pkgname, pkg->install_logdir);
1542 if (pkg->meta_data.meta_display != NULL)
1543 fputs(pkg->meta_data.meta_display, stdout);
1545 pkg_register_views(pkg);
1547 status = 0;
1548 goto clean_memory;
1550 nuke_pkg:
1551 if (!Fake) {
1552 if (pkg->other_version) {
1553 warnx("Updating of %s to %s failed.",
1554 pkg->other_version, pkg->pkgname);
1555 warnx("Remember to run pkg_admin rebuild-tree after fixing this.");
1557 delete_package(FALSE, &pkg->plist, FALSE, Destdir);
1560 nuke_pkgdb:
1561 if (!Fake) {
1562 if (recursive_remove(pkg->install_logdir, 1))
1563 warn("Couldn't remove %s", pkg->install_logdir);
1564 free(pkg->install_logdir_real);
1565 free(pkg->install_logdir);
1566 free(pkg->logdir);
1567 pkg->install_logdir_real = NULL;
1568 pkg->install_logdir = NULL;
1569 pkg->logdir = NULL;
1572 clean_memory:
1573 if (pkg->logdir != NULL && NoRecord && !Fake) {
1574 if (recursive_remove(pkg->install_logdir, 1))
1575 warn("Couldn't remove %s", pkg->install_logdir);
1577 free(pkg->install_prefix);
1578 free(pkg->install_logdir_real);
1579 free(pkg->install_logdir);
1580 free(pkg->logdir);
1581 free_buildinfo(pkg);
1582 free_plist(&pkg->plist);
1583 free_meta_data(pkg);
1584 if (pkg->archive)
1585 archive_read_finish(pkg->archive);
1586 free(pkg->other_version);
1587 free(pkg->pkgname);
1588 clean_find_archive:
1589 free(pkg);
1590 return status;
1594 pkg_perform(lpkg_head_t *pkgs)
1596 int errors = 0;
1597 lpkg_t *lpp;
1599 while ((lpp = TAILQ_FIRST(pkgs)) != NULL) {
1600 if (pkg_do(lpp->lp_name, Automatic, 1))
1601 ++errors;
1602 TAILQ_REMOVE(pkgs, lpp, lp_link);
1603 free_lpkg(lpp);
1606 return errors;