From 36b7319742ddd913fef91b3fd8b52ed3db79baed Mon Sep 17 00:00:00 2001 From: "Jordan K. Hubbard" Date: Wed, 25 Oct 1995 15:38:37 +0000 Subject: [PATCH] Bring forward my changes from 2.1 --- usr.sbin/pkg_install/add/add.h | 5 +- usr.sbin/pkg_install/add/main.c | 7 +- usr.sbin/pkg_install/add/perform.c | 377 +++++++++++++------------- usr.sbin/pkg_install/create/create.h | 4 +- usr.sbin/pkg_install/create/main.c | 6 +- usr.sbin/pkg_install/create/perform.c | 8 +- usr.sbin/pkg_install/info/info.h | 4 +- usr.sbin/pkg_install/info/main.c | 6 +- usr.sbin/pkg_install/info/perform.c | 14 +- usr.sbin/pkg_install/lib/file.c | 134 ++++++--- usr.sbin/pkg_install/lib/lib.h | 9 +- usr.sbin/pkg_install/lib/pen.c | 124 +++++---- usr.sbin/pkg_install/lib/str.c | 12 + 13 files changed, 400 insertions(+), 310 deletions(-) diff --git a/usr.sbin/pkg_install/add/add.h b/usr.sbin/pkg_install/add/add.h index fe9b5fa29c7e..d2d89702d4cd 100644 --- a/usr.sbin/pkg_install/add/add.h +++ b/usr.sbin/pkg_install/add/add.h @@ -1,4 +1,4 @@ -/* $Id: add.h,v 1.4 1994/12/06 00:51:31 jkh Exp $ */ +/* $Id: add.h,v 1.5.4.2 1995/10/14 19:10:59 jkh Exp $ */ /* * FreeBSD install - a package for the installation and maintainance @@ -34,9 +34,8 @@ extern char *Owner; extern char *Group; extern char *Directory; extern char *PkgName; -extern char *PlayPen; +extern char FirstPen[]; extern add_mode_t AddMode; -extern char *Home; int make_hierarchy(char *); void extract_plist(char *, Package *); diff --git a/usr.sbin/pkg_install/add/main.c b/usr.sbin/pkg_install/add/main.c index 47d81a5922e4..750121f55739 100644 --- a/usr.sbin/pkg_install/add/main.c +++ b/usr.sbin/pkg_install/add/main.c @@ -1,5 +1,5 @@ #ifndef lint -static char *rcsid = "$Id: main.c,v 1.6 1995/04/09 15:04:50 jkh Exp $"; +static char *rcsid = "$Id: main.c,v 1.7.4.2 1995/10/14 19:11:01 jkh Exp $"; #endif /* @@ -38,8 +38,7 @@ char *Owner = NULL; char *Group = NULL; char *PkgName = NULL; char *Directory = NULL; -char *PlayPen = NULL; -char *Home = NULL; +char FirstPen[FILENAME_MAX]; add_mode_t AddMode = NORMAL; int @@ -78,7 +77,7 @@ main(int argc, char **argv) break; case 't': - PlayPen = optarg; + strcpy(FirstPen, optarg); break; case 'S': diff --git a/usr.sbin/pkg_install/add/perform.c b/usr.sbin/pkg_install/add/perform.c index 7438edd41367..bee2fbbf03f3 100644 --- a/usr.sbin/pkg_install/add/perform.c +++ b/usr.sbin/pkg_install/add/perform.c @@ -1,5 +1,5 @@ #ifndef lint -static const char *rcsid = "$Id: perform.c,v 1.28 1995/08/06 03:20:01 jkh Exp $"; +static const char *rcsid = "$Id: perform.c,v 1.26.2.5 1995/10/23 12:33:38 jkh Exp $"; #endif /* @@ -32,7 +32,6 @@ static int pkg_do(char *); static int sanity_check(char *); static char LogDir[FILENAME_MAX]; - int pkg_perform(char **pkgs) { @@ -51,6 +50,7 @@ pkg_perform(char **pkgs) } static Package Plist; +static char *Home; /* * This is seriously ugly code following. Written very fast! @@ -61,212 +61,137 @@ static int pkg_do(char *pkg) { char pkg_fullname[FILENAME_MAX]; - char home[FILENAME_MAX]; + char playpen[FILENAME_MAX]; char extract_contents[FILENAME_MAX]; char *where_to, *tmp; FILE *cfile; - int code = 0; + int code; PackingList p; struct stat sb; char *isTMP = NULL; + char *cp; + int inPlace; - /* Reset some state */ - if (Plist.head) - free_plist(&Plist); + code = 0; LogDir[0] = '\0'; + strcpy(playpen, FirstPen); + inPlace = 0; /* Are we coming in for a second pass, everything already extracted? */ - if (AddMode == SLAVE) { - char tmp_dir[FILENAME_MAX]; - - fgets(tmp_dir, FILENAME_MAX, stdin); - tmp_dir[strlen(tmp_dir) - 1] = '\0'; /* pesky newline! */ - if (chdir(tmp_dir) == FAIL) { - whinge("pkg_add in SLAVE mode can't chdir to %s.", tmp_dir); + if (!pkg) { + fgets(playpen, FILENAME_MAX, stdin); + playpen[strlen(playpen) - 1] = '\0'; /* pesky newline! */ + if (chdir(playpen) == FAIL) { + whinge("pkg_add in SLAVE mode can't chdir to %s.", playpen); return 1; } read_plist(&Plist, stdin); + where_to = playpen; } /* Nope - do it now */ else { - if (!getcwd(home, FILENAME_MAX)) - upchuck("getcwd"); - + /* Is it an ftp://foo.bar.baz/file.tgz specification? */ if (isURL(pkg)) { - char *newname = fileGetURL(pkg); - - if (!newname) { + if (!(Home = fileGetURL(NULL, pkg))) { whinge("Unable to fetch `%s' by URL.", pkg); return 1; } - strcpy(pkg_fullname, newname); - isTMP = pkg_fullname; + where_to = Home; + strcpy(pkg_fullname, pkg); + cfile = fopen(CONTENTS_FNAME, "r"); + if (!cfile) { + whinge("Unable to open table of contents file `%s' - not a package?", CONTENTS_FNAME); + goto bomb; + } + read_plist(&Plist, cfile); + fclose(cfile); } else { if (pkg[0] == '/') /* full pathname? */ strcpy(pkg_fullname, pkg); else - sprintf(pkg_fullname, "%s/%s", home, pkg); + sprintf(pkg_fullname, "./%s", pkg); if (!fexists(pkg_fullname)) { - char *tmp = fileFindByPath(pkg); + cp = fileFindByPath(NULL, pkg); - if (!tmp) { + if (!cp) { whinge("Can't find package `%s'.", pkg); return 1; } - strcpy(pkg_fullname, tmp); + strcpy(pkg_fullname, cp); } - } - if (stat(pkg_fullname, &sb) == FAIL) { - whinge("Can't stat package file '%s'.", pkg_fullname); - goto bomb; - } - Home = make_playpen(PlayPen, sb.st_size * 4); - where_to = PlayPen; - sprintf(extract_contents, "--fast-read %s", CONTENTS_FNAME); - if (unpack(pkg_fullname, extract_contents)) { - whinge("Unable to extract table of contents file from `%s' - not a package?.", pkg_fullname); - goto bomb; - } - cfile = fopen(CONTENTS_FNAME, "r"); - if (!cfile) { - whinge("Unable to open table of contents file `%s' - not a package?", CONTENTS_FNAME); - goto bomb; - } - read_plist(&Plist, cfile); - fclose(cfile); + if (stat(pkg_fullname, &sb) == FAIL) { + whinge("Can't stat package file '%s'.", pkg_fullname); + goto bomb; + } + Home = make_playpen(playpen, sb.st_size * 4); + if (!Home) + whinge("Unable to make playpen for %d bytes.\n", sb.st_size * 4); + where_to = Home; + sprintf(extract_contents, "--fast-read %s", CONTENTS_FNAME); + if (unpack(pkg_fullname, extract_contents)) { + whinge("Unable to extract table of contents file from `%s' - not a package?.", pkg_fullname); + goto bomb; + } + cfile = fopen(CONTENTS_FNAME, "r"); + if (!cfile) { + whinge("Unable to open table of contents file `%s' - not a package?", CONTENTS_FNAME); + goto bomb; + } + read_plist(&Plist, cfile); + fclose(cfile); - /* - * If we have a prefix, delete the first one we see and add this - * one in place of it. - */ - if (Prefix) { - delete_plist(&Plist, FALSE, PLIST_CWD, NULL); - add_plist_top(&Plist, PLIST_CWD, Prefix); - } - - /* Extract directly rather than moving? Oh goodie! */ - if (find_plist_option(&Plist, "extract-in-place")) { - if (Verbose) - printf("Doing in-place extraction for %s\n", pkg_fullname); - p = find_plist(&Plist, PLIST_CWD); - if (p) { - if (!isdir(p->name) && !Fake) { - if (Verbose) - printf("Desired prefix of %s does not exist, creating..\n", p->name); - vsystem("mkdir -p %s", p->name); - if (chdir(p->name)) { - whinge("Unable to change directory to `%s' - no permission?", p->name); - perror("chdir"); - goto bomb; + /* Extract directly rather than moving? Oh goodie! */ + if (find_plist_option(&Plist, "extract-in-place")) { + if (Verbose) + printf("Doing in-place extraction for %s\n", pkg_fullname); + p = find_plist(&Plist, PLIST_CWD); + if (p) { + if (!isdir(p->name) && !Fake) { + if (Verbose) + printf("Desired prefix of %s does not exist, creating..\n", p->name); + vsystem("mkdir -p %s", p->name); + if (chdir(p->name) == -1) { + whinge("Unable to change directory to `%s' - no permission?", p->name); + perror("chdir"); + goto bomb; + } } + where_to = p->name; + inPlace = 1; + } + else { + whinge("No prefix specified in `%s' - this is a bad package!", pkg_fullname); + goto bomb; } - where_to = p->name; } - else { - whinge("No prefix specified in `%s' - this is a bad package!", - pkg_fullname); + + /* + * Apply a crude heuristic to see how much space the package will + * take up once it's unpacked. I've noticed that most packages + * compress an average of 75%, so multiply by 4 for good measure. + */ + + if (min_free(where_to) < sb.st_size * 4) { + whinge("Projected size of %d exceeds available free space.\n" + "Please set your PKG_TMPDIR variable to point to a location with more\n" + "free space and try again.", sb.st_size * 4); + whinge("Not extracting %s\ninto %s, sorry!", pkg_fullname, where_to); + goto bomb; + } + + /* If this is a direct extract and we didn't want it, stop now */ + if (inPlace && Fake) + goto success; + + /* Finally unpack the whole mess */ + if (unpack(pkg_fullname, NULL)) { + whinge("Unable to extract `%s'!", pkg_fullname); goto bomb; } } - - /* - * Apply a crude heuristic to see how much space the package will - * take up once it's unpacked. I've noticed that most packages - * compress an average of 75%, so multiply by 4 for good measure. - */ - - if (min_free(where_to) < sb.st_size * 4) { - whinge("Projected size of %d exceeds available free space.\nPlease set your PKG_TMPDIR variable to point to a location with more\nfree space and try again.", sb.st_size * 4); - whinge("Not extracting %s\ninto %s, sorry!", pkg_fullname, where_to); - goto bomb; - } - - setenv(PKG_PREFIX_VNAME, - (p = find_plist(&Plist, PLIST_CWD)) ? p->name : NULL, 1); - /* Protect against old packages with bogus @name fields */ - PkgName = (p = find_plist(&Plist, PLIST_NAME)) ? p->name : "anonymous"; - - /* See if we're already registered */ - sprintf(LogDir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, - basename_of(PkgName)); - if (isdir(LogDir)) { - char tmp[FILENAME_MAX]; - - whinge("Package `%s' already recorded as installed.\n", PkgName); - code = 1; - goto success; /* close enough for government work */ - } - - /* Now check the packing list for dependencies */ - for (p = Plist.head; p ; p = p->next) { - char *isTMP = NULL; /* local copy for depends only */ - - if (p->type != PLIST_PKGDEP) - continue; - if (Verbose) - printf("Package `%s' depends on `%s'", pkg, p->name); - if (!Fake && vsystem("pkg_info -e %s", p->name)) { - char path[FILENAME_MAX], *cp = NULL; - - if (Verbose) - printf(" which is not currently loaded"); - if (!isURL(p->name)) { - snprintf(path, FILENAME_MAX, "%s/%s.tgz", Home, p->name); - if (fexists(path)) - cp = path; - else - cp = fileFindByPath(p->name); - } - else { - cp = fileGetURL(p->name); - isTMP = cp; - } - if (cp) { - if (Verbose) - printf(" but was found - loading:\n"); - if (!Fake && vsystem("pkg_add %s", cp)) { - whinge("Autoload of dependency `%s' failed%s", - p->name, Force ? " (proceeding anyway)" : "!"); - if (!Force) - ++code; - } - else if (Verbose) - printf("\t`%s' loaded successfully.\n", p->name); - /* Nuke the temporary URL copy */ - if (isTMP) { - unlink(isTMP); - isTMP = NULL; - } - } - else { - if (Verbose) - printf("and was not found%s.\n", - Force ? " (proceeding anyway)" : ""); - else - printf("Package dependency %s for %s not found%s\n", - p->name, pkg, - Force ? " (proceeding anyway)" : "!"); - if (!Force) - ++code; - } - } - else if (Verbose) - printf(" - already installed.\n"); - } - - /* If this is a direct extract and we didn't want it, stop now */ - if (where_to != PlayPen && Fake) - goto success; - - /* Finally unpack the whole mess */ - if (unpack(pkg_fullname, NULL)) { - whinge("Unable to extract `%s'!", pkg_fullname); - goto bomb; - } - /* Check for sanity and dependencies */ - if (sanity_check(pkg_fullname)) + if (sanity_check(pkg)) goto bomb; /* If we're running in MASTER mode, just output the plist and return */ @@ -277,14 +202,89 @@ pkg_do(char *pkg) } } + /* + * If we have a prefix, delete the first one we see and add this + * one in place of it. + */ + if (Prefix) { + delete_plist(&Plist, FALSE, PLIST_CWD, NULL); + add_plist_top(&Plist, PLIST_CWD, Prefix); + } + + setenv(PKG_PREFIX_VNAME, (p = find_plist(&Plist, PLIST_CWD)) ? p->name : ".", 1); + /* Protect against old packages with bogus @name fields */ + PkgName = (p = find_plist(&Plist, PLIST_NAME)) ? p->name : "anonymous"; + + /* See if we're already registered */ + sprintf(LogDir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, PkgName); + if (isdir(LogDir)) { + char tmp[FILENAME_MAX]; + + whinge("Package `%s' already recorded as installed.\n", PkgName); + code = 1; + goto success; /* close enough for government work */ + } + + /* Now check the packing list for dependencies */ + for (p = Plist.head; p ; p = p->next) { + if (p->type != PLIST_PKGDEP) + continue; + if (Verbose) + printf("Package `%s' depends on `%s'.\n", PkgName, p->name); + if (!Fake && vsystem("pkg_info -e %s", p->name)) { + char path[FILENAME_MAX], *cp = NULL; + + if (!Fake && !isURL(pkg)) { + snprintf(path, FILENAME_MAX, "%s/%s.tgz", Home, p->name); + if (fexists(path)) + cp = path; + else + cp = fileFindByPath(pkg, p->name); + if (cp) { + if (Verbose) + printf("Loading it from %s.\n", cp); + if (vsystem("pkg_add %s", cp)) { + whinge("Autoload of dependency `%s' failed%s", cp, Force ? " (proceeding anyway)" : "!"); + if (!Force) + ++code; + } + } + } + else if (!Fake && (cp = fileGetURL(pkg, p->name)) != NULL) { + if (Verbose) + printf("Finished loading %s over FTP.\n", p->name); + if (!Fake && (!fexists("+CONTENTS") || vsystem("(pwd; cat +CONTENTS) | pkg_add %s-S"), + Verbose ? "-v " : "")) { + whinge("Autoload of dependency `%s' failed%s", p->name, Force ? " (proceeding anyway)" : "!"); + if (!Force) + ++code; + } + else if (Verbose) + printf("\t`%s' loaded successfully.\n", p->name); + /* Nuke the temporary playpen */ + leave_playpen(cp); + } + else { + if (Verbose) + printf("and was not found%s.\n", Force ? " (proceeding anyway)" : ""); + else + printf("Package dependency %s for %s not found%s\n", p->name, pkg, + Force ? " (proceeding anyway)" : "!"); + if (!Force) + ++code; + } + } + else if (Verbose) + printf(" - already installed.\n"); + } + /* Look for the requirements file */ if (fexists(REQUIRE_FNAME)) { vsystem("chmod +x %s", REQUIRE_FNAME); /* be sure */ if (Verbose) printf("Running requirements file first for %s..\n", PkgName); if (!Fake && vsystem("./%s %s INSTALL", REQUIRE_FNAME, PkgName)) { - whinge("Package %s fails requirements %s", - pkg_fullname, + whinge("Package %s fails requirements %s", pkg_fullname, Force ? "installing anyway" : "- not installed."); if (!Force) { code = 1; @@ -307,19 +307,17 @@ pkg_do(char *pkg) } /* Now finally extract the entire show if we're not going direct */ - if (where_to == PlayPen && !Fake) - extract_plist(home, &Plist); + if (!inPlace && !Fake) + extract_plist(".", &Plist); if (!Fake && fexists(MTREE_FNAME)) { if (Verbose) printf("Running mtree for %s..\n", PkgName); p = find_plist(&Plist, PLIST_CWD); if (Verbose) - printf("mtree -U -f %s -d -e -p %s\n", MTREE_FNAME, - p ? p->name : "/"); + printf("mtree -U -f %s -d -e -p %s\n", MTREE_FNAME, p ? p->name : "/"); if (!Fake) { - if (vsystem("/usr/sbin/mtree -U -f %s -d -e -p %s", - MTREE_FNAME, p ? p->name : "/")) + if (vsystem("/usr/sbin/mtree -U -f %s -d -e -p %s", MTREE_FNAME, p ? p->name : "/")) whinge("mtree returned a non-zero status - continuing."); } unlink(MTREE_FNAME); @@ -351,9 +349,7 @@ pkg_do(char *pkg) code = 1; goto success; /* well, partial anyway */ } - sprintf(LogDir, "%s/%s", - (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, - basename_of(PkgName)); + sprintf(LogDir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, PkgName); if (Verbose) printf("Attempting to record package into %s..\n", LogDir); if (make_hierarchy(LogDir)) { @@ -372,8 +368,7 @@ pkg_do(char *pkg) sprintf(contents, "%s/%s", LogDir, CONTENTS_FNAME); cfile = fopen(contents, "w"); if (!cfile) { - whinge("Can't open new contents file '%s'! Can't register pkg.", - contents); + whinge("Can't open new contents file '%s'! Can't register pkg.", contents); goto success; /* can't log, but still keep pkg */ } write_plist(&Plist, cfile); @@ -386,16 +381,15 @@ pkg_do(char *pkg) if (p->type != PLIST_PKGDEP) continue; if (Verbose) - printf("Attempting to record dependency on package `%s'\n", - p->name); - sprintf(contents, "%s/%s/%s", - (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, + printf("Attempting to record dependency on package `%s'\n", p->name); + sprintf(contents, "%s/%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, basename_of(p->name), REQUIRED_BY_FNAME); cfile = fopen(contents, "a"); if (!cfile) - whinge("Warning: Can't open dependency file '%s'!\n\tDependency registration is incomplete.", contents); + whinge("Warning: Can't open dependency file '%s'!\n" + "\tDependency registration is incomplete.", contents); else { - fprintf(cfile, "%s\n", basename_of(PkgName)); + fprintf(cfile, "%s\n", PkgName); if (fclose(cfile) == EOF) warn("Cannot properly close file %s", contents); } @@ -431,9 +425,8 @@ pkg_do(char *pkg) success: /* delete the packing list contents */ - leave_playpen(); - if (isTMP) - unlink(isTMP); + free_plist(&Plist); + leave_playpen(Home); return code; } @@ -470,5 +463,5 @@ cleanup(int signo) } if (!Fake && LogDir[0]) vsystem("%s -rf %s", REMOVE_CMD, LogDir); - leave_playpen(); + leave_playpen(Home); } diff --git a/usr.sbin/pkg_install/create/create.h b/usr.sbin/pkg_install/create/create.h index 8f4db25b06fe..60dd490b3835 100644 --- a/usr.sbin/pkg_install/create/create.h +++ b/usr.sbin/pkg_install/create/create.h @@ -1,4 +1,4 @@ -/* $Id: create.h,v 1.7 1995/04/09 15:04:57 jkh Exp $ */ +/* $Id: create.h,v 1.8.4.1 1995/10/09 11:16:23 jkh Exp $ */ /* * FreeBSD install - a package for the installation and maintainance @@ -31,7 +31,7 @@ extern char *Install; extern char *DeInstall; extern char *Contents; extern char *Require; -extern char *PlayPen; +extern char PlayPen[]; extern char *ExcludeFrom; extern char *Mtree; extern char *Pkgdeps; diff --git a/usr.sbin/pkg_install/create/main.c b/usr.sbin/pkg_install/create/main.c index f2531b32a40e..757a0e23acd1 100644 --- a/usr.sbin/pkg_install/create/main.c +++ b/usr.sbin/pkg_install/create/main.c @@ -1,5 +1,5 @@ #ifndef lint -static const char *rcsid = "$Id: main.c,v 1.10 1995/04/22 00:03:07 jkh Exp $"; +static const char *rcsid = "$Id: main.c,v 1.11.4.1 1995/10/09 11:16:24 jkh Exp $"; #endif /* @@ -26,7 +26,7 @@ char *Install = NULL; char *DeInstall = NULL; char *Contents = NULL; char *Require = NULL; -char *PlayPen = NULL; +char PlayPen[FILENAME_MAX]; char *ExcludeFrom = NULL; char *Mtree = NULL; char *Pkgdeps = NULL; @@ -88,7 +88,7 @@ main(int argc, char **argv) break; case 't': - PlayPen = optarg; + strcpy(PlayPen, optarg); break; case 'X': diff --git a/usr.sbin/pkg_install/create/perform.c b/usr.sbin/pkg_install/create/perform.c index 0c773e9c5bd7..b1a67ec82162 100644 --- a/usr.sbin/pkg_install/create/perform.c +++ b/usr.sbin/pkg_install/create/perform.c @@ -1,5 +1,5 @@ #ifndef lint -static const char *rcsid = "$Id: perform.c,v 1.26 1995/05/10 20:46:06 jkh Exp $"; +static const char *rcsid = "$Id: perform.c,v 1.27.4.1 1995/10/14 19:11:22 jkh Exp $"; #endif /* @@ -31,11 +31,13 @@ static const char *rcsid = "$Id: perform.c,v 1.26 1995/05/10 20:46:06 jkh Exp $" static void sanity_check(void); static void make_dist(char *, char *, char *, Package *); +static char *home; + int pkg_perform(char **pkgs) { char *pkg = *pkgs; /* Only one arg to create */ - char *home, *cp; + char *cp; FILE *pkg_in, *fp; Package plist; char *suffix; /* What we tack on to the end of the finished package */ @@ -268,5 +270,5 @@ sanity_check() void cleanup(int sig) { - leave_playpen(); + leave_playpen(home); } diff --git a/usr.sbin/pkg_install/info/info.h b/usr.sbin/pkg_install/info/info.h index 860a27578699..56ad7dbfaab0 100644 --- a/usr.sbin/pkg_install/info/info.h +++ b/usr.sbin/pkg_install/info/info.h @@ -1,4 +1,4 @@ -/* $Id: info.h,v 1.6 1994/12/06 00:51:42 jkh Exp $ */ +/* $Id: info.h,v 1.7.4.1 1995/10/09 11:16:25 jkh Exp $ */ /* * FreeBSD install - a package for the installation and maintainance @@ -48,7 +48,7 @@ extern int Flags; extern Boolean AllInstalled; extern Boolean Quiet; extern char *InfoPrefix; -extern char *PlayPen; +extern char PlayPen[]; extern char *CheckPkg; extern void show_file(char *, char *); diff --git a/usr.sbin/pkg_install/info/main.c b/usr.sbin/pkg_install/info/main.c index d63ff13a5789..bcd78d945537 100644 --- a/usr.sbin/pkg_install/info/main.c +++ b/usr.sbin/pkg_install/info/main.c @@ -1,5 +1,5 @@ #ifndef lint -static char *rcsid = "$Id: main.c,v 1.8 1994/12/06 00:51:44 jkh Exp $"; +static char *rcsid = "$Id: main.c,v 1.9.4.1 1995/10/09 11:16:26 jkh Exp $"; #endif /* @@ -32,7 +32,7 @@ int Flags = 0; Boolean AllInstalled = FALSE; Boolean Quiet = FALSE; char *InfoPrefix = ""; -char *PlayPen = NULL; +char PlayPen[FILENAME_MAX]; char *CheckPkg = NULL; int @@ -113,7 +113,7 @@ main(int argc, char **argv) break; case 't': - PlayPen = optarg; + strcpy(PlayPen, optarg); break; case 'e': diff --git a/usr.sbin/pkg_install/info/perform.c b/usr.sbin/pkg_install/info/perform.c index e09abadac569..ed6b259b7596 100644 --- a/usr.sbin/pkg_install/info/perform.c +++ b/usr.sbin/pkg_install/info/perform.c @@ -1,5 +1,5 @@ #ifndef lint -static const char *rcsid = "$Id: perform.c,v 1.16 1995/05/30 03:49:59 rgrimes Exp $"; +static const char *rcsid = "$Id: perform.c,v 1.17 1995/07/30 01:44:38 ache Exp $"; #endif /* @@ -73,6 +73,8 @@ pkg_perform(char **pkgs) return err_cnt; } +static char *Home; + static int pkg_do(char *pkg) { @@ -86,7 +88,7 @@ pkg_do(char *pkg) int code = 0; if (isURL(pkg)) { - if ((cp = fileGetURL(pkg)) != NULL) { + if ((cp = fileGetURL(NULL, pkg)) != NULL) { strcpy(fname, cp); isTMP = TRUE; } @@ -105,7 +107,7 @@ pkg_do(char *pkg) cp = fname; } else { - if ((cp = fileFindByPath(pkg)) != NULL) + if ((cp = fileFindByPath(NULL, pkg)) != NULL) strncpy(fname, cp, FILENAME_MAX); } if (cp) { @@ -120,7 +122,7 @@ pkg_do(char *pkg) code = 1; goto bail; } - (void)make_playpen(PlayPen, sb.st_size / 2); + Home = make_playpen(PlayPen, sb.st_size / 2); if (unpack(fname, "+*")) { whinge("Error during unpacking, no info for '%s' available.", pkg); code = 1; @@ -195,7 +197,7 @@ pkg_do(char *pkg) } free_plist(&plist); bail: - leave_playpen(); + leave_playpen(Home); if (isTMP) unlink(fname); return code; @@ -204,5 +206,5 @@ pkg_do(char *pkg) void cleanup(int sig) { - leave_playpen(); + leave_playpen(Home); } diff --git a/usr.sbin/pkg_install/lib/file.c b/usr.sbin/pkg_install/lib/file.c index 829fa126aa8f..86e00054985f 100644 --- a/usr.sbin/pkg_install/lib/file.c +++ b/usr.sbin/pkg_install/lib/file.c @@ -1,5 +1,5 @@ #ifndef lint -static const char *rcsid = "$Id: file.c,v 1.15 1995/08/01 07:16:50 jkh Exp $"; +static const char *rcsid = "$Id: file.c,v 1.10.4.6 1995/10/15 14:08:40 jkh Exp $"; #endif /* @@ -103,6 +103,8 @@ isURL(char *fname) * also be looking for here, but for now I'll just be happy to get ftp * working. */ + if (!fname) + return FALSE; while (isspace(*fname)) ++fname; if (!strncmp(fname, "ftp://", 6)) @@ -164,24 +166,58 @@ fileURLFilename(char *fname, char *where, int max) #define HOSTNAME_MAX 64 /* - * Try and fetch a file by URL, returning the fd of open - * file if fetched successfully. + * Try and fetch a file by URL, returning the directory name for where + * it's unpacked, if successful. */ char * -fileGetURL(char *fname) +fileGetURL(char *base, char *spec) { char host[HOSTNAME_MAX], file[FILENAME_MAX], dir[FILENAME_MAX]; - char pword[HOSTNAME_MAX + 40], *uname, *cp; - static char tmpl[40]; + char pword[HOSTNAME_MAX + 40], *uname, *cp, *rp, *tmp; + char fname[511]; + char pen[FILENAME_MAX]; struct passwd *pw; FTP_t ftp; + pid_t tpid; int fd, fd2, i, len = 0; char ch; time_t start, stop; - if (!isURL(fname)) - return NULL; + rp = NULL; + if (!isURL(spec)) { + int len; + if (!base) + return NULL; + /* We've been given an existing URL (that's known-good) and now we need + to construct a composite one out of that and the basename we were + handed as a dependency. */ + strncpy(fname, base, 511); + fname[511] = '\0'; + cp = strrchr(fname, '/'); + if (cp) { + *cp = '\0'; /* Eliminate the filename portion */ + len = strlen(fname); + /* Special case for the all category */ + if (len > 3 && !strcmp(cp - 3, "All")) + sprintf(cp, "/%s", spec); + else { + /* Replace category with All */ + if ((cp = strrchr(fname, '/')) != NULL) { + strcat(cp + 1, "All/"); + strcat(cp + 4, spec); + } + else { + strcat(fname, "All/"); + strcat(fname, spec); + } + } + } + else + return NULL; + } + else + strcpy(fname, spec); ftp = FtpInit(); cp = fileURLHost(fname, host, HOSTNAME_MAX); if (!*cp) { @@ -206,9 +242,9 @@ fileGetURL(char *fname) } else snprintf(pword, HOSTNAME_MAX + 40, "%s@%s", pw->pw_name, host); - if (Verbose) - printf("Trying to fetch %s from %s.\n", file, host); + if (Verbose) + printf("Trying to log into %s as %s.\n", host, uname); FtpOpen(ftp, host, uname, pword); if (getenv("FTP_PASSIVE_MODE")) FtpPassive(ftp, TRUE); @@ -223,41 +259,77 @@ fileGetURL(char *fname) } FtpBinary(ftp, TRUE); if (Verbose) printf("FTP: trying to get %s\n", basename_of(file)); - fd = FtpGet(ftp, basename_of(file)); - if (fd < 0) - return NULL; - if ((cp = getenv("PKG_TMPDIR")) != NULL) - sprintf(tmpl, "%s/instpkg-XXXXXX.tgz", cp); + tmp = basename_of(file); + if (!strstr(tmp, ".tgz")) + tmp = strconcat(tmp, ".tgz"); + fd = FtpGet(ftp, tmp); + if (fd >= 0) { + pen[0] = '\0'; + if (rp = make_playpen(pen, 0)) { + if (Verbose) + printf("Extracting from FTP connection into %s\n", pen); + tpid = fork(); + if (!tpid) { + dup2(fd, 0); + i = execl("/usr/bin/tar", "tar", Verbose ? "-xzvf" : "-xzf", "-", 0); + if (Verbose) + printf("tar command returns %d status\n", i); + exit(i); + } + else { + int pstat; + + close(fd); + tpid = waitpid(tpid, &pstat, 0); + } + } + else + printf("Error: Unable to construct a new playpen for FTP!\n"); + } else - strcpy(tmpl, "/var/tmp/instpkg-XXXXXX.tgz"); - fd2 = mkstemp(tmpl); - if (fd2 < 0) { - whinge("Unable to create a temporary file for ftp: %s", tmpl); - return NULL; - } - if (Verbose) printf("FTP: Trying to copy from ftp connection to temporary: %s\n", tmpl); - (void)time(&start); - while (read(fd, &ch, 1) == 1) { - ++len; - write(fd2, &ch, 1); - } - (void)time(&stop); - if (Verbose) printf("FTP: Read %d bytes from connection, %d elapsed seconds.\n%FTP: Average transfer rate: %d bytes/second.\n", len, stop - start, len / ((stop - start) + 1)); + printf("Error: FTP Unable to get %s\n", basename_of(file)); FtpEOF(ftp); FtpClose(ftp); - return tmpl; + return rp; } char * -fileFindByPath(char *fname) +fileFindByPath(char *base, char *fname) { static char tmp[FILENAME_MAX]; char *cp; + int len; if (fexists(fname) && isfile(fname)) { strcpy(tmp, fname); return tmp; } + if (base) { + strcpy(tmp, base); + cp = strchr(tmp, '/'); + len = strlen(tmp); + + if (cp) { + /* Special case for the all category */ + if (len > 3 && !strncmp(cp - 3, "All/", 4)) + strcat(cp + 1, fname); + else { + *cp = '\0'; + /* Replace category with All */ + if ((cp = strrchr(tmp, '/')) != NULL) { + strcat(cp + 1, "All/"); + strcat(cp, fname); + } + else { + strcat(tmp, "All/"); + strcat(tmp, fname); + } + } + } + if (fexists(tmp)) + return tmp; + } + cp = getenv("PKG_PATH"); while (cp) { char *cp2 = strsep(&cp, ":"); diff --git a/usr.sbin/pkg_install/lib/lib.h b/usr.sbin/pkg_install/lib/lib.h index a5c2fa531db4..d0e770b19152 100644 --- a/usr.sbin/pkg_install/lib/lib.h +++ b/usr.sbin/pkg_install/lib/lib.h @@ -1,4 +1,4 @@ -/* $Id: lib.h,v 1.17 1995/07/30 01:44:45 ache Exp $ */ +/* $Id: lib.h,v 1.18 1995/08/26 10:15:12 jkh Exp $ */ /* * FreeBSD install - a package for the installation and maintainance @@ -107,8 +107,8 @@ typedef struct _pack Package; int vsystem(const char *, ...); void cleanup(int); char *make_playpen(char *, size_t); -void leave_playpen(void); char *where_playpen(void); +void leave_playpen(char *); size_t min_free(char *); /* String */ @@ -118,6 +118,7 @@ Boolean suffix(char *, char *); void nuke_suffix(char *); void str_lowercase(char *); char *basename_of(char *); +char *strconcat(char *, char *); /* File */ Boolean fexists(char *); @@ -125,10 +126,10 @@ Boolean isdir(char *); Boolean isfile(char *); Boolean isempty(char *); Boolean isURL(char *); -char *fileGetURL(char *); +char *fileGetURL(char *, char *); char *fileURLFilename(char *, char *, int); char *fileURLHost(char *, char *, int); -char *fileFindByPath(char *); +char *fileFindByPath(char *, char *); char *fileGetContents(char *); void write_file(char *, char *); void copy_file(char *, char *, char *); diff --git a/usr.sbin/pkg_install/lib/pen.c b/usr.sbin/pkg_install/lib/pen.c index d242ddda09d1..5d07e6eade05 100644 --- a/usr.sbin/pkg_install/lib/pen.c +++ b/usr.sbin/pkg_install/lib/pen.c @@ -1,5 +1,5 @@ #ifndef lint -static const char *rcsid = "$Id: pen.c,v 1.17 1995/08/26 18:36:27 jkh Exp $"; +static const char *rcsid = "$Id: pen.c,v 1.13.4.6 1995/10/23 12:33:43 jkh Exp $"; #endif /* @@ -28,29 +28,41 @@ static const char *rcsid = "$Id: pen.c,v 1.17 1995/08/26 18:36:27 jkh Exp $"; #include /* For keeping track of where we are */ -static char Cwd[FILENAME_MAX]; -static char Pen[FILENAME_MAX]; -extern char *PlayPen; +static char Current[FILENAME_MAX]; +static char Previous[FILENAME_MAX]; + +char * +where_playpen(void) +{ + return Current; +} /* Find a good place to play. */ static char * -find_play_pen(size_t sz) +find_play_pen(char *pen, size_t sz) { char *cp; struct stat sb; - if ((cp = getenv("PKG_TMPDIR")) != NULL && stat(cp, &sb) != FAIL && (min_free(cp) >= sz)) - sprintf(Pen, "%s/instmp.XXXXXX", cp); + if (pen[0] && stat(pen, &sb) != FAIL && (min_free(pen) >= sz)) + return pen; + else if ((cp = getenv("PKG_TMPDIR")) != NULL && stat(cp, &sb) != FAIL && (min_free(cp) >= sz)) + sprintf(pen, "%s/instmp.XXXXXX", cp); else if ((cp = getenv("TMPDIR")) != NULL && stat(cp, &sb) != FAIL && (min_free(cp) >= sz)) - sprintf(Pen, "%s/instmp.XXXXXX", cp); + sprintf(pen, "%s/instmp.XXXXXX", cp); else if (stat("/var/tmp", &sb) != FAIL && min_free("/var/tmp") >= sz) - strcpy(Pen, "/var/tmp/instmp.XXXXXX"); + strcpy(pen, "/var/tmp/instmp.XXXXXX"); else if (stat("/tmp", &sb) != FAIL && min_free("/tmp") >= sz) - strcpy(Pen, "/tmp/instmp.XXXXXX"); - else if ((stat("/usr/tmp", &sb) == SUCCESS | mkdir("/usr/tmp", 01777) == SUCCESS) && min_free("/usr/tmp") >= sz) - strcpy(Pen, "/usr/tmp/instmp.XXXXXX"); - else barf("Can't find enough temporary space to extract the files, please set\nyour PKG_TMPDIR environment variable to a location with at least %d bytes\nfree.", sz); - return Pen; + strcpy(pen, "/tmp/instmp.XXXXXX"); + else if ((stat("/usr/tmp", &sb) == SUCCESS || mkdir("/usr/tmp", 01777) == SUCCESS) && min_free("/usr/tmp") >= sz) + strcpy(pen, "/usr/tmp/instmp.XXXXXX"); + else { + barf("Can't find enough temporary space to extract the files, please set\n" + "your PKG_TMPDIR environment variable to a location with at least %d bytes\n" + "free.", sz); + return NULL; + } + return pen; } /* @@ -60,62 +72,62 @@ find_play_pen(size_t sz) char * make_playpen(char *pen, size_t sz) { - if (!pen) - PlayPen = find_play_pen(sz); - else { - strcpy(Pen, pen); - PlayPen = Pen; + char *tmp; + + if (!find_play_pen(pen, sz)) + return NULL; + + if (!mktemp(pen)) { + barf("Can't mktemp '%s'.", pen); + return NULL; } - if (!getcwd(Cwd, FILENAME_MAX)) - upchuck("getcwd"); - if (!mktemp(Pen)) - barf("Can't mktemp '%s'.", Pen); - if (mkdir(Pen, 0755) == FAIL) - barf("Can't mkdir '%s'.", Pen); - if (Verbose) - { + if (mkdir(pen, 0755) == FAIL) { + barf("Can't mkdir '%s'.", pen); + return NULL; + } + if (Verbose) { if (sz) - fprintf(stderr, "Projected package size: %d bytes, -free temp space: %d bytes in %s\n", (int)sz, min_free(Pen), Pen); + fprintf(stderr, "Requested space: %d bytes, free space: %d bytes in %s\n", (int)sz, min_free(pen), pen); } - if (min_free(Pen) < sz) { - rmdir(Pen); - barf("Not enough free space to create `%s'.\nPlease set your PKG_TMPDIR -environment variable to a location with more space and\ntry the command -again.", Pen); - PlayPen = NULL; + if (min_free(pen) < sz) { + rmdir(pen); + barf("Not enough free space to create: `%s'\n" + "Please set your PKG_TMPDIR environment variable to a location\n" + "with more space and\ntry the command again.", pen); + return NULL; } - if (chdir(Pen) == FAIL) - barf("Can't chdir to '%s'.", Pen); - return Cwd; + if (Current[0]) + strcpy(Previous, Current); + else if (!getcwd(Previous, FILENAME_MAX)) { + upchuck("getcwd"); + return NULL; + } + if (chdir(pen) == FAIL) + barf("Can't chdir to '%s'.", pen); + strcpy(Current, pen); + return Previous; } /* Convenience routine for getting out of playpen */ void -leave_playpen(void) +leave_playpen(char *save) { void (*oldsig)(int); /* Don't interrupt while we're cleaning up */ oldsig = signal(SIGINT, SIG_IGN); - if (Cwd[0]) { - if (chdir(Cwd) == FAIL) - barf("Can't chdir back to '%s'.", Cwd); - if (vsystem("rm -rf %s", Pen)) - fprintf(stderr, "Couldn't remove temporary dir '%s'\n", Pen); - Cwd[0] = '\0'; + if (Previous[0] && chdir(Previous) == FAIL) + barf("Can't chdir back to '%s'.", Previous); + else if (Current[0]) { + if (vsystem("rm -rf %s", Current)) + whinge("Couldn't remove temporary dir '%s'", Current); + strcpy(Current, Previous); } - signal(SIGINT, oldsig); -} - -/* Accessor function for telling us where the pen is */ -char * -where_playpen(void) -{ - if (Cwd[0]) - return Pen; + if (save) + strcpy(Previous, save); else - return NULL; + Previous[0] = '\0'; + signal(SIGINT, oldsig); } size_t @@ -123,8 +135,6 @@ min_free(char *tmpdir) { struct statfs buf; - if (!tmpdir) - tmpdir = Pen; if (statfs(tmpdir, &buf) != 0) { perror("Error in statfs"); return -1; diff --git a/usr.sbin/pkg_install/lib/str.c b/usr.sbin/pkg_install/lib/str.c index 3e397807a3bb..a9f130009612 100644 --- a/usr.sbin/pkg_install/lib/str.c +++ b/usr.sbin/pkg_install/lib/str.c @@ -35,6 +35,18 @@ basename_of(char *str) return basename; } +char * +strconcat(char *s1, char *s2) +{ + static char tmp[FILENAME_MAX]; + + tmp[0] = '\0'; + strncpy(tmp, s1 ? s1 : s2, FILENAME_MAX); + if (s1 && s2) + strncat(tmp, s2, FILENAME_MAX - strlen(tmp)); + return tmp; +} + /* Get a string parameter as a file spec or as a "contents follow -" spec */ char * get_dash_string(char **str)