1/*	$NetBSD: perform.c,v 1.1.1.18.6.2 2012/02/24 17:50:17 riz 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.1.1.18.6.2 2012/02/24 17:50:17 riz 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
64struct 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
82struct 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
106static 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
130static int pkg_do(const char *, int, int);
131
132static int
133end_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
150static int
151compatible_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    /* find offset of first difference */
160    for (i=0; (host[i] != '\0') && (host[i] == package[i]);)
161	i++;
162
163    if (end_of_version(opsys, host+i) && end_of_version(opsys, package+i))
164	return 1;
165
166    return 0;
167}
168
169static int
170mkdir_p(const char *path)
171{
172	char *p, *cur_end;
173	int done, saved_errno;
174	struct stat sb;
175
176	/*
177	 * Handle the easy case of direct success or
178	 * pre-existing directory first.
179	 */
180	if (mkdir(path, 0777) == 0)
181		return 0;
182	if (stat(path, &sb) == 0) {
183		if (S_ISDIR(sb.st_mode))
184			return 0;
185		errno = ENOTDIR;
186		return -1;
187	}
188
189	cur_end = p = xstrdup(path);
190
191	for (;;) {
192		/*
193		 * First skip leading slashes either from / or
194		 * from the last iteration.
195		 */
196		cur_end += strspn(cur_end, "/");
197		/* Find end of actual directory name. */
198		cur_end += strcspn(cur_end, "/");
199
200		/*
201		 * Remember if this is the last component and
202		 * overwrite / if needed.
203		 */
204		done = (*cur_end == '\0');
205		*cur_end = '\0';
206
207		if (mkdir(p, 0777) == -1) {
208			saved_errno = errno;
209			if (stat(p, &sb) == 0) {
210				if (S_ISDIR(sb.st_mode))
211					goto pass;
212				errno = ENOTDIR;
213			} else {
214				errno = saved_errno;
215			}
216			free(p);
217			return -1;
218		}
219pass:
220		if (done)
221			break;
222		*cur_end = '/';
223	}
224
225	free(p);
226	return 0;
227}
228
229/*
230 * Read meta data from archive.
231 * Bail out if a required entry is missing or entries are in the wrong order.
232 */
233static int
234read_meta_data(struct pkg_task *pkg)
235{
236	const struct pkg_meta_desc *descr, *last_descr;
237	const char *fname;
238	char **target;
239	int64_t size;
240	int r, found_required;
241
242	found_required = 0;
243
244	r = ARCHIVE_OK;
245	last_descr = 0;
246
247	if (pkg->entry != NULL)
248		goto skip_header;
249
250	for (;;) {
251		r = archive_read_next_header(pkg->archive, &pkg->entry);
252		if (r != ARCHIVE_OK)
253				break;
254skip_header:
255		fname = archive_entry_pathname(pkg->entry);
256
257		for (descr = pkg_meta_descriptors; descr->entry_filename;
258		     ++descr) {
259			if (strcmp(descr->entry_filename, fname) == 0)
260				break;
261		}
262		if (descr->entry_filename == NULL)
263			break;
264
265		if (descr->required_file)
266			++found_required;
267
268		target = (char **)((char *)&pkg->meta_data +
269		    descr->entry_offset);
270		if (*target) {
271			warnx("duplicate entry, package corrupt");
272			return -1;
273		}
274		if (descr < last_descr) {
275			warnx("misordered package");
276			return -1;
277		}
278		last_descr = descr;
279
280		size = archive_entry_size(pkg->entry);
281		if (size > SSIZE_MAX - 1) {
282			warnx("package meta data too large to process");
283			return -1;
284		}
285		*target = xmalloc(size + 1);
286		if (archive_read_data(pkg->archive, *target, size) != size) {
287			warnx("cannot read package meta data");
288			return -1;
289		}
290		(*target)[size] = '\0';
291	}
292
293	if (r != ARCHIVE_OK)
294		pkg->entry = NULL;
295	if (r == ARCHIVE_EOF)
296		r = ARCHIVE_OK;
297
298	for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) {
299		if (descr->required_file)
300			--found_required;
301	}
302
303	return !found_required && r == ARCHIVE_OK ? 0 : -1;
304}
305
306/*
307 * Free meta data.
308 */
309static void
310free_meta_data(struct pkg_task *pkg)
311{
312	const struct pkg_meta_desc *descr;
313	char **target;
314
315	for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) {
316		target = (char **)((char *)&pkg->meta_data +
317		    descr->entry_offset);
318		free(*target);
319		*target = NULL;
320	}
321}
322
323/*
324 * Parse PLIST and populate pkg.
325 */
326static int
327pkg_parse_plist(struct pkg_task *pkg)
328{
329	plist_t *p;
330
331	parse_plist(&pkg->plist, pkg->meta_data.meta_contents);
332	if ((p = find_plist(&pkg->plist, PLIST_NAME)) == NULL) {
333		warnx("Invalid PLIST: missing @name");
334		return -1;
335	}
336	if (pkg->pkgname == NULL)
337		pkg->pkgname = xstrdup(p->name);
338	else if (strcmp(pkg->pkgname, p->name) != 0) {
339		warnx("Signature and PLIST differ on package name");
340		return -1;
341	}
342	if ((p = find_plist(&pkg->plist, PLIST_CWD)) == NULL) {
343		warnx("Invalid PLIST: missing @cwd");
344		return -1;
345	}
346
347	if (Prefix != NULL &&
348	    strcmp(p->name, Prefix) != 0) {
349		size_t len;
350
351		delete_plist(&pkg->plist, FALSE, PLIST_CWD, NULL);
352		add_plist_top(&pkg->plist, PLIST_CWD, Prefix);
353		free(pkg->meta_data.meta_contents);
354		stringify_plist(&pkg->plist, &pkg->meta_data.meta_contents, &len,
355		    Prefix);
356		pkg->prefix = Prefix;
357	} else
358		pkg->prefix = p->name;
359
360	if (Destdir != NULL)
361		pkg->install_prefix = xasprintf("%s/%s", Destdir, pkg->prefix);
362	else
363		pkg->install_prefix = xstrdup(pkg->prefix);
364
365	return 0;
366}
367
368/*
369 * Helper function to extract value from a string of the
370 * form key=value ending at eol.
371 */
372static char *
373dup_value(const char *line, const char *eol)
374{
375	const char *key;
376	char *val;
377
378	key = strchr(line, '=');
379	val = xmalloc(eol - key);
380	memcpy(val, key + 1, eol - key - 1);
381	val[eol - key - 1] = '\0';
382	return val;
383}
384
385static int
386check_already_installed(struct pkg_task *pkg)
387{
388	char *filename;
389	int fd;
390
391	filename = pkgdb_pkg_file(pkg->pkgname, CONTENTS_FNAME);
392	fd = open(filename, O_RDONLY);
393	free(filename);
394	if (fd == -1)
395		return 1;
396	close(fd);
397
398	if (ReplaceSame) {
399		struct stat sb;
400
401		pkg->install_logdir_real = pkg->install_logdir;
402		pkg->install_logdir = xasprintf("%s.xxxxxx", pkg->install_logdir);
403		if (stat(pkg->install_logdir, &sb) == 0) {
404			warnx("package `%s' already has a temporary update "
405			    "directory `%s', remove it manually",
406			    pkg->pkgname, pkg->install_logdir);
407			return -1;
408		}
409		return 1;
410	}
411
412	if (Force)
413		return 1;
414
415	/* We can only arrive here for explicitly requested packages. */
416	if (!Automatic && is_automatic_installed(pkg->pkgname)) {
417		if (Fake ||
418		    mark_as_automatic_installed(pkg->pkgname, 0) == 0)
419			warnx("package `%s' was already installed as "
420			      "dependency, now marked as installed "
421			      "manually", pkg->pkgname);
422	} else {
423		warnx("package `%s' already recorded as installed",
424		      pkg->pkgname);
425	}
426	return 0;
427
428}
429
430static int
431check_other_installed(struct pkg_task *pkg)
432{
433	FILE *f, *f_pkg;
434	size_t len;
435	char *pkgbase, *iter, *filename;
436	package_t plist;
437	plist_t *p;
438	int status;
439
440	if (pkg->install_logdir_real) {
441		pkg->other_version = xstrdup(pkg->pkgname);
442		return 0;
443	}
444
445	pkgbase = xstrdup(pkg->pkgname);
446
447	if ((iter = strrchr(pkgbase, '-')) == NULL) {
448		free(pkgbase);
449		warnx("Invalid package name %s", pkg->pkgname);
450		return -1;
451	}
452	*iter = '\0';
453	pkg->other_version = find_best_matching_installed_pkg(pkgbase);
454	free(pkgbase);
455	if (pkg->other_version == NULL)
456		return 0;
457
458	if (!Replace) {
459		/* XXX This is redundant to the implicit conflict check. */
460		warnx("A different version of %s is already installed: %s",
461		    pkg->pkgname, pkg->other_version);
462		return -1;
463	}
464
465	filename = pkgdb_pkg_file(pkg->other_version, REQUIRED_BY_FNAME);
466	errno = 0;
467	f = fopen(filename, "r");
468	free(filename);
469	if (f == NULL) {
470		if (errno == ENOENT) {
471			/* No packages depend on this, so everything is well. */
472			return 0;
473		}
474		warnx("Can't open +REQUIRED_BY of %s", pkg->other_version);
475		return -1;
476	}
477
478	status = 0;
479
480	while ((iter = fgetln(f, &len)) != NULL) {
481		if (iter[len - 1] == '\n')
482			iter[len - 1] = '\0';
483		filename = pkgdb_pkg_file(iter, CONTENTS_FNAME);
484		if ((f_pkg = fopen(filename, "r")) == NULL) {
485			warnx("Can't open +CONTENTS of depending package %s",
486			    iter);
487			fclose(f);
488			return -1;
489		}
490		read_plist(&plist, f_pkg);
491		fclose(f_pkg);
492		for (p = plist.head; p != NULL; p = p->next) {
493			if (p->type == PLIST_IGNORE) {
494				p = p->next;
495				continue;
496			} else if (p->type != PLIST_PKGDEP)
497				continue;
498			/*
499			 * XXX This is stricter than necessary.
500			 * XXX One pattern might be fulfilled by
501			 * XXX a different package and still need this
502			 * XXX one for a different pattern.
503			 */
504			if (pkg_match(p->name, pkg->other_version) == 0)
505				continue;
506			if (pkg_match(p->name, pkg->pkgname) == 1)
507				continue; /* Both match, ok. */
508			warnx("Dependency of %s fulfilled by %s, but not by %s",
509			    iter, pkg->other_version, pkg->pkgname);
510			if (!ForceDepending)
511				status = -1;
512			break;
513		}
514		free_plist(&plist);
515	}
516
517	fclose(f);
518
519	return status;
520}
521
522/*
523 * Read package build information from meta data.
524 */
525static int
526read_buildinfo(struct pkg_task *pkg)
527{
528	const char *data, *eol, *next_line;
529
530	data = pkg->meta_data.meta_build_info;
531
532	for (; data != NULL && *data != '\0'; data = next_line) {
533		if ((eol = strchr(data, '\n')) == NULL) {
534			eol = data + strlen(data);
535			next_line = eol;
536		} else
537			next_line = eol + 1;
538
539		if (strncmp(data, "OPSYS=", 6) == 0)
540			pkg->buildinfo[BI_OPSYS] = dup_value(data, eol);
541		else if (strncmp(data, "OS_VERSION=", 11) == 0)
542			pkg->buildinfo[BI_OS_VERSION] = dup_value(data, eol);
543		else if (strncmp(data, "MACHINE_ARCH=", 13) == 0)
544			pkg->buildinfo[BI_MACHINE_ARCH] = dup_value(data, eol);
545		else if (strncmp(data, "IGNORE_RECOMMENDED=", 19) == 0)
546			pkg->buildinfo[BI_IGNORE_RECOMMENDED] = dup_value(data,
547			    eol);
548		else if (strncmp(data, "USE_ABI_DEPENDS=", 16) == 0)
549			pkg->buildinfo[BI_USE_ABI_DEPENDS] = dup_value(data,
550			    eol);
551		else if (strncmp(data, "LICENSE=", 8) == 0)
552			pkg->buildinfo[BI_LICENSE] = dup_value(data, eol);
553		else if (strncmp(data, "PKGTOOLS_VERSION=", 17) == 0)
554			pkg->buildinfo[BI_PKGTOOLS_VERSION] = dup_value(data,
555			    eol);
556	}
557	if (pkg->buildinfo[BI_OPSYS] == NULL ||
558	    pkg->buildinfo[BI_OS_VERSION] == NULL ||
559	    pkg->buildinfo[BI_MACHINE_ARCH] == NULL) {
560		warnx("Not all required build information are present.");
561		return -1;
562	}
563
564	if ((pkg->buildinfo[BI_USE_ABI_DEPENDS] != NULL &&
565	    strcasecmp(pkg->buildinfo[BI_USE_ABI_DEPENDS], "YES") != 0) ||
566	    (pkg->buildinfo[BI_IGNORE_RECOMMENDED] != NULL &&
567	    strcasecmp(pkg->buildinfo[BI_IGNORE_RECOMMENDED], "NO") != 0)) {
568		warnx("%s was built to ignore ABI dependencies", pkg->pkgname);
569	}
570
571	return 0;
572}
573
574/*
575 * Free buildinfo.
576 */
577static void
578free_buildinfo(struct pkg_task *pkg)
579{
580	size_t i;
581
582	for (i = 0; i < BI_ENUM_COUNT; ++i) {
583		free(pkg->buildinfo[i]);
584		pkg->buildinfo[i] = NULL;
585	}
586}
587
588/*
589 * Write meta data files to pkgdb after creating the directory.
590 */
591static int
592write_meta_data(struct pkg_task *pkg)
593{
594	const struct pkg_meta_desc *descr;
595	char *filename, **target;
596	size_t len;
597	ssize_t ret;
598	int fd;
599
600	if (Fake)
601		return 0;
602
603	if (mkdir_p(pkg->install_logdir)) {
604		warn("Can't create pkgdb entry: %s", pkg->install_logdir);
605		return -1;
606	}
607
608	for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) {
609		target = (char **)((char *)&pkg->meta_data +
610		    descr->entry_offset);
611		if (*target == NULL)
612			continue;
613		filename = xasprintf("%s/%s", pkg->install_logdir,
614		    descr->entry_filename);
615		(void)unlink(filename);
616		fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, descr->perm);
617		if (fd == -1) {
618			warn("Can't open meta data file: %s", filename);
619			return -1;
620		}
621		len = strlen(*target);
622		do {
623			ret = write(fd, *target, len);
624			if (ret == -1) {
625				warn("Can't write meta data file: %s",
626				    filename);
627				free(filename);
628				close(fd);
629				return -1;
630			}
631			len -= ret;
632		} while (ret > 0);
633		if (close(fd) == -1) {
634			warn("Can't close meta data file: %s", filename);
635			free(filename);
636			return -1;
637		}
638		free(filename);
639	}
640
641	return 0;
642}
643
644/*
645 * Helper function for extract_files.
646 */
647static int
648copy_data_to_disk(struct archive *reader, struct archive *writer,
649    const char *filename)
650{
651	int r;
652	const void *buff;
653	size_t size;
654	off_t offset;
655
656	for (;;) {
657		r = archive_read_data_block(reader, &buff, &size, &offset);
658		if (r == ARCHIVE_EOF)
659			return 0;
660		if (r != ARCHIVE_OK) {
661			warnx("Read error for %s: %s", filename,
662			    archive_error_string(reader));
663			return -1;
664		}
665		r = archive_write_data_block(writer, buff, size, offset);
666		if (r != ARCHIVE_OK) {
667			warnx("Write error for %s: %s", filename,
668			    archive_error_string(writer));
669			return -1;
670		}
671	}
672}
673
674/*
675 * Extract package.
676 * Any misordered, missing or unlisted file in the package is an error.
677 */
678
679static const int extract_flags = ARCHIVE_EXTRACT_OWNER |
680    ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_UNLINK |
681    ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR;
682
683static int
684extract_files(struct pkg_task *pkg)
685{
686	char    cmd[MaxPathSize];
687	const char *owner, *group, *permissions;
688	struct archive *writer;
689	int r;
690	plist_t *p;
691	const char *last_file;
692	char *fullpath;
693
694	if (Fake)
695		return 0;
696
697	if (mkdir_p(pkg->install_prefix)) {
698		warn("Can't create prefix: %s", pkg->install_prefix);
699		return -1;
700	}
701
702	if (!NoRecord && !pkgdb_open(ReadWrite)) {
703		warn("Can't open pkgdb for writing");
704		return -1;
705	}
706
707	if (chdir(pkg->install_prefix) == -1) {
708		warn("Can't change into prefix: %s", pkg->install_prefix);
709		return -1;
710	}
711
712	writer = archive_write_disk_new();
713	archive_write_disk_set_options(writer, extract_flags);
714	archive_write_disk_set_standard_lookup(writer);
715
716	owner = NULL;
717	group = NULL;
718	permissions = NULL;
719	last_file = NULL;
720
721	r = -1;
722
723	for (p = pkg->plist.head; p != NULL; p = p->next) {
724		switch (p->type) {
725		case PLIST_FILE:
726			last_file = p->name;
727			if (pkg->entry == NULL) {
728				warnx("PLIST entry not in package (%s)",
729				    archive_entry_pathname(pkg->entry));
730				goto out;
731			}
732			if (strcmp(p->name, archive_entry_pathname(pkg->entry))) {
733				warnx("PLIST entry and package don't match (%s vs %s)",
734				    p->name, archive_entry_pathname(pkg->entry));
735				goto out;
736			}
737			fullpath = xasprintf("%s/%s", pkg->prefix, p->name);
738			pkgdb_store(fullpath, pkg->pkgname);
739			free(fullpath);
740			if (Verbose)
741				printf("%s", p->name);
742			break;
743
744		case PLIST_PKGDIR:
745			fullpath = xasprintf("%s/%s", pkg->prefix, p->name);
746			mkdir_p(fullpath);
747			free(fullpath);
748			add_pkgdir(pkg->pkgname, pkg->prefix, p->name);
749			continue;
750
751		case PLIST_CMD:
752			if (format_cmd(cmd, sizeof(cmd), p->name, pkg->prefix, last_file))
753				return -1;
754			printf("Executing '%s'\n", cmd);
755			if (!Fake && system(cmd))
756				warnx("command '%s' failed", cmd); /* XXX bail out? */
757			continue;
758
759		case PLIST_CHMOD:
760			permissions = p->name;
761			continue;
762
763		case PLIST_CHOWN:
764			owner = p->name;
765			continue;
766
767		case PLIST_CHGRP:
768			group = p->name;
769			continue;
770
771		case PLIST_IGNORE:
772			p = p->next;
773			continue;
774
775		default:
776			continue;
777		}
778
779		r = archive_write_header(writer, pkg->entry);
780		if (r != ARCHIVE_OK) {
781			warnx("Failed to write %s for %s: %s",
782			    archive_entry_pathname(pkg->entry),
783			    pkg->pkgname,
784			    archive_error_string(writer));
785			goto out;
786		}
787
788		if (owner != NULL)
789			archive_entry_set_uname(pkg->entry, owner);
790		if (group != NULL)
791			archive_entry_set_uname(pkg->entry, group);
792		if (permissions != NULL) {
793			mode_t mode;
794
795			mode = archive_entry_mode(pkg->entry);
796			mode = getmode(setmode(permissions), mode);
797			archive_entry_set_mode(pkg->entry, mode);
798		}
799
800		r = copy_data_to_disk(pkg->archive, writer,
801		    archive_entry_pathname(pkg->entry));
802		if (r)
803			goto out;
804		if (Verbose)
805			printf("\n");
806
807		r = archive_read_next_header(pkg->archive, &pkg->entry);
808		if (r == ARCHIVE_EOF) {
809			pkg->entry = NULL;
810			continue;
811		}
812		if (r != ARCHIVE_OK) {
813			warnx("Failed to read from archive for %s: %s",
814			    pkg->pkgname,
815			    archive_error_string(pkg->archive));
816			goto out;
817		}
818	}
819
820	if (pkg->entry != NULL) {
821		warnx("Package contains entries not in PLIST: %s",
822		    archive_entry_pathname(pkg->entry));
823		goto out;
824	}
825
826	r = 0;
827
828out:
829	if (!NoRecord)
830		pkgdb_close();
831	archive_write_close(writer);
832	archive_write_finish(writer);
833
834	return r;
835}
836
837/*
838 * Register dependencies after sucessfully installing the package.
839 */
840static void
841pkg_register_depends(struct pkg_task *pkg)
842{
843	int fd;
844	size_t text_len, i;
845	char *required_by, *text;
846
847	if (Fake)
848		return;
849
850	text = xasprintf("%s\n", pkg->pkgname);
851	text_len = strlen(text);
852
853	for (i = 0; i < pkg->dep_length; ++i) {
854		required_by = pkgdb_pkg_file(pkg->dependencies[i], REQUIRED_BY_FNAME);
855
856		fd = open(required_by, O_WRONLY | O_APPEND | O_CREAT, 0644);
857		if (fd == -1) {
858			warn("can't open dependency file '%s',"
859			    "registration is incomplete!", required_by);
860		} else if (write(fd, text, text_len) != (ssize_t)text_len) {
861			warn("can't write to dependency file `%s'", required_by);
862			close(fd);
863		} else if (close(fd) == -1)
864			warn("cannot close file %s", required_by);
865
866		free(required_by);
867	}
868
869	free(text);
870}
871
872/*
873 * Reduce the result from uname(3) to a canonical form.
874 */
875static void
876normalise_platform(struct utsname *host_name)
877{
878#ifdef NUMERIC_VERSION_ONLY
879	size_t span;
880
881	span = strspn(host_name->release, "0123456789.");
882	host_name->release[span] = '\0';
883#endif
884}
885
886/*
887 * Check build platform of the package against local host.
888 */
889static int
890check_platform(struct pkg_task *pkg)
891{
892	struct utsname host_uname;
893	const char *effective_arch;
894	int fatal;
895
896	if (uname(&host_uname) < 0) {
897		if (Force) {
898			warnx("uname() failed, continuing.");
899			return 0;
900		} else {
901			warnx("uname() failed, aborting.");
902			return -1;
903		}
904	}
905
906	normalise_platform(&host_uname);
907
908	if (OverrideMachine != NULL)
909		effective_arch = OverrideMachine;
910	else
911		effective_arch = MACHINE_ARCH;
912
913	/* If either the OS or arch are different, bomb */
914	if (strcmp(OPSYS_NAME, pkg->buildinfo[BI_OPSYS]) ||
915	    strcmp(effective_arch, pkg->buildinfo[BI_MACHINE_ARCH]) != 0)
916		fatal = 1;
917	else
918		fatal = 0;
919
920	if (fatal ||
921	    compatible_platform(OPSYS_NAME, host_uname.release,
922				pkg->buildinfo[BI_OS_VERSION]) != 1) {
923		warnx("Warning: package `%s' was built for a platform:",
924		    pkg->pkgname);
925		warnx("%s/%s %s (pkg) vs. %s/%s %s (this host)",
926		    pkg->buildinfo[BI_OPSYS],
927		    pkg->buildinfo[BI_MACHINE_ARCH],
928		    pkg->buildinfo[BI_OS_VERSION],
929		    OPSYS_NAME,
930		    effective_arch,
931		    host_uname.release);
932		if (!Force && fatal)
933			return -1;
934	}
935	return 0;
936}
937
938static int
939check_pkgtools_version(struct pkg_task *pkg)
940{
941	const char *val = pkg->buildinfo[BI_PKGTOOLS_VERSION];
942	int version;
943
944	if (val == NULL) {
945		warnx("Warning: package `%s' lacks pkg_install version data",
946		    pkg->pkgname);
947		return 0;
948	}
949
950	if (strlen(val) != 8 || strspn(val, "0123456789") != 8) {
951		warnx("Warning: package `%s' contains an invalid pkg_install version",
952		    pkg->pkgname);
953		return Force ? 0 : -1;
954	}
955	version = atoi(val);
956	if (version > PKGTOOLS_VERSION) {
957		warnx("%s: package `%s' was built with a newer pkg_install version",
958		    Force ? "Warning" : "Error", pkg->pkgname);
959		return Force ? 0 : -1;
960	}
961	return 0;
962}
963
964/*
965 * Run the install script.
966 */
967static int
968run_install_script(struct pkg_task *pkg, const char *argument)
969{
970	int ret;
971	char *filename;
972
973	if (pkg->meta_data.meta_install == NULL || NoInstall)
974		return 0;
975
976	if (Destdir != NULL)
977		setenv(PKG_DESTDIR_VNAME, Destdir, 1);
978	setenv(PKG_PREFIX_VNAME, pkg->prefix, 1);
979	setenv(PKG_METADATA_DIR_VNAME, pkg->logdir, 1);
980	setenv(PKG_REFCOUNT_DBDIR_VNAME, config_pkg_refcount_dbdir, 1);
981
982	if (Verbose)
983		printf("Running install with PRE-INSTALL for %s.\n", pkg->pkgname);
984	if (Fake)
985		return 0;
986
987	filename = pkgdb_pkg_file(pkg->pkgname, INSTALL_FNAME);
988
989	ret = 0;
990	errno = 0;
991	if (fcexec(pkg->install_logdir, filename, pkg->pkgname, argument,
992	    (void *)NULL)) {
993		if (errno != 0)
994			warn("exec of install script failed");
995		else
996			warnx("install script returned error status");
997		ret = -1;
998	}
999	free(filename);
1000
1001	return ret;
1002}
1003
1004struct find_conflict_data {
1005	const char *pkg;
1006	const char *old_pkg;
1007	const char *pattern;
1008};
1009
1010static int
1011check_explicit_conflict_iter(const char *cur_pkg, void *cookie)
1012{
1013	struct find_conflict_data *data = cookie;
1014
1015	if (data->old_pkg && strcmp(data->old_pkg, cur_pkg) == 0)
1016		return 0;
1017
1018	warnx("Package `%s' conflicts with `%s', and `%s' is installed.",
1019	    data->pkg, data->pattern, cur_pkg);
1020
1021	return 1;
1022}
1023
1024static int
1025check_explicit_conflict(struct pkg_task *pkg)
1026{
1027	struct find_conflict_data data;
1028	char *installed, *installed_pattern;
1029	plist_t *p;
1030	int status;
1031
1032	status = 0;
1033
1034	for (p = pkg->plist.head; p != NULL; p = p->next) {
1035		if (p->type == PLIST_IGNORE) {
1036			p = p->next;
1037			continue;
1038		}
1039		if (p->type != PLIST_PKGCFL)
1040			continue;
1041		data.pkg = pkg->pkgname;
1042		data.old_pkg = pkg->other_version;
1043		data.pattern = p->name;
1044		status |= match_installed_pkgs(p->name,
1045		    check_explicit_conflict_iter, &data);
1046	}
1047
1048	if (some_installed_package_conflicts_with(pkg->pkgname,
1049	    pkg->other_version, &installed, &installed_pattern)) {
1050		warnx("Installed package `%s' conflicts with `%s' when trying to install `%s'.",
1051			installed, installed_pattern, pkg->pkgname);
1052		free(installed);
1053		free(installed_pattern);
1054		status |= -1;
1055	}
1056
1057	return status;
1058}
1059
1060static int
1061check_implicit_conflict(struct pkg_task *pkg)
1062{
1063	plist_t *p;
1064	char *fullpath, *existing;
1065	int status;
1066
1067	if (!pkgdb_open(ReadOnly)) {
1068#if notyet /* XXX empty pkgdb without database? */
1069		warn("Can't open pkgdb for reading");
1070		return -1;
1071#else
1072		return 0;
1073#endif
1074	}
1075
1076	status = 0;
1077
1078	for (p = pkg->plist.head; p != NULL; p = p->next) {
1079		if (p->type == PLIST_IGNORE) {
1080			p = p->next;
1081			continue;
1082		} else if (p->type != PLIST_FILE)
1083			continue;
1084
1085		fullpath = xasprintf("%s/%s", pkg->prefix, p->name);
1086		existing = pkgdb_retrieve(fullpath);
1087		free(fullpath);
1088		if (existing == NULL)
1089			continue;
1090		if (pkg->other_version != NULL &&
1091		    strcmp(pkg->other_version, existing) == 0)
1092			continue;
1093
1094		warnx("Conflicting PLIST with %s: %s", existing, p->name);
1095		if (!Force) {
1096			status = -1;
1097			if (!Verbose)
1098				break;
1099		}
1100	}
1101
1102	pkgdb_close();
1103	return status;
1104}
1105
1106static int
1107check_dependencies(struct pkg_task *pkg)
1108{
1109	plist_t *p;
1110	char *best_installed;
1111	int status;
1112	size_t i;
1113
1114	status = 0;
1115
1116	for (p = pkg->plist.head; p != NULL; p = p->next) {
1117		if (p->type == PLIST_IGNORE) {
1118			p = p->next;
1119			continue;
1120		} else if (p->type != PLIST_PKGDEP)
1121			continue;
1122
1123		best_installed = find_best_matching_installed_pkg(p->name);
1124
1125		if (best_installed == NULL) {
1126			/* XXX check cyclic dependencies? */
1127			if (Fake || NoRecord) {
1128				if (!Force) {
1129					warnx("Missing dependency %s\n",
1130					     p->name);
1131					status = -1;
1132					break;
1133				}
1134				warnx("Missing dependency %s, continuing",
1135				    p->name);
1136				continue;
1137			}
1138			if (pkg_do(p->name, 1, 0)) {
1139				if (ForceDepends) {
1140					warnx("Can't install dependency %s, "
1141					    "continuing", p->name);
1142					continue;
1143				} else {
1144					warnx("Can't install dependency %s",
1145					    p->name);
1146					status = -1;
1147					break;
1148				}
1149			}
1150			best_installed = find_best_matching_installed_pkg(p->name);
1151			if (best_installed == NULL && ForceDepends) {
1152				warnx("Missing dependency %s ignored", p->name);
1153				continue;
1154			} else if (best_installed == NULL) {
1155				warnx("Just installed dependency %s disappeared", p->name);
1156				status = -1;
1157				break;
1158			}
1159		}
1160		for (i = 0; i < pkg->dep_length; ++i) {
1161			if (strcmp(best_installed, pkg->dependencies[i]) == 0)
1162				break;
1163		}
1164		if (i < pkg->dep_length) {
1165			/* Already used as dependency, so skip it. */
1166			free(best_installed);
1167			continue;
1168		}
1169		if (pkg->dep_length + 1 >= pkg->dep_allocated) {
1170			char **tmp;
1171			pkg->dep_allocated = 2 * pkg->dep_allocated + 1;
1172			pkg->dependencies = xrealloc(pkg->dependencies,
1173			    pkg->dep_allocated * sizeof(*tmp));
1174		}
1175		pkg->dependencies[pkg->dep_length++] = best_installed;
1176	}
1177
1178	return status;
1179}
1180
1181/*
1182 * If this package uses pkg_views, register it in the default view.
1183 */
1184static void
1185pkg_register_views(struct pkg_task *pkg)
1186{
1187	if (Fake || NoView || pkg->meta_data.meta_views == NULL)
1188		return;
1189
1190	if (Verbose) {
1191		printf("%s/pkg_view -d %s %s%s %s%s %sadd %s\n",
1192			BINDIR, pkgdb_get_dir(),
1193			View ? "-w " : "", View ? View : "",
1194			Viewbase ? "-W " : "", Viewbase ? Viewbase : "",
1195			Verbose ? "-v " : "", pkg->pkgname);
1196	}
1197
1198	fexec_skipempty(BINDIR "/pkg_view", "-d", pkgdb_get_dir(),
1199			View ? "-w " : "", View ? View : "",
1200			Viewbase ? "-W " : "", Viewbase ? Viewbase : "",
1201			Verbose ? "-v " : "", "add", pkg->pkgname,
1202			(void *)NULL);
1203}
1204
1205static int
1206preserve_meta_data_file(struct pkg_task *pkg, const char *name)
1207{
1208	char *old_file, *new_file;
1209	int rv;
1210
1211	if (Fake)
1212		return 0;
1213
1214	old_file = pkgdb_pkg_file(pkg->other_version, name);
1215	new_file = xasprintf("%s/%s", pkg->install_logdir, name);
1216	rv = 0;
1217	if (rename(old_file, new_file) == -1 && errno != ENOENT) {
1218		warn("Can't move %s from %s to %s", name, old_file, new_file);
1219		rv = -1;
1220	}
1221	free(old_file);
1222	free(new_file);
1223	return rv;
1224}
1225
1226static int
1227start_replacing(struct pkg_task *pkg)
1228{
1229	if (preserve_meta_data_file(pkg, REQUIRED_BY_FNAME))
1230		return -1;
1231
1232	if (preserve_meta_data_file(pkg, PRESERVE_FNAME))
1233		return -1;
1234
1235	if (pkg->meta_data.meta_installed_info == NULL &&
1236	    preserve_meta_data_file(pkg, INSTALLED_INFO_FNAME))
1237		return -1;
1238
1239	if (Verbose || Fake) {
1240		printf("%s/pkg_delete -K %s -p %s%s%s '%s'\n",
1241			BINDIR, pkgdb_get_dir(), pkg->prefix,
1242			Destdir ? " -P ": "", Destdir ? Destdir : "",
1243			pkg->other_version);
1244	}
1245	if (!Fake)
1246		fexec_skipempty(BINDIR "/pkg_delete", "-K", pkgdb_get_dir(),
1247		    "-p", pkg->prefix,
1248		    Destdir ? "-P": "", Destdir ? Destdir : "",
1249		    pkg->other_version, NULL);
1250
1251	/* XXX Check return value and do what? */
1252	return 0;
1253}
1254
1255static int check_input(const char *line, size_t len)
1256{
1257	if (line == NULL || len == 0)
1258		return 1;
1259	switch (*line) {
1260	case 'Y':
1261	case 'y':
1262	case 'T':
1263	case 't':
1264	case '1':
1265		return 0;
1266	default:
1267		return 1;
1268	}
1269}
1270
1271static int
1272check_signature(struct pkg_task *pkg, int invalid_sig)
1273{
1274	char *line;
1275	size_t len;
1276
1277	if (strcasecmp(verified_installation, "never") == 0)
1278		return 0;
1279	if (strcasecmp(verified_installation, "always") == 0) {
1280		if (invalid_sig)
1281			warnx("No valid signature found, rejected");
1282		return invalid_sig;
1283	}
1284	if (strcasecmp(verified_installation, "trusted") == 0) {
1285		if (!invalid_sig)
1286			return 0;
1287		fprintf(stderr, "No valid signature found for %s.\n",
1288		    pkg->pkgname);
1289		fprintf(stderr,
1290		    "Do you want to proceed with the installation [y/n]?\n");
1291		line = fgetln(stdin, &len);
1292		if (check_input(line, len)) {
1293			fprintf(stderr, "Cancelling installation\n");
1294			return 1;
1295		}
1296		return 0;
1297	}
1298	if (strcasecmp(verified_installation, "interactive") == 0) {
1299		fprintf(stderr, "Do you want to proceed with "
1300		    "the installation of %s [y/n]?\n", pkg->pkgname);
1301		line = fgetln(stdin, &len);
1302		if (check_input(line, len)) {
1303			fprintf(stderr, "Cancelling installation\n");
1304			return 1;
1305		}
1306		return 0;
1307	}
1308	warnx("Unknown value of configuration variable VERIFIED_INSTALLATION");
1309	return 1;
1310}
1311
1312static int
1313check_vulnerable(struct pkg_task *pkg)
1314{
1315	static struct pkg_vulnerabilities *pv;
1316	int require_check;
1317	char *line;
1318	size_t len;
1319
1320	if (strcasecmp(check_vulnerabilities, "never") == 0)
1321		return 0;
1322	else if (strcasecmp(check_vulnerabilities, "always") == 0)
1323		require_check = 1;
1324	else if (strcasecmp(check_vulnerabilities, "interactive") == 0)
1325		require_check = 0;
1326	else {
1327		warnx("Unknown value of the configuration variable"
1328		    "CHECK_VULNERABILITIES");
1329		return 1;
1330	}
1331
1332	if (pv == NULL) {
1333		pv = read_pkg_vulnerabilities_file(pkg_vulnerabilities_file,
1334		    require_check, 0);
1335		if (pv == NULL)
1336			return require_check;
1337	}
1338
1339	if (!audit_package(pv, pkg->pkgname, NULL, 2))
1340		return 0;
1341
1342	if (require_check)
1343		return 1;
1344
1345	fprintf(stderr, "Do you want to proceed with the installation of %s"
1346	    " [y/n]?\n", pkg->pkgname);
1347	line = fgetln(stdin, &len);
1348	if (check_input(line, len)) {
1349		fprintf(stderr, "Cancelling installation\n");
1350		return 1;
1351	}
1352	return 0;
1353}
1354
1355static int
1356check_license(struct pkg_task *pkg)
1357{
1358	if (LicenseCheck == 0)
1359		return 0;
1360
1361	if ((pkg->buildinfo[BI_LICENSE] == NULL ||
1362	     *pkg->buildinfo[BI_LICENSE] == '\0')) {
1363
1364		if (LicenseCheck == 1)
1365			return 0;
1366		warnx("No LICENSE set for package `%s'", pkg->pkgname);
1367		return 1;
1368	}
1369
1370	switch (acceptable_license(pkg->buildinfo[BI_LICENSE])) {
1371	case 0:
1372		warnx("License `%s' of package `%s' is not acceptable",
1373		    pkg->buildinfo[BI_LICENSE], pkg->pkgname);
1374		return 1;
1375	case 1:
1376		return 0;
1377	default:
1378		warnx("Invalid LICENSE for package `%s'", pkg->pkgname);
1379		return 1;
1380	}
1381}
1382
1383/*
1384 * Install a single package.
1385 */
1386static int
1387pkg_do(const char *pkgpath, int mark_automatic, int top_level)
1388{
1389	char *archive_name;
1390	int status, invalid_sig;
1391	struct pkg_task *pkg;
1392
1393	pkg = xcalloc(1, sizeof(*pkg));
1394
1395	status = -1;
1396
1397	pkg->archive = find_archive(pkgpath, top_level, &archive_name);
1398	if (pkg->archive == NULL) {
1399		warnx("no pkg found for '%s', sorry.", pkgpath);
1400		goto clean_find_archive;
1401	}
1402
1403	invalid_sig = pkg_verify_signature(archive_name, &pkg->archive, &pkg->entry,
1404	    &pkg->pkgname);
1405	free(archive_name);
1406
1407	if (pkg->archive == NULL)
1408		goto clean_memory;
1409
1410	if (read_meta_data(pkg))
1411		goto clean_memory;
1412
1413	/* Parse PLIST early, so that messages can use real package name. */
1414	if (pkg_parse_plist(pkg))
1415		goto clean_memory;
1416
1417	if (check_signature(pkg, invalid_sig))
1418		goto clean_memory;
1419
1420	if (read_buildinfo(pkg))
1421		goto clean_memory;
1422
1423	if (check_pkgtools_version(pkg))
1424		goto clean_memory;
1425
1426	if (check_vulnerable(pkg))
1427		goto clean_memory;
1428
1429	if (check_license(pkg))
1430		goto clean_memory;
1431
1432	if (pkg->meta_data.meta_mtree != NULL)
1433		warnx("mtree specification in pkg `%s' ignored", pkg->pkgname);
1434
1435	if (pkg->meta_data.meta_views != NULL) {
1436		pkg->logdir = xstrdup(pkg->prefix);
1437		pkgdb_set_dir(dirname_of(pkg->logdir), 4);
1438	} else {
1439		pkg->logdir = xasprintf("%s/%s", config_pkg_dbdir, pkg->pkgname);
1440	}
1441
1442	if (Destdir != NULL)
1443		pkg->install_logdir = xasprintf("%s/%s", Destdir, pkg->logdir);
1444	else
1445		pkg->install_logdir = xstrdup(pkg->logdir);
1446
1447	if (NoRecord && !Fake) {
1448		const char *tmpdir;
1449
1450		tmpdir = getenv("TMPDIR");
1451		if (tmpdir == NULL)
1452			tmpdir = "/tmp";
1453
1454		free(pkg->install_logdir);
1455		pkg->install_logdir = xasprintf("%s/pkg_install.XXXXXX", tmpdir);
1456		/* XXX pkg_add -u... */
1457		if (mkdtemp(pkg->install_logdir) == NULL) {
1458			warn("mkdtemp failed");
1459			goto clean_memory;
1460		}
1461	}
1462
1463	switch (check_already_installed(pkg)) {
1464	case 0:
1465		status = 0;
1466		goto clean_memory;
1467	case 1:
1468		break;
1469	case -1:
1470		goto clean_memory;
1471	}
1472
1473	if (check_platform(pkg))
1474		goto clean_memory;
1475
1476	if (check_other_installed(pkg))
1477		goto clean_memory;
1478
1479	if (check_explicit_conflict(pkg))
1480		goto clean_memory;
1481
1482	if (check_implicit_conflict(pkg))
1483		goto clean_memory;
1484
1485	if (pkg->other_version != NULL) {
1486		/*
1487		 * Replacing an existing package.
1488		 * Write meta-data, get rid of the old version,
1489		 * install/update dependencies and finally extract.
1490		 */
1491		if (write_meta_data(pkg))
1492			goto nuke_pkgdb;
1493
1494		if (start_replacing(pkg))
1495			goto nuke_pkgdb;
1496
1497		if (pkg->install_logdir_real) {
1498			rename(pkg->install_logdir, pkg->install_logdir_real);
1499			free(pkg->install_logdir);
1500			pkg->install_logdir = pkg->install_logdir_real;
1501			pkg->install_logdir_real = NULL;
1502		}
1503
1504		if (check_dependencies(pkg))
1505			goto nuke_pkgdb;
1506	} else {
1507		/*
1508		 * Normal installation.
1509		 * Install/update dependencies first and
1510		 * write the current package to disk afterwards.
1511		 */
1512		if (check_dependencies(pkg))
1513			goto clean_memory;
1514
1515		if (write_meta_data(pkg))
1516			goto nuke_pkgdb;
1517	}
1518
1519	if (run_install_script(pkg, "PRE-INSTALL"))
1520		goto nuke_pkgdb;
1521
1522	if (extract_files(pkg))
1523		goto nuke_pkg;
1524
1525	if (run_install_script(pkg, "POST-INSTALL"))
1526		goto nuke_pkgdb;
1527
1528	/* XXX keep +INSTALL_INFO for updates? */
1529	/* XXX keep +PRESERVE for updates? */
1530	if (mark_automatic)
1531		mark_as_automatic_installed(pkg->pkgname, 1);
1532
1533	pkg_register_depends(pkg);
1534
1535	if (Verbose)
1536		printf("Package %s registered in %s\n", pkg->pkgname, pkg->install_logdir);
1537
1538	if (pkg->meta_data.meta_display != NULL)
1539		fputs(pkg->meta_data.meta_display, stdout);
1540
1541	pkg_register_views(pkg);
1542
1543	status = 0;
1544	goto clean_memory;
1545
1546nuke_pkg:
1547	if (!Fake) {
1548		if (pkg->other_version) {
1549			warnx("Updating of %s to %s failed.",
1550			    pkg->other_version, pkg->pkgname);
1551			warnx("Remember to run pkg_admin rebuild-tree after fixing this.");
1552		}
1553		delete_package(FALSE, &pkg->plist, FALSE, Destdir);
1554	}
1555
1556nuke_pkgdb:
1557	if (!Fake) {
1558		if (recursive_remove(pkg->install_logdir, 1))
1559			warn("Couldn't remove %s", pkg->install_logdir);
1560		free(pkg->install_logdir_real);
1561		free(pkg->install_logdir);
1562		free(pkg->logdir);
1563		pkg->install_logdir_real = NULL;
1564		pkg->install_logdir = NULL;
1565		pkg->logdir = NULL;
1566	}
1567
1568clean_memory:
1569	if (pkg->logdir != NULL && NoRecord && !Fake) {
1570		if (recursive_remove(pkg->install_logdir, 1))
1571			warn("Couldn't remove %s", pkg->install_logdir);
1572	}
1573	free(pkg->install_prefix);
1574	free(pkg->install_logdir_real);
1575	free(pkg->install_logdir);
1576	free(pkg->logdir);
1577	free_buildinfo(pkg);
1578	free_plist(&pkg->plist);
1579	free_meta_data(pkg);
1580	if (pkg->archive)
1581		archive_read_finish(pkg->archive);
1582	free(pkg->other_version);
1583	free(pkg->pkgname);
1584clean_find_archive:
1585	free(pkg);
1586	return status;
1587}
1588
1589int
1590pkg_perform(lpkg_head_t *pkgs)
1591{
1592	int     errors = 0;
1593	lpkg_t *lpp;
1594
1595	while ((lpp = TAILQ_FIRST(pkgs)) != NULL) {
1596		if (pkg_do(lpp->lp_name, Automatic, 1))
1597			++errors;
1598		TAILQ_REMOVE(pkgs, lpp, lp_link);
1599		free_lpkg(lpp);
1600	}
1601
1602	return errors;
1603}
1604