1327Sjkh/* 2228990Suqs * FreeBSD install - a package for the installation and maintenance 3327Sjkh * of non-core utilities. 4327Sjkh * 5327Sjkh * Redistribution and use in source and binary forms, with or without 6327Sjkh * modification, are permitted provided that the following conditions 7327Sjkh * are met: 8327Sjkh * 1. Redistributions of source code must retain the above copyright 9327Sjkh * notice, this list of conditions and the following disclaimer. 10327Sjkh * 2. Redistributions in binary form must reproduce the above copyright 11327Sjkh * notice, this list of conditions and the following disclaimer in the 12327Sjkh * documentation and/or other materials provided with the distribution. 13327Sjkh * 14327Sjkh * Jordan K. Hubbard 15327Sjkh * 18 July 1993 16327Sjkh * 17327Sjkh * This is the main body of the create module. 18327Sjkh * 19327Sjkh */ 20327Sjkh 2193520Sobrien#include <sys/cdefs.h> 2293520Sobrien__FBSDID("$FreeBSD$"); 2393520Sobrien 24222035Sflz#include "lib.h" 25327Sjkh#include "create.h" 26327Sjkh 2730221Scharnier#include <err.h> 2883663Ssobomax#include <libgen.h> 29327Sjkh#include <signal.h> 3089458Ssobomax#include <stdlib.h> 31179352Skeramida#include <sys/types.h> 32179352Skeramida#include <sys/stat.h> 338051Sjkh#include <sys/syslimits.h> 3416549Sjkh#include <sys/wait.h> 3513946Sjdp#include <unistd.h> 36327Sjkh 37327Sjkhstatic void sanity_check(void); 3884745Ssobomaxstatic void make_dist(const char *, const char *, const char *, Package *); 39147043Ssobomaxstatic int create_from_installed_recursive(const char *, const char *); 40147043Ssobomaxstatic int create_from_installed(const char *, const char *, const char *); 41327Sjkh 42327Sjkhint 43327Sjkhpkg_perform(char **pkgs) 44327Sjkh{ 45194497Sbrian static const char *home; 46327Sjkh char *pkg = *pkgs; /* Only one arg to create */ 4711780Sjkh char *cp; 48327Sjkh FILE *pkg_in, *fp; 49327Sjkh Package plist; 5038933Sjkh int len; 5184745Ssobomax const char *suf; 52327Sjkh 53327Sjkh /* Preliminary setup */ 5484670Ssobomax if (InstalledPkg == NULL) 5584670Ssobomax sanity_check(); 567986Sjkh if (Verbose && !PlistOnly) 57327Sjkh printf("Creating package %s\n", pkg); 58327Sjkh 5941530Sasami /* chop suffix off if already specified, remembering if we want to compress */ 6038933Sjkh len = strlen(pkg); 6149637Sbillf if (len > 4) { 62102384Sobrien if (!strcmp(&pkg[len - 4], ".tbz")) { 63102384Sobrien Zipper = BZIP2; 64102384Sobrien pkg[len - 4] = '\0'; 65102384Sobrien } 66102384Sobrien else if (!strcmp(&pkg[len - 4], ".tgz")) { 6795161Sobrien Zipper = GZIP; 6841530Sasami pkg[len - 4] = '\0'; 6941530Sasami } 70213718Sflz else if (!strcmp(&pkg[len - 4], ".txz")) { 71213718Sflz Zipper = XZ; 72213718Sflz pkg[len - 4] = '\0'; 73213718Sflz } 7441530Sasami else if (!strcmp(&pkg[len - 4], ".tar")) { 7595161Sobrien Zipper = NONE; 7641530Sasami pkg[len - 4] = '\0'; 7741530Sasami } 7849637Sbillf } 7995161Sobrien if (Zipper == BZIP2) { 80101302Sobrien suf = "tbz"; 81102384Sobrien setenv("BZIP2", "--best", 0); 8295161Sobrien } else if (Zipper == GZIP) { 8341530Sasami suf = "tgz"; 8489458Ssobomax setenv("GZIP", "-9", 0); 85213718Sflz } else if (Zipper == XZ) { 86213718Sflz suf = "txz"; 8789458Ssobomax } else 8841530Sasami suf = "tar"; 89327Sjkh 90147043Ssobomax if (InstalledPkg != NULL) { 91152210Skrion char *pkgglob[] = { InstalledPkg, NULL }; 92152210Skrion char **matched, **pkgs; 93152210Skrion int i, error; 94152210Skrion 95152210Skrion pkgs = pkgglob; 96152210Skrion if (MatchType != MATCH_EXACT) { 97152210Skrion matched = matchinstalled(MatchType, pkgs, &error); 98152210Skrion if (!error && matched != NULL) 99152210Skrion pkgs = matched; 100152210Skrion else if (MatchType != MATCH_GLOB) 101152210Skrion errx(1, "no packages match pattern"); 102152210Skrion } 103152210Skrion /* 104152210Skrion * Is there is only one installed package matching the pattern, 105152210Skrion * we need to respect the optional pkg-filename parameter. If, 106152210Skrion * however, the pattern matches several packages, this parameter 107152210Skrion * makes no sense and is ignored. 108152210Skrion */ 109152210Skrion if (pkgs[1] == NULL) { 110152210Skrion if (pkg == InstalledPkg) 111152210Skrion pkg = *pkgs; 112152210Skrion InstalledPkg = *pkgs; 113152210Skrion if (!Recursive) 114152210Skrion return (create_from_installed(InstalledPkg, pkg, suf)); 115152210Skrion return (create_from_installed_recursive(pkg, suf)); 116152210Skrion } 117152210Skrion for (i = 0; pkgs[i] != NULL; i++) { 118152210Skrion InstalledPkg = pkg = pkgs[i]; 119152210Skrion if (!Recursive) 120152210Skrion create_from_installed(pkg, pkg, suf); 121152210Skrion else 122152210Skrion create_from_installed_recursive(pkg, suf); 123152210Skrion } 124152210Skrion return TRUE; 125147043Ssobomax } 12684670Ssobomax 12784670Ssobomax get_dash_string(&Comment); 12884670Ssobomax get_dash_string(&Desc); 12984670Ssobomax if (!strcmp(Contents, "-")) 13084670Ssobomax pkg_in = stdin; 13184670Ssobomax else { 13284670Ssobomax pkg_in = fopen(Contents, "r"); 13384670Ssobomax if (!pkg_in) { 13484670Ssobomax cleanup(0); 13596388Salfred errx(2, "%s: unable to open contents file '%s' for input", 13696392Salfred __func__, Contents); 13784670Ssobomax } 13884670Ssobomax } 13984670Ssobomax plist.head = plist.tail = NULL; 14084670Ssobomax 1417713Sjkh /* Stick the dependencies, if any, at the top */ 1427733Sjkh if (Pkgdeps) { 14396076Ssobomax char **deps, *deporigin; 14474295Ssobomax int i; 14574295Ssobomax int ndeps = 0; 14674295Ssobomax 1477991Sjkh if (Verbose && !PlistOnly) 1487733Sjkh printf("Registering depends:"); 14974295Ssobomax 15074295Ssobomax /* Count number of dependencies */ 15174295Ssobomax for (cp = Pkgdeps; cp != NULL && *cp != '\0'; 15274295Ssobomax cp = strpbrk(++cp, " \t\n")) { 15374295Ssobomax ndeps++; 15474295Ssobomax } 15574295Ssobomax 15674295Ssobomax if (ndeps != 0) { 15774295Ssobomax /* Create easy to use NULL-terminated list */ 15874295Ssobomax deps = alloca(sizeof(*deps) * ndeps + 1); 15974295Ssobomax if (deps == NULL) { 16096392Salfred errx(2, "%s: alloca() failed", __func__); 16174295Ssobomax /* Not reached */ 16274295Ssobomax } 16390985Ssobomax for (i = 0; Pkgdeps;) { 16474295Ssobomax cp = strsep(&Pkgdeps, " \t\n"); 16590985Ssobomax if (*cp) { 16674295Ssobomax deps[i] = cp; 16790985Ssobomax i++; 16890985Ssobomax } 16974295Ssobomax } 17090985Ssobomax ndeps = i; 17174295Ssobomax deps[ndeps] = NULL; 17274295Ssobomax 17374295Ssobomax sortdeps(deps); 17474295Ssobomax for (i = 0; i < ndeps; i++) { 17596076Ssobomax deporigin = strchr(deps[i], ':'); 17696076Ssobomax if (deporigin != NULL) { 17796076Ssobomax *deporigin = '\0'; 17896076Ssobomax add_plist_top(&plist, PLIST_DEPORIGIN, ++deporigin); 17996076Ssobomax } 18074295Ssobomax add_plist_top(&plist, PLIST_PKGDEP, deps[i]); 1817992Sjkh if (Verbose && !PlistOnly) 18274295Ssobomax printf(" %s", deps[i]); 1837733Sjkh } 1847713Sjkh } 18574295Ssobomax 1867991Sjkh if (Verbose && !PlistOnly) 1877733Sjkh printf(".\n"); 1887713Sjkh } 18926473Sjkh 190113594Skris /* Put the conflicts directly after the dependencies, if any */ 191113594Skris if (Conflicts) { 192113594Skris if (Verbose && !PlistOnly) 193113594Skris printf("Registering conflicts:"); 194113594Skris while (Conflicts) { 195113594Skris cp = strsep(&Conflicts, " \t\n"); 196113594Skris if (*cp) { 197113594Skris add_plist(&plist, PLIST_CONFLICTS, cp); 198113594Skris if (Verbose && !PlistOnly) 199113594Skris printf(" %s", cp); 200113594Skris } 201113594Skris } 202113594Skris if (Verbose && !PlistOnly) 203113594Skris printf(".\n"); 204113594Skris } 205113594Skris 20626473Sjkh /* If a SrcDir override is set, add it now */ 20726473Sjkh if (SrcDir) { 20826473Sjkh if (Verbose && !PlistOnly) 20926473Sjkh printf("Using SrcDir value of %s\n", SrcDir); 21026473Sjkh add_plist(&plist, PLIST_SRC, SrcDir); 21126473Sjkh } 21226473Sjkh 213327Sjkh /* Slurp in the packing list */ 214327Sjkh read_plist(&plist, pkg_in); 215327Sjkh 21631166Sjkh /* Prefix should add an @cwd to the packing list */ 217231300Seadler if (Prefix) { 218240682Sbapt if (Prefix[0] != '/') { 219240682Sbapt char resolved_prefix[PATH_MAX]; 220240682Sbapt if (realpath(Prefix, resolved_prefix) == NULL) 221240682Sbapt err(EXIT_FAILURE, "couldn't resolve path for prefix: %s", Prefix); 222240682Sbapt add_plist_top(&plist, PLIST_CWD, resolved_prefix); 223240682Sbapt } else { 224240682Sbapt add_plist_top(&plist, PLIST_CWD, Prefix); 225240682Sbapt } 226231300Seadler } 22796066Ssobomax 22896066Ssobomax /* Add the origin if asked, at the top */ 22996066Ssobomax if (Origin) 23096066Ssobomax add_plist_top(&plist, PLIST_ORIGIN, Origin); 23196066Ssobomax 232379Sjkh /* 233379Sjkh * Run down the list and see if we've named it, if not stick in a name 234379Sjkh * at the top. 235379Sjkh */ 2361546Sjkh if (find_plist(&plist, PLIST_NAME) == NULL) 23781571Sobrien add_plist_top(&plist, PLIST_NAME, basename(pkg)); 238379Sjkh 23984750Ssobomax if (asprintf(&cp, "PKG_FORMAT_REVISION:%d.%d", PLIST_FMT_VER_MAJOR, 24084750Ssobomax PLIST_FMT_VER_MINOR) == -1) { 24196392Salfred errx(2, "%s: asprintf() failed", __func__); 24284750Ssobomax } 24384750Ssobomax add_plist_top(&plist, PLIST_COMMENT, cp); 24484750Ssobomax free(cp); 24584750Ssobomax 2467986Sjkh /* 2477986Sjkh * We're just here for to dump out a revised plist for the FreeBSD ports 2487986Sjkh * hack. It's not a real create in progress. 2497986Sjkh */ 2507986Sjkh if (PlistOnly) { 25127192Sjkh check_list(home, &plist); 2527986Sjkh write_plist(&plist, stdout); 2537986Sjkh exit(0); 2547986Sjkh } 2557986Sjkh 256327Sjkh /* Make a directory to stomp around in */ 2573577Sjkh home = make_playpen(PlayPen, 0); 258327Sjkh signal(SIGINT, cleanup); 259327Sjkh signal(SIGHUP, cleanup); 260327Sjkh 261327Sjkh /* Make first "real contents" pass over it */ 262327Sjkh check_list(home, &plist); 26376739Ssobomax (void) umask(022); /* 26476739Ssobomax * Make sure gen'ed directories, files don't have 26576739Ssobomax * group or other write bits. 26676739Ssobomax */ 2678000Sjkh /* copy_plist(home, &plist); */ 2688000Sjkh /* mark_plist(&plist); */ 269327Sjkh 270327Sjkh /* Now put the release specific items in */ 271231300Seadler if (!Prefix) { 272231300Seadler add_plist(&plist, PLIST_CWD, "."); 273231300Seadler } 274327Sjkh write_file(COMMENT_FNAME, Comment); 275327Sjkh add_plist(&plist, PLIST_IGNORE, NULL); 276327Sjkh add_plist(&plist, PLIST_FILE, COMMENT_FNAME); 277131277Seik add_cksum(&plist, plist.tail, COMMENT_FNAME); 278327Sjkh write_file(DESC_FNAME, Desc); 279327Sjkh add_plist(&plist, PLIST_IGNORE, NULL); 280327Sjkh add_plist(&plist, PLIST_FILE, DESC_FNAME); 281131277Seik add_cksum(&plist, plist.tail, DESC_FNAME); 282327Sjkh 283327Sjkh if (Install) { 284327Sjkh copy_file(home, Install, INSTALL_FNAME); 285327Sjkh add_plist(&plist, PLIST_IGNORE, NULL); 286327Sjkh add_plist(&plist, PLIST_FILE, INSTALL_FNAME); 287131277Seik add_cksum(&plist, plist.tail, INSTALL_FNAME); 288327Sjkh } 28941866Sjkh if (PostInstall) { 29041866Sjkh copy_file(home, PostInstall, POST_INSTALL_FNAME); 29141866Sjkh add_plist(&plist, PLIST_IGNORE, NULL); 29241866Sjkh add_plist(&plist, PLIST_FILE, POST_INSTALL_FNAME); 293131277Seik add_cksum(&plist, plist.tail, POST_INSTALL_FNAME); 29441866Sjkh } 295327Sjkh if (DeInstall) { 296327Sjkh copy_file(home, DeInstall, DEINSTALL_FNAME); 297327Sjkh add_plist(&plist, PLIST_IGNORE, NULL); 298327Sjkh add_plist(&plist, PLIST_FILE, DEINSTALL_FNAME); 299131277Seik add_cksum(&plist, plist.tail, DEINSTALL_FNAME); 300327Sjkh } 30141866Sjkh if (PostDeInstall) { 30241866Sjkh copy_file(home, PostDeInstall, POST_DEINSTALL_FNAME); 30341866Sjkh add_plist(&plist, PLIST_IGNORE, NULL); 30441866Sjkh add_plist(&plist, PLIST_FILE, POST_DEINSTALL_FNAME); 305131277Seik add_cksum(&plist, plist.tail, POST_DEINSTALL_FNAME); 30641866Sjkh } 307327Sjkh if (Require) { 308327Sjkh copy_file(home, Require, REQUIRE_FNAME); 309327Sjkh add_plist(&plist, PLIST_IGNORE, NULL); 310327Sjkh add_plist(&plist, PLIST_FILE, REQUIRE_FNAME); 311131277Seik add_cksum(&plist, plist.tail, REQUIRE_FNAME); 312327Sjkh } 3134996Sjkh if (Display) { 3144996Sjkh copy_file(home, Display, DISPLAY_FNAME); 3154996Sjkh add_plist(&plist, PLIST_IGNORE, NULL); 3164996Sjkh add_plist(&plist, PLIST_FILE, DISPLAY_FNAME); 317131277Seik add_cksum(&plist, plist.tail, DISPLAY_FNAME); 3184996Sjkh add_plist(&plist, PLIST_DISPLAY, DISPLAY_FNAME); 3194996Sjkh } 3204996Sjkh if (Mtree) { 3214996Sjkh copy_file(home, Mtree, MTREE_FNAME); 3224996Sjkh add_plist(&plist, PLIST_IGNORE, NULL); 3234996Sjkh add_plist(&plist, PLIST_FILE, MTREE_FNAME); 324131277Seik add_cksum(&plist, plist.tail, MTREE_FNAME); 3254996Sjkh add_plist(&plist, PLIST_MTREE, MTREE_FNAME); 3264996Sjkh } 327327Sjkh 328327Sjkh /* Finally, write out the packing list */ 329327Sjkh fp = fopen(CONTENTS_FNAME, "w"); 33039068Sjkh if (!fp) { 33139068Sjkh cleanup(0); 33296388Salfred errx(2, "%s: can't open file %s for writing", 33396392Salfred __func__, CONTENTS_FNAME); 33439068Sjkh } 335327Sjkh write_plist(&plist, fp); 33639068Sjkh if (fclose(fp)) { 33739068Sjkh cleanup(0); 33896388Salfred errx(2, "%s: error while closing %s", 33996392Salfred __func__, CONTENTS_FNAME); 34039068Sjkh } 341327Sjkh 342327Sjkh /* And stick it into a tar ball */ 34341530Sasami make_dist(home, pkg, suf, &plist); 344327Sjkh 345327Sjkh /* Cleanup */ 346327Sjkh free(Comment); 347327Sjkh free(Desc); 348327Sjkh free_plist(&plist); 34933427Sjkh leave_playpen(); 350327Sjkh return TRUE; /* Success */ 351327Sjkh} 352327Sjkh 353327Sjkhstatic void 35484745Ssobomaxmake_dist(const char *homedir, const char *pkg, const char *suff, Package *plist) 355327Sjkh{ 356179352Skeramida struct stat sb; 357327Sjkh char tball[FILENAME_MAX]; 3588419Sjkh PackingList p; 35916549Sjkh int ret; 36084745Ssobomax const char *args[50]; /* Much more than enough. */ 3618419Sjkh int nargs = 0; 36213946Sjdp int pipefds[2]; 36313946Sjdp FILE *totar; 36413946Sjdp pid_t pid; 36584745Ssobomax const char *cname; 366154102Skrion char *prefix = NULL; 367327Sjkh 368154102Skrion 3698419Sjkh args[nargs++] = "tar"; /* argv[0] */ 3708419Sjkh 3712389Sadam if (*pkg == '/') 37284745Ssobomax snprintf(tball, FILENAME_MAX, "%s.%s", pkg, suff); 3732389Sadam else 37484745Ssobomax snprintf(tball, FILENAME_MAX, "%s/%s.%s", homedir, pkg, suff); 3758419Sjkh 376179352Skeramida /* 377179352Skeramida * If the package tarball exists already, and we are running in `no 378179352Skeramida * clobber' mode, skip this package. 379179352Skeramida */ 380179352Skeramida if (stat(tball, &sb) == 0 && Regenerate == FALSE) { 381179352Skeramida if (Verbose) 382179352Skeramida printf("Skipping package '%s'. It already exists.\n", tball); 383179352Skeramida return; 384179352Skeramida } 385179352Skeramida 3868419Sjkh args[nargs++] = "-c"; 3878419Sjkh args[nargs++] = "-f"; 3888419Sjkh args[nargs++] = tball; 38984745Ssobomax if (strchr(suff, 'z')) { /* Compress/gzip/bzip2? */ 39095161Sobrien if (Zipper == BZIP2) { 39195161Sobrien args[nargs++] = "-j"; 39271373Ssobomax cname = "bzip'd "; 39371373Ssobomax } 394213718Sflz else if (Zipper == XZ) { 395213718Sflz args[nargs++] = "-J"; 396213718Sflz cname = "xz'd "; 397213718Sflz } 39871373Ssobomax else { 39971373Ssobomax args[nargs++] = "-z"; 40071373Ssobomax cname = "gzip'd "; 40171373Ssobomax } 40271373Ssobomax } else { 40371373Ssobomax cname = ""; 40471373Ssobomax } 4051520Salm if (Dereference) 4068419Sjkh args[nargs++] = "-h"; 4078419Sjkh if (ExcludeFrom) { 4088419Sjkh args[nargs++] = "-X"; 4098419Sjkh args[nargs++] = ExcludeFrom; 4108419Sjkh } 41113946Sjdp args[nargs++] = "-T"; /* Take filenames from file instead of args. */ 41213946Sjdp args[nargs++] = "-"; /* Use stdin for the file. */ 41313946Sjdp args[nargs] = NULL; 4148419Sjkh 415327Sjkh if (Verbose) 41671373Ssobomax printf("Creating %star ball in '%s'\n", cname, tball); 4178419Sjkh 41813946Sjdp /* Set up a pipe for passing the filenames, and fork off a tar process. */ 41939068Sjkh if (pipe(pipefds) == -1) { 42039068Sjkh cleanup(0); 42196392Salfred errx(2, "%s: cannot create pipe", __func__); 42239068Sjkh } 42339068Sjkh if ((pid = fork()) == -1) { 42439068Sjkh cleanup(0); 42596392Salfred errx(2, "%s: cannot fork process for tar", __func__); 42639068Sjkh } 42713946Sjdp if (pid == 0) { /* The child */ 42813946Sjdp dup2(pipefds[0], 0); 42914728Sjdp close(pipefds[0]); 43013946Sjdp close(pipefds[1]); 43184745Ssobomax execv("/usr/bin/tar", (char * const *)(uintptr_t)args); 43230221Scharnier cleanup(0); 43396392Salfred errx(2, "%s: failed to execute tar command", __func__); 43413946Sjdp } 4358419Sjkh 43613946Sjdp /* Meanwhile, back in the parent process ... */ 43713946Sjdp close(pipefds[0]); 43839068Sjkh if ((totar = fdopen(pipefds[1], "w")) == NULL) { 43939068Sjkh cleanup(0); 44096392Salfred errx(2, "%s: fdopen failed", __func__); 44139068Sjkh } 44213946Sjdp 44313946Sjdp fprintf(totar, "%s\n", CONTENTS_FNAME); 44413946Sjdp fprintf(totar, "%s\n", COMMENT_FNAME); 44513946Sjdp fprintf(totar, "%s\n", DESC_FNAME); 44613946Sjdp 4478419Sjkh if (Install) 44813946Sjdp fprintf(totar, "%s\n", INSTALL_FNAME); 44941866Sjkh if (PostInstall) 45041866Sjkh fprintf(totar, "%s\n", POST_INSTALL_FNAME); 4518419Sjkh if (DeInstall) 45213946Sjdp fprintf(totar, "%s\n", DEINSTALL_FNAME); 45341866Sjkh if (PostDeInstall) 45441866Sjkh fprintf(totar, "%s\n", POST_DEINSTALL_FNAME); 4558419Sjkh if (Require) 45613946Sjdp fprintf(totar, "%s\n", REQUIRE_FNAME); 4578419Sjkh if (Display) 45813946Sjdp fprintf(totar, "%s\n", DISPLAY_FNAME); 4598419Sjkh if (Mtree) 46013946Sjdp fprintf(totar, "%s\n", MTREE_FNAME); 4618419Sjkh 4628000Sjkh for (p = plist->head; p; p = p->next) { 4638419Sjkh if (p->type == PLIST_FILE) 46413946Sjdp fprintf(totar, "%s\n", p->name); 465154102Skrion else if (p->type == PLIST_CWD && p->name == NULL) 466154102Skrion fprintf(totar, "-C\n%s\n", prefix); 467131277Seik else if (p->type == PLIST_CWD && BaseDir && p->name && p->name[0] == '/') 468131277Seik fprintf(totar, "-C\n%s%s\n", BaseDir, p->name); 46913946Sjdp else if (p->type == PLIST_CWD || p->type == PLIST_SRC) 47013946Sjdp fprintf(totar, "-C\n%s\n", p->name); 4718000Sjkh else if (p->type == PLIST_IGNORE) 4728000Sjkh p = p->next; 473154102Skrion if (p->type == PLIST_CWD && !prefix) 474154102Skrion prefix = p->name; 475154102Skrion 4768000Sjkh } 47713946Sjdp 47813946Sjdp fclose(totar); 47913946Sjdp wait(&ret); 4808419Sjkh /* assume either signal or bad exit is enough for us */ 48139068Sjkh if (ret) { 48239068Sjkh cleanup(0); 48396392Salfred errx(2, "%s: tar command failed with code %d", __func__, ret); 48439068Sjkh } 485327Sjkh} 486327Sjkh 487327Sjkhstatic void 488327Sjkhsanity_check() 489327Sjkh{ 49039068Sjkh if (!Comment) { 49139068Sjkh cleanup(0); 49296388Salfred errx(2, "%s: required package comment string is missing (-c comment)", 49396392Salfred __func__); 49439068Sjkh } 49539068Sjkh if (!Desc) { 49639068Sjkh cleanup(0); 49796388Salfred errx(2, "%s: required package description string is missing (-d desc)", 49896392Salfred __func__); 49939068Sjkh } 50039068Sjkh if (!Contents) { 50139068Sjkh cleanup(0); 50296388Salfred errx(2, "%s: required package contents list is missing (-f [-]file)", 50396392Salfred __func__); 50439068Sjkh } 505327Sjkh} 506327Sjkh 507327Sjkh 508327Sjkh/* Clean up those things that would otherwise hang around */ 509327Sjkhvoid 510327Sjkhcleanup(int sig) 511327Sjkh{ 51233427Sjkh int in_cleanup = 0; 51333427Sjkh 51433427Sjkh if (!in_cleanup) { 51533427Sjkh in_cleanup = 1; 51633427Sjkh leave_playpen(); 51733427Sjkh } 51837914Sjkh if (sig) 51937914Sjkh exit(1); 520327Sjkh} 52184670Ssobomax 52284670Ssobomaxstatic int 523147043Ssobomaxcreate_from_installed_recursive(const char *pkg, const char *suf) 52484670Ssobomax{ 52584670Ssobomax FILE *fp; 52684670Ssobomax Package plist; 527147043Ssobomax PackingList p; 528147043Ssobomax char tmp[PATH_MAX]; 529147043Ssobomax int rval; 530147043Ssobomax 531147043Ssobomax if (!create_from_installed(InstalledPkg, pkg, suf)) 532147043Ssobomax return FALSE; 533147043Ssobomax snprintf(tmp, sizeof(tmp), "%s/%s/%s", LOG_DIR, InstalledPkg, CONTENTS_FNAME); 534147043Ssobomax if (!fexists(tmp)) { 535147043Ssobomax warnx("can't find package '%s' installed!", InstalledPkg); 536147043Ssobomax return FALSE; 537147043Ssobomax } 538147043Ssobomax /* Suck in the contents list */ 539147043Ssobomax plist.head = plist.tail = NULL; 540147043Ssobomax fp = fopen(tmp, "r"); 541147043Ssobomax if (!fp) { 542147043Ssobomax warnx("unable to open %s file", tmp); 543147043Ssobomax return FALSE; 544147043Ssobomax } 545147043Ssobomax read_plist(&plist, fp); 546147043Ssobomax fclose(fp); 547147043Ssobomax rval = TRUE; 548147043Ssobomax for (p = plist.head; p ; p = p->next) { 549147043Ssobomax if (p->type != PLIST_PKGDEP) 550147043Ssobomax continue; 551147043Ssobomax if (Verbose) 552147043Ssobomax printf("Creating package %s\n", p->name); 553147043Ssobomax if (!create_from_installed(p->name, p->name, suf)) { 554147043Ssobomax rval = FALSE; 555147043Ssobomax break; 556147043Ssobomax } 557147043Ssobomax } 558147043Ssobomax free_plist(&plist); 559147043Ssobomax return rval; 560147043Ssobomax} 561147043Ssobomax 562147043Ssobomaxstatic int 563147043Ssobomaxcreate_from_installed(const char *ipkg, const char *pkg, const char *suf) 564147043Ssobomax{ 565147043Ssobomax FILE *fp; 566147043Ssobomax Package plist; 56784745Ssobomax char homedir[MAXPATHLEN], log_dir[FILENAME_MAX]; 56884670Ssobomax 569147043Ssobomax snprintf(log_dir, sizeof(log_dir), "%s/%s", LOG_DIR, ipkg); 57084670Ssobomax if (!fexists(log_dir)) { 571147043Ssobomax warnx("can't find package '%s' installed!", ipkg); 57296300Ssobomax return FALSE; 57384670Ssobomax } 57484745Ssobomax getcwd(homedir, sizeof(homedir)); 57584670Ssobomax if (chdir(log_dir) == FAIL) { 57684670Ssobomax warnx("can't change directory to '%s'!", log_dir); 57796300Ssobomax return FALSE; 57884670Ssobomax } 57984670Ssobomax /* Suck in the contents list */ 58084670Ssobomax plist.head = plist.tail = NULL; 58184670Ssobomax fp = fopen(CONTENTS_FNAME, "r"); 58284670Ssobomax if (!fp) { 58384670Ssobomax warnx("unable to open %s file", CONTENTS_FNAME); 58496300Ssobomax return FALSE; 58584670Ssobomax } 58684670Ssobomax read_plist(&plist, fp); 58784670Ssobomax fclose(fp); 58884670Ssobomax 589132789Skan Install = isfile(INSTALL_FNAME) ? (char *)INSTALL_FNAME : NULL; 590132789Skan PostInstall = isfile(POST_INSTALL_FNAME) ? 591132789Skan (char *)POST_INSTALL_FNAME : NULL; 592132789Skan DeInstall = isfile(DEINSTALL_FNAME) ? (char *)DEINSTALL_FNAME : NULL; 593132789Skan PostDeInstall = isfile(POST_DEINSTALL_FNAME) ? 594132789Skan (char *)POST_DEINSTALL_FNAME : NULL; 595132789Skan Require = isfile(REQUIRE_FNAME) ? (char *)REQUIRE_FNAME : NULL; 596132789Skan Display = isfile(DISPLAY_FNAME) ? (char *)DISPLAY_FNAME : NULL; 597132789Skan Mtree = isfile(MTREE_FNAME) ? (char *)MTREE_FNAME : NULL; 59896300Ssobomax 59984745Ssobomax make_dist(homedir, pkg, suf, &plist); 60084670Ssobomax 60184670Ssobomax free_plist(&plist); 602147043Ssobomax if (chdir(homedir) == FAIL) { 603147043Ssobomax warnx("can't change directory to '%s'!", homedir); 604147043Ssobomax return FALSE; 605147043Ssobomax } 60684670Ssobomax return TRUE; 60784670Ssobomax} 608