xref: /netbsd-src/external/bsd/pkg_install/dist/delete/pkg_delete.c (revision 9ddb6ab554e70fb9bbd90c3d96b812bc57755a14)
1 /*-
2  * Copyright (c) 2009 Joerg Sonnenberger <joerg@NetBSD.org>.
3  * Copyright (c) 2003 Johnny Lam <jlam@NetBSD.org>.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
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.
16  *
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.
29  */
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.1.1.8 2012/02/19 17:46:46 tron Exp $");
38 
39 #if HAVE_ERR_H
40 #include <err.h>
41 #endif
42 #include <stdio.h>
43 #include <stdlib.h>
44 
45 #include "lib.h"
46 
47 static const char *pkgdb;
48 static const char *destdir;
49 static const char *prefix;
50 
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;
59 
60 static void
61 usage(void)
62 {
63 	fprintf(stderr, "usage: pkg_delete [-DFfkNnORrVv] [-K pkg_dbdir]"
64 	    " [-P destdir] [-p prefix] pkg-name ...\n");
65 	exit(1);
66 }
67 
68 static int
69 add_by_filename(lpkg_head_t *pkgs, const char *filename)
70 {
71 	lpkg_t *lpp;
72 	char *s;
73 
74 	if ((s = pkgdb_retrieve(filename)) == NULL) {
75 		warnx("No matching package for file `%s' in pkgdb", filename);
76 		return 1;
77 	}
78 
79 	/* XXX Verify that pkgdb is consistent? Trust it for now... */
80 
81 	lpp = alloc_lpkg(s);
82 	TAILQ_INSERT_TAIL(pkgs, lpp, lp_link);
83 	return 0;
84 }
85 
86 static int
87 add_by_pattern(lpkg_head_t *pkgs, const char *pattern)
88 {
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;
99 	}
100 }
101 
102 /*
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.
106  */
107 static int
108 add_by_pkgname(lpkg_head_t *pkgs, char *pkg)
109 {
110 	char *s;
111 	lpkg_t *lpp;
112 	size_t l;
113 	const char *orig_pkg = pkg;
114 
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;
121 		}
122 		pkg += l + 1;
123 	}
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;
128 	}
129 	pkg[l] = '\0';
130 
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;
137 	}
138 	free(s);
139 
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;
151 	}
152 }
153 
154 /*
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
161  */
162 static int
163 process_required_by(const char *pkg, lpkg_head_t *pkgs,
164     lpkg_head_t *sorted_pkgs, int action)
165 {
166 	char line[MaxPathSize], *eol, *fname;
167 	FILE *fp;
168 	lpkg_t *lpp;
169 	int got_match, got_miss;
170 
171 	fname = pkgdb_pkg_file(pkg, REQUIRED_BY_FNAME);
172 	if (!fexists(fname)) {
173 		free(fname);
174 		return 0;
175 	}
176 
177 	if ((fp = fopen(fname, "r")) == NULL) {
178 		warn("Failed to open `%s'", fname);
179 		free(fname);
180 		return -1;
181 	}
182 	free(fname);
183 
184 	got_match = 0;
185 	got_miss = 0;
186 
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;
193 		}
194 		if (lpp != NULL) {
195 			got_match = 1;
196 			continue;
197 		}
198 		got_miss = 1;
199 		if (pkgs) {
200 			TAILQ_FOREACH(lpp, pkgs, lp_link) {
201 				if (strcmp(lpp->lp_name, line) == 0)
202 					break;
203 			}
204 			if (lpp != NULL)
205 				continue;
206 		}
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;
221 		}
222 	}
223 
224 	fclose(fp);
225 
226 	return (action == 3 ? got_match : got_miss);
227 }
228 
229 /*
230  * Main function to order the patterns from the command line and
231  * add the subtrees for -r processing as needed.
232  *
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).
241  *
242  * If no progress is made, the remaining packages are moved to sorted_pkgs
243  * and an error is returned for the !Force case.
244  */
245 static int
246 sort_and_recurse(lpkg_head_t *pkgs, lpkg_head_t *sorted_pkgs)
247 {
248 	lpkg_t *lpp, *lpp2, *lpp_next, *lpp_old_tail, *lpp_old_head;
249 	int rv;
250 
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;
256 		}
257 		if (lpp2 == NULL)
258 			continue;
259 		TAILQ_REMOVE(pkgs, lpp, lp_link);
260 		free_lpkg(lpp);
261 	}
262 
263 	while (!TAILQ_EMPTY(pkgs)) {
264 		lpp_old_tail = TAILQ_LAST(sorted_pkgs, _lpkg_head_t);
265 		lpp_old_head = TAILQ_FIRST(pkgs);
266 
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);
274 		}
275 
276 		if (lpp_old_tail == TAILQ_LAST(sorted_pkgs, _lpkg_head_t) &&
277 		    lpp_old_head == TAILQ_FIRST(pkgs))
278 			break;
279 	}
280 
281 	if (TAILQ_EMPTY(pkgs))
282 		return 0;
283 
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);
295 	}
296 
297 	return !Force;
298 }
299 
300 struct find_leaves_data {
301 	lpkg_head_t *pkgs;
302 	int progress;
303 };
304 
305 /*
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 appended to the sorted list.
311  * As this package can't have depending packages left, the topological order
312  * remains consistent.
313  */
314 static int
315 find_new_leaves_iter(const char *pkg, void *cookie)
316 {
317 	char *fname;
318 	struct find_leaves_data *data = cookie;
319 	lpkg_t *lpp;
320 
321 	fname = pkgdb_pkg_file(pkg, PRESERVE_FNAME);
322 	if (fexists(fname)) {
323 		free(fname);
324 		return 0;
325 	}
326 	free(fname);
327 
328 	if (delete_automatic_leaves && !delete_new_leaves &&
329 	    !is_automatic_installed(pkg))
330 		return 0;
331 
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;
336 	}
337 
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 = 1;
342 	}
343 
344 	return 0;
345 }
346 
347 /*
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.
350  */
351 static void
352 find_new_leaves(lpkg_head_t *pkgs)
353 {
354 	struct find_leaves_data data;
355 
356 	data.pkgs = pkgs;
357 	do {
358 		data.progress = 0;
359 		iterate_pkg_db(find_new_leaves_iter, &data);
360 	} while (data.progress);
361 }
362 
363 /*
364  * Check that no entry on the package list is marked as not for deletion.
365  */
366 static int
367 find_preserve_pkgs(lpkg_head_t *pkgs)
368 {
369 	lpkg_t *lpp, *lpp_next;
370 	char *fname;
371 	int found_preserve;
372 
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;
379 		}
380 		free(fname);
381 		if (keep_preserve) {
382 			TAILQ_REMOVE(pkgs, lpp, lp_link);
383 			free_lpkg(lpp);
384 			continue;
385 		}
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);
391 	}
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;
398 }
399 
400 /*
401  * Remove package from view.  This is calling pkg_deinstall again.
402  */
403 static int
404 remove_pkg_from_view(const char *pkg)
405 {
406 	char line[MaxPathSize], *fname, *eol;
407 	FILE *fp;
408 
409 	fname = pkgdb_pkg_file(pkg, VIEWS_FNAME);
410 	if (isemptyfile(fname)) {
411 		free(fname);
412 		return 0;
413 	}
414 	if ((fp = fopen(fname, "r")) == NULL) {
415 		warn("Unable to open `%s', aborting", fname);
416 		free(fname);
417 		return 1;
418 	}
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;
437 		}
438 	}
439 	fclose(fp);
440 	return 0;
441 }
442 
443 /*
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.
447  */
448 static int
449 run_deinstall_script(const char *pkg, int do_postdeinstall)
450 {
451 	const char *target, *text;
452 	char *fname, *fname2, *pkgdir;
453 	int rv;
454 
455 	fname = pkgdb_pkg_file(pkg, DEINSTALL_FNAME);
456 	if (!fexists(fname)) {
457 		free(fname);
458 		return 0;
459 	}
460 
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;
467 		}
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";
476 	}
477 	free(fname2);
478 
479 	if (Fake) {
480 		printf("Would execute %s script with argument %s now\n",
481 		    text, target);
482 		free(fname);
483 		return 0;
484 	}
485 
486 	pkgdir = pkgdb_pkg_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;
495 }
496 
497 /*
498  * Copy lines from fname to fname_tmp, filtering out lines equal to text.
499  * Afterwards rename fname_tmp to fname;
500  */
501 static int
502 remove_line(const char *fname, const char *fname_tmp, const char *text)
503 {
504 	FILE *fp, *fp_out;
505 	char line[MaxPathSize], *eol;
506 	int rv;
507 
508 	if ((fp = fopen(fname, "r")) == NULL) {
509 		warn("Unable to open `%s'", fname);
510 		return 1;
511 	}
512 	if ((fp_out = fopen(fname_tmp, "w")) == NULL) {
513 		warn("Unable to open `%s'", fname_tmp);
514 		fclose(fp);
515 		return 1;
516 	}
517 
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);
524 	}
525 	fclose(fp);
526 
527 	if (fclose(fp_out) == EOF) {
528 		remove(fname_tmp);
529 		warnx("Failure while closing `%s' temp file", fname_tmp);
530 		return 1;
531 	}
532 
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);
539 
540 	return rv;
541 }
542 
543 /*
544  * Unregister the package from the depot it is registered in.
545  */
546 static int
547 remove_pkg_from_depot(const char *pkg)
548 {
549 	FILE *fp;
550 	char line[MaxPathSize], *eol;
551 	char *fname, *fname2;
552 	int rv;
553 
554 	fname = pkgdb_pkg_file(pkg, DEPOT_FNAME);
555 	if (isemptyfile(fname)) {
556 		free(fname);
557 		return 0;
558 	}
559 
560 	if (Verbose)
561 		printf("Attempting to remove the `%s' registration "
562 		    "on package `%s'\n", fname, pkg);
563 
564 	if (Fake) {
565 		free(fname);
566 		return 1;
567 	}
568 
569 	if ((fp = fopen(fname, "r")) == NULL) {
570 		warn("Unable to open `%s' file", fname);
571 		free(fname);
572 		return 1;
573 	}
574 	if (fgets(line, sizeof(line), fp) == NULL) {
575 		fclose(fp);
576 		warnx("Empty depot file `%s'", fname);
577 		free(fname);
578 		return 1;
579 	}
580 	if ((eol = strrchr(line, '\n')) != NULL)
581 		*eol = '\0';
582 	fclose(fp);
583 	free(fname);
584 
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);
590 
591 	return rv;
592 }
593 
594 /*
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.
600  */
601 static int
602 remove_depend(const char *cur_pkg, void *cookie)
603 {
604 	const char *pkg = cookie;
605 	char *fname, *fname2;
606 	int rv;
607 
608 	fname = pkgdb_pkg_file(cur_pkg, REQUIRED_BY_FNAME);
609 	if (isemptyfile(fname)) {
610 		free(fname);
611 		return 0;
612 	}
613 	fname2 = pkgdb_pkg_file(cur_pkg, REQUIRED_BY_FNAME_TMP);
614 
615 	rv = remove_line(fname, fname2, pkg);
616 
617 	free(fname2);
618 	free(fname);
619 
620 	return rv;
621 }
622 
623 static int
624 remove_pkg(const char *pkg)
625 {
626 	FILE *fp;
627 	char *fname, *pkgdir;
628 	package_t plist;
629 	plist_t *p;
630 	int is_depoted_pkg, rv, late_error;
631 
632 	if (pkgdb_update_only)
633 		return pkgdb_remove_pkg(pkg) ? 0 : 1;
634 
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;
640 	}
641 	free(fname);
642 
643 	/* +REQUIRED_BY and +PRESERVE already checked */
644 	if (remove_pkg_from_view(pkg))
645 		return 1;
646 
647 	/*
648 	 * The views related code has bad error handling, if e.g.
649 	 * the deinstall script fails, the package remains unregistered.
650 	 */
651 
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;
657 	}
658 	read_plist(&plist, fp);
659 	fclose(fp);
660 
661 	/*
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.
666 	 */
667 	if (prefix) {
668 		delete_plist(&plist, FALSE, PLIST_CWD, NULL);
669 		add_plist_top(&plist, PLIST_CWD, prefix);
670 	}
671 	if ((p = find_plist(&plist, PLIST_CWD)) == NULL) {
672 		warnx("Package `%s' doesn't have a prefix", pkg);
673 		return 1;
674 	}
675 
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);
680 	}
681 
682 	setenv(PKG_REFCOUNT_DBDIR_VNAME, config_pkg_refcount_dbdir, 1);
683 	fname = pkgdb_pkg_dir(pkg);
684 	setenv(PKG_METADATA_DIR_VNAME, fname, 1);
685 	free(fname);
686 	setenv(PKG_PREFIX_VNAME, p->name, 1);
687 
688 	if (!no_deinstall && !unregister_only) {
689 		if (run_deinstall_script(pkg, 0) && !Force)
690 			return 1;
691 	}
692 
693 	late_error = 0;
694 
695 	if (Fake)
696 		printf("Attempting to delete package `%s'\n", pkg);
697 	else if (delete_package(FALSE, &plist, unregister_only,
698 			        destdir) == FAIL) {
699 		warnx("couldn't entirely delete package `%s'", pkg);
700 		/*
701 		 * XXX It could be nice to error out here explicitly,
702 		 * XXX but this is problematic for missing or changed files.
703 		 * XXX At least the inability to remove files at all should
704 		 * XXX be handled though.
705 		 */
706 	}
707 
708 	/*
709 	 * Past the point of no return. Files are gone, all that is left
710 	 * is cleaning up registered dependencies and removing the meta data.
711 	 * Errors in the remaining part are counted, but don't stop the
712 	 * processing.
713 	 */
714 
715 	fname = pkgdb_pkg_file(pkg, DEPOT_FNAME);
716 	if (fexists(fname)) {
717 		late_error |= remove_pkg_from_depot(pkg);
718 		/* XXX error checking */
719 	} else {
720 		for (p = plist.head; p; p = p->next) {
721 			if (p->type != PLIST_PKGDEP)
722 				continue;
723 			if (Verbose)
724 				printf("Attempting to remove dependency "
725 				    "on package `%s'\n", p->name);
726 			if (Fake)
727 				continue;
728 			match_installed_pkgs(p->name, remove_depend,
729 			    __UNCONST(pkg));
730 		}
731 	}
732 	free(fname);
733 
734 	free_plist(&plist);
735 
736 	if (!no_deinstall && !unregister_only)
737 		late_error |= run_deinstall_script(pkg, 1);
738 
739 	fname = pkgdb_pkg_file(pkg, VIEWS_FNAME);
740 	if (fexists(fname))
741 		is_depoted_pkg = TRUE;
742 	else
743 		is_depoted_pkg = FALSE;
744 	free(fname);
745 
746 	if (Fake)
747 		return 0;
748 
749 	/*
750 	 * Kill the pkgdb subdirectory. The files have been removed, so
751 	 * this is way beyond the point of no return.
752 	 */
753 	pkgdir = pkgdb_pkg_dir(pkg);
754 	(void) remove_files(pkgdir, "+*");
755 	rv = 1;
756 	if (isemptydir(pkgdir)&& rmdir(pkgdir) == 0)
757 		rv = 0;
758 	else if (is_depoted_pkg)
759 		warnx("Depot directory `%s' is not empty", pkgdir);
760 	else if (!Force)
761 		warnx("Couldn't remove package directory in `%s'", pkgdir);
762 	else if (recursive_remove(pkgdir, 1))
763 		warn("Couldn't remove package directory `%s'", pkgdir);
764 	else
765 		warnx("Package directory `%s' forcefully removed", pkgdir);
766 	free(pkgdir);
767 
768 	return rv | late_error;
769 }
770 
771 int
772 main(int argc, char *argv[])
773 {
774 	lpkg_head_t pkgs, sorted_pkgs;
775 	int ch, r, has_error;
776 	unsigned long bad_count;
777 
778 	TAILQ_INIT(&pkgs);
779 	TAILQ_INIT(&sorted_pkgs);
780 
781 	setprogname(argv[0]);
782 	while ((ch = getopt(argc, argv, "ADFfK:kNnOP:p:RrVv")) != -1) {
783 		switch (ch) {
784 		case 'A':
785 			delete_automatic_leaves = 1;
786 			break;
787 		case 'D':
788 			no_deinstall = 1;
789 			break;
790 		case 'F':
791 			find_by_filename = 1;
792 			break;
793 		case 'f':
794 			++Force;
795 			break;
796 		case 'K':
797 			pkgdb_set_dir(optarg, 3);
798 			break;
799 		case 'k':
800 			keep_preserve = 1;
801 			break;
802 		case 'N':
803 			unregister_only = 1;
804 			break;
805 		case 'n':
806 			Fake = 1;
807 			break;
808 		case 'O':
809 			pkgdb_update_only = 1;
810 			break;
811 		case 'P':
812 			destdir = optarg;
813 			break;
814 		case 'p':
815 			prefix = optarg;
816 			break;
817 		case 'R':
818 			delete_new_leaves = 1;
819 			break;
820 		case 'r':
821 			delete_recursive = 1;
822 			break;
823 		case 'V':
824 			show_version();
825 			/* NOTREACHED */
826 		case 'v':
827 			++Verbose;
828 			break;
829 		default:
830 			usage();
831 			break;
832 		}
833 	}
834 
835 	pkg_install_config();
836 
837 	pkgdb = xstrdup(pkgdb_get_dir());
838 
839 	if (destdir != NULL) {
840 		char *pkgdbdir;
841 
842 		pkgdbdir = xasprintf("%s/%s", destdir, pkgdb);
843 		pkgdb_set_dir(pkgdbdir, 4);
844 		free(pkgdbdir);
845 	}
846 
847 	argc -= optind;
848 	argv += optind;
849 
850 	if (argc == 0) {
851 		if (find_by_filename)
852 			warnx("Missing filename(s)");
853 		else
854 			warnx("Missing package name(s)");
855 		usage();
856 	}
857 
858 	if (Fake)
859 		r = pkgdb_open(ReadOnly);
860 	else
861 		r = pkgdb_open(ReadWrite);
862 
863 	if (!r)
864 		errx(EXIT_FAILURE, "Opening pkgdb failed");
865 
866 	/* First, process all command line options. */
867 
868 	has_error = 0;
869 	for (; argc != 0; --argc, ++argv) {
870 		if (find_by_filename)
871 			has_error |= add_by_filename(&pkgs, *argv);
872 		else if (ispkgpattern(*argv))
873 			has_error |= add_by_pattern(&pkgs, *argv);
874 		else
875 			has_error |= add_by_pkgname(&pkgs, *argv);
876 	}
877 
878 	if (has_error && !Force) {
879 		pkgdb_close();
880 		return EXIT_FAILURE;
881 	}
882 
883 	/* Second, reorder and recursive if necessary. */
884 
885 	if (sort_and_recurse(&pkgs, &sorted_pkgs)) {
886 		pkgdb_close();
887 		return EXIT_FAILURE;
888 	}
889 
890 	/* Third, add leaves if necessary. */
891 
892 	if (delete_new_leaves || delete_automatic_leaves)
893 		find_new_leaves(&sorted_pkgs);
894 
895 	/*
896 	 * Now that all packages to remove are known, check
897 	 * if all are removable.  After that, start the actual
898 	 * removal.
899 	 */
900 
901 	if (find_preserve_pkgs(&sorted_pkgs)) {
902 		pkgdb_close();
903 		return EXIT_FAILURE;
904 	}
905 
906 	setenv(PKG_REFCOUNT_DBDIR_VNAME, pkgdb_refcount_dir(), 1);
907 
908 	bad_count = 0;
909 	while (!TAILQ_EMPTY(&sorted_pkgs)) {
910 		lpkg_t *lpp;
911 
912 		lpp = TAILQ_FIRST(&sorted_pkgs);
913 		TAILQ_REMOVE(&sorted_pkgs, lpp, lp_link);
914 		if (remove_pkg(lpp->lp_name)) {
915 			++bad_count;
916 			if (!Force)
917 				break;
918 		}
919 		free_lpkg(lpp);
920 	}
921 
922 	pkgdb_close();
923 
924 	if (Force && bad_count && Verbose)
925 		warnx("Removal of %lu packages failed", bad_count);
926 
927 	return bad_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS;
928 }
929