perform.c revision 222035
1/* 2 * FreeBSD install - a package for the installation and maintainance 3 * of non-core utilities. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * Jordan K. Hubbard 15 * 18 July 1993 16 * 17 * This is the main body of the add module. 18 * 19 */ 20 21#include <sys/cdefs.h> 22__FBSDID("$FreeBSD: head/usr.sbin/pkg_install/add/perform.c 222035 2011-05-17 19:11:47Z flz $"); 23 24#include <err.h> 25#include <paths.h> 26#include "lib.h" 27#include "add.h" 28 29#include <libgen.h> 30#include <signal.h> 31#include <sys/wait.h> 32 33static int pkg_do(char *); 34static int sanity_check(char *); 35static char LogDir[FILENAME_MAX]; 36static int zapLogDir; /* Should we delete LogDir? */ 37 38int 39pkg_perform(char **pkgs) 40{ 41 int i, err_cnt = 0; 42 43 signal(SIGINT, cleanup); 44 signal(SIGHUP, cleanup); 45 46 if (AddMode == SLAVE) 47 err_cnt = pkg_do(NULL); 48 else { 49 for (i = 0; pkgs[i]; i++) 50 err_cnt += pkg_do(pkgs[i]); 51 } 52 return err_cnt; 53} 54 55/* 56 * This is seriously ugly code following. Written very fast! 57 * [And subsequently made even worse.. Sigh! This code was just born 58 * to be hacked, I guess.. :) -jkh] 59 */ 60static int 61pkg_do(char *pkg) 62{ 63 Package Plist; 64 char pkg_fullname[FILENAME_MAX]; 65 char playpen[FILENAME_MAX]; 66 char extract_contents[FILENAME_MAX]; 67 char *extract; 68 const char *where_to; 69 FILE *cfile; 70 int code; 71 PackingList p; 72 struct stat sb; 73 int inPlace, conflictsfound, errcode; 74 /* support for separate pre/post install scripts */ 75 int new_m = 0; 76 char pre_script[FILENAME_MAX] = INSTALL_FNAME; 77 char post_script[FILENAME_MAX]; 78 char pre_arg[FILENAME_MAX], post_arg[FILENAME_MAX]; 79 char *conflict[2]; 80 char **matched; 81 int fd; 82 83 conflictsfound = 0; 84 code = 0; 85 zapLogDir = 0; 86 LogDir[0] = '\0'; 87 strcpy(playpen, FirstPen); 88 inPlace = 0; 89 90 memset(&Plist, '\0', sizeof(Plist)); 91 92 /* Are we coming in for a second pass, everything already extracted? */ 93 if (!pkg) { 94 fgets(playpen, FILENAME_MAX, stdin); 95 playpen[strlen(playpen) - 1] = '\0'; /* pesky newline! */ 96 if (chdir(playpen) == FAIL) { 97 warnx("pkg_add in SLAVE mode can't chdir to %s", playpen); 98 return 1; 99 } 100 read_plist(&Plist, stdin); 101 where_to = playpen; 102 } 103 /* Nope - do it now */ 104 else { 105 /* Is it an ftp://foo.bar.baz/file.t[bg]z specification? */ 106 if (isURL(pkg)) { 107 if (!(where_to = fileGetURL(NULL, pkg, KeepPackage))) { 108 warnx("unable to fetch '%s' by URL", pkg); 109 return 1; 110 } 111 strcpy(pkg_fullname, pkg); 112 cfile = fopen(CONTENTS_FNAME, "r"); 113 if (!cfile) { 114 warnx( 115 "unable to open table of contents file '%s' - not a package?", 116 CONTENTS_FNAME); 117 goto bomb; 118 } 119 read_plist(&Plist, cfile); 120 fclose(cfile); 121 } 122 else { 123 strcpy(pkg_fullname, pkg); /* 124 * Copy for sanity's sake, 125 * could remove pkg_fullname 126 */ 127 if (strcmp(pkg, "-")) { 128 if (stat(pkg_fullname, &sb) == FAIL) { 129 warnx("can't stat package file '%s'", pkg_fullname); 130 goto bomb; 131 } 132 sprintf(extract_contents, "--fast-read %s", CONTENTS_FNAME); 133 extract = extract_contents; 134 } 135 else { 136 extract = NULL; 137 sb.st_size = 100000; /* Make up a plausible average size */ 138 } 139 if (!(where_to = make_playpen(playpen, sb.st_size * 4))) 140 errx(1, "unable to make playpen for %lld bytes", (long long)sb.st_size * 4); 141 /* Since we can call ourselves recursively, keep notes on where we came from */ 142 if (!getenv("_TOP")) 143 setenv("_TOP", where_to, 1); 144 if (unpack(pkg_fullname, extract)) { 145 warnx( 146 "unable to extract table of contents file from '%s' - not a package?", 147 pkg_fullname); 148 goto bomb; 149 } 150 cfile = fopen(CONTENTS_FNAME, "r"); 151 if (!cfile) { 152 warnx( 153 "unable to open table of contents file '%s' - not a package?", 154 CONTENTS_FNAME); 155 goto bomb; 156 } 157 read_plist(&Plist, cfile); 158 fclose(cfile); 159 160 /* Extract directly rather than moving? Oh goodie! */ 161 if (find_plist_option(&Plist, "extract-in-place")) { 162 if (Verbose) 163 printf("Doing in-place extraction for %s\n", pkg_fullname); 164 p = find_plist(&Plist, PLIST_CWD); 165 if (p) { 166 if (!isdir(p->name) && !Fake) { 167 if (Verbose) 168 printf("Desired prefix of %s does not exist, creating..\n", p->name); 169 vsystem("/bin/mkdir -p %s", p->name); 170 if (chdir(p->name) == -1) { 171 warn("unable to change directory to '%s'", p->name); 172 goto bomb; 173 } 174 } 175 where_to = p->name; 176 inPlace = 1; 177 } 178 else { 179 warnx( 180 "no prefix specified in '%s' - this is a bad package!", 181 pkg_fullname); 182 goto bomb; 183 } 184 } 185 186 /* 187 * Apply a crude heuristic to see how much space the package will 188 * take up once it's unpacked. I've noticed that most packages 189 * compress an average of 75%, so multiply by 4 for good measure. 190 */ 191 192 if (!extract && !inPlace && min_free(playpen) < sb.st_size * 4) { 193 warnx("projected size of %lld exceeds available free space.\n" 194"Please set your PKG_TMPDIR variable to point to a location with more\n" 195 "free space and try again", (long long)sb.st_size * 4); 196 warnx("not extracting %s\ninto %s, sorry!", 197 pkg_fullname, where_to); 198 goto bomb; 199 } 200 201 /* If this is a direct extract and we didn't want it, stop now */ 202 if (inPlace && Fake) 203 goto success; 204 205 /* Finally unpack the whole mess. If extract is null we 206 already + did so so don't bother doing it again. */ 207 if (extract && unpack(pkg_fullname, NULL)) { 208 warnx("unable to extract '%s'!", pkg_fullname); 209 goto bomb; 210 } 211 } 212 213 /* Check for sanity and dependencies */ 214 if (sanity_check(pkg)) 215 goto bomb; 216 217 /* If we're running in MASTER mode, just output the plist and return */ 218 if (AddMode == MASTER) { 219 printf("%s\n", where_playpen()); 220 write_plist(&Plist, stdout); 221 return 0; 222 } 223 } 224 225 /* 226 * If we have a prefix, delete the first one we see and add this 227 * one in place of it. 228 */ 229 if (Prefix) { 230 delete_plist(&Plist, FALSE, PLIST_CWD, NULL); 231 add_plist_top(&Plist, PLIST_CWD, Prefix); 232 } 233 234 setenv(PKG_PREFIX_VNAME, (p = find_plist(&Plist, PLIST_CWD)) ? p->name : ".", 1); 235 /* Protect against old packages with bogus @name and origin fields */ 236 if (Plist.name == NULL) 237 Plist.name = "anonymous"; 238 if (Plist.origin == NULL) 239 Plist.origin = "anonymous/anonymous"; 240 241 /* 242 * See if we're already registered either with the same name (the same 243 * version) or some other version with the same origin. 244 */ 245 if ((isinstalledpkg(Plist.name) > 0 || 246 matchbyorigin(Plist.origin, NULL) != NULL) && !Force) { 247 warnx("package '%s' or its older version already installed%s", 248 Plist.name, FailOnAlreadyInstalled ? "" : " (ignored)"); 249 code = FailOnAlreadyInstalled != FALSE; 250 goto success; /* close enough for government work */ 251 } 252 253 /* Now check the packing list for conflicts */ 254 if (!IgnoreDeps){ 255 for (p = Plist.head; p != NULL; p = p->next) { 256 if (p->type == PLIST_CONFLICTS) { 257 int i; 258 conflict[0] = strdup(p->name); 259 conflict[1] = NULL; 260 matched = matchinstalled(MATCH_GLOB, conflict, &errcode); 261 free(conflict[0]); 262 if (errcode == 0 && matched != NULL) 263 for (i = 0; matched[i] != NULL; i++) 264 if (isinstalledpkg(matched[i]) > 0) { 265 warnx("package '%s' conflicts with %s", Plist.name, 266 matched[i]); 267 conflictsfound = 1; 268 } 269 270 continue; 271 } 272 } 273 if(conflictsfound) { 274 if(!Force) { 275 warnx("please use pkg_delete first to remove conflicting package(s) or -f to force installation"); 276 code = 1; 277 goto bomb; 278 } else 279 warnx("-f specified; proceeding anyway"); 280 } 281 282#if ENSURE_THAT_ALL_REQUIREMENTS_ARE_MET 283 /* 284 * Before attempting to do the slave mode bit, ensure that we've 285 * downloaded & processed everything we need. 286 * It's possible that we haven't already installed all of our 287 * dependencies if the dependency list was misgenerated due to 288 * other dynamic dependencies or if a dependency was added to a 289 * package without all REQUIRED_BY packages being regenerated. 290 */ 291 for (p = pkg ? Plist.head : NULL; p; p = p->next) { 292 const char *ext; 293 char *deporigin; 294 295 if (p->type != PLIST_PKGDEP) 296 continue; 297 deporigin = (p->next->type == PLIST_DEPORIGIN) ? p->next->name : NULL; 298 299 if (isinstalledpkg(p->name) <= 0 && 300 !(deporigin != NULL && matchbyorigin(deporigin, NULL) != NULL)) { 301 char subpkg[FILENAME_MAX], *sep; 302 303 strlcpy(subpkg, pkg, sizeof subpkg); 304 if ((sep = strrchr(subpkg, '/')) != NULL) { 305 *sep = '\0'; 306 if ((sep = strrchr(subpkg, '/')) != NULL) { 307 *sep = '\0'; 308 strlcat(subpkg, "/All/", sizeof subpkg); 309 strlcat(subpkg, p->name, sizeof subpkg); 310 if ((ext = strrchr(pkg, '.')) == NULL) 311 ext = ".tbz"; 312 strlcat(subpkg, ext, sizeof subpkg); 313 pkg_do(subpkg); 314 } 315 } 316 } 317 } 318#endif 319 320 /* Now check the packing list for dependencies */ 321 for (p = Plist.head; p ; p = p->next) { 322 char *deporigin; 323 324 if (p->type != PLIST_PKGDEP) 325 continue; 326 deporigin = (p->next->type == PLIST_DEPORIGIN) ? p->next->name : NULL; 327 if (Verbose) { 328 printf("Package '%s' depends on '%s'", Plist.name, p->name); 329 if (deporigin != NULL) 330 printf(" with '%s' origin", deporigin); 331 printf(".\n"); 332 } 333 if (isinstalledpkg(p->name) <= 0 && 334 !(deporigin != NULL && matchbyorigin(deporigin, NULL) != NULL)) { 335 char path[FILENAME_MAX]; 336 const char *cp = NULL; 337 338 if (!Fake) { 339 char prefixArg[2 + MAXPATHLEN]; /* "-P" + Prefix */ 340 if (PrefixRecursive) { 341 strlcpy(prefixArg, "-P", sizeof(prefixArg)); 342 strlcat(prefixArg, Prefix, sizeof(prefixArg)); 343 } 344 if (!isURL(pkg) && !getenv("PKG_ADD_BASE")) { 345 const char *ext; 346 347 ext = strrchr(pkg_fullname, '.'); 348 if (ext == NULL) 349 ext = ".tbz"; 350 snprintf(path, FILENAME_MAX, "%s/%s%s", getenv("_TOP"), p->name, ext); 351 if (fexists(path)) 352 cp = path; 353 else 354 cp = fileFindByPath(pkg, p->name); 355 if (cp) { 356 if (Verbose) 357 printf("Loading it from %s.\n", cp); 358 if (vsystem("%s %s %s '%s'", PkgAddCmd, Verbose ? "-v " : "", PrefixRecursive ? prefixArg : "", cp)) { 359 warnx("autoload of dependency '%s' failed%s", 360 cp, Force ? " (proceeding anyway)" : "!"); 361 if (!Force) 362 ++code; 363 } 364 } 365 else { 366 warnx("could not find package %s %s", 367 p->name, Force ? " (proceeding anyway)" : "!"); 368 if (!Force) 369 ++code; 370 } 371 } 372 else if ((cp = fileGetURL(pkg, p->name, KeepPackage)) != NULL) { 373 if (Verbose) 374 printf("Finished loading %s via a URL\n", p->name); 375 if (!fexists("+CONTENTS")) { 376 warnx("autoloaded package %s has no +CONTENTS file?", 377 p->name); 378 if (!Force) 379 ++code; 380 } 381 else if (vsystem("(pwd; /bin/cat +CONTENTS) | %s %s %s %s -S", PkgAddCmd, Verbose ? "-v" : "", PrefixRecursive ? prefixArg : "", KeepPackage ? "-K" : "")) { 382 warnx("pkg_add of dependency '%s' failed%s", 383 p->name, Force ? " (proceeding anyway)" : "!"); 384 if (!Force) 385 ++code; 386 } 387 else if (Verbose) 388 printf("\t'%s' loaded successfully.\n", p->name); 389 /* Nuke the temporary playpen */ 390 leave_playpen(); 391 } 392 } 393 else { 394 if (Verbose) 395 printf("and was not found%s.\n", Force ? " (proceeding anyway)" : ""); 396 else 397 printf("Package dependency %s for %s not found%s\n", p->name, pkg, 398 Force ? " (proceeding anyway)" : "!"); 399 if (!Force) 400 ++code; 401 } 402 } 403 else if (Verbose) 404 printf(" - already installed.\n"); 405 } 406 } /* if (!IgnoreDeps) */ 407 408 if (code != 0) 409 goto bomb; 410 411 /* Look for the requirements file */ 412 if ((fd = open(REQUIRE_FNAME, O_RDWR)) != -1) { 413 fstat(fd, &sb); 414 fchmod(fd, sb.st_mode | S_IXALL); /* be sure, chmod a+x */ 415 close(fd); 416 if (Verbose) 417 printf("Running requirements file first for %s..\n", Plist.name); 418 if (!Fake && vsystem("./%s %s INSTALL", REQUIRE_FNAME, Plist.name)) { 419 warnx("package %s fails requirements %s", pkg_fullname, 420 Force ? "installing anyway" : "- not installed"); 421 if (!Force) { 422 code = 1; 423 goto success; /* close enough for government work */ 424 } 425 } 426 } 427 428 /* 429 * Test whether to use the old method of passing tokens to installation 430 * scripts, and set appropriate variables.. 431 */ 432 433 if (fexists(POST_INSTALL_FNAME)) { 434 new_m = 1; 435 sprintf(post_script, "%s", POST_INSTALL_FNAME); 436 pre_arg[0] = '\0'; 437 post_arg[0] = '\0'; 438 } else { 439 if (fexists(INSTALL_FNAME)) { 440 sprintf(post_script, "%s", INSTALL_FNAME); 441 sprintf(pre_arg, "PRE-INSTALL"); 442 sprintf(post_arg, "POST-INSTALL"); 443 } 444 } 445 446 /* If we're really installing, and have an installation file, run it */ 447 if (!NoInstall && (fd = open(pre_script, O_RDWR)) != -1) { 448 fstat(fd, &sb); 449 fchmod(fd, sb.st_mode | S_IXALL); /* be sure, chmod a+x */ 450 close(fd); 451 if (Verbose) 452 printf("Running pre-install for %s..\n", Plist.name); 453 if (!Fake && vsystem("./%s %s %s", pre_script, Plist.name, pre_arg)) { 454 warnx("install script returned error status"); 455 unlink(pre_script); 456 code = 1; 457 goto success; /* nothing to uninstall yet */ 458 } 459 } 460 461 /* Now finally extract the entire show if we're not going direct */ 462 if (!inPlace && !Fake) 463 extract_plist(".", &Plist); 464 465 if (!Fake && fexists(MTREE_FNAME)) { 466 if (Verbose) 467 printf("Running mtree for %s..\n", Plist.name); 468 p = find_plist(&Plist, PLIST_CWD); 469 if (Verbose) 470 printf("mtree -U -f %s -d -e -p %s >%s\n", MTREE_FNAME, p ? p->name : "/", _PATH_DEVNULL); 471 if (!Fake) { 472 if (vsystem("/usr/sbin/mtree -U -f %s -d -e -p %s >%s", MTREE_FNAME, p ? p->name : "/", _PATH_DEVNULL)) 473 warnx("mtree returned a non-zero status - continuing"); 474 } 475 } 476 477 /* Run the installation script one last time? */ 478 if (!NoInstall && (fd = open(post_script, O_RDWR)) != -1) { 479 fstat(fd, &sb); 480 fchmod(fd, sb.st_mode | S_IXALL); /* be sure, chmod a+x */ 481 close(fd); 482 if (Verbose) 483 printf("Running post-install for %s..\n", Plist.name); 484 if (!Fake && vsystem("./%s %s %s", post_script, Plist.name, post_arg)) { 485 warnx("install script returned error status"); 486 unlink(post_script); 487 code = 1; 488 goto fail; 489 } 490 } 491 492 /* Time to record the deed? */ 493 if (!NoRecord && !Fake) { 494 char contents[FILENAME_MAX]; 495 char **depnames = NULL, **deporigins = NULL, ***depmatches; 496 int i, dep_count = 0; 497 FILE *contfile; 498 499 if (getuid() != 0) 500 warnx("not running as root - trying to record install anyway"); 501 sprintf(LogDir, "%s/%s", LOG_DIR, Plist.name); 502 zapLogDir = 1; 503 if (Verbose) 504 printf("Attempting to record package into %s..\n", LogDir); 505 if (make_hierarchy(LogDir)) { 506 warnx("can't record package into '%s', you're on your own!", 507 LogDir); 508 bzero(LogDir, FILENAME_MAX); 509 code = 1; 510 goto success; /* close enough for government work */ 511 } 512 /* Make sure pkg_info can read the entry */ 513 fd = open(LogDir, O_RDWR); 514 fstat(fd, &sb); 515 fchmod(fd, sb.st_mode | S_IRALL | S_IXALL); /* be sure, chmod a+rx */ 516 close(fd); 517 move_file(".", DESC_FNAME, LogDir); 518 move_file(".", COMMENT_FNAME, LogDir); 519 if (fexists(INSTALL_FNAME)) 520 move_file(".", INSTALL_FNAME, LogDir); 521 if (fexists(POST_INSTALL_FNAME)) 522 move_file(".", POST_INSTALL_FNAME, LogDir); 523 if (fexists(DEINSTALL_FNAME)) 524 move_file(".", DEINSTALL_FNAME, LogDir); 525 if (fexists(POST_DEINSTALL_FNAME)) 526 move_file(".", POST_DEINSTALL_FNAME, LogDir); 527 if (fexists(REQUIRE_FNAME)) 528 move_file(".", REQUIRE_FNAME, LogDir); 529 if (fexists(DISPLAY_FNAME)) 530 move_file(".", DISPLAY_FNAME, LogDir); 531 if (fexists(MTREE_FNAME)) 532 move_file(".", MTREE_FNAME, LogDir); 533 sprintf(contents, "%s/%s", LogDir, CONTENTS_FNAME); 534 contfile = fopen(contents, "w"); 535 if (!contfile) { 536 warnx("can't open new contents file '%s'! can't register pkg", 537 contents); 538 goto success; /* can't log, but still keep pkg */ 539 } 540 write_plist(&Plist, contfile); 541 fclose(contfile); 542 for (p = Plist.head; p ; p = p->next) { 543 char *deporigin; 544 545 if (p->type != PLIST_PKGDEP) 546 continue; 547 deporigin = (p->next->type == PLIST_DEPORIGIN) ? p->next->name : 548 NULL; 549 if (Verbose) { 550 printf("Trying to record dependency on package '%s'", p->name); 551 if (deporigin != NULL) 552 printf(" with '%s' origin", deporigin); 553 printf(".\n"); 554 } 555 556 if (deporigin) { 557 /* Defer to origin lookup */ 558 depnames = realloc(depnames, (dep_count + 1) * sizeof(*depnames)); 559 depnames[dep_count] = p->name; 560 deporigins = realloc(deporigins, (dep_count + 2) * sizeof(*deporigins)); 561 deporigins[dep_count] = deporigin; 562 deporigins[dep_count + 1] = NULL; 563 dep_count++; 564 } else { 565 /* No origin recorded, try to register on literal package name */ 566 sprintf(contents, "%s/%s/%s", LOG_DIR, p->name, 567 REQUIRED_BY_FNAME); 568 contfile = fopen(contents, "a"); 569 if (!contfile) { 570 warnx("can't open dependency file '%s'!\n" 571 "dependency registration is incomplete", contents); 572 } else { 573 fprintf(contfile, "%s\n", Plist.name); 574 if (fclose(contfile) == EOF) { 575 warnx("cannot properly close file %s", contents); 576 } 577 } 578 } 579 } 580 if (dep_count > 0) { 581 depmatches = matchallbyorigin((const char **)deporigins, NULL); 582 free(deporigins); 583 if (!IgnoreDeps && depmatches) { 584 for (i = 0; i < dep_count; i++) { 585 if (depmatches[i]) { 586 int j; 587 char **tmp = depmatches[i]; 588 for (j = 0; tmp[j] != NULL; j++) { 589 /* Origin looked up */ 590 sprintf(contents, "%s/%s/%s", LOG_DIR, tmp[j], 591 REQUIRED_BY_FNAME); 592 if (depnames[i] && strcmp(depnames[i], tmp[j]) != 0) 593 warnx("warning: package '%s' requires '%s', but '%s' " 594 "is installed", Plist.name, depnames[i], tmp[j]); 595 contfile = fopen(contents, "a"); 596 if (!contfile) { 597 warnx("can't open dependency file '%s'!\n" 598 "dependency registration is incomplete", contents); 599 } else { 600 fprintf(contfile, "%s\n", Plist.name); 601 if (fclose(contfile) == EOF) 602 warnx("cannot properly close file %s", contents); 603 } 604 } 605 } else if (depnames[i]) { 606 /* No package present with this origin, try literal package name */ 607 sprintf(contents, "%s/%s/%s", LOG_DIR, depnames[i], 608 REQUIRED_BY_FNAME); 609 contfile = fopen(contents, "a"); 610 if (!contfile) { 611 warnx("can't open dependency file '%s'!\n" 612 "dependency registration is incomplete", contents); 613 } else { 614 fprintf(contfile, "%s\n", Plist.name); 615 if (fclose(contfile) == EOF) { 616 warnx("cannot properly close file %s", contents); 617 } 618 } 619 } 620 } 621 } 622 } 623 if (Verbose) 624 printf("Package %s registered in %s\n", Plist.name, LogDir); 625 } 626 627 if ((p = find_plist(&Plist, PLIST_DISPLAY)) != NULL) { 628 FILE *fp; 629 char buf[BUFSIZ]; 630 631 snprintf(buf, sizeof buf, "%s/%s", LogDir, p->name); 632 fp = fopen(buf, "r"); 633 if (fp) { 634 putc('\n', stdout); 635 while (fgets(buf, sizeof(buf), fp)) 636 fputs(buf, stdout); 637 putc('\n', stdout); 638 (void) fclose(fp); 639 } else { 640 if (!Fake) { 641 warnx("cannot open %s as display file", buf); 642 } 643 } 644 } 645 646 goto success; 647 648 bomb: 649 code = 1; 650 goto success; 651 652 fail: 653 /* Nuke the whole (installed) show, XXX but don't clean directories */ 654 if (!Fake) 655 delete_package(FALSE, FALSE, &Plist); 656 657 success: 658 /* delete the packing list contents */ 659 free_plist(&Plist); 660 leave_playpen(); 661 return code; 662} 663 664static int 665sanity_check(char *pkg) 666{ 667 int code = 0; 668 669 if (!fexists(CONTENTS_FNAME)) { 670 warnx("package %s has no CONTENTS file!", pkg); 671 code = 1; 672 } 673 else if (!fexists(COMMENT_FNAME)) { 674 warnx("package %s has no COMMENT file!", pkg); 675 code = 1; 676 } 677 else if (!fexists(DESC_FNAME)) { 678 warnx("package %s has no DESC file!", pkg); 679 code = 1; 680 } 681 return code; 682} 683 684void 685cleanup(int sig) 686{ 687 static int in_cleanup = 0; 688 689 if (!in_cleanup) { 690 in_cleanup = 1; 691 if (sig) 692 printf("Signal %d received, cleaning up..\n", sig); 693 if (!Fake && zapLogDir && LogDir[0]) 694 vsystem("%s -rf %s", REMOVE_CMD, LogDir); 695 while (leave_playpen()) 696 ; 697 } 698 if (sig) 699 exit(1); 700} 701