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