1 /*	$NetBSD: perform.c,v 1.1.1.13 2010/02/20 04:41:55 joerg Exp $	*/
2 
3 #if HAVE_CONFIG_H
4 #include "config.h"
5 #endif
6 #include <nbcompat.h>
7 #if HAVE_SYS_CDEFS_H
8 #include <sys/cdefs.h>
9 #endif
10 #if HAVE_SYS_QUEUE_H
11 #include <sys/queue.h>
12 #endif
13 #if HAVE_SYS_WAIT_H
14 #include <sys/wait.h>
15 #endif
16 __RCSID("$NetBSD: perform.c,v 1.1.1.13 2010/02/20 04:41:55 joerg Exp $");
17 
18 /*-
19  * Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>.
20  * All rights reserved.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  *
26  * 1. Redistributions of source code must retain the above copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in
30  *    the documentation and/or other materials provided with the
31  *    distribution.
32  *
33  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
34  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
35  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
36  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
37  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
38  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
39  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
40  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
41  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
42  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
43  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44  * SUCH DAMAGE.
45  */
46 
47 /*
48  * FreeBSD install - a package for the installation and maintainance
49  * of non-core utilities.
50  *
51  * Redistribution and use in source and binary forms, with or without
52  * modification, are permitted provided that the following conditions
53  * are met:
54  * 1. Redistributions of source code must retain the above copyright
55  *    notice, this list of conditions and the following disclaimer.
56  * 2. Redistributions in binary form must reproduce the above copyright
57  *    notice, this list of conditions and the following disclaimer in the
58  *    documentation and/or other materials provided with the distribution.
59  *
60  * Jordan K. Hubbard
61  * 23 Aug 1993
62  *
63  * This is the main body of the info module.
64  *
65  */
66 
67 #include "lib.h"
68 #include "info.h"
69 
70 #if HAVE_SYS_TYPES_H
71 #include <sys/types.h>
72 #endif
73 #if HAVE_SYS_STAT_H
74 #include <sys/stat.h>
75 #endif
76 
77 #ifndef BOOTSTRAP
78 #include <archive.h>
79 #include <archive_entry.h>
80 #endif
81 #if HAVE_ERR_H
82 #include <err.h>
83 #endif
84 #if HAVE_ERRNO_H
85 #include <errno.h>
86 #endif
87 #if HAVE_FCNTL_H
88 #include <fcntl.h>
89 #endif
90 #if HAVE_SIGNAL_H
91 #include <signal.h>
92 #endif
93 #if HAVE_DIRENT_H
94 #include <dirent.h>
95 #endif
96 #if HAVE_CTYPE_H
97 #include <ctype.h>
98 #endif
99 #include <stddef.h>
100 
101 #define	LOAD_CONTENTS		(1 << 0)
102 #define	LOAD_COMMENT		(1 << 1)
103 #define	LOAD_DESC		(1 << 2)
104 #define	LOAD_INSTALL		(1 << 3)
105 #define	LOAD_DEINSTALL		(1 << 4)
106 #define	LOAD_DISPLAY		(1 << 5)
107 #define	LOAD_MTREE		(1 << 6)
108 #define	LOAD_BUILD_VERSION	(1 << 7)
109 #define	LOAD_BUILD_INFO		(1 << 8)
110 #define	LOAD_SIZE_PKG		(1 << 9)
111 #define	LOAD_SIZE_ALL		(1 << 10)
112 #define	LOAD_PRESERVE		(1 << 11)
113 #define	LOAD_VIEWS		(1 << 12)
114 #define	LOAD_REQUIRED_BY	(1 << 13)
115 #define	LOAD_INSTALLED_INFO	(1 << 14)
116 
117 static const struct pkg_meta_desc {
118 	size_t entry_offset;
119 	const char *entry_filename;
120 	int entry_mask;
121 	int required_file;
122 } pkg_meta_descriptors[] = {
123 	{ offsetof(struct pkg_meta, meta_contents), CONTENTS_FNAME,
124 	    LOAD_CONTENTS, 1},
125 	{ offsetof(struct pkg_meta, meta_comment), COMMENT_FNAME,
126 	    LOAD_COMMENT, 1 },
127 	{ offsetof(struct pkg_meta, meta_desc), DESC_FNAME,
128 	    LOAD_DESC, 1 },
129 	{ offsetof(struct pkg_meta, meta_install), INSTALL_FNAME,
130 	    LOAD_INSTALL, 0 },
131 	{ offsetof(struct pkg_meta, meta_deinstall), DEINSTALL_FNAME,
132 	    LOAD_DEINSTALL, 0 },
133 	{ offsetof(struct pkg_meta, meta_display), DISPLAY_FNAME,
134 	    LOAD_DISPLAY, 0 },
135 	{ offsetof(struct pkg_meta, meta_mtree), MTREE_FNAME,
136 	    LOAD_MTREE, 0 },
137 	{ offsetof(struct pkg_meta, meta_build_version), BUILD_VERSION_FNAME,
138 	    LOAD_BUILD_VERSION, 0 },
139 	{ offsetof(struct pkg_meta, meta_build_info), BUILD_INFO_FNAME,
140 	    LOAD_BUILD_INFO, 0 },
141 	{ offsetof(struct pkg_meta, meta_size_pkg), SIZE_PKG_FNAME,
142 	    LOAD_SIZE_PKG, 0 },
143 	{ offsetof(struct pkg_meta, meta_size_all), SIZE_ALL_FNAME,
144 	    LOAD_SIZE_ALL, 0 },
145 	{ offsetof(struct pkg_meta, meta_preserve), PRESERVE_FNAME,
146 	    LOAD_PRESERVE, 0 },
147 	{ offsetof(struct pkg_meta, meta_views), VIEWS_FNAME,
148 	    LOAD_VIEWS, 0 },
149 	{ offsetof(struct pkg_meta, meta_required_by), REQUIRED_BY_FNAME,
150 	    LOAD_REQUIRED_BY, 0 },
151 	{ offsetof(struct pkg_meta, meta_installed_info), INSTALLED_INFO_FNAME,
152 	    LOAD_INSTALLED_INFO, 0 },
153 	{ 0, NULL, 0, 0 },
154 };
155 
156 static int desired_meta_data;
157 
158 static void
159 free_pkg_meta(struct pkg_meta *meta)
160 {
161 	const struct pkg_meta_desc *descr;
162 
163 	for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr)
164 		free(*(char **)((char *)meta + descr->entry_offset));
165 
166 	free(meta);
167 }
168 
169 #ifndef BOOTSTRAP
170 static struct pkg_meta *
171 read_meta_data_from_archive(struct archive *archive,
172     struct archive_entry *entry)
173 {
174 	struct pkg_meta *meta;
175 	const char *fname;
176 	const struct pkg_meta_desc *descr, *last_descr;
177 	char **target;
178 	int64_t size;
179 	int r, found_required;
180 
181 	found_required = 0;
182 
183 	meta = xcalloc(1, sizeof(*meta));
184 
185 	last_descr = 0;
186 	if (entry != NULL) {
187 		r = ARCHIVE_OK;
188 		goto has_entry;
189 	}
190 
191 	while ((r = archive_read_next_header(archive, &entry)) == ARCHIVE_OK) {
192 has_entry:
193 		fname = archive_entry_pathname(entry);
194 
195 		for (descr = pkg_meta_descriptors; descr->entry_filename;
196 		     ++descr) {
197 			if (strcmp(descr->entry_filename, fname) == 0)
198 				break;
199 		}
200 		if (descr->entry_filename == NULL)
201 			break;
202 
203 		if (descr->required_file)
204 			++found_required;
205 
206 		target = (char **)((char *)meta + descr->entry_offset);
207 		if (*target)
208 			errx(2, "duplicate entry, package corrupt");
209 		if (descr < last_descr)
210 			warnx("misordered package, continuing");
211 		else
212 			last_descr = descr;
213 
214 		if ((descr->entry_mask & desired_meta_data) == 0) {
215 			if (archive_read_data_skip(archive))
216 				errx(2, "cannot read package meta data");
217 			continue;
218 		}
219 
220 		size = archive_entry_size(entry);
221 		if (size > SSIZE_MAX - 1)
222 			errx(2, "package meta data too large to process");
223 		*target = xmalloc(size + 1);
224 		if (archive_read_data(archive, *target, size) != size)
225 			errx(2, "cannot read package meta data");
226 		(*target)[size] = '\0';
227 	}
228 
229 	for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) {
230 		if (descr->required_file)
231 			--found_required;
232 	}
233 
234 	meta->is_installed = 0;
235 	if (found_required != 0 || (r != ARCHIVE_OK && r != ARCHIVE_EOF)) {
236 		free_pkg_meta(meta);
237 		meta = NULL;
238 	}
239 
240 	return meta;
241 }
242 #endif
243 
244 static struct pkg_meta *
245 read_meta_data_from_pkgdb(const char *pkg)
246 {
247 	struct pkg_meta *meta;
248 	const struct pkg_meta_desc *descr;
249 	char **target;
250 	char *fname;
251 	int fd;
252 	struct stat st;
253 
254 	meta = xcalloc(1, sizeof(*meta));
255 
256 	for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) {
257 		if ((descr->entry_mask & desired_meta_data) == 0)
258 			continue;
259 
260 		fname = pkgdb_pkg_file(pkg, descr->entry_filename);
261 		fd = open(fname, O_RDONLY, 0);
262 		free(fname);
263 		if (fd == -1) {
264 			if (errno == ENOENT && descr->required_file == 0)
265 				continue;
266 			err(2, "cannot read meta data file %s of package %s",
267 			    descr->entry_filename, pkg);
268 		}
269 		target = (char **)((char *)meta + descr->entry_offset);
270 
271 		if (fstat(fd, &st) == -1)
272 			err(2, "cannot stat meta data");
273 		if ((st.st_mode & S_IFMT) != S_IFREG)
274 			errx(1, "meta data is not regular file");
275 		if (st.st_size > SSIZE_MAX - 1)
276 			err(2, "meta data file too large to process");
277 		*target = xmalloc(st.st_size + 1);
278 		if (read(fd, *target, st.st_size) != st.st_size)
279 			err(2, "cannot read meta data");
280 		(*target)[st.st_size] = '\0';
281 		close(fd);
282 	}
283 
284 	meta->is_installed = 1;
285 
286 	return meta;
287 }
288 
289 static void
290 build_full_reqby(lpkg_head_t *reqby, struct pkg_meta *meta, int limit)
291 {
292 	char *iter, *eol, *next;
293 	lpkg_t *lpp;
294 	struct pkg_meta *meta_dep;
295 
296 	if (limit == 65536)
297 		errx(1, "Cycle in the dependency tree, bailing out");
298 
299 	if (meta->is_installed == 0 || meta->meta_required_by == NULL)
300 		return;
301 
302 	for (iter = meta->meta_required_by; *iter != '\0'; iter = next) {
303 		eol = iter + strcspn(iter, "\n");
304 		if (*eol == '\n')
305 			next = eol + 1;
306 		else
307 			next = eol;
308 		if (iter == eol)
309 			continue;
310 		TAILQ_FOREACH(lpp, reqby, lp_link) {
311 			if (strlen(lpp->lp_name) + iter != eol)
312 				continue;
313 			if (memcmp(lpp->lp_name, iter, eol - iter) == 0)
314 				break;
315 		}
316 		if (lpp != NULL)
317 			continue;
318 		*eol = '\0';
319 		lpp = alloc_lpkg(iter);
320 		if (next != eol)
321 			*eol = '\n';
322 
323 		meta_dep = read_meta_data_from_pkgdb(lpp->lp_name);
324 		if (meta_dep == NULL)
325 			continue;
326 		build_full_reqby(reqby, meta_dep, limit + 1);
327 		free_pkg_meta(meta_dep);
328 
329 		TAILQ_INSERT_HEAD(reqby, lpp, lp_link);
330 	}
331 }
332 
333 static lfile_head_t files;
334 
335 static int
336 pkg_do(const char *pkg)
337 {
338 	struct pkg_meta *meta;
339 	int     code = 0;
340 	const char   *binpkgfile = NULL;
341 	char *pkgdir;
342 
343 	if (IS_URL(pkg) || (fexists(pkg) && isfile(pkg))) {
344 #ifdef BOOTSTRAP
345 		errx(2, "Binary packages not supported during bootstrap");
346 #else
347 		struct archive *archive;
348 		struct archive_entry *entry;
349 		char *archive_name, *pkgname;
350 
351 		archive = open_archive(pkg, &archive_name);
352 		if (archive == NULL) {
353 			warnx("can't find package `%s', skipped", pkg);
354 			return -1;
355 		}
356 		pkgname = NULL;
357 		entry = NULL;
358 		pkg_verify_signature(archive_name, &archive, &entry, &pkgname);
359 		if (archive == NULL)
360 			return -1;
361 		free(pkgname);
362 
363 		meta = read_meta_data_from_archive(archive, entry);
364 		archive_read_finish(archive);
365 		if (!IS_URL(pkg))
366 			binpkgfile = pkg;
367 #endif
368 	} else {
369 		/*
370 	         * It's not an uninstalled package, try and find it among the
371 	         * installed
372 	         */
373 		pkgdir = pkgdb_pkg_dir(pkg);
374 		if (!fexists(pkgdir) || !(isdir(pkgdir) || islinktodir(pkgdir))) {
375 			switch (add_installed_pkgs_by_basename(pkg, &pkgs)) {
376 			case 1:
377 				return 0;
378 			case 0:
379 				/* No match */
380 				warnx("can't find package `%s'", pkg);
381 				return 1;
382 			case -1:
383 				errx(EXIT_FAILURE, "Error during search in pkgdb for %s", pkg);
384 			}
385 		}
386 		free(pkgdir);
387 		meta = read_meta_data_from_pkgdb(pkg);
388 	}
389 
390 	if (meta == NULL) {
391 		warnx("invalid package `%s' skipped", pkg);
392 		return 1;
393 	}
394 
395 	/*
396          * Index is special info type that has to override all others to make
397          * any sense.
398          */
399 	if (Flags & SHOW_INDEX) {
400 		char    tmp[MaxPathSize];
401 
402 		(void) snprintf(tmp, sizeof(tmp), "%-19s ", pkg);
403 		show_index(meta->meta_comment, tmp);
404 	} else if (Flags & SHOW_BI_VAR) {
405 		if (strcspn(BuildInfoVariable, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
406 		    == strlen(BuildInfoVariable)) {
407 			if (meta->meta_installed_info)
408 				show_var(meta->meta_installed_info, BuildInfoVariable);
409 		} else {
410 			if (meta->meta_build_info)
411 				show_var(meta->meta_build_info, BuildInfoVariable);
412 			else
413 				warnx("Build information missing");
414 		}
415 	} else {
416 		package_t plist;
417 
418 		/* Read the contents list */
419 		parse_plist(&plist, meta->meta_contents);
420 
421 		/* Start showing the package contents */
422 		if (!Quiet && !(Flags & SHOW_SUMMARY)) {
423 			printf("%sInformation for %s:\n\n", InfoPrefix, pkg);
424 			if (meta->meta_preserve) {
425 				printf("*** PACKAGE MAY NOT BE DELETED ***\n");
426 			}
427 		}
428 		if (Flags & SHOW_SUMMARY) {
429 			show_summary(meta, &plist, binpkgfile);
430 		}
431 		if (Flags & SHOW_COMMENT) {
432 			show_file(meta->meta_comment, "Comment:\n", TRUE);
433 		}
434 		if (Flags & SHOW_DEPENDS) {
435 			show_depends("Requires:\n", &plist);
436 		}
437 		if (Flags & SHOW_BLD_DEPENDS) {
438 			show_bld_depends("Built using:\n", &plist);
439 		}
440 		if ((Flags & SHOW_REQBY) && meta->meta_required_by) {
441 			show_file(meta->meta_required_by, "Required by:\n", TRUE);
442 		}
443 		if ((Flags & SHOW_FULL_REQBY) && meta->is_installed) {
444 			lpkg_head_t reqby;
445 			TAILQ_INIT(&reqby);
446 			build_full_reqby(&reqby, meta, 0);
447 			show_list(&reqby, "Full required by list:\n");
448 		}
449 		if (Flags & SHOW_DESC) {
450 			show_file(meta->meta_desc, "Description:\n", TRUE);
451 		}
452 		if ((Flags & SHOW_DISPLAY) && meta->meta_display) {
453 			show_file(meta->meta_display, "Install notice:\n",
454 				  TRUE);
455 		}
456 		if (Flags & SHOW_PLIST) {
457 			show_plist("Packing list:\n", &plist, PLIST_SHOW_ALL);
458 		}
459 		if ((Flags & SHOW_INSTALL) && meta->meta_install) {
460 			show_file(meta->meta_install, "Install script:\n",
461 				  TRUE);
462 		}
463 		if ((Flags & SHOW_DEINSTALL) && meta->meta_deinstall) {
464 			show_file(meta->meta_deinstall, "De-Install script:\n",
465 				  TRUE);
466 		}
467 		if ((Flags & SHOW_MTREE) && meta->meta_mtree) {
468 			show_file(meta->meta_mtree, "mtree file:\n", TRUE);
469 		}
470 		if (Flags & SHOW_PREFIX) {
471 			show_plist("Prefix(s):\n", &plist, PLIST_CWD);
472 		}
473 		if (Flags & SHOW_FILES) {
474 			show_files("Files:\n", &plist);
475 		}
476 		if ((Flags & SHOW_BUILD_VERSION) && meta->meta_build_version) {
477 			show_file(meta->meta_build_version, "Build version:\n",
478 				  TRUE);
479 		}
480 		if (Flags & SHOW_BUILD_INFO) {
481 			if (meta->meta_build_info) {
482 				show_file(meta->meta_build_info, "Build information:\n",
483 					  TRUE);
484 			}
485 			if (meta->meta_installed_info) {
486 				show_file(meta->meta_installed_info, "Installed information:\n",
487 					  TRUE);
488 			}
489 		}
490 		if ((Flags & SHOW_PKG_SIZE) && meta->meta_size_pkg) {
491 			show_file(meta->meta_size_pkg, "Size of this package in bytes: ",
492 				  TRUE);
493 		}
494 		if ((Flags & SHOW_ALL_SIZE) && meta->meta_size_all) {
495 			show_file(meta->meta_size_all, "Size in bytes including required pkgs: ",
496 				  TRUE);
497 		}
498 		if (!Quiet && !(Flags & SHOW_SUMMARY)) {
499 			if (meta->meta_preserve) {
500 				printf("*** PACKAGE MAY NOT BE DELETED ***\n\n");
501 			}
502 			puts(InfoPrefix);
503 		}
504 		free_plist(&plist);
505 	}
506 	free_pkg_meta(meta);
507 	return code;
508 }
509 
510 struct print_matching_arg {
511 	const char *pattern;
512 	int got_match;
513 };
514 
515 static int
516 print_matching_pkg(const char *pkgname, void *cookie)
517 {
518 	struct print_matching_arg *arg= cookie;
519 
520 	if (pkg_match(arg->pattern, pkgname)) {
521 		if (!Quiet)
522 			puts(pkgname);
523 		arg->got_match = 1;
524 	}
525 
526 	return 0;
527 }
528 
529 /*
530  * Returns 0 if at least one package matching pkgname.
531  * Returns 1 otherwise.
532  *
533  * If -q was not specified, print all matching packages to stdout.
534  */
535 int
536 CheckForPkg(const char *pkgname)
537 {
538 	struct print_matching_arg arg;
539 
540 	arg.pattern = pkgname;
541 	arg.got_match = 0;
542 
543 	if (iterate_pkg_db(print_matching_pkg, &arg) == -1) {
544 		warnx("cannot iterate pkgdb");
545 		return 1;
546 	}
547 
548 	if (arg.got_match == 0 && !ispkgpattern(pkgname)) {
549 		char *pattern;
550 
551 		pattern = xasprintf("%s-[0-9]*", pkgname);
552 
553 		arg.pattern = pattern;
554 		arg.got_match = 0;
555 
556 		if (iterate_pkg_db(print_matching_pkg, &arg) == -1) {
557 			free(pattern);
558 			warnx("cannot iterate pkgdb");
559 			return 1;
560 		}
561 		free(pattern);
562 	}
563 
564 	if (arg.got_match)
565 		return 0;
566 	else
567 		return 1;
568 }
569 
570 /*
571  * Returns 0 if at least one package matching pkgname.
572  * Returns 1 otherwise.
573  *
574  * If -q was not specified, print best match to stdout.
575  */
576 int
577 CheckForBestPkg(const char *pkgname)
578 {
579 	char *pattern, *best_match;
580 
581 	best_match = find_best_matching_installed_pkg(pkgname);
582 	if (best_match == NULL) {
583 		if (ispkgpattern(pkgname))
584 			return 1;
585 
586 		pattern = xasprintf("%s-[0-9]*", pkgname);
587 		best_match = find_best_matching_installed_pkg(pattern);
588 		free(pattern);
589 	}
590 
591 	if (best_match == NULL)
592 		return 1;
593 	if (!Quiet)
594 		puts(best_match);
595 	free(best_match);
596 	return 0;
597 }
598 
599 static int
600 perform_single_pkg(const char *pkg, void *cookie)
601 {
602 	int *err_cnt = cookie;
603 
604 	if (Which == WHICH_ALL || !is_automatic_installed(pkg))
605 		*err_cnt += pkg_do(pkg);
606 
607 	return 0;
608 }
609 
610 int
611 pkg_perform(lpkg_head_t *pkghead)
612 {
613 	int     err_cnt = 0;
614 
615 	TAILQ_INIT(&files);
616 
617 	desired_meta_data = 0;
618 	if ((Flags & (SHOW_INDEX | SHOW_BI_VAR)) == 0)
619 		desired_meta_data |= LOAD_PRESERVE;
620 	if ((Flags & (SHOW_INDEX | SHOW_BI_VAR)) == 0)
621 		desired_meta_data |= LOAD_CONTENTS;
622 	if (Flags & (SHOW_COMMENT | SHOW_INDEX | SHOW_SUMMARY))
623 		desired_meta_data |= LOAD_COMMENT;
624 	if (Flags & (SHOW_BI_VAR | SHOW_BUILD_INFO | SHOW_SUMMARY))
625 		desired_meta_data |= LOAD_BUILD_INFO | LOAD_INSTALLED_INFO;
626 	if (Flags & (SHOW_SUMMARY | SHOW_PKG_SIZE))
627 		desired_meta_data |= LOAD_SIZE_PKG;
628 	if (Flags & SHOW_ALL_SIZE)
629 		desired_meta_data |= LOAD_SIZE_ALL;
630 	if (Flags & (SHOW_SUMMARY | SHOW_DESC))
631 		desired_meta_data |= LOAD_DESC;
632 	if (Flags & (SHOW_REQBY | SHOW_FULL_REQBY))
633 		desired_meta_data |= LOAD_REQUIRED_BY;
634 	if (Flags & SHOW_DISPLAY)
635 		desired_meta_data |= LOAD_DISPLAY;
636 	if (Flags & SHOW_INSTALL)
637 		desired_meta_data |= LOAD_INSTALL;
638 	if (Flags & SHOW_DEINSTALL)
639 		desired_meta_data |= LOAD_DEINSTALL;
640 	if (Flags & SHOW_MTREE)
641 		desired_meta_data |= LOAD_MTREE;
642 	if (Flags & SHOW_BUILD_VERSION)
643 		desired_meta_data |= LOAD_BUILD_VERSION;
644 
645 	if (Which != WHICH_LIST) {
646 		if (File2Pkg) {
647 			/* Show all files with the package they belong to */
648 			if (pkgdb_dump() == -1)
649 				err_cnt = 1;
650 		} else {
651 			if (iterate_pkg_db(perform_single_pkg, &err_cnt) == -1)
652 				err_cnt = 1;
653 		}
654 	} else {
655 		/* Show info on individual pkg(s) */
656 		lpkg_t *lpp;
657 
658 		while ((lpp = TAILQ_FIRST(pkghead)) != NULL) {
659 			TAILQ_REMOVE(pkghead, lpp, lp_link);
660 			err_cnt += pkg_do(lpp->lp_name);
661 			free_lpkg(lpp);
662 		}
663 	}
664 	return err_cnt;
665 }
666