Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / bsd / pkg_install / dist / add / perform.c
blob55483e17486157642e6b42884f1c13268e2cd871
1 /* $NetBSD: perform.c,v 1.91 2009/10/07 12:53:26 joerg 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.91 2009/10/07 12:53:26 joerg 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 * All rights reserved.
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in
26 * the documentation and/or other materials provided with the
27 * distribution.
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
32 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
33 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
34 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
35 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
36 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
37 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
38 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
39 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * SUCH DAMAGE.
43 #include <sys/utsname.h>
44 #if HAVE_ERR_H
45 #include <err.h>
46 #endif
47 #include <errno.h>
48 #if HAVE_FCNTL_H
49 #include <fcntl.h>
50 #endif
51 #include <stdlib.h>
52 #include <string.h>
53 #include <unistd.h>
55 #include <archive.h>
56 #include <archive_entry.h>
58 #include "lib.h"
59 #include "add.h"
61 struct pkg_meta {
62 char *meta_contents;
63 char *meta_comment;
64 char *meta_desc;
65 char *meta_mtree;
66 char *meta_build_version;
67 char *meta_build_info;
68 char *meta_size_pkg;
69 char *meta_size_all;
70 char *meta_required_by;
71 char *meta_display;
72 char *meta_install;
73 char *meta_deinstall;
74 char *meta_preserve;
75 char *meta_views;
76 char *meta_installed_info;
79 struct pkg_task {
80 char *pkgname;
82 const char *prefix;
83 char *install_prefix;
85 char *logdir;
86 char *install_logdir;
87 char *other_version;
89 package_t plist;
91 struct pkg_meta meta_data;
93 struct archive *archive;
94 struct archive_entry *entry;
96 char *buildinfo[BI_ENUM_COUNT];
98 size_t dep_length, dep_allocated;
99 char **dependencies;
102 static const struct pkg_meta_desc {
103 size_t entry_offset;
104 const char *entry_filename;
105 int required_file;
106 mode_t perm;
107 } pkg_meta_descriptors[] = {
108 { offsetof(struct pkg_meta, meta_contents), CONTENTS_FNAME, 1, 0644 },
109 { offsetof(struct pkg_meta, meta_comment), COMMENT_FNAME, 1, 0444},
110 { offsetof(struct pkg_meta, meta_desc), DESC_FNAME, 1, 0444},
111 { offsetof(struct pkg_meta, meta_install), INSTALL_FNAME, 0, 0555 },
112 { offsetof(struct pkg_meta, meta_deinstall), DEINSTALL_FNAME, 0, 0555 },
113 { offsetof(struct pkg_meta, meta_display), DISPLAY_FNAME, 0, 0444 },
114 { offsetof(struct pkg_meta, meta_mtree), MTREE_FNAME, 0, 0444 },
115 { offsetof(struct pkg_meta, meta_build_version), BUILD_VERSION_FNAME, 0, 0444 },
116 { offsetof(struct pkg_meta, meta_build_info), BUILD_INFO_FNAME, 0, 0444 },
117 { offsetof(struct pkg_meta, meta_size_pkg), SIZE_PKG_FNAME, 0, 0444 },
118 { offsetof(struct pkg_meta, meta_size_all), SIZE_ALL_FNAME, 0, 0444 },
119 { offsetof(struct pkg_meta, meta_preserve), PRESERVE_FNAME, 0, 0444 },
120 { offsetof(struct pkg_meta, meta_views), VIEWS_FNAME, 0, 0444 },
121 { offsetof(struct pkg_meta, meta_required_by), REQUIRED_BY_FNAME, 0, 0644 },
122 { offsetof(struct pkg_meta, meta_installed_info), INSTALLED_INFO_FNAME, 0, 0644 },
123 { 0, NULL, 0, 0 },
126 static int pkg_do(const char *, int, int);
128 static int
129 mkdir_p(const char *path)
131 char *p, *cur_end;
132 int done;
135 * Handle the easy case of direct success or
136 * pre-existing directory first.
138 if (mkdir(path, 0777) == 0 || errno == EEXIST)
139 return 0;
140 if (errno != ENOENT)
141 return -1;
143 cur_end = p = xstrdup(path);
145 for (;;) {
147 * First skip leading slashes either from / or
148 * from the last iteration.
150 cur_end += strspn(cur_end, "/");
151 /* Find end of actual directory name. */
152 cur_end += strcspn(cur_end, "/");
155 * Remember if this is the last component and
156 * overwrite / if needed.
158 done = (*cur_end == '\0');
159 *cur_end = '\0';
162 * ENOENT can only happen if something else races us,
163 * in which case we should better give up.
165 if (mkdir(p, 0777) == -1 && errno != EEXIST) {
166 free(p);
167 return -1;
169 if (done)
170 break;
171 *cur_end = '/';
174 free(p);
175 return 0;
179 * Read meta data from archive.
180 * Bail out if a required entry is missing or entries are in the wrong order.
182 static int
183 read_meta_data(struct pkg_task *pkg)
185 const struct pkg_meta_desc *descr, *last_descr;
186 const char *fname;
187 char **target;
188 int64_t size;
189 int r, found_required;
191 found_required = 0;
193 r = ARCHIVE_OK;
194 last_descr = 0;
196 if (pkg->entry != NULL)
197 goto skip_header;
199 for (;;) {
200 r = archive_read_next_header(pkg->archive, &pkg->entry);
201 if (r != ARCHIVE_OK)
202 break;
203 skip_header:
204 fname = archive_entry_pathname(pkg->entry);
206 for (descr = pkg_meta_descriptors; descr->entry_filename;
207 ++descr) {
208 if (strcmp(descr->entry_filename, fname) == 0)
209 break;
211 if (descr->entry_filename == NULL)
212 break;
214 if (descr->required_file)
215 ++found_required;
217 target = (char **)((char *)&pkg->meta_data +
218 descr->entry_offset);
219 if (*target) {
220 warnx("duplicate entry, package corrupt");
221 return -1;
223 if (descr < last_descr) {
224 warnx("misordered package");
225 return -1;
227 last_descr = descr;
229 size = archive_entry_size(pkg->entry);
230 if (size > SSIZE_MAX - 1) {
231 warnx("package meta data too large to process");
232 return -1;
234 *target = xmalloc(size + 1);
235 if (archive_read_data(pkg->archive, *target, size) != size) {
236 warnx("cannot read package meta data");
237 return -1;
239 (*target)[size] = '\0';
242 if (r != ARCHIVE_OK)
243 pkg->entry = NULL;
244 if (r == ARCHIVE_EOF)
245 r = ARCHIVE_OK;
247 for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) {
248 if (descr->required_file)
249 --found_required;
252 return !found_required && r == ARCHIVE_OK ? 0 : -1;
256 * Free meta data.
258 static void
259 free_meta_data(struct pkg_task *pkg)
261 const struct pkg_meta_desc *descr;
262 char **target;
264 for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) {
265 target = (char **)((char *)&pkg->meta_data +
266 descr->entry_offset);
267 free(*target);
268 *target = NULL;
273 * Parse PLIST and populate pkg.
275 static int
276 pkg_parse_plist(struct pkg_task *pkg)
278 plist_t *p;
280 parse_plist(&pkg->plist, pkg->meta_data.meta_contents);
281 if ((p = find_plist(&pkg->plist, PLIST_NAME)) == NULL) {
282 warnx("Invalid PLIST: missing @name");
283 return -1;
285 if (pkg->pkgname == NULL)
286 pkg->pkgname = xstrdup(p->name);
287 else if (strcmp(pkg->pkgname, p->name) != 0) {
288 warnx("Signature and PLIST differ on package name");
289 return -1;
291 if ((p = find_plist(&pkg->plist, PLIST_CWD)) == NULL) {
292 warnx("Invalid PLIST: missing @cwd");
293 return -1;
296 if (Prefix != NULL &&
297 strcmp(p->name, Prefix) != 0) {
298 size_t len;
300 delete_plist(&pkg->plist, FALSE, PLIST_CWD, NULL);
301 add_plist_top(&pkg->plist, PLIST_CWD, Prefix);
302 free(pkg->meta_data.meta_contents);
303 stringify_plist(&pkg->plist, &pkg->meta_data.meta_contents, &len,
304 Prefix);
305 pkg->prefix = Prefix;
306 } else
307 pkg->prefix = p->name;
309 if (Destdir != NULL)
310 pkg->install_prefix = xasprintf("%s/%s", Destdir, pkg->prefix);
311 else
312 pkg->install_prefix = xstrdup(pkg->prefix);
314 return 0;
318 * Helper function to extract value from a string of the
319 * form key=value ending at eol.
321 static char *
322 dup_value(const char *line, const char *eol)
324 const char *key;
325 char *val;
327 key = strchr(line, '=');
328 val = xmalloc(eol - key);
329 memcpy(val, key + 1, eol - key - 1);
330 val[eol - key - 1] = '\0';
331 return val;
334 static int
335 check_already_installed(struct pkg_task *pkg)
337 char *filename;
338 int fd;
340 if (Force)
341 return -1;
343 filename = pkgdb_pkg_file(pkg->pkgname, CONTENTS_FNAME);
344 fd = open(filename, O_RDONLY);
345 free(filename);
346 if (fd == -1)
347 return -1;
349 /* We can only arrive here for explicitly requested packages. */
350 if (!Automatic && is_automatic_installed(pkg->pkgname)) {
351 if (Fake ||
352 mark_as_automatic_installed(pkg->pkgname, 0) == 0)
353 warnx("package `%s' was already installed as "
354 "dependency, now marked as installed "
355 "manually", pkg->pkgname);
356 } else {
357 warnx("package `%s' already recorded as installed",
358 pkg->pkgname);
360 close(fd);
361 return 0;
365 static int
366 check_other_installed(struct pkg_task *pkg)
368 FILE *f, *f_pkg;
369 size_t len;
370 char *pkgbase, *iter, *filename;
371 package_t plist;
372 plist_t *p;
373 int status;
375 pkgbase = xstrdup(pkg->pkgname);
377 if ((iter = strrchr(pkgbase, '-')) == NULL) {
378 free(pkgbase);
379 warnx("Invalid package name %s", pkg->pkgname);
380 return -1;
382 *iter = '\0';
383 pkg->other_version = find_best_matching_installed_pkg(pkgbase);
384 free(pkgbase);
385 if (pkg->other_version == NULL)
386 return 0;
388 if (!Replace) {
389 /* XXX This is redundant to the implicit conflict check. */
390 warnx("A different version of %s is already installed: %s",
391 pkg->pkgname, pkg->other_version);
392 return -1;
395 filename = pkgdb_pkg_file(pkg->other_version, REQUIRED_BY_FNAME);
396 errno = 0;
397 f = fopen(filename, "r");
398 free(filename);
399 if (f == NULL) {
400 if (errno == ENOENT) {
401 /* No packages depend on this, so everything is well. */
402 return 0;
404 warnx("Can't open +REQUIRED_BY of %s", pkg->other_version);
405 return -1;
408 status = 0;
410 while ((iter = fgetln(f, &len)) != NULL) {
411 if (iter[len - 1] == '\n')
412 iter[len - 1] = '\0';
413 filename = pkgdb_pkg_file(iter, CONTENTS_FNAME);
414 if ((f_pkg = fopen(filename, "r")) == NULL) {
415 warnx("Can't open +CONTENTS of depending package %s",
416 iter);
417 fclose(f);
418 return -1;
420 read_plist(&plist, f_pkg);
421 fclose(f_pkg);
422 for (p = plist.head; p != NULL; p = p->next) {
423 if (p->type == PLIST_IGNORE) {
424 p = p->next;
425 continue;
426 } else if (p->type != PLIST_PKGDEP)
427 continue;
429 * XXX This is stricter than necessary.
430 * XXX One pattern might be fulfilled by
431 * XXX a different package and still need this
432 * XXX one for a different pattern.
434 if (pkg_match(p->name, pkg->other_version) == 0)
435 continue;
436 if (pkg_match(p->name, pkg->pkgname) == 1)
437 continue; /* Both match, ok. */
438 warnx("Dependency of %s fulfilled by %s, but not by %s",
439 iter, pkg->other_version, pkg->pkgname);
440 if (!Force)
441 status = -1;
442 break;
444 free_plist(&plist);
447 fclose(f);
449 return status;
453 * Read package build information from meta data.
455 static int
456 read_buildinfo(struct pkg_task *pkg)
458 const char *data, *eol, *next_line;
460 data = pkg->meta_data.meta_build_info;
462 for (; data != NULL && *data != '\0'; data = next_line) {
463 if ((eol = strchr(data, '\n')) == NULL) {
464 eol = data + strlen(data);
465 next_line = eol;
466 } else
467 next_line = eol + 1;
469 if (strncmp(data, "OPSYS=", 6) == 0)
470 pkg->buildinfo[BI_OPSYS] = dup_value(data, eol);
471 else if (strncmp(data, "OS_VERSION=", 11) == 0)
472 pkg->buildinfo[BI_OS_VERSION] = dup_value(data, eol);
473 else if (strncmp(data, "MACHINE_ARCH=", 13) == 0)
474 pkg->buildinfo[BI_MACHINE_ARCH] = dup_value(data, eol);
475 else if (strncmp(data, "IGNORE_RECOMMENDED=", 19) == 0)
476 pkg->buildinfo[BI_IGNORE_RECOMMENDED] = dup_value(data,
477 eol);
478 else if (strncmp(data, "USE_ABI_DEPENDS=", 16) == 0)
479 pkg->buildinfo[BI_USE_ABI_DEPENDS] = dup_value(data,
480 eol);
481 else if (strncmp(data, "LICENSE=", 8) == 0)
482 pkg->buildinfo[BI_LICENSE] = dup_value(data, eol);
484 if (pkg->buildinfo[BI_OPSYS] == NULL ||
485 pkg->buildinfo[BI_OS_VERSION] == NULL ||
486 pkg->buildinfo[BI_MACHINE_ARCH] == NULL) {
487 warnx("Not all required build information are present.");
488 return -1;
491 if ((pkg->buildinfo[BI_USE_ABI_DEPENDS] != NULL &&
492 strcasecmp(pkg->buildinfo[BI_USE_ABI_DEPENDS], "YES") != 0) ||
493 (pkg->buildinfo[BI_IGNORE_RECOMMENDED] != NULL &&
494 strcasecmp(pkg->buildinfo[BI_IGNORE_RECOMMENDED], "NO") != 0)) {
495 warnx("%s was built to ignore ABI dependencies", pkg->pkgname);
498 return 0;
502 * Free buildinfo.
504 static void
505 free_buildinfo(struct pkg_task *pkg)
507 size_t i;
509 for (i = 0; i < BI_ENUM_COUNT; ++i) {
510 free(pkg->buildinfo[i]);
511 pkg->buildinfo[i] = NULL;
516 * Write meta data files to pkgdb after creating the directory.
518 static int
519 write_meta_data(struct pkg_task *pkg)
521 const struct pkg_meta_desc *descr;
522 char *filename, **target;
523 size_t len;
524 ssize_t ret;
525 int fd;
527 if (Fake)
528 return 0;
530 if (mkdir_p(pkg->install_logdir)) {
531 warn("Can't create pkgdb entry: %s", pkg->install_logdir);
532 return -1;
535 for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) {
536 target = (char **)((char *)&pkg->meta_data +
537 descr->entry_offset);
538 if (*target == NULL)
539 continue;
540 filename = xasprintf("%s/%s", pkg->install_logdir,
541 descr->entry_filename);
542 (void)unlink(filename);
543 fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, descr->perm);
544 if (fd == -1) {
545 warn("Can't open meta data file: %s", filename);
546 return -1;
548 len = strlen(*target);
549 do {
550 ret = write(fd, *target, len);
551 if (ret == -1) {
552 warn("Can't write meta data file: %s",
553 filename);
554 free(filename);
555 close(fd);
556 return -1;
558 len -= ret;
559 } while (ret > 0);
560 if (close(fd) == -1) {
561 warn("Can't close meta data file: %s", filename);
562 free(filename);
563 return -1;
565 free(filename);
568 return 0;
572 * Helper function for extract_files.
574 static int
575 copy_data_to_disk(struct archive *reader, struct archive *writer,
576 const char *filename)
578 int r;
579 const void *buff;
580 size_t size;
581 off_t offset;
583 for (;;) {
584 r = archive_read_data_block(reader, &buff, &size, &offset);
585 if (r == ARCHIVE_EOF)
586 return 0;
587 if (r != ARCHIVE_OK) {
588 warnx("Read error for %s: %s", filename,
589 archive_error_string(reader));
590 return -1;
592 r = archive_write_data_block(writer, buff, size, offset);
593 if (r != ARCHIVE_OK) {
594 warnx("Write error for %s: %s", filename,
595 archive_error_string(writer));
596 return -1;
602 * Extract package.
603 * Any misordered, missing or unlisted file in the package is an error.
606 static const int extract_flags = ARCHIVE_EXTRACT_OWNER |
607 ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_UNLINK |
608 ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR;
610 static int
611 extract_files(struct pkg_task *pkg)
613 char cmd[MaxPathSize];
614 const char *owner, *group, *permissions;
615 struct archive *writer;
616 int r;
617 plist_t *p;
618 const char *last_file;
619 char *fullpath;
621 if (Fake)
622 return 0;
624 if (mkdir_p(pkg->install_prefix)) {
625 warn("Can't create prefix: %s", pkg->install_prefix);
626 return -1;
629 if (!NoRecord && !pkgdb_open(ReadWrite)) {
630 warn("Can't open pkgdb for writing");
631 return -1;
634 if (chdir(pkg->install_prefix) == -1) {
635 warn("Can't change into prefix: %s", pkg->install_prefix);
636 return -1;
639 writer = archive_write_disk_new();
640 archive_write_disk_set_options(writer, extract_flags);
641 archive_write_disk_set_standard_lookup(writer);
643 owner = NULL;
644 group = NULL;
645 permissions = NULL;
646 last_file = NULL;
648 r = -1;
650 for (p = pkg->plist.head; p != NULL; p = p->next) {
651 switch (p->type) {
652 case PLIST_FILE:
653 last_file = p->name;
654 if (pkg->entry == NULL) {
655 warnx("PLIST entry not in package (%s)",
656 archive_entry_pathname(pkg->entry));
657 goto out;
659 if (strcmp(p->name, archive_entry_pathname(pkg->entry))) {
660 warnx("PLIST entry and package don't match (%s vs %s)",
661 p->name, archive_entry_pathname(pkg->entry));
662 goto out;
664 fullpath = xasprintf("%s/%s", pkg->prefix, p->name);
665 pkgdb_store(fullpath, pkg->pkgname);
666 free(fullpath);
667 if (Verbose)
668 printf("%s", p->name);
669 break;
671 case PLIST_PKGDIR:
672 fullpath = xasprintf("%s/%s", pkg->prefix, p->name);
673 mkdir_p(fullpath);
674 free(fullpath);
675 add_pkgdir(pkg->pkgname, pkg->prefix, p->name);
676 continue;
678 case PLIST_CMD:
679 if (format_cmd(cmd, sizeof(cmd), p->name, pkg->prefix, last_file))
680 return -1;
681 printf("Executing '%s'\n", cmd);
682 if (!Fake && system(cmd))
683 warnx("command '%s' failed", cmd); /* XXX bail out? */
684 continue;
686 case PLIST_CHMOD:
687 permissions = p->name;
688 continue;
690 case PLIST_CHOWN:
691 owner = p->name;
692 continue;
694 case PLIST_CHGRP:
695 group = p->name;
696 continue;
698 case PLIST_IGNORE:
699 p = p->next;
700 continue;
702 default:
703 continue;
706 r = archive_write_header(writer, pkg->entry);
707 if (r != ARCHIVE_OK) {
708 warnx("Failed to write %s: %s",
709 archive_entry_pathname(pkg->entry),
710 archive_error_string(writer));
711 goto out;
714 if (owner != NULL)
715 archive_entry_set_uname(pkg->entry, owner);
716 if (group != NULL)
717 archive_entry_set_uname(pkg->entry, group);
718 if (permissions != NULL) {
719 mode_t mode;
721 mode = archive_entry_mode(pkg->entry);
722 mode = getmode(setmode(permissions), mode);
723 archive_entry_set_mode(pkg->entry, mode);
726 r = copy_data_to_disk(pkg->archive, writer,
727 archive_entry_pathname(pkg->entry));
728 if (r)
729 goto out;
730 if (Verbose)
731 printf("\n");
733 r = archive_read_next_header(pkg->archive, &pkg->entry);
734 if (r == ARCHIVE_EOF) {
735 pkg->entry = NULL;
736 continue;
738 if (r != ARCHIVE_OK) {
739 warnx("Failed to read from archive: %s",
740 archive_error_string(pkg->archive));
741 goto out;
745 if (pkg->entry != NULL) {
746 warnx("Package contains entries not in PLIST: %s",
747 archive_entry_pathname(pkg->entry));
748 goto out;
751 r = 0;
753 out:
754 if (!NoRecord)
755 pkgdb_close();
756 archive_write_close(writer);
757 archive_write_finish(writer);
759 return r;
763 * Register dependencies after sucessfully installing the package.
765 static void
766 pkg_register_depends(struct pkg_task *pkg)
768 int fd;
769 size_t text_len, i;
770 char *required_by, *text;
772 if (Fake)
773 return;
775 text = xasprintf("%s\n", pkg->pkgname);
776 text_len = strlen(text);
778 for (i = 0; i < pkg->dep_length; ++i) {
779 required_by = pkgdb_pkg_file(pkg->dependencies[i], REQUIRED_BY_FNAME);
781 fd = open(required_by, O_WRONLY | O_APPEND | O_CREAT, 0644);
782 if (fd == -1) {
783 warn("can't open dependency file '%s',"
784 "registration is incomplete!", required_by);
785 } else if (write(fd, text, text_len) != (ssize_t)text_len) {
786 warn("can't write to dependency file `%s'", required_by);
787 close(fd);
788 } else if (close(fd) == -1)
789 warn("cannot close file %s", required_by);
791 free(required_by);
794 free(text);
798 * Reduce the result from uname(3) to a canonical form.
800 static void
801 normalise_platform(struct utsname *host_name)
803 #ifdef NUMERIC_VERSION_ONLY
804 size_t span;
806 span = strspn(host_name->release, "0123456789.");
807 host_name->release[span] = '\0';
808 #endif
812 * Check build platform of the package against local host.
814 static int
815 check_platform(struct pkg_task *pkg)
817 struct utsname host_uname;
818 const char *effective_arch;
819 int fatal;
821 if (uname(&host_uname) < 0) {
822 if (Force) {
823 warnx("uname() failed, continuing.");
824 return 0;
825 } else {
826 warnx("uname() failed, aborting.");
827 return -1;
831 normalise_platform(&host_uname);
833 if (OverrideMachine != NULL)
834 effective_arch = OverrideMachine;
835 else
836 effective_arch = MACHINE_ARCH;
838 /* If either the OS or arch are different, bomb */
839 if (strcmp(OPSYS_NAME, pkg->buildinfo[BI_OPSYS]) ||
840 strcmp(effective_arch, pkg->buildinfo[BI_MACHINE_ARCH]) != 0)
841 fatal = 1;
842 else
843 fatal = 0;
845 if (fatal ||
846 strcmp(host_uname.release, pkg->buildinfo[BI_OS_VERSION]) != 0) {
847 warnx("Warning: package `%s' was built for a platform:",
848 pkg->pkgname);
849 warnx("%s/%s %s (pkg) vs. %s/%s %s (this host)",
850 pkg->buildinfo[BI_OPSYS],
851 pkg->buildinfo[BI_MACHINE_ARCH],
852 pkg->buildinfo[BI_OS_VERSION],
853 OPSYS_NAME,
854 effective_arch,
855 host_uname.release);
856 if (!Force && fatal)
857 return -1;
859 return 0;
863 * Run the install script.
865 static int
866 run_install_script(struct pkg_task *pkg, const char *argument)
868 int ret;
869 char *filename;
871 if (pkg->meta_data.meta_install == NULL || NoInstall)
872 return 0;
874 if (Destdir != NULL)
875 setenv(PKG_DESTDIR_VNAME, Destdir, 1);
876 setenv(PKG_PREFIX_VNAME, pkg->prefix, 1);
877 setenv(PKG_METADATA_DIR_VNAME, pkg->logdir, 1);
878 setenv(PKG_REFCOUNT_DBDIR_VNAME, pkgdb_refcount_dir(), 1);
880 if (Verbose)
881 printf("Running install with PRE-INSTALL for %s.\n", pkg->pkgname);
882 if (Fake)
883 return 0;
885 filename = pkgdb_pkg_file(pkg->pkgname, INSTALL_FNAME);
887 ret = 0;
888 errno = 0;
889 if (fcexec(pkg->install_logdir, filename, pkg->pkgname, argument,
890 (void *)NULL)) {
891 if (errno != 0)
892 warn("exec of install script failed");
893 else
894 warnx("install script returned error status");
895 ret = -1;
897 free(filename);
899 return ret;
902 struct find_conflict_data {
903 const char *pkg;
904 const char *old_pkg;
905 const char *pattern;
908 static int
909 check_explicit_conflict_iter(const char *cur_pkg, void *cookie)
911 struct find_conflict_data *data = cookie;
913 if (data->old_pkg && strcmp(data->old_pkg, cur_pkg) == 0)
914 return 0;
916 warnx("Package `%s' conflicts with `%s', and `%s' is installed.",
917 data->pkg, data->pattern, cur_pkg);
919 return 1;
922 static int
923 check_explicit_conflict(struct pkg_task *pkg)
925 struct find_conflict_data data;
926 char *installed, *installed_pattern;
927 plist_t *p;
928 int status;
930 status = 0;
932 for (p = pkg->plist.head; p != NULL; p = p->next) {
933 if (p->type == PLIST_IGNORE) {
934 p = p->next;
935 continue;
937 if (p->type != PLIST_PKGCFL)
938 continue;
939 data.pkg = pkg->pkgname;
940 data.old_pkg = pkg->other_version;
941 data.pattern = p->name;
942 status |= match_installed_pkgs(p->name,
943 check_explicit_conflict_iter, &data);
946 if (some_installed_package_conflicts_with(pkg->pkgname,
947 pkg->other_version, &installed, &installed_pattern)) {
948 warnx("Installed package `%s' conflicts with `%s' when trying to install `%s'.",
949 installed, installed_pattern, pkg->pkgname);
950 free(installed);
951 free(installed_pattern);
952 status |= -1;
955 return status;
958 static int
959 check_implicit_conflict(struct pkg_task *pkg)
961 plist_t *p;
962 char *fullpath, *existing;
963 int status;
965 if (!pkgdb_open(ReadOnly)) {
966 #if notyet /* XXX empty pkgdb without database? */
967 warn("Can't open pkgdb for reading");
968 return -1;
969 #else
970 return 0;
971 #endif
974 status = 0;
976 for (p = pkg->plist.head; p != NULL; p = p->next) {
977 if (p->type == PLIST_IGNORE) {
978 p = p->next;
979 continue;
980 } else if (p->type != PLIST_FILE)
981 continue;
983 fullpath = xasprintf("%s/%s", pkg->prefix, p->name);
984 existing = pkgdb_retrieve(fullpath);
985 free(fullpath);
986 if (existing == NULL)
987 continue;
988 if (pkg->other_version != NULL &&
989 strcmp(pkg->other_version, existing) == 0)
990 continue;
992 warnx("Conflicting PLIST with %s: %s", existing, p->name);
993 if (!Force) {
994 status = -1;
995 if (!Verbose)
996 break;
1000 pkgdb_close();
1001 return status;
1004 static int
1005 check_dependencies(struct pkg_task *pkg)
1007 plist_t *p;
1008 char *best_installed;
1009 int status;
1010 size_t i;
1012 status = 0;
1014 for (p = pkg->plist.head; p != NULL; p = p->next) {
1015 if (p->type == PLIST_IGNORE) {
1016 p = p->next;
1017 continue;
1018 } else if (p->type != PLIST_PKGDEP)
1019 continue;
1021 best_installed = find_best_matching_installed_pkg(p->name);
1023 if (best_installed == NULL) {
1024 /* XXX check cyclic dependencies? */
1025 if (Fake || NoRecord) {
1026 if (!Force) {
1027 warnx("Missing dependency %s\n",
1028 p->name);
1029 status = -1;
1030 break;
1032 warnx("Missing dependency %s, continuing",
1033 p->name);
1034 continue;
1036 if (pkg_do(p->name, 1, 0)) {
1037 if (ForceDepends) {
1038 warnx("Can't install dependency %s, "
1039 "continuing", p->name);
1040 continue;
1041 } else {
1042 warnx("Can't install dependency %s",
1043 p->name);
1044 status = -1;
1045 break;
1048 best_installed = find_best_matching_installed_pkg(p->name);
1049 if (best_installed == NULL && ForceDepends) {
1050 warnx("Missing dependency %s ignored", p->name);
1051 continue;
1052 } else if (best_installed == NULL) {
1053 warnx("Just installed dependency %s disappeared", p->name);
1054 status = -1;
1055 break;
1058 for (i = 0; i < pkg->dep_length; ++i) {
1059 if (strcmp(best_installed, pkg->dependencies[i]) == 0)
1060 break;
1062 if (i < pkg->dep_length) {
1063 /* Already used as dependency, so skip it. */
1064 free(best_installed);
1065 continue;
1067 if (pkg->dep_length + 1 >= pkg->dep_allocated) {
1068 char **tmp;
1069 pkg->dep_allocated = 2 * pkg->dep_allocated + 1;
1070 pkg->dependencies = xrealloc(pkg->dependencies,
1071 pkg->dep_allocated * sizeof(*tmp));
1073 pkg->dependencies[pkg->dep_length++] = best_installed;
1076 return status;
1080 * If this package uses pkg_views, register it in the default view.
1082 static void
1083 pkg_register_views(struct pkg_task *pkg)
1085 if (Fake || NoView || pkg->meta_data.meta_views == NULL)
1086 return;
1088 if (Verbose) {
1089 printf("%s/pkg_view -d %s %s%s %s%s %sadd %s\n",
1090 BINDIR, _pkgdb_getPKGDB_DIR(),
1091 View ? "-w " : "", View ? View : "",
1092 Viewbase ? "-W " : "", Viewbase ? Viewbase : "",
1093 Verbose ? "-v " : "", pkg->pkgname);
1096 fexec_skipempty(BINDIR "/pkg_view", "-d", _pkgdb_getPKGDB_DIR(),
1097 View ? "-w " : "", View ? View : "",
1098 Viewbase ? "-W " : "", Viewbase ? Viewbase : "",
1099 Verbose ? "-v " : "", "add", pkg->pkgname,
1100 (void *)NULL);
1103 static int
1104 preserve_meta_data_file(struct pkg_task *pkg, const char *name)
1106 char *old_file, *new_file;
1107 int rv;
1109 if (Fake)
1110 return 0;
1112 old_file = pkgdb_pkg_file(pkg->other_version, name);
1113 new_file = pkgdb_pkg_file(pkg->pkgname, name);
1114 rv = 0;
1115 if (rename(old_file, new_file) == -1 && errno != ENOENT) {
1116 warn("Can't move %s from %s to %s", name, old_file, new_file);
1117 rv = -1;
1119 free(old_file);
1120 free(new_file);
1121 return rv;
1124 static int
1125 start_replacing(struct pkg_task *pkg)
1127 if (preserve_meta_data_file(pkg, REQUIRED_BY_FNAME))
1128 return -1;
1130 if (preserve_meta_data_file(pkg, PRESERVE_FNAME))
1131 return -1;
1133 if (pkg->meta_data.meta_installed_info == NULL &&
1134 preserve_meta_data_file(pkg, INSTALLED_INFO_FNAME))
1135 return -1;
1137 if (Verbose || Fake) {
1138 printf("%s/pkg_delete -K %s -p %s%s%s '%s'\n",
1139 BINDIR, _pkgdb_getPKGDB_DIR(), pkg->prefix,
1140 Destdir ? " -P ": "", Destdir ? Destdir : "",
1141 pkg->other_version);
1143 if (!Fake)
1144 fexec_skipempty(BINDIR "/pkg_delete", "-K", _pkgdb_getPKGDB_DIR(),
1145 "-p", pkg->prefix,
1146 Destdir ? "-P": "", Destdir ? Destdir : "",
1147 pkg->other_version, NULL);
1149 /* XXX Check return value and do what? */
1150 return 0;
1153 static int check_input(const char *line, size_t len)
1155 if (line == NULL || len == 0)
1156 return 1;
1157 switch (*line) {
1158 case 'Y':
1159 case 'y':
1160 case 'T':
1161 case 't':
1162 case '1':
1163 return 0;
1164 default:
1165 return 1;
1169 static int
1170 check_signature(struct pkg_task *pkg, int invalid_sig)
1172 char *line;
1173 size_t len;
1175 if (strcasecmp(verified_installation, "never") == 0)
1176 return 0;
1177 if (strcasecmp(verified_installation, "always") == 0) {
1178 if (invalid_sig)
1179 warnx("No valid signature found, rejected");
1180 return invalid_sig;
1182 if (strcasecmp(verified_installation, "trusted") == 0) {
1183 if (!invalid_sig)
1184 return 0;
1185 fprintf(stderr, "No valid signature found for %s.\n",
1186 pkg->pkgname);
1187 fprintf(stderr,
1188 "Do you want to proceed with the installation [y/n]?\n");
1189 line = fgetln(stdin, &len);
1190 if (check_input(line, len)) {
1191 fprintf(stderr, "Cancelling installation\n");
1192 return 1;
1194 return 0;
1196 if (strcasecmp(verified_installation, "interactive") == 0) {
1197 fprintf(stderr, "Do you want to proceed with "
1198 "the installation of %s [y/n]?\n", pkg->pkgname);
1199 line = fgetln(stdin, &len);
1200 if (check_input(line, len)) {
1201 fprintf(stderr, "Cancelling installation\n");
1202 return 1;
1204 return 0;
1206 warnx("Unknown value of configuration variable VERIFIED_INSTALLATION");
1207 return 1;
1210 static int
1211 check_vulnerable(struct pkg_task *pkg)
1213 static struct pkg_vulnerabilities *pv;
1214 int require_check;
1215 char *line;
1216 size_t len;
1218 if (strcasecmp(check_vulnerabilities, "never") == 0)
1219 return 0;
1220 else if (strcasecmp(check_vulnerabilities, "always"))
1221 require_check = 1;
1222 else if (strcasecmp(check_vulnerabilities, "interactive"))
1223 require_check = 0;
1224 else {
1225 warnx("Unknown value of the configuration variable"
1226 "CHECK_VULNERABILITIES");
1227 return 1;
1230 if (pv == NULL) {
1231 pv = read_pkg_vulnerabilities(pkg_vulnerabilities_file,
1232 require_check, 0);
1233 if (pv == NULL)
1234 return require_check;
1237 if (!audit_package(pv, pkg->pkgname, NULL, 0, 2))
1238 return 0;
1240 if (require_check)
1241 return 1;
1243 fprintf(stderr, "Do you want to proceed with the installation of %s"
1244 " [y/n]?\n", pkg->pkgname);
1245 line = fgetln(stdin, &len);
1246 if (check_input(line, len)) {
1247 fprintf(stderr, "Cancelling installation\n");
1248 return 1;
1250 return 0;
1253 static int
1254 check_license(struct pkg_task *pkg)
1256 if (LicenseCheck == 0)
1257 return 0;
1259 if ((pkg->buildinfo[BI_LICENSE] == NULL ||
1260 *pkg->buildinfo[BI_LICENSE] == '\0')) {
1262 if (LicenseCheck == 1)
1263 return 0;
1264 warnx("No LICENSE set for package `%s'", pkg->pkgname);
1265 return 1;
1268 switch (acceptable_license(pkg->buildinfo[BI_LICENSE])) {
1269 case 0:
1270 warnx("License `%s' of package `%s' is not acceptable",
1271 pkg->buildinfo[BI_LICENSE], pkg->pkgname);
1272 return 1;
1273 case 1:
1274 return 0;
1275 default:
1276 warnx("Invalid LICENSE for package `%s'", pkg->pkgname);
1277 return 1;
1282 * Install a single package.
1284 static int
1285 pkg_do(const char *pkgpath, int mark_automatic, int top_level)
1287 int status, invalid_sig;
1288 struct pkg_task *pkg;
1290 pkg = xcalloc(1, sizeof(*pkg));
1292 status = -1;
1294 pkg->archive = find_archive(pkgpath, top_level);
1295 if (pkg->archive == NULL) {
1296 warnx("no pkg found for '%s', sorry.", pkgpath);
1297 goto clean_find_archive;
1300 invalid_sig = pkg_verify_signature(&pkg->archive, &pkg->entry,
1301 &pkg->pkgname);
1303 if (pkg->archive == NULL)
1304 goto clean_memory;
1306 if (read_meta_data(pkg))
1307 goto clean_memory;
1309 /* Parse PLIST early, so that messages can use real package name. */
1310 if (pkg_parse_plist(pkg))
1311 goto clean_memory;
1313 if (check_signature(pkg, invalid_sig))
1314 goto clean_memory;
1316 if (read_buildinfo(pkg))
1317 goto clean_memory;
1319 if (check_vulnerable(pkg))
1320 goto clean_memory;
1322 if (check_license(pkg))
1323 goto clean_memory;
1325 if (pkg->meta_data.meta_mtree != NULL)
1326 warnx("mtree specification in pkg `%s' ignored", pkg->pkgname);
1328 if (pkg->meta_data.meta_views != NULL) {
1329 pkg->logdir = xstrdup(pkg->prefix);
1330 _pkgdb_setPKGDB_DIR(dirname_of(pkg->logdir));
1331 } else {
1332 pkg->logdir = xasprintf("%s/%s", PlainPkgdb, pkg->pkgname);
1335 if (Destdir != NULL)
1336 pkg->install_logdir = xasprintf("%s/%s", Destdir, pkg->logdir);
1337 else
1338 pkg->install_logdir = xstrdup(pkg->logdir);
1340 if (NoRecord && !Fake) {
1341 const char *tmpdir;
1343 tmpdir = getenv("TMPDIR");
1344 if (tmpdir == NULL)
1345 tmpdir = "/tmp";
1347 free(pkg->install_logdir);
1348 pkg->install_logdir = xasprintf("%s/pkg_install.XXXXXX", tmpdir);
1349 /* XXX pkg_add -u... */
1350 if (mkdtemp(pkg->install_logdir) == NULL) {
1351 warn("mkdtemp failed");
1352 goto clean_memory;
1356 if (check_already_installed(pkg) == 0) {
1357 status = 0;
1358 goto clean_memory;
1361 if (check_platform(pkg))
1362 goto clean_memory;
1364 if (check_other_installed(pkg))
1365 goto clean_memory;
1367 if (check_explicit_conflict(pkg))
1368 goto clean_memory;
1370 if (check_implicit_conflict(pkg))
1371 goto clean_memory;
1373 if (pkg->other_version != NULL) {
1375 * Replacing an existing package.
1376 * Write meta-data, get rid of the old version,
1377 * install/update dependencies and finally extract.
1379 if (write_meta_data(pkg))
1380 goto nuke_pkgdb;
1382 if (start_replacing(pkg))
1383 goto nuke_pkgdb;
1385 if (check_dependencies(pkg))
1386 goto nuke_pkgdb;
1387 } else {
1389 * Normal installation.
1390 * Install/update dependencies first and
1391 * write the current package to disk afterwards.
1393 if (check_dependencies(pkg))
1394 goto clean_memory;
1396 if (write_meta_data(pkg))
1397 goto nuke_pkgdb;
1400 if (run_install_script(pkg, "PRE-INSTALL"))
1401 goto nuke_pkgdb;
1403 if (extract_files(pkg))
1404 goto nuke_pkg;
1406 if (run_install_script(pkg, "POST-INSTALL"))
1407 goto nuke_pkgdb;
1409 /* XXX keep +INSTALL_INFO for updates? */
1410 /* XXX keep +PRESERVE for updates? */
1411 if (mark_automatic)
1412 mark_as_automatic_installed(pkg->pkgname, 1);
1414 pkg_register_depends(pkg);
1416 if (Verbose)
1417 printf("Package %s registered in %s\n", pkg->pkgname, pkg->install_logdir);
1419 if (pkg->meta_data.meta_display != NULL)
1420 fputs(pkg->meta_data.meta_display, stdout);
1422 pkg_register_views(pkg);
1424 status = 0;
1425 goto clean_memory;
1427 nuke_pkg:
1428 if (!Fake) {
1429 if (pkg->other_version) {
1430 warnx("Updating of %s to %s failed.",
1431 pkg->other_version, pkg->pkgname);
1432 warnx("Remember to run pkg_admin rebuild-tree after fixing this.");
1434 delete_package(FALSE, &pkg->plist, FALSE, Destdir);
1437 nuke_pkgdb:
1438 if (!Fake) {
1439 if (recursive_remove(pkg->install_logdir, 1))
1440 warn("Couldn't remove %s", pkg->install_logdir);
1441 free(pkg->install_logdir);
1442 free(pkg->logdir);
1443 pkg->install_logdir = NULL;
1444 pkg->logdir = NULL;
1447 clean_memory:
1448 if (pkg->logdir != NULL && NoRecord && !Fake) {
1449 if (recursive_remove(pkg->install_logdir, 1))
1450 warn("Couldn't remove %s", pkg->install_logdir);
1452 free(pkg->install_prefix);
1453 free(pkg->install_logdir);
1454 free(pkg->logdir);
1455 free_buildinfo(pkg);
1456 free_plist(&pkg->plist);
1457 free_meta_data(pkg);
1458 if (pkg->archive)
1459 archive_read_finish(pkg->archive);
1460 free(pkg->other_version);
1461 free(pkg->pkgname);
1462 clean_find_archive:
1463 free(pkg);
1464 return status;
1468 pkg_perform(lpkg_head_t *pkgs)
1470 int errors = 0;
1471 lpkg_t *lpp;
1473 while ((lpp = TAILQ_FIRST(pkgs)) != NULL) {
1474 if (pkg_do(lpp->lp_name, Automatic, 1))
1475 ++errors;
1476 TAILQ_REMOVE(pkgs, lpp, lp_link);
1477 free_lpkg(lpp);
1480 return errors;