xref: /netbsd-src/external/bsd/pkg_install/dist/info/perform.c (revision f46918ca2125b9b1e7ca5a22c07d1414c618e467)
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@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
free_pkg_meta(struct pkg_meta * meta)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 *
read_meta_data_from_archive(struct archive * archive,struct archive_entry * entry)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 *
read_meta_data_from_pkgdb(const char * pkg)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
build_full_reqby(lpkg_head_t * reqby,struct pkg_meta * meta,int limit)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
pkg_do(const char * pkg)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
print_matching_pkg(const char * pkgname,void * cookie)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
CheckForPkg(const char * pkgname)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
CheckForBestPkg(const char * pkgname)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
perform_single_pkg(const char * pkg,void * cookie)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
pkg_perform(lpkg_head_t * pkghead)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