xref: /minix3/external/bsd/pkg_install/dist/add/perform.c (revision a824f5a1008ee67499d167f8c48e64aae26960ca)
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 $");
10 
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.
18  *
19  * Redistribution and use in source and binary forms, with or without
20  * modification, are permitted provided that the following conditions
21  * are met:
22  *
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.
29  *
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.
42  */
43 
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>
56 
57 #include <archive.h>
58 #include <archive_entry.h>
59 
60 #include "lib.h"
61 #include "add.h"
62 #include "version.h"
63 
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;
80 };
81 
82 struct pkg_task {
83 	char *pkgname;
84 
85 	const char *prefix;
86 	char *install_prefix;
87 
88 	char *logdir;
89 	char *install_logdir;
90 	char *install_logdir_real;
91 	char *other_version;
92 
93 	package_t plist;
94 
95 	struct pkg_meta meta_data;
96 
97 	struct archive *archive;
98 	struct archive_entry *entry;
99 
100 	char *buildinfo[BI_ENUM_COUNT];
101 
102 	size_t dep_length, dep_allocated;
103 	char **dependencies;
104 };
105 
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 },
128 };
129 
130 static int pkg_do(const char *, int, int);
131 
132 static int
end_of_version(const char * opsys,const char * version_end)133 end_of_version(const char *opsys, const char *version_end)
134 {
135     if (*version_end == '\0')
136 	return 1;
137 
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;
145     }
146 
147     return 0;
148 }
149 
150 static int
compatible_platform(const char * opsys,const char * host,const char * package)151 compatible_platform(const char *opsys, const char *host, const char *package)
152 {
153     int i = 0;
154 
155     /* returns 1 if host and package operating system match */
156     if (strcmp(host, package) == 0)
157 	return 1;
158 
159     /* accept, if host version is a minor release of package version */
160     if (strncmp(host, package, strlen(package)) == 0)
161 	return 1;
162 
163     /* find offset of first difference */
164     for (i=0; (host[i] != '\0') && (host[i] == package[i]);)
165 	i++;
166 
167     if (end_of_version(opsys, host+i) && end_of_version(opsys, package+i))
168 	return 1;
169 
170     return 0;
171 }
172 
173 static int
mkdir_p(const char * path)174 mkdir_p(const char *path)
175 {
176 	char *p, *cur_end;
177 	int done, saved_errno;
178 	struct stat sb;
179 
180 	/*
181 	 * Handle the easy case of direct success or
182 	 * pre-existing directory first.
183 	 */
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;
191 	}
192 
193 	cur_end = p = xstrdup(path);
194 
195 	for (;;) {
196 		/*
197 		 * First skip leading slashes either from / or
198 		 * from the last iteration.
199 		 */
200 		cur_end += strspn(cur_end, "/");
201 		/* Find end of actual directory name. */
202 		cur_end += strcspn(cur_end, "/");
203 
204 		/*
205 		 * Remember if this is the last component and
206 		 * overwrite / if needed.
207 		 */
208 		done = (*cur_end == '\0');
209 		*cur_end = '\0';
210 
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;
219 			}
220 			free(p);
221 			return -1;
222 		}
223 pass:
224 		if (done)
225 			break;
226 		*cur_end = '/';
227 	}
228 
229 	free(p);
230 	return 0;
231 }
232 
233 /*
234  * Read meta data from archive.
235  * Bail out if a required entry is missing or entries are in the wrong order.
236  */
237 static int
read_meta_data(struct pkg_task * pkg)238 read_meta_data(struct pkg_task *pkg)
239 {
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;
245 
246 	found_required = 0;
247 
248 	r = ARCHIVE_OK;
249 	last_descr = 0;
250 
251 	if (pkg->entry != NULL)
252 		goto skip_header;
253 
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);
260 
261 		for (descr = pkg_meta_descriptors; descr->entry_filename;
262 		     ++descr) {
263 			if (strcmp(descr->entry_filename, fname) == 0)
264 				break;
265 		}
266 		if (descr->entry_filename == NULL)
267 			break;
268 
269 		if (descr->required_file)
270 			++found_required;
271 
272 		target = (char **)((char *)&pkg->meta_data +
273 		    descr->entry_offset);
274 		if (*target) {
275 			warnx("duplicate entry, package corrupt");
276 			return -1;
277 		}
278 		if (descr < last_descr) {
279 			warnx("misordered package");
280 			return -1;
281 		}
282 		last_descr = descr;
283 
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;
288 		}
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;
293 		}
294 		(*target)[size] = '\0';
295 	}
296 
297 	if (r != ARCHIVE_OK)
298 		pkg->entry = NULL;
299 	if (r == ARCHIVE_EOF)
300 		r = ARCHIVE_OK;
301 
302 	for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) {
303 		if (descr->required_file)
304 			--found_required;
305 	}
306 
307 	return !found_required && r == ARCHIVE_OK ? 0 : -1;
308 }
309 
310 /*
311  * Free meta data.
312  */
313 static void
free_meta_data(struct pkg_task * pkg)314 free_meta_data(struct pkg_task *pkg)
315 {
316 	const struct pkg_meta_desc *descr;
317 	char **target;
318 
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;
324 	}
325 }
326 
327 /*
328  * Parse PLIST and populate pkg.
329  */
330 static int
pkg_parse_plist(struct pkg_task * pkg)331 pkg_parse_plist(struct pkg_task *pkg)
332 {
333 	plist_t *p;
334 
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;
339 	}
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;
345 	}
346 	if ((p = find_plist(&pkg->plist, PLIST_CWD)) == NULL) {
347 		warnx("Invalid PLIST: missing @cwd");
348 		return -1;
349 	}
350 
351 	if (Prefix != NULL &&
352 	    strcmp(p->name, Prefix) != 0) {
353 		size_t len;
354 
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;
363 
364 	if (Destdir != NULL)
365 		pkg->install_prefix = xasprintf("%s/%s", Destdir, pkg->prefix);
366 	else
367 		pkg->install_prefix = xstrdup(pkg->prefix);
368 
369 	return 0;
370 }
371 
372 /*
373  * Helper function to extract value from a string of the
374  * form key=value ending at eol.
375  */
376 static char *
dup_value(const char * line,const char * eol)377 dup_value(const char *line, const char *eol)
378 {
379 	const char *key;
380 	char *val;
381 
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;
387 }
388 
389 static int
check_already_installed(struct pkg_task * pkg)390 check_already_installed(struct pkg_task *pkg)
391 {
392 	char *filename;
393 	int fd;
394 
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);
401 
402 	if (ReplaceSame) {
403 		struct stat sb;
404 
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;
412 		}
413 		return 1;
414 	}
415 
416 	if (Force)
417 		return 1;
418 
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);
429 	}
430 	return 0;
431 
432 }
433 
434 static int
check_other_installed(struct pkg_task * pkg)435 check_other_installed(struct pkg_task *pkg)
436 {
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;
443 
444 	if (pkg->install_logdir_real) {
445 		pkg->other_version = xstrdup(pkg->pkgname);
446 		return 0;
447 	}
448 
449 	pkgbase = xstrdup(pkg->pkgname);
450 
451 	if ((iter = strrchr(pkgbase, '-')) == NULL) {
452 		free(pkgbase);
453 		warnx("Invalid package name %s", pkg->pkgname);
454 		return -1;
455 	}
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;
461 
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;
467 	}
468 
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;
477 		}
478 		warnx("Can't open +REQUIRED_BY of %s", pkg->other_version);
479 		return -1;
480 	}
481 
482 	status = 0;
483 
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;
493 		}
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;
502 			/*
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.
507 			 */
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;
517 		}
518 		free_plist(&plist);
519 	}
520 
521 	fclose(f);
522 
523 	return status;
524 }
525 
526 /*
527  * Read package build information from meta data.
528  */
529 static int
read_buildinfo(struct pkg_task * pkg)530 read_buildinfo(struct pkg_task *pkg)
531 {
532 	const char *data, *eol, *next_line;
533 
534 	data = pkg->meta_data.meta_build_info;
535 
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;
542 
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);
560 	}
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;
566 	}
567 
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);
573 	}
574 
575 	return 0;
576 }
577 
578 /*
579  * Free buildinfo.
580  */
581 static void
free_buildinfo(struct pkg_task * pkg)582 free_buildinfo(struct pkg_task *pkg)
583 {
584 	size_t i;
585 
586 	for (i = 0; i < BI_ENUM_COUNT; ++i) {
587 		free(pkg->buildinfo[i]);
588 		pkg->buildinfo[i] = NULL;
589 	}
590 }
591 
592 /*
593  * Write meta data files to pkgdb after creating the directory.
594  */
595 static int
write_meta_data(struct pkg_task * pkg)596 write_meta_data(struct pkg_task *pkg)
597 {
598 	const struct pkg_meta_desc *descr;
599 	char *filename, **target;
600 	size_t len;
601 	ssize_t ret;
602 	int fd;
603 
604 	if (Fake)
605 		return 0;
606 
607 	if (mkdir_p(pkg->install_logdir)) {
608 		warn("Can't create pkgdb entry: %s", pkg->install_logdir);
609 		return -1;
610 	}
611 
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;
624 		}
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;
634 			}
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;
641 		}
642 		free(filename);
643 	}
644 
645 	return 0;
646 }
647 
648 /*
649  * Helper function for extract_files.
650  */
651 static int
copy_data_to_disk(struct archive * reader,struct archive * writer,const char * filename)652 copy_data_to_disk(struct archive *reader, struct archive *writer,
653     const char *filename)
654 {
655 	int r;
656 	const void *buff;
657 	size_t size;
658 	off_t offset;
659 
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;
668 		}
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;
674 		}
675 	}
676 }
677 
678 /*
679  * Extract package.
680  * Any misordered, missing or unlisted file in the package is an error.
681  */
682 
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;
686 
687 static int
extract_files(struct pkg_task * pkg)688 extract_files(struct pkg_task *pkg)
689 {
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;
697 
698 	if (Fake)
699 		return 0;
700 
701 	if (mkdir_p(pkg->install_prefix)) {
702 		warn("Can't create prefix: %s", pkg->install_prefix);
703 		return -1;
704 	}
705 
706 	if (!NoRecord && !pkgdb_open(ReadWrite)) {
707 		warn("Can't open pkgdb for writing");
708 		return -1;
709 	}
710 
711 	if (chdir(pkg->install_prefix) == -1) {
712 		warn("Can't change into prefix: %s", pkg->install_prefix);
713 		return -1;
714 	}
715 
716 	writer = archive_write_disk_new();
717 	archive_write_disk_set_options(writer, extract_flags);
718 	archive_write_disk_set_standard_lookup(writer);
719 
720 	owner = NULL;
721 	group = NULL;
722 	permissions = NULL;
723 	last_file = NULL;
724 
725 	r = -1;
726 
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;
735 			}
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;
740 			}
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;
747 
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;
754 
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;
762 
763 		case PLIST_CHMOD:
764 			permissions = p->name;
765 			continue;
766 
767 		case PLIST_CHOWN:
768 			owner = p->name;
769 			continue;
770 
771 		case PLIST_CHGRP:
772 			group = p->name;
773 			continue;
774 
775 		case PLIST_IGNORE:
776 			p = p->next;
777 			continue;
778 
779 		default:
780 			continue;
781 		}
782 
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;
790 		}
791 
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;
798 
799 			mode = archive_entry_mode(pkg->entry);
800 			mode = getmode(setmode(permissions), mode);
801 			archive_entry_set_mode(pkg->entry, mode);
802 		}
803 
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");
810 
811 		r = archive_read_next_header(pkg->archive, &pkg->entry);
812 		if (r == ARCHIVE_EOF) {
813 			pkg->entry = NULL;
814 			continue;
815 		}
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;
821 		}
822 	}
823 
824 	if (pkg->entry != NULL) {
825 		warnx("Package contains entries not in PLIST: %s",
826 		    archive_entry_pathname(pkg->entry));
827 		goto out;
828 	}
829 
830 	r = 0;
831 
832 out:
833 	if (!NoRecord)
834 		pkgdb_close();
835 	archive_write_close(writer);
836 	archive_write_finish(writer);
837 
838 	return r;
839 }
840 
841 /*
842  * Register dependencies after sucessfully installing the package.
843  */
844 static void
pkg_register_depends(struct pkg_task * pkg)845 pkg_register_depends(struct pkg_task *pkg)
846 {
847 	int fd;
848 	size_t text_len, i;
849 	char *required_by, *text;
850 
851 	if (Fake)
852 		return;
853 
854 	text = xasprintf("%s\n", pkg->pkgname);
855 	text_len = strlen(text);
856 
857 	for (i = 0; i < pkg->dep_length; ++i) {
858 		required_by = pkgdb_pkg_file(pkg->dependencies[i], REQUIRED_BY_FNAME);
859 
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);
869 
870 		free(required_by);
871 	}
872 
873 	free(text);
874 }
875 
876 /*
877  * Reduce the result from uname(3) to a canonical form.
878  */
879 static void
normalise_platform(struct utsname * host_name)880 normalise_platform(struct utsname *host_name)
881 {
882 #ifdef NUMERIC_VERSION_ONLY
883 	size_t span;
884 
885 	span = strspn(host_name->release, "0123456789.");
886 	host_name->release[span] = '\0';
887 #endif
888 }
889 
890 /*
891  * Check build platform of the package against local host.
892  */
893 static int
check_platform(struct pkg_task * pkg)894 check_platform(struct pkg_task *pkg)
895 {
896 	struct utsname host_uname;
897 	const char *effective_arch;
898 	int fatal;
899 
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;
907 		}
908 	}
909 
910 	normalise_platform(&host_uname);
911 
912 	if (OverrideMachine != NULL)
913 		effective_arch = OverrideMachine;
914 	else
915 		effective_arch = MACHINE_ARCH;
916 
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;
923 
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;
938 	}
939 	return 0;
940 }
941 
942 static int
check_pkgtools_version(struct pkg_task * pkg)943 check_pkgtools_version(struct pkg_task *pkg)
944 {
945 	const char *val = pkg->buildinfo[BI_PKGTOOLS_VERSION];
946 	int version;
947 
948 	if (val == NULL) {
949 		warnx("Warning: package `%s' lacks pkg_install version data",
950 		    pkg->pkgname);
951 		return 0;
952 	}
953 
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;
958 	}
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;
964 	}
965 	return 0;
966 }
967 
968 /*
969  * Run the install script.
970  */
971 static int
run_install_script(struct pkg_task * pkg,const char * argument)972 run_install_script(struct pkg_task *pkg, const char *argument)
973 {
974 	int ret;
975 	char *filename;
976 
977 	if (pkg->meta_data.meta_install == NULL || NoInstall)
978 		return 0;
979 
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);
985 
986 	if (Verbose)
987 		printf("Running install with PRE-INSTALL for %s.\n", pkg->pkgname);
988 	if (Fake)
989 		return 0;
990 
991 	filename = pkgdb_pkg_file(pkg->pkgname, INSTALL_FNAME);
992 
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;
1002 	}
1003 	free(filename);
1004 
1005 	return ret;
1006 }
1007 
1008 struct find_conflict_data {
1009 	const char *pkg;
1010 	const char *old_pkg;
1011 	const char *pattern;
1012 };
1013 
1014 static int
check_explicit_conflict_iter(const char * cur_pkg,void * cookie)1015 check_explicit_conflict_iter(const char *cur_pkg, void *cookie)
1016 {
1017 	struct find_conflict_data *data = cookie;
1018 
1019 	if (data->old_pkg && strcmp(data->old_pkg, cur_pkg) == 0)
1020 		return 0;
1021 
1022 	warnx("Package `%s' conflicts with `%s', and `%s' is installed.",
1023 	    data->pkg, data->pattern, cur_pkg);
1024 
1025 	return 1;
1026 }
1027 
1028 static int
check_explicit_conflict(struct pkg_task * pkg)1029 check_explicit_conflict(struct pkg_task *pkg)
1030 {
1031 	struct find_conflict_data data;
1032 	char *installed, *installed_pattern;
1033 	plist_t *p;
1034 	int status;
1035 
1036 	status = 0;
1037 
1038 	for (p = pkg->plist.head; p != NULL; p = p->next) {
1039 		if (p->type == PLIST_IGNORE) {
1040 			p = p->next;
1041 			continue;
1042 		}
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);
1050 	}
1051 
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;
1059 	}
1060 
1061 	return status;
1062 }
1063 
1064 static int
check_implicit_conflict(struct pkg_task * pkg)1065 check_implicit_conflict(struct pkg_task *pkg)
1066 {
1067 	plist_t *p;
1068 	char *fullpath, *existing;
1069 	int status;
1070 
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
1078 	}
1079 
1080 	status = 0;
1081 
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;
1088 
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;
1097 
1098 		warnx("Conflicting PLIST with %s: %s", existing, p->name);
1099 		if (!Force) {
1100 			status = -1;
1101 			if (!Verbose)
1102 				break;
1103 		}
1104 	}
1105 
1106 	pkgdb_close();
1107 	return status;
1108 }
1109 
1110 static int
check_dependencies(struct pkg_task * pkg)1111 check_dependencies(struct pkg_task *pkg)
1112 {
1113 	plist_t *p;
1114 	char *best_installed;
1115 	int status;
1116 	size_t i;
1117 
1118 	status = 0;
1119 
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;
1126 
1127 		best_installed = find_best_matching_installed_pkg(p->name);
1128 
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;
1137 				}
1138 				warnx("Missing dependency %s, continuing",
1139 				    p->name);
1140 				continue;
1141 			}
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;
1152 				}
1153 			}
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;
1162 			}
1163 		}
1164 		for (i = 0; i < pkg->dep_length; ++i) {
1165 			if (strcmp(best_installed, pkg->dependencies[i]) == 0)
1166 				break;
1167 		}
1168 		if (i < pkg->dep_length) {
1169 			/* Already used as dependency, so skip it. */
1170 			free(best_installed);
1171 			continue;
1172 		}
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));
1178 		}
1179 		pkg->dependencies[pkg->dep_length++] = best_installed;
1180 	}
1181 
1182 	return status;
1183 }
1184 
1185 /*
1186  * If this package uses pkg_views, register it in the default view.
1187  */
1188 static void
pkg_register_views(struct pkg_task * pkg)1189 pkg_register_views(struct pkg_task *pkg)
1190 {
1191 	if (Fake || NoView || pkg->meta_data.meta_views == NULL)
1192 		return;
1193 
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);
1200 	}
1201 
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);
1207 }
1208 
1209 static int
preserve_meta_data_file(struct pkg_task * pkg,const char * name)1210 preserve_meta_data_file(struct pkg_task *pkg, const char *name)
1211 {
1212 	char *old_file, *new_file;
1213 	int rv;
1214 
1215 	if (Fake)
1216 		return 0;
1217 
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;
1224 	}
1225 	free(old_file);
1226 	free(new_file);
1227 	return rv;
1228 }
1229 
1230 static int
start_replacing(struct pkg_task * pkg)1231 start_replacing(struct pkg_task *pkg)
1232 {
1233 	if (preserve_meta_data_file(pkg, REQUIRED_BY_FNAME))
1234 		return -1;
1235 
1236 	if (preserve_meta_data_file(pkg, PRESERVE_FNAME))
1237 		return -1;
1238 
1239 	if (pkg->meta_data.meta_installed_info == NULL &&
1240 	    preserve_meta_data_file(pkg, INSTALLED_INFO_FNAME))
1241 		return -1;
1242 
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);
1248 	}
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);
1254 
1255 	/* XXX Check return value and do what? */
1256 	return 0;
1257 }
1258 
check_input(const char * line,size_t len)1259 static int check_input(const char *line, size_t len)
1260 {
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;
1272 	}
1273 }
1274 
1275 static int
check_signature(struct pkg_task * pkg,int invalid_sig)1276 check_signature(struct pkg_task *pkg, int invalid_sig)
1277 {
1278 	char *line;
1279 	size_t len;
1280 
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;
1287 	}
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;
1299 		}
1300 		return 0;
1301 	}
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;
1309 		}
1310 		return 0;
1311 	}
1312 	warnx("Unknown value of configuration variable VERIFIED_INSTALLATION");
1313 	return 1;
1314 }
1315 
1316 static int
check_vulnerable(struct pkg_task * pkg)1317 check_vulnerable(struct pkg_task *pkg)
1318 {
1319 	static struct pkg_vulnerabilities *pv;
1320 	int require_check;
1321 	char *line;
1322 	size_t len;
1323 
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;
1334 	}
1335 
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;
1341 	}
1342 
1343 	if (!audit_package(pv, pkg->pkgname, NULL, 2))
1344 		return 0;
1345 
1346 	if (require_check)
1347 		return 1;
1348 
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;
1355 	}
1356 	return 0;
1357 }
1358 
1359 static int
check_license(struct pkg_task * pkg)1360 check_license(struct pkg_task *pkg)
1361 {
1362 	if (LicenseCheck == 0)
1363 		return 0;
1364 
1365 	if ((pkg->buildinfo[BI_LICENSE] == NULL ||
1366 	     *pkg->buildinfo[BI_LICENSE] == '\0')) {
1367 
1368 		if (LicenseCheck == 1)
1369 			return 0;
1370 		warnx("No LICENSE set for package `%s'", pkg->pkgname);
1371 		return 1;
1372 	}
1373 
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;
1384 	}
1385 }
1386 
1387 /*
1388  * Install a single package.
1389  */
1390 static int
pkg_do(const char * pkgpath,int mark_automatic,int top_level)1391 pkg_do(const char *pkgpath, int mark_automatic, int top_level)
1392 {
1393 	char *archive_name;
1394 	int status, invalid_sig;
1395 	struct pkg_task *pkg;
1396 
1397 	pkg = xcalloc(1, sizeof(*pkg));
1398 
1399 	status = -1;
1400 
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;
1405 	}
1406 
1407 	invalid_sig = pkg_verify_signature(archive_name, &pkg->archive, &pkg->entry,
1408 	    &pkg->pkgname);
1409 	free(archive_name);
1410 
1411 	if (pkg->archive == NULL)
1412 		goto clean_memory;
1413 
1414 	if (read_meta_data(pkg))
1415 		goto clean_memory;
1416 
1417 	/* Parse PLIST early, so that messages can use real package name. */
1418 	if (pkg_parse_plist(pkg))
1419 		goto clean_memory;
1420 
1421 	if (check_signature(pkg, invalid_sig))
1422 		goto clean_memory;
1423 
1424 	if (read_buildinfo(pkg))
1425 		goto clean_memory;
1426 
1427 	if (check_pkgtools_version(pkg))
1428 		goto clean_memory;
1429 
1430 	if (check_vulnerable(pkg))
1431 		goto clean_memory;
1432 
1433 	if (check_license(pkg))
1434 		goto clean_memory;
1435 
1436 	if (pkg->meta_data.meta_mtree != NULL)
1437 		warnx("mtree specification in pkg `%s' ignored", pkg->pkgname);
1438 
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);
1444 	}
1445 
1446 	if (Destdir != NULL)
1447 		pkg->install_logdir = xasprintf("%s/%s", Destdir, pkg->logdir);
1448 	else
1449 		pkg->install_logdir = xstrdup(pkg->logdir);
1450 
1451 	if (NoRecord && !Fake) {
1452 		const char *tmpdir;
1453 
1454 		tmpdir = getenv("TMPDIR");
1455 		if (tmpdir == NULL)
1456 			tmpdir = "/tmp";
1457 
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;
1464 		}
1465 	}
1466 
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;
1475 	}
1476 
1477 	if (check_platform(pkg))
1478 		goto clean_memory;
1479 
1480 	if (check_other_installed(pkg))
1481 		goto clean_memory;
1482 
1483 	if (check_explicit_conflict(pkg))
1484 		goto clean_memory;
1485 
1486 	if (check_implicit_conflict(pkg))
1487 		goto clean_memory;
1488 
1489 	if (pkg->other_version != NULL) {
1490 		/*
1491 		 * Replacing an existing package.
1492 		 * Write meta-data, get rid of the old version,
1493 		 * install/update dependencies and finally extract.
1494 		 */
1495 		if (write_meta_data(pkg))
1496 			goto nuke_pkgdb;
1497 
1498 		if (start_replacing(pkg))
1499 			goto nuke_pkgdb;
1500 
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;
1506 		}
1507 
1508 		if (check_dependencies(pkg))
1509 			goto nuke_pkgdb;
1510 	} else {
1511 		/*
1512 		 * Normal installation.
1513 		 * Install/update dependencies first and
1514 		 * write the current package to disk afterwards.
1515 		 */
1516 		if (check_dependencies(pkg))
1517 			goto clean_memory;
1518 
1519 		if (write_meta_data(pkg))
1520 			goto nuke_pkgdb;
1521 	}
1522 
1523 	if (run_install_script(pkg, "PRE-INSTALL"))
1524 		goto nuke_pkgdb;
1525 
1526 	if (extract_files(pkg))
1527 		goto nuke_pkg;
1528 
1529 	if (run_install_script(pkg, "POST-INSTALL"))
1530 		goto nuke_pkgdb;
1531 
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);
1536 
1537 	pkg_register_depends(pkg);
1538 
1539 	if (Verbose)
1540 		printf("Package %s registered in %s\n", pkg->pkgname, pkg->install_logdir);
1541 
1542 	if (pkg->meta_data.meta_display != NULL)
1543 		fputs(pkg->meta_data.meta_display, stdout);
1544 
1545 	pkg_register_views(pkg);
1546 
1547 	status = 0;
1548 	goto clean_memory;
1549 
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.");
1556 		}
1557 		delete_package(FALSE, &pkg->plist, FALSE, Destdir);
1558 	}
1559 
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;
1570 	}
1571 
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);
1576 	}
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;
1591 }
1592 
1593 int
pkg_perform(lpkg_head_t * pkgs)1594 pkg_perform(lpkg_head_t *pkgs)
1595 {
1596 	int     errors = 0;
1597 	lpkg_t *lpp;
1598 
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);
1604 	}
1605 
1606 	return errors;
1607 }
1608