2 * Copyright (c) 2009 Joerg Sonnenberger <joerg@NetBSD.org>.
3 * Copyright (c) 2003 Johnny Lam <jlam@NetBSD.org>.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
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
35 #include <sys/cdefs.h>
37 __RCSID("$NetBSD: pkg_delete.c,v 1.8 2009/08/06 16:53:34 joerg Exp $");
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
;
63 fprintf(stderr
, "usage: pkg_delete [-DFfkNnORrVv] [-K pkg_dbdir]"
64 " [-P destdir] [-p prefix] pkg-name ...\n");
69 add_by_filename(lpkg_head_t
*pkgs
, const char *filename
)
74 if ((s
= pkgdb_retrieve(filename
)) == NULL
) {
75 warnx("No matching package for file `%s' in pkgdb", filename
);
79 /* XXX Verify that pkgdb is consistent? Trust it for now... */
82 TAILQ_INSERT_TAIL(pkgs
, lpp
, lp_link
);
87 add_by_pattern(lpkg_head_t
*pkgs
, const char *pattern
)
89 switch (add_installed_pkgs_by_pattern(pattern
, pkgs
)) {
91 warnx("No package matching `%s' found", pattern
);
94 warnx("Error while iterating package database for `%s'",
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.
108 add_by_pkgname(lpkg_head_t
*pkgs
, char *pkg
)
113 const char *orig_pkg
= pkg
;
117 if (strncmp(pkg
, pkgdb
, l
) || pkg
[l
] != '/') {
118 warnx("Absolute path is not relative to "
119 "package database, skipping: %s", pkg
);
124 l
= strcspn(pkg
, "/");
125 if (pkg
[l
+ strspn(pkg
+ l
, "/")] != '\0') {
126 warnx("`%s' is not a package name, skipping", orig_pkg
);
131 s
= pkgdb_pkg_file(pkg
, CONTENTS_FNAME
);
134 lpp
= alloc_lpkg(pkg
);
135 TAILQ_INSERT_TAIL(pkgs
, lpp
, lp_link
);
140 switch (add_installed_pkgs_by_basename(pkg
, pkgs
)) {
142 warnx("No matching package for basename `%s' of `%s'",
146 warnx("Error expanding basename `%s' of `%s'",
155 * Evaluate +REQUIRED_BY. This function is used for four different
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
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
;
169 int got_match
, got_miss
;
171 fname
= pkgdb_pkg_file(pkg
, REQUIRED_BY_FNAME
);
172 if (!fexists(fname
)) {
177 if ((fp
= fopen(fname
, "r")) == NULL
) {
178 warn("Failed to open `%s'", fname
);
187 while (fgets(line
, sizeof(line
), fp
)) {
188 if ((eol
= strrchr(line
, '\n')) != NULL
)
190 TAILQ_FOREACH(lpp
, sorted_pkgs
, lp_link
) {
191 if (strcmp(lpp
->lp_name
, line
) == 0)
200 TAILQ_FOREACH(lpp
, pkgs
, lp_link
) {
201 if (strcmp(lpp
->lp_name
, line
) == 0)
212 lpp
= alloc_lpkg(line
);
213 TAILQ_INSERT_HEAD(pkgs
, lpp
, lp_link
);
216 fprintf(stderr
, "\t%s\n", line
);
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.
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
;
251 TAILQ_FOREACH_SAFE(lpp
, pkgs
, lp_link
, lpp_next
) {
252 TAILQ_FOREACH(lpp2
, pkgs
, lp_link
) {
254 strcmp(lpp
->lp_name
, lpp2
->lp_name
) == 0)
259 TAILQ_REMOVE(pkgs
, lpp
, lp_link
);
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);
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
))
281 if (TAILQ_EMPTY(pkgs
))
284 while (!TAILQ_EMPTY(pkgs
)) {
285 lpp
= TAILQ_FIRST(pkgs
);
286 TAILQ_REMOVE(pkgs
, lpp
, lp_link
);
288 "Package `%s' is still required by other packages:\n",
290 process_required_by(lpp
->lp_name
, NULL
, sorted_pkgs
, 2);
292 TAILQ_INSERT_TAIL(sorted_pkgs
, lpp
, lp_link
);
300 struct find_leaves_data
{
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.
315 find_new_leaves_iter(const char *pkg
, void *cookie
)
318 struct find_leaves_data
*data
= cookie
;
321 fname
= pkgdb_pkg_file(pkg
, PRESERVE_FNAME
);
322 if (fexists(fname
)) {
328 if (delete_automatic_leaves
&& !delete_new_leaves
&&
329 !is_automatic_installed(pkg
))
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)
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
);
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.
352 find_new_leaves(lpkg_head_t
*pkgs
)
354 struct find_leaves_data data
;
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.
367 find_preserve_pkgs(lpkg_head_t
*pkgs
)
369 lpkg_t
*lpp
, *lpp_next
;
374 TAILQ_FOREACH_SAFE(lpp
, pkgs
, lp_link
, lpp_next
) {
375 fname
= pkgdb_pkg_file(lpp
->lp_name
, PRESERVE_FNAME
);
376 if (!fexists(fname
)) {
382 TAILQ_REMOVE(pkgs
, lpp
, lp_link
);
387 warnx("The following packages are marked as not "
390 fprintf(stderr
, "\t%s\n", lpp
->lp_name
);
394 if (Force
== 0 || (!unregister_only
&& Force
== 1))
396 fprintf(stderr
, "...but will delete them anyway\n");
401 * Remove package from view. This is calling pkg_deinstall again.
404 remove_pkg_from_view(const char *pkg
)
406 char line
[MaxPathSize
], *fname
, *eol
;
409 fname
= pkgdb_pkg_file(pkg
, VIEWS_FNAME
);
410 if (isemptyfile(fname
)) {
414 if ((fp
= fopen(fname
, "r")) == NULL
) {
415 warn("Unable to open `%s', aborting", fname
);
420 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
421 if ((eol
= strrchr(line
, '\n')) != NULL
)
424 printf("Deleting package `%s' instance from `%s' view\n",
428 if (fexec_skipempty(BINDIR
"/pkg_delete", "-K", line
,
430 (Force
> 1) ? "-f" : "",
431 (Force
> 0) ? "-f" : "",
433 warnx("Unable to delete package `%s' from view `%s'",
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.
449 run_deinstall_script(const char *pkg
, int do_postdeinstall
)
451 const char *target
, *text
;
452 char *fname
, *fname2
, *pkgdir
;
455 fname
= pkgdb_pkg_file(pkg
, DEINSTALL_FNAME
);
456 if (!fexists(fname
)) {
461 fname2
= pkgdb_pkg_file(pkg
, DEPOT_FNAME
);
462 if (fexists(fname2
)) {
463 if (do_postdeinstall
) {
468 target
= "VIEW-DEINSTALL";
469 text
= "view deinstall";
470 } else if (do_postdeinstall
) {
471 target
= "POST-DEINSTALL";
472 text
= "post-deinstall";
474 target
= "DEINSTALL";
480 printf("Would execute %s script with argument %s now\n",
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
);
491 warnx("%s script returned error status", text
);
498 * Copy lines from fname to fname_tmp, filtering out lines equal to text.
499 * Afterwards rename fname_tmp to fname;
502 remove_line(const char *fname
, const char *fname_tmp
, const char *text
)
505 char line
[MaxPathSize
], *eol
;
508 if ((fp
= fopen(fname
, "r")) == NULL
) {
509 warn("Unable to open `%s'", fname
);
512 if ((fp_out
= fopen(fname_tmp
, "w")) == NULL
) {
513 warn("Unable to open `%s'", fname_tmp
);
518 while (fgets(line
, sizeof(line
), fp
) != NULL
) {
519 if ((eol
= strrchr(line
, '\n')) != NULL
)
521 if (strcmp(line
, text
) == 0)
523 fprintf(fp_out
, "%s\n", line
);
527 if (fclose(fp_out
) == EOF
) {
529 warnx("Failure while closing `%s' temp file", fname_tmp
);
533 if (rename(fname_tmp
, fname
) == -1) {
534 warn("Unable to rename `%s' to `%s'", fname_tmp
, fname
);
544 * Unregister the package from the depot it is registered in.
547 remove_pkg_from_depot(const char *pkg
)
550 char line
[MaxPathSize
], *eol
;
551 char *fname
, *fname2
;
554 fname
= pkgdb_pkg_file(pkg
, DEPOT_FNAME
);
555 if (isemptyfile(fname
)) {
561 printf("Attempting to remove the `%s' registration "
562 "on package `%s'\n", fname
, pkg
);
569 if ((fp
= fopen(fname
, "r")) == NULL
) {
570 warn("Unable to open `%s' file", fname
);
574 if (fgets(line
, sizeof(line
), fp
) == NULL
) {
576 warnx("Empty depot file `%s'", fname
);
580 if ((eol
= strrchr(line
, '\n')) != NULL
)
585 fname
= pkgdb_pkg_file(pkg
, VIEWS_FNAME
);
586 fname2
= pkgdb_pkg_file(pkg
, VIEWS_FNAME_TMP
);
587 rv
= remove_line(fname
, fname2
, line
);
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.
602 remove_depend(const char *cur_pkg
, void *cookie
)
604 const char *pkg
= cookie
;
605 char *fname
, *fname2
;
608 fname
= pkgdb_pkg_file(cur_pkg
, REQUIRED_BY_FNAME
);
609 if (isemptyfile(fname
)) {
613 fname2
= pkgdb_pkg_file(cur_pkg
, REQUIRED_BY_FNAME_TMP
);
615 rv
= remove_line(fname
, fname2
, pkg
);
624 remove_pkg(const char *pkg
)
627 char *fname
, *pkgdir
;
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
);
643 /* +REQUIRED_BY and +PRESERVE already checked */
644 if (remove_pkg_from_view(pkg
))
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
);
658 read_plist(&plist
, 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
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
);
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);
687 if (!no_deinstall
&& !unregister_only
) {
688 if (run_deinstall_script(pkg
, 0) && !Force
)
695 printf("Attempting to delete package `%s'\n", pkg
);
696 else if (delete_package(FALSE
, &plist
, unregister_only
,
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
714 fname
= pkgdb_pkg_file(pkg
, DEPOT_FNAME
);
715 if (fexists(fname
)) {
716 late_error
|= remove_pkg_from_depot(pkg
);
717 /* XXX error checking */
719 for (p
= plist
.head
; p
; p
= p
->next
) {
720 if (p
->type
!= PLIST_PKGDEP
)
723 printf("Attempting to remove dependency "
724 "on package `%s'\n", p
->name
);
727 match_installed_pkgs(p
->name
, remove_depend
,
735 if (!no_deinstall
&& !unregister_only
)
736 late_error
|= run_deinstall_script(pkg
, 1);
738 fname
= pkgdb_pkg_file(pkg
, VIEWS_FNAME
);
740 is_depoted_pkg
= TRUE
;
742 is_depoted_pkg
= FALSE
;
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
, "+*");
755 if (isemptydir(pkgdir
)&& rmdir(pkgdir
) == 0)
757 else if (is_depoted_pkg
)
758 warnx("Depot directory `%s' is not empty", pkgdir
);
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
);
764 warnx("Package directory `%s' forcefully removed", 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
;
778 TAILQ_INIT(&sorted_pkgs
);
780 setprogname(argv
[0]);
781 while ((ch
= getopt(argc
, argv
, "ADFfK:kNnOP:p:RrVv")) != -1) {
784 delete_automatic_leaves
= 1;
790 find_by_filename
= 1;
808 pkgdb_update_only
= 1;
817 delete_new_leaves
= 1;
820 delete_recursive
= 1;
834 if (destdir
!= NULL
) {
838 pkgdb
= _pkgdb_getPKGDB_DIR();
840 pkgdbdir
= xasprintf("%s/%s", destdir
, pkgdb
);
841 _pkgdb_setPKGDB_DIR(pkgdbdir
);
843 } else if (pkgdb
!= NULL
) {
844 _pkgdb_setPKGDB_DIR(pkgdb
);
846 pkgdb
= _pkgdb_getPKGDB_DIR();
853 if (find_by_filename
)
854 warnx("Missing filename(s)");
856 warnx("Missing package name(s)");
861 r
= pkgdb_open(ReadOnly
);
863 r
= pkgdb_open(ReadWrite
);
866 errx(EXIT_FAILURE
, "Opening pkgdb failed");
868 /* First, process all command line options. */
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
);
877 has_error
|= add_by_pkgname(&pkgs
, *argv
);
880 if (has_error
&& !Force
) {
885 /* Second, reorder and recursive if necessary. */
887 if (sort_and_recurse(&pkgs
, &sorted_pkgs
)) {
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
903 if (find_preserve_pkgs(&sorted_pkgs
)) {
908 setenv(PKG_REFCOUNT_DBDIR_VNAME
, pkgdb_refcount_dir(), 1);
911 while (!TAILQ_EMPTY(&sorted_pkgs
)) {
914 lpp
= TAILQ_FIRST(&sorted_pkgs
);
915 TAILQ_REMOVE(&sorted_pkgs
, lpp
, lp_link
);
916 if (remove_pkg(lpp
->lp_name
)) {
926 if (Force
&& bad_count
&& Verbose
)
927 warnx("Removal of %lu packages failed", bad_count
);
929 return bad_count
> 0 ? EXIT_FAILURE
: EXIT_SUCCESS
;