Annotation of pkgsrc/pkgtools/pkg_install/files/info/perform.c, Revision 1.60
1.60 ! joerg 1: /* $NetBSD: perform.c,v 1.59 2009/08/02 17:56:45 joerg Exp $ */
1.1 schmonz 2:
1.8 jlam 3: #if HAVE_CONFIG_H
4: #include "config.h"
5: #endif
1.9 jlam 6: #include <nbcompat.h>
1.8 jlam 7: #if HAVE_SYS_CDEFS_H
1.1 schmonz 8: #include <sys/cdefs.h>
1.8 jlam 9: #endif
1.26 ben 10: #if HAVE_SYS_QUEUE_H
11: #include <sys/queue.h>
12: #endif
1.41 joerg 13: #if HAVE_SYS_WAIT_H
14: #include <sys/wait.h>
15: #endif
1.60 ! joerg 16: __RCSID("$NetBSD: perform.c,v 1.59 2009/08/02 17:56:45 joerg Exp $");
1.1 schmonz 17:
1.41 joerg 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:
1.1 schmonz 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:
1.8 jlam 70: #if HAVE_SYS_TYPES_H
1.1 schmonz 71: #include <sys/types.h>
1.8 jlam 72: #endif
73: #if HAVE_SYS_STAT_H
1.1 schmonz 74: #include <sys/stat.h>
75: #endif
76:
1.41 joerg 77: #ifndef BOOTSTRAP
78: #include <archive.h>
79: #include <archive_entry.h>
80: #endif
1.8 jlam 81: #if HAVE_ERR_H
1.1 schmonz 82: #include <err.h>
83: #endif
1.41 joerg 84: #if HAVE_ERRNO_H
85: #include <errno.h>
86: #endif
1.42 joerg 87: #if HAVE_FCNTL_H
88: #include <fcntl.h>
89: #endif
1.8 jlam 90: #if HAVE_SIGNAL_H
1.1 schmonz 91: #include <signal.h>
1.8 jlam 92: #endif
93: #if HAVE_DIRENT_H
1.1 schmonz 94: #include <dirent.h>
95: #endif
1.8 jlam 96: #if HAVE_CTYPE_H
1.1 schmonz 97: #include <ctype.h>
1.8 jlam 98: #endif
1.41 joerg 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;
1.44 joerg 121: int required_file;
1.41 joerg 122: } pkg_meta_descriptors[] = {
1.49 joerg 123: { offsetof(struct pkg_meta, meta_contents), CONTENTS_FNAME,
1.44 joerg 124: LOAD_CONTENTS, 1},
1.41 joerg 125: { offsetof(struct pkg_meta, meta_comment), COMMENT_FNAME,
1.44 joerg 126: LOAD_COMMENT, 1 },
1.41 joerg 127: { offsetof(struct pkg_meta, meta_desc), DESC_FNAME,
1.44 joerg 128: LOAD_DESC, 1 },
1.41 joerg 129: { offsetof(struct pkg_meta, meta_install), INSTALL_FNAME,
1.44 joerg 130: LOAD_INSTALL, 0 },
1.41 joerg 131: { offsetof(struct pkg_meta, meta_deinstall), DEINSTALL_FNAME,
1.44 joerg 132: LOAD_DEINSTALL, 0 },
1.41 joerg 133: { offsetof(struct pkg_meta, meta_display), DISPLAY_FNAME,
1.44 joerg 134: LOAD_DISPLAY, 0 },
1.41 joerg 135: { offsetof(struct pkg_meta, meta_mtree), MTREE_FNAME,
1.44 joerg 136: LOAD_MTREE, 0 },
1.41 joerg 137: { offsetof(struct pkg_meta, meta_build_version), BUILD_VERSION_FNAME,
1.44 joerg 138: LOAD_BUILD_VERSION, 0 },
1.41 joerg 139: { offsetof(struct pkg_meta, meta_build_info), BUILD_INFO_FNAME,
1.44 joerg 140: LOAD_BUILD_INFO, 0 },
1.41 joerg 141: { offsetof(struct pkg_meta, meta_size_pkg), SIZE_PKG_FNAME,
1.44 joerg 142: LOAD_SIZE_PKG, 0 },
1.41 joerg 143: { offsetof(struct pkg_meta, meta_size_all), SIZE_ALL_FNAME,
1.44 joerg 144: LOAD_SIZE_ALL, 0 },
1.41 joerg 145: { offsetof(struct pkg_meta, meta_preserve), PRESERVE_FNAME,
1.44 joerg 146: LOAD_PRESERVE, 0 },
1.41 joerg 147: { offsetof(struct pkg_meta, meta_views), VIEWS_FNAME,
1.44 joerg 148: LOAD_VIEWS, 0 },
1.41 joerg 149: { offsetof(struct pkg_meta, meta_required_by), REQUIRED_BY_FNAME,
1.44 joerg 150: LOAD_REQUIRED_BY, 0 },
1.41 joerg 151: { offsetof(struct pkg_meta, meta_installed_info), INSTALLED_INFO_FNAME,
1.44 joerg 152: LOAD_INSTALLED_INFO, 0 },
153: { 0, NULL, 0, 0 },
1.41 joerg 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:
1.46 joerg 169: #ifndef BOOTSTRAP
1.41 joerg 170: static struct pkg_meta *
1.49 joerg 171: read_meta_data_from_archive(struct archive *archive,
172: struct archive_entry *entry)
1.41 joerg 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;
1.44 joerg 179: int r, found_required;
180:
181: found_required = 0;
1.41 joerg 182:
1.49 joerg 183: meta = xcalloc(1, sizeof(*meta));
1.41 joerg 184:
1.49 joerg 185: last_descr = 0;
1.56 joerg 186: if (entry != NULL) {
187: r = ARCHIVE_OK;
1.49 joerg 188: goto has_entry;
1.56 joerg 189: }
1.41 joerg 190:
191: while ((r = archive_read_next_header(archive, &entry)) == ARCHIVE_OK) {
1.49 joerg 192: has_entry:
1.41 joerg 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:
1.44 joerg 203: if (descr->required_file)
204: ++found_required;
205:
1.41 joerg 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");
1.49 joerg 223: *target = xmalloc(size + 1);
1.41 joerg 224: if (archive_read_data(archive, *target, size) != size)
225: errx(2, "cannot read package meta data");
226: (*target)[size] = '\0';
227: }
228:
1.44 joerg 229: for (descr = pkg_meta_descriptors; descr->entry_filename; ++descr) {
230: if (descr->required_file)
231: --found_required;
232: }
1.56 joerg 233:
234: meta->is_installed = 0;
1.58 joerg 235: if (found_required != 0 || (r != ARCHIVE_OK && r != ARCHIVE_EOF)) {
1.44 joerg 236: free_pkg_meta(meta);
1.49 joerg 237: meta = NULL;
1.44 joerg 238: }
239:
1.41 joerg 240: return meta;
1.46 joerg 241: }
1.41 joerg 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:
1.49 joerg 254: meta = xcalloc(1, sizeof(*meta));
1.41 joerg 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) {
1.45 joerg 264: if (errno == ENOENT && descr->required_file == 0)
1.41 joerg 265: continue;
1.45 joerg 266: err(2, "cannot read meta data file %s of package %s",
267: descr->entry_filename, pkg);
268: }
1.41 joerg 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");
1.49 joerg 277: *target = xmalloc(st.st_size + 1);
1.41 joerg 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: }
1.1 schmonz 283:
1.53 joerg 284: meta->is_installed = 1;
285:
1.41 joerg 286: return meta;
287: }
1.1 schmonz 288:
1.53 joerg 289: static void
1.57 joerg 290: build_full_reqby(lpkg_head_t *reqby, struct pkg_meta *meta, int limit)
1.53 joerg 291: {
292: char *iter, *eol, *next;
293: lpkg_t *lpp;
294: struct pkg_meta *meta_dep;
295:
1.57 joerg 296: if (limit == 65536)
297: errx(1, "Cycle in the dependency tree, bailing out");
298:
1.53 joerg 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) {
1.59 joerg 311: if (strlen(lpp->lp_name) + iter != eol)
1.53 joerg 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';
1.57 joerg 322:
1.53 joerg 323: meta_dep = read_meta_data_from_pkgdb(lpp->lp_name);
324: if (meta_dep == NULL)
325: continue;
1.57 joerg 326: build_full_reqby(reqby, meta_dep, limit + 1);
1.53 joerg 327: free_pkg_meta(meta_dep);
1.57 joerg 328:
1.58 joerg 329: TAILQ_INSERT_HEAD(reqby, lpp, lp_link);
1.53 joerg 330: }
331: }
332:
1.26 ben 333: static lfile_head_t files;
334:
1.1 schmonz 335: static int
1.35 joerg 336: pkg_do(const char *pkg)
1.1 schmonz 337: {
1.41 joerg 338: struct pkg_meta *meta;
1.1 schmonz 339: int code = 0;
1.41 joerg 340: const char *binpkgfile = NULL;
1.60 ! joerg 341: char *pkgdir;
1.1 schmonz 342:
1.49 joerg 343: if (IS_URL(pkg) || (fexists(pkg) && isfile(pkg))) {
1.46 joerg 344: #ifdef BOOTSTRAP
345: errx(2, "Binary packages not supported during bootstrap");
346: #else
347: struct archive *archive;
1.49 joerg 348: struct archive_entry *entry;
349: char *pkgname;
350:
1.54 joerg 351: archive = open_archive(pkg);
1.49 joerg 352: if (archive == NULL) {
353: warnx("can't find package `%s', skipped", pkg);
354: return -1;
355: }
356: pkgname = NULL;
357: entry = NULL;
1.54 joerg 358: pkg_verify_signature(&archive, &entry, &pkgname);
1.51 joerg 359: if (archive == NULL)
360: return -1;
1.49 joerg 361: free(pkgname);
362:
363: meta = read_meta_data_from_archive(archive, entry);
1.54 joerg 364: archive_read_finish(archive);
1.49 joerg 365: if (!IS_URL(pkg))
366: binpkgfile = pkg;
1.46 joerg 367: #endif
1.1 schmonz 368: } else {
369: /*
370: * It's not an uninstalled package, try and find it among the
371: * installed
372: */
1.60 ! joerg 373: pkgdir = pkgdb_pkg_dir(pkg);
! 374: if (!fexists(pkgdir) || !(isdir(pkgdir) || islinktodir(pkgdir))) {
1.33 joerg 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);
1.1 schmonz 384: }
385: }
1.60 ! joerg 386: free(pkgdir);
1.41 joerg 387: meta = read_meta_data_from_pkgdb(pkg);
1.1 schmonz 388: }
389:
1.44 joerg 390: if (meta == NULL) {
1.43 joerg 391: warnx("invalid package `%s' skipped", pkg);
392: return 1;
393: }
394:
1.1 schmonz 395: /*
396: * Index is special info type that has to override all others to make
397: * any sense.
398: */
399: if (Flags & SHOW_INDEX) {
1.18 agc 400: char tmp[MaxPathSize];
1.1 schmonz 401:
402: (void) snprintf(tmp, sizeof(tmp), "%-19s ", pkg);
1.41 joerg 403: show_index(meta->meta_comment, tmp);
1.15 jlam 404: } else if (Flags & SHOW_BI_VAR) {
1.23 wiz 405: if (strcspn(BuildInfoVariable, "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
1.50 joerg 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: }
1.1 schmonz 415: } else {
416: package_t plist;
417:
418: /* Read the contents list */
1.41 joerg 419: parse_plist(&plist, meta->meta_contents);
1.1 schmonz 420:
421: /* Start showing the package contents */
1.28 dillo 422: if (!Quiet && !(Flags & SHOW_SUMMARY)) {
1.1 schmonz 423: printf("%sInformation for %s:\n\n", InfoPrefix, pkg);
1.41 joerg 424: if (meta->meta_preserve) {
1.5 jschauma 425: printf("*** PACKAGE MAY NOT BE DELETED ***\n");
1.8 jlam 426: }
1.1 schmonz 427: }
1.28 dillo 428: if (Flags & SHOW_SUMMARY) {
1.41 joerg 429: show_summary(meta, &plist, binpkgfile);
1.28 dillo 430: }
1.1 schmonz 431: if (Flags & SHOW_COMMENT) {
1.41 joerg 432: show_file(meta->meta_comment, "Comment:\n", TRUE);
1.1 schmonz 433: }
434: if (Flags & SHOW_DEPENDS) {
435: show_depends("Requires:\n", &plist);
436: }
1.8 jlam 437: if (Flags & SHOW_BLD_DEPENDS) {
438: show_bld_depends("Built using:\n", &plist);
439: }
1.41 joerg 440: if ((Flags & SHOW_REQBY) && meta->meta_required_by) {
441: show_file(meta->meta_required_by, "Required by:\n", TRUE);
1.1 schmonz 442: }
1.53 joerg 443: if ((Flags & SHOW_FULL_REQBY) && meta->is_installed) {
444: lpkg_head_t reqby;
445: TAILQ_INIT(&reqby);
1.57 joerg 446: build_full_reqby(&reqby, meta, 0);
1.53 joerg 447: show_list(&reqby, "Full required by list:\n");
448: }
1.1 schmonz 449: if (Flags & SHOW_DESC) {
1.41 joerg 450: show_file(meta->meta_desc, "Description:\n", TRUE);
1.1 schmonz 451: }
1.41 joerg 452: if ((Flags & SHOW_DISPLAY) && meta->meta_display) {
453: show_file(meta->meta_display, "Install notice:\n",
454: TRUE);
1.1 schmonz 455: }
456: if (Flags & SHOW_PLIST) {
457: show_plist("Packing list:\n", &plist, PLIST_SHOW_ALL);
458: }
1.41 joerg 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);
1.1 schmonz 466: }
1.41 joerg 467: if ((Flags & SHOW_MTREE) && meta->meta_mtree) {
468: show_file(meta->meta_mtree, "mtree file:\n", TRUE);
1.1 schmonz 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: }
1.41 joerg 476: if ((Flags & SHOW_BUILD_VERSION) && meta->meta_build_version) {
477: show_file(meta->meta_build_version, "Build version:\n",
478: TRUE);
1.1 schmonz 479: }
1.23 wiz 480: if (Flags & SHOW_BUILD_INFO) {
1.41 joerg 481: if (meta->meta_build_info) {
482: show_file(meta->meta_build_info, "Build information:\n",
483: TRUE);
1.23 wiz 484: }
1.41 joerg 485: if (meta->meta_installed_info) {
486: show_file(meta->meta_installed_info, "Installed information:\n",
487: TRUE);
1.23 wiz 488: }
1.1 schmonz 489: }
1.41 joerg 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);
1.1 schmonz 497: }
1.28 dillo 498: if (!Quiet && !(Flags & SHOW_SUMMARY)) {
1.41 joerg 499: if (meta->meta_preserve) {
1.5 jschauma 500: printf("*** PACKAGE MAY NOT BE DELETED ***\n\n");
501: }
1.1 schmonz 502: puts(InfoPrefix);
503: }
504: free_plist(&plist);
505: }
1.41 joerg 506: free_pkg_meta(meta);
1.1 schmonz 507: return code;
508: }
509:
1.38 joerg 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:
1.1 schmonz 529: /*
1.38 joerg 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.
1.1 schmonz 534: */
1.40 joerg 535: int
1.33 joerg 536: CheckForPkg(const char *pkgname)
1.1 schmonz 537: {
1.38 joerg 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: }
1.33 joerg 547:
1.38 joerg 548: if (arg.got_match == 0 && !ispkgpattern(pkgname)) {
1.33 joerg 549: char *pattern;
1.1 schmonz 550:
1.49 joerg 551: pattern = xasprintf("%s-[0-9]*", pkgname);
1.1 schmonz 552:
1.38 joerg 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: }
1.33 joerg 561: free(pattern);
1.1 schmonz 562: }
563:
1.38 joerg 564: if (arg.got_match)
1.39 joerg 565: return 0;
566: else
1.33 joerg 567: return 1;
1.1 schmonz 568: }
569:
1.40 joerg 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:
1.49 joerg 586: pattern = xasprintf("%s-[0-9]*", pkgname);
1.40 joerg 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:
1.36 joerg 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:
1.1 schmonz 610: int
611: pkg_perform(lpkg_head_t *pkghead)
612: {
613: int err_cnt = 0;
614:
1.26 ben 615: TAILQ_INIT(&files);
616:
1.41 joerg 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;
1.53 joerg 632: if (Flags & (SHOW_REQBY | SHOW_FULL_REQBY))
1.41 joerg 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:
1.40 joerg 645: if (Which != WHICH_LIST) {
1.1 schmonz 646: if (File2Pkg) {
647: /* Show all files with the package they belong to */
1.36 joerg 648: if (pkgdb_dump() == -1)
649: err_cnt = 1;
1.1 schmonz 650: } else {
1.36 joerg 651: if (iterate_pkg_db(perform_single_pkg, &err_cnt) == -1)
652: err_cnt = 1;
1.1 schmonz 653: }
654: } else {
655: /* Show info on individual pkg(s) */
656: lpkg_t *lpp;
657:
1.59 joerg 658: while ((lpp = TAILQ_FIRST(pkghead)) != NULL) {
1.1 schmonz 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: }
CVSweb <webmaster@jp.NetBSD.org>