Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / pkg_install / dist / delete / pkg_delete.c
blob20aa62bbd403b1d1984c5e78076ba378b2cbdfbe
1 /*-
2 * Copyright (c) 2009 Joerg Sonnenberger <joerg@NetBSD.org>.
3 * Copyright (c) 2003 Johnny Lam <jlam@NetBSD.org>.
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
27 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
30 #if HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33 #include <nbcompat.h>
34 #if HAVE_SYS_CDEFS_H
35 #include <sys/cdefs.h>
36 #endif
37 __RCSID("$NetBSD: pkg_delete.c,v 1.8 2009/08/06 16:53:34 joerg Exp $");
39 #if HAVE_ERR_H
40 #include <err.h>
41 #endif
42 #include <stdio.h>
43 #include <stdlib.h>
45 #include "lib.h"
47 static const char *pkgdb;
48 static const char *destdir;
49 static const char *prefix;
51 static int keep_preserve;
52 static int no_deinstall;
53 static int find_by_filename;
54 static int unregister_only;
55 static int pkgdb_update_only;
56 static int delete_recursive;
57 static int delete_new_leaves;
58 static int delete_automatic_leaves;
60 static void
61 usage(void)
63 fprintf(stderr, "usage: pkg_delete [-DFfkNnORrVv] [-K pkg_dbdir]"
64 " [-P destdir] [-p prefix] pkg-name ...\n");
65 exit(1);
68 static int
69 add_by_filename(lpkg_head_t *pkgs, const char *filename)
71 lpkg_t *lpp;
72 char *s;
74 if ((s = pkgdb_retrieve(filename)) == NULL) {
75 warnx("No matching package for file `%s' in pkgdb", filename);
76 return 1;
79 /* XXX Verify that pkgdb is consistent? Trust it for now... */
81 lpp = alloc_lpkg(s);
82 TAILQ_INSERT_TAIL(pkgs, lpp, lp_link);
83 return 0;
86 static int
87 add_by_pattern(lpkg_head_t *pkgs, const char *pattern)
89 switch (add_installed_pkgs_by_pattern(pattern, pkgs)) {
90 case 0:
91 warnx("No package matching `%s' found", pattern);
92 return 1;
93 case -1:
94 warnx("Error while iterating package database for `%s'",
95 pattern);
96 return 1;
97 default:
98 return 0;
103 * The argument is either a fixed package name or an absolute path.
104 * The latter is recognized for legacy compatibility and must point
105 * into the package database.
107 static int
108 add_by_pkgname(lpkg_head_t *pkgs, char *pkg)
110 char *s;
111 lpkg_t *lpp;
112 size_t l;
113 const char *orig_pkg = pkg;
115 if (pkg[0] == '/') {
116 l = strlen(pkgdb);
117 if (strncmp(pkg, pkgdb, l) || pkg[l] != '/') {
118 warnx("Absolute path is not relative to "
119 "package database, skipping: %s", pkg);
120 return 1;
122 pkg += l + 1;
124 l = strcspn(pkg, "/");
125 if (pkg[l + strspn(pkg + l, "/")] != '\0') {
126 warnx("`%s' is not a package name, skipping", orig_pkg);
127 return 1;
129 pkg[l] = '\0';
131 s = pkgdb_pkg_file(pkg, CONTENTS_FNAME);
132 if (fexists(s)) {
133 free(s);
134 lpp = alloc_lpkg(pkg);
135 TAILQ_INSERT_TAIL(pkgs, lpp, lp_link);
136 return 0;
138 free(s);
140 switch (add_installed_pkgs_by_basename(pkg, pkgs)) {
141 case 0:
142 warnx("No matching package for basename `%s' of `%s'",
143 pkg, orig_pkg);
144 return 1;
145 case -1:
146 warnx("Error expanding basename `%s' of `%s'",
147 pkg, orig_pkg);
148 return 1;
149 default:
150 return 0;
155 * Evaluate +REQUIRED_BY. This function is used for four different
156 * tasks:
157 * 0: check if no depending packages remain
158 * 1: like 0, but prepend the depending packages to pkgs if they exist
159 * 2: print remaining packages to stderr
160 * 3: check all and at least one depending packages have been removed
162 static int
163 process_required_by(const char *pkg, lpkg_head_t *pkgs,
164 lpkg_head_t *sorted_pkgs, int action)
166 char line[MaxPathSize], *eol, *fname;
167 FILE *fp;
168 lpkg_t *lpp;
169 int got_match, got_miss;
171 fname = pkgdb_pkg_file(pkg, REQUIRED_BY_FNAME);
172 if (!fexists(fname)) {
173 free(fname);
174 return 0;
177 if ((fp = fopen(fname, "r")) == NULL) {
178 warn("Failed to open `%s'", fname);
179 free(fname);
180 return -1;
182 free(fname);
184 got_match = 0;
185 got_miss = 0;
187 while (fgets(line, sizeof(line), fp)) {
188 if ((eol = strrchr(line, '\n')) != NULL)
189 *eol = '\0';
190 TAILQ_FOREACH(lpp, sorted_pkgs, lp_link) {
191 if (strcmp(lpp->lp_name, line) == 0)
192 break;
194 if (lpp != NULL) {
195 got_match = 1;
196 continue;
198 got_miss = 1;
199 if (pkgs) {
200 TAILQ_FOREACH(lpp, pkgs, lp_link) {
201 if (strcmp(lpp->lp_name, line) == 0)
202 break;
204 if (lpp != NULL)
205 continue;
207 switch (action) {
208 case 0:
209 fclose(fp);
210 return 1;
211 case 1:
212 lpp = alloc_lpkg(line);
213 TAILQ_INSERT_HEAD(pkgs, lpp, lp_link);
214 break;
215 case 2:
216 fprintf(stderr, "\t%s\n", line);
217 break;
218 case 3:
219 fclose(fp);
220 return 0;
224 fclose(fp);
226 return (action == 3 ? got_match : got_miss);
230 * Main function to order the patterns from the command line and
231 * add the subtrees for -r processing as needed.
233 * The first part ensures that all packages are listed at most once
234 * in pkgs. Afterwards the list is scanned for packages without depending
235 * packages. Each such package is moved to sorted_pkgs in order.
236 * If -r is given, all dependencies are inserted at the head of pkgs.
237 * The loop has to continue as long as progress is made. This can happen
238 * either because another package has been added to pkgs due to recursion
239 * (head of pkgs changed) or because a package has no more depending packages
240 * (tail of sorted_pkgs changed).
242 * If no progress is made, the remaining packages are moved to sorted_pkgs
243 * and an error is returned for the !Force case.
245 static int
246 sort_and_recurse(lpkg_head_t *pkgs, lpkg_head_t *sorted_pkgs)
248 lpkg_t *lpp, *lpp2, *lpp_next, *lpp_old_tail, *lpp_old_head;
249 int rv;
251 TAILQ_FOREACH_SAFE(lpp, pkgs, lp_link, lpp_next) {
252 TAILQ_FOREACH(lpp2, pkgs, lp_link) {
253 if (lpp != lpp2 &&
254 strcmp(lpp->lp_name, lpp2->lp_name) == 0)
255 break;
257 if (lpp2 == NULL)
258 continue;
259 TAILQ_REMOVE(pkgs, lpp, lp_link);
260 free_lpkg(lpp);
263 while (!TAILQ_EMPTY(pkgs)) {
264 lpp_old_tail = TAILQ_LAST(sorted_pkgs, _lpkg_head_t);
265 lpp_old_head = TAILQ_FIRST(pkgs);
267 TAILQ_FOREACH_SAFE(lpp, pkgs, lp_link, lpp_next) {
268 rv = process_required_by(lpp->lp_name, pkgs,
269 sorted_pkgs, delete_recursive ? 1 : 0);
270 if (rv)
271 continue;
272 TAILQ_REMOVE(pkgs, lpp, lp_link);
273 TAILQ_INSERT_TAIL(sorted_pkgs, lpp, lp_link);
276 if (lpp_old_tail == TAILQ_LAST(sorted_pkgs, _lpkg_head_t) &&
277 lpp_old_head == TAILQ_FIRST(pkgs))
278 break;
281 if (TAILQ_EMPTY(pkgs))
282 return 0;
284 while (!TAILQ_EMPTY(pkgs)) {
285 lpp = TAILQ_FIRST(pkgs);
286 TAILQ_REMOVE(pkgs, lpp, lp_link);
287 fprintf(stderr,
288 "Package `%s' is still required by other packages:\n",
289 lpp->lp_name);
290 process_required_by(lpp->lp_name, NULL, sorted_pkgs, 2);
291 if (Force) {
292 TAILQ_INSERT_TAIL(sorted_pkgs, lpp, lp_link);
293 } else
294 free_lpkg(lpp);
297 return !Force;
300 struct find_leaves_data {
301 lpkg_head_t *pkgs;
302 int progress;
306 * Iterator for finding leaf packages.
307 * Packages that are marked as not for deletion are not considered as
308 * leaves. For all other packages it is checked if at least one package
309 * that depended on them is to be removed AND no depending package remains.
310 * If that is the case, the package is appened to the sorted list.
311 * As this package can't have depending packages left, the topological order
312 * remains consistent.
314 static int
315 find_new_leaves_iter(const char *pkg, void *cookie)
317 char *fname;
318 struct find_leaves_data *data = cookie;
319 lpkg_t *lpp;
321 fname = pkgdb_pkg_file(pkg, PRESERVE_FNAME);
322 if (fexists(fname)) {
323 free(fname);
324 return 0;
326 free(fname);
328 if (delete_automatic_leaves && !delete_new_leaves &&
329 !is_automatic_installed(pkg))
330 return 0;
332 /* Check whether this package is already on the list first. */
333 TAILQ_FOREACH(lpp, data->pkgs, lp_link) {
334 if (strcmp(lpp->lp_name, pkg) == 0)
335 return 0;
338 if (process_required_by(pkg, NULL, data->pkgs, 3) == 1) {
339 lpp = alloc_lpkg(pkg);
340 TAILQ_INSERT_TAIL(data->pkgs, lpp, lp_link);
341 data->progress = 0;
344 return 0;
348 * Iterate over all installed packages and look for new leaf packages.
349 * As long as the loop adds one new leaf package, processing continues.
351 static void
352 find_new_leaves(lpkg_head_t *pkgs)
354 struct find_leaves_data data;
356 data.pkgs = pkgs;
357 do {
358 data.progress = 0;
359 iterate_pkg_db(find_new_leaves_iter, &data);
360 } while (data.progress);
364 * Check that no entry on the package list is marked as not for deletion.
366 static int
367 find_preserve_pkgs(lpkg_head_t *pkgs)
369 lpkg_t *lpp, *lpp_next;
370 char *fname;
371 int found_preserve;
373 found_preserve = 0;
374 TAILQ_FOREACH_SAFE(lpp, pkgs, lp_link, lpp_next) {
375 fname = pkgdb_pkg_file(lpp->lp_name, PRESERVE_FNAME);
376 if (!fexists(fname)) {
377 free(fname);
378 continue;
380 free(fname);
381 if (keep_preserve) {
382 TAILQ_REMOVE(pkgs, lpp, lp_link);
383 free_lpkg(lpp);
384 continue;
386 if (!found_preserve)
387 warnx("The following packages are marked as not "
388 "for deletion:");
389 found_preserve = 1;
390 fprintf(stderr, "\t%s\n", lpp->lp_name);
392 if (!found_preserve)
393 return 0;
394 if (Force == 0 || (!unregister_only && Force == 1))
395 return 1;
396 fprintf(stderr, "...but will delete them anyway\n");
397 return 0;
401 * Remove package from view. This is calling pkg_deinstall again.
403 static int
404 remove_pkg_from_view(const char *pkg)
406 char line[MaxPathSize], *fname, *eol;
407 FILE *fp;
409 fname = pkgdb_pkg_file(pkg, VIEWS_FNAME);
410 if (isemptyfile(fname)) {
411 free(fname);
412 return 0;
414 if ((fp = fopen(fname, "r")) == NULL) {
415 warn("Unable to open `%s', aborting", fname);
416 free(fname);
417 return 1;
419 free(fname);
420 while (fgets(line, sizeof(line), fp) != NULL) {
421 if ((eol = strrchr(line, '\n')) != NULL)
422 *eol = '\0';
423 if (Verbose || Fake)
424 printf("Deleting package `%s' instance from `%s' view\n",
425 pkg, line);
426 if (Fake)
427 continue;
428 if (fexec_skipempty(BINDIR "/pkg_delete", "-K", line,
429 Fake ? "-n" : "",
430 (Force > 1) ? "-f" : "",
431 (Force > 0) ? "-f" : "",
432 pkg, NULL) != 0) {
433 warnx("Unable to delete package `%s' from view `%s'",
434 pkg, line);
435 fclose(fp);
436 return 1;
439 fclose(fp);
440 return 0;
444 * Run the +DEINSTALL script. Depending on whether this is
445 * a depoted package and whether this pre- or post-deinstall phase,
446 * different arguments are passed down.
448 static int
449 run_deinstall_script(const char *pkg, int do_postdeinstall)
451 const char *target, *text;
452 char *fname, *fname2, *pkgdir;
453 int rv;
455 fname = pkgdb_pkg_file(pkg, DEINSTALL_FNAME);
456 if (!fexists(fname)) {
457 free(fname);
458 return 0;
461 fname2 = pkgdb_pkg_file(pkg, DEPOT_FNAME);
462 if (fexists(fname2)) {
463 if (do_postdeinstall) {
464 free(fname);
465 free(fname2);
466 return 0;
468 target = "VIEW-DEINSTALL";
469 text = "view deinstall";
470 } else if (do_postdeinstall) {
471 target = "POST-DEINSTALL";
472 text = "post-deinstall";
473 } else {
474 target = "DEINSTALL";
475 text = "deinstall";
477 free(fname2);
479 if (Fake) {
480 printf("Would execute %s script with argument %s now\n",
481 text, target);
482 free(fname);
483 return 0;
486 pkgdir = xasprintf("%s/%s", _pkgdb_getPKGDB_DIR(), pkg);
487 if (chmod(fname, 0555))
488 warn("chmod of `%s' failed", fname);
489 rv = fcexec(pkgdir, fname, pkg, target, NULL);
490 if (rv)
491 warnx("%s script returned error status", text);
492 free(pkgdir);
493 free(fname);
494 return rv;
498 * Copy lines from fname to fname_tmp, filtering out lines equal to text.
499 * Afterwards rename fname_tmp to fname;
501 static int
502 remove_line(const char *fname, const char *fname_tmp, const char *text)
504 FILE *fp, *fp_out;
505 char line[MaxPathSize], *eol;
506 int rv;
508 if ((fp = fopen(fname, "r")) == NULL) {
509 warn("Unable to open `%s'", fname);
510 return 1;
512 if ((fp_out = fopen(fname_tmp, "w")) == NULL) {
513 warn("Unable to open `%s'", fname_tmp);
514 fclose(fp);
515 return 1;
518 while (fgets(line, sizeof(line), fp) != NULL) {
519 if ((eol = strrchr(line, '\n')) != NULL)
520 *eol = '\0';
521 if (strcmp(line, text) == 0)
522 continue;
523 fprintf(fp_out, "%s\n", line);
525 fclose(fp);
527 if (fclose(fp_out) == EOF) {
528 remove(fname_tmp);
529 warnx("Failure while closing `%s' temp file", fname_tmp);
530 return 1;
533 if (rename(fname_tmp, fname) == -1) {
534 warn("Unable to rename `%s' to `%s'", fname_tmp, fname);
535 rv = 1;
536 } else
537 rv = 0;
538 remove(fname_tmp);
540 return rv;
544 * Unregister the package from the depot it is registered in.
546 static int
547 remove_pkg_from_depot(const char *pkg)
549 FILE *fp;
550 char line[MaxPathSize], *eol;
551 char *fname, *fname2;
552 int rv;
554 fname = pkgdb_pkg_file(pkg, DEPOT_FNAME);
555 if (isemptyfile(fname)) {
556 free(fname);
557 return 0;
560 if (Verbose)
561 printf("Attempting to remove the `%s' registration "
562 "on package `%s'\n", fname, pkg);
564 if (Fake) {
565 free(fname);
566 return 1;
569 if ((fp = fopen(fname, "r")) == NULL) {
570 warn("Unable to open `%s' file", fname);
571 free(fname);
572 return 1;
574 if (fgets(line, sizeof(line), fp) == NULL) {
575 fclose(fp);
576 warnx("Empty depot file `%s'", fname);
577 free(fname);
578 return 1;
580 if ((eol = strrchr(line, '\n')) != NULL)
581 *eol = '\0';
582 fclose(fp);
583 free(fname);
585 fname = pkgdb_pkg_file(pkg, VIEWS_FNAME);
586 fname2 = pkgdb_pkg_file(pkg, VIEWS_FNAME_TMP);
587 rv = remove_line(fname, fname2, line);
588 free(fname2);
589 free(fname);
591 return rv;
595 * remove_depend is used as iterator function below.
596 * The passed-in package name should be removed from the
597 * +REQUIRED_BY list of the dependency. Such an entry
598 * can miss in a fully correct package database, if the pattern
599 * matches more than one package.
601 static int
602 remove_depend(const char *cur_pkg, void *cookie)
604 const char *pkg = cookie;
605 char *fname, *fname2;
606 int rv;
608 fname = pkgdb_pkg_file(cur_pkg, REQUIRED_BY_FNAME);
609 if (isemptyfile(fname)) {
610 free(fname);
611 return 0;
613 fname2 = pkgdb_pkg_file(cur_pkg, REQUIRED_BY_FNAME_TMP);
615 rv = remove_line(fname, fname2, pkg);
617 free(fname2);
618 free(fname);
620 return rv;
623 static int
624 remove_pkg(const char *pkg)
626 FILE *fp;
627 char *fname, *pkgdir;
628 package_t plist;
629 plist_t *p;
630 int is_depoted_pkg, rv, late_error;
632 if (pkgdb_update_only)
633 return pkgdb_remove_pkg(pkg) ? 0 : 1;
635 fname = pkgdb_pkg_file(pkg, CONTENTS_FNAME);
636 if (!fexists(fname)) {
637 warnx("package `%s' is not installed, `%s' missing", pkg, fname);
638 free(fname);
639 return 1;
641 free(fname);
643 /* +REQUIRED_BY and +PRESERVE already checked */
644 if (remove_pkg_from_view(pkg))
645 return 1;
648 * The views related code has bad error handling, if e.g.
649 * the deinstall script fails, the package remains unregistered.
652 fname = pkgdb_pkg_file(pkg, CONTENTS_FNAME);
653 if ((fp = fopen(fname, "r")) == NULL) {
654 warnx("Failed to open `%s'", fname);
655 free(fname);
656 return 1;
658 read_plist(&plist, fp);
659 fclose(fp);
662 * If a prefix has been provided, remove the first @cwd and
663 * prepend that prefix. This allows removing packages without
664 * @cwd if really necessary. pkg_admin rebuild is likely needed
665 * afterwards though.
667 if (prefix) {
668 delete_plist(&plist, FALSE, PLIST_CWD, NULL);
669 add_plist_top(&plist, PLIST_CWD, prefix);
671 if ((p = find_plist(&plist, PLIST_CWD)) == NULL) {
672 warnx("Package `%s' doesn't have a prefix", pkg);
673 return 1;
676 if (find_plist(&plist, PLIST_NAME) == NULL) {
677 /* Cheat a bit to allow removal of such bad packages. */
678 warnx("Package `%s' doesn't have a name", pkg);
679 add_plist_top(&plist, PLIST_NAME, pkg);
682 setenv(PKG_PREFIX_VNAME, p->name, 1);
683 fname = xasprintf("%s/%s", _pkgdb_getPKGDB_DIR(), pkg);
684 setenv(PKG_METADATA_DIR_VNAME, fname, 1);
685 free(fname);
687 if (!no_deinstall && !unregister_only) {
688 if (run_deinstall_script(pkg, 0) && !Force)
689 return 1;
692 late_error = 0;
694 if (Fake)
695 printf("Attempting to delete package `%s'\n", pkg);
696 else if (delete_package(FALSE, &plist, unregister_only,
697 destdir) == FAIL) {
698 warnx("couldn't entirely delete package `%s'", pkg);
700 * XXX It could be nice to error out here explicitly,
701 * XXX but this is problematic for missing or changed files.
702 * XXX At least the inability to remove files at all should
703 * XXX be handled though.
708 * Past the point of no return. Files are gone, all that is left
709 * is cleaning up registered dependencies and removing the meta data.
710 * Errors in the remaining part are counted, but don't stop the
711 * processing.
714 fname = pkgdb_pkg_file(pkg, DEPOT_FNAME);
715 if (fexists(fname)) {
716 late_error |= remove_pkg_from_depot(pkg);
717 /* XXX error checking */
718 } else {
719 for (p = plist.head; p; p = p->next) {
720 if (p->type != PLIST_PKGDEP)
721 continue;
722 if (Verbose)
723 printf("Attempting to remove dependency "
724 "on package `%s'\n", p->name);
725 if (Fake)
726 continue;
727 match_installed_pkgs(p->name, remove_depend,
728 __UNCONST(pkg));
731 free(fname);
733 free_plist(&plist);
735 if (!no_deinstall && !unregister_only)
736 late_error |= run_deinstall_script(pkg, 1);
738 fname = pkgdb_pkg_file(pkg, VIEWS_FNAME);
739 if (fexists(fname))
740 is_depoted_pkg = TRUE;
741 else
742 is_depoted_pkg = FALSE;
743 free(fname);
745 if (Fake)
746 return 0;
749 * Kill the pkgdb subdirectory. The files have been removed, so
750 * this is way beyond the point of no return.
752 pkgdir = xasprintf("%s/%s", _pkgdb_getPKGDB_DIR(), pkg);
753 (void) remove_files(pkgdir, "+*");
754 rv = 1;
755 if (isemptydir(pkgdir)&& rmdir(pkgdir) == 0)
756 rv = 0;
757 else if (is_depoted_pkg)
758 warnx("Depot directory `%s' is not empty", pkgdir);
759 else if (!Force)
760 warnx("Couldn't remove package directory in `%s'", pkgdir);
761 else if (recursive_remove(pkgdir, 1))
762 warn("Couldn't remove package directory `%s'", pkgdir);
763 else
764 warnx("Package directory `%s' forcefully removed", pkgdir);
765 free(pkgdir);
767 return rv | late_error;
771 main(int argc, char *argv[])
773 lpkg_head_t pkgs, sorted_pkgs;
774 int ch, r, has_error;
775 unsigned long bad_count;
777 TAILQ_INIT(&pkgs);
778 TAILQ_INIT(&sorted_pkgs);
780 setprogname(argv[0]);
781 while ((ch = getopt(argc, argv, "ADFfK:kNnOP:p:RrVv")) != -1) {
782 switch (ch) {
783 case 'A':
784 delete_automatic_leaves = 1;
785 break;
786 case 'D':
787 no_deinstall = 1;
788 break;
789 case 'F':
790 find_by_filename = 1;
791 break;
792 case 'f':
793 ++Force;
794 break;
795 case 'K':
796 pkgdb = optarg;
797 break;
798 case 'k':
799 keep_preserve = 1;
800 break;
801 case 'N':
802 unregister_only = 1;
803 break;
804 case 'n':
805 Fake = 1;
806 break;
807 case 'O':
808 pkgdb_update_only = 1;
809 break;
810 case 'P':
811 destdir = optarg;
812 break;
813 case 'p':
814 prefix = optarg;
815 break;
816 case 'R':
817 delete_new_leaves = 1;
818 break;
819 case 'r':
820 delete_recursive = 1;
821 break;
822 case 'V':
823 show_version();
824 /* NOTREACHED */
825 case 'v':
826 ++Verbose;
827 break;
828 default:
829 usage();
830 break;
834 if (destdir != NULL) {
835 char *pkgdbdir;
837 if (pkgdb == NULL)
838 pkgdb = _pkgdb_getPKGDB_DIR();
840 pkgdbdir = xasprintf("%s/%s", destdir, pkgdb);
841 _pkgdb_setPKGDB_DIR(pkgdbdir);
842 free(pkgdbdir);
843 } else if (pkgdb != NULL) {
844 _pkgdb_setPKGDB_DIR(pkgdb);
845 } else {
846 pkgdb = _pkgdb_getPKGDB_DIR();
849 argc -= optind;
850 argv += optind;
852 if (argc == 0) {
853 if (find_by_filename)
854 warnx("Missing filename(s)");
855 else
856 warnx("Missing package name(s)");
857 usage();
860 if (Fake)
861 r = pkgdb_open(ReadOnly);
862 else
863 r = pkgdb_open(ReadWrite);
865 if (!r)
866 errx(EXIT_FAILURE, "Opening pkgdb failed");
868 /* First, process all command line options. */
870 has_error = 0;
871 for (; argc != 0; --argc, ++argv) {
872 if (find_by_filename)
873 has_error |= add_by_filename(&pkgs, *argv);
874 else if (ispkgpattern(*argv))
875 has_error |= add_by_pattern(&pkgs, *argv);
876 else
877 has_error |= add_by_pkgname(&pkgs, *argv);
880 if (has_error && !Force) {
881 pkgdb_close();
882 return EXIT_FAILURE;
885 /* Second, reorder and recursive if necessary. */
887 if (sort_and_recurse(&pkgs, &sorted_pkgs)) {
888 pkgdb_close();
889 return EXIT_FAILURE;
892 /* Third, add leaves if necessary. */
894 if (delete_new_leaves || delete_automatic_leaves)
895 find_new_leaves(&sorted_pkgs);
898 * Now that all packages to remove are known, check
899 * if all are removable. After that, start the actual
900 * removal.
903 if (find_preserve_pkgs(&sorted_pkgs)) {
904 pkgdb_close();
905 return EXIT_FAILURE;
908 setenv(PKG_REFCOUNT_DBDIR_VNAME, pkgdb_refcount_dir(), 1);
910 bad_count = 0;
911 while (!TAILQ_EMPTY(&sorted_pkgs)) {
912 lpkg_t *lpp;
914 lpp = TAILQ_FIRST(&sorted_pkgs);
915 TAILQ_REMOVE(&sorted_pkgs, lpp, lp_link);
916 if (remove_pkg(lpp->lp_name)) {
917 ++bad_count;
918 if (!Force)
919 break;
921 free_lpkg(lpp);
924 pkgdb_close();
926 if (Force && bad_count && Verbose)
927 warnx("Removal of %lu packages failed", bad_count);
929 return bad_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS;