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