diff options
-rw-r--r-- | usr.sbin/pkg_install/add/perform.c | 62 | ||||
-rw-r--r-- | usr.sbin/pkg_install/create/perform.c | 3 | ||||
-rw-r--r-- | usr.sbin/pkg_install/info/perform.c | 6 | ||||
-rw-r--r-- | usr.sbin/pkg_install/lib/lib.h | 6 | ||||
-rw-r--r-- | usr.sbin/pkg_install/lib/pen.c | 43 | ||||
-rw-r--r-- | usr.sbin/pkg_install/lib/url.c | 5 |
6 files changed, 81 insertions, 44 deletions
diff --git a/usr.sbin/pkg_install/add/perform.c b/usr.sbin/pkg_install/add/perform.c index 872c7a8..c391fee 100644 --- a/usr.sbin/pkg_install/add/perform.c +++ b/usr.sbin/pkg_install/add/perform.c @@ -52,9 +52,6 @@ pkg_perform(char **pkgs) return err_cnt; } -static Package Plist; -static char *Home; - /* * This is seriously ugly code following. Written very fast! * [And subsequently made even worse.. Sigh! This code was just born @@ -63,10 +60,12 @@ static char *Home; static int pkg_do(char *pkg) { + Package Plist; char pkg_fullname[FILENAME_MAX]; char playpen[FILENAME_MAX]; char extract_contents[FILENAME_MAX]; - char *where_to, *extract; + char *extract; + const char *where_to; FILE *cfile; int code; PackingList p; @@ -87,6 +86,8 @@ pkg_do(char *pkg) strcpy(playpen, FirstPen); inPlace = 0; + memset(&Plist, '\0', sizeof(Plist)); + /* Are we coming in for a second pass, everything already extracted? */ if (!pkg) { fgets(playpen, FILENAME_MAX, stdin); @@ -102,11 +103,10 @@ pkg_do(char *pkg) else { /* Is it an ftp://foo.bar.baz/file.t[bg]z specification? */ if (isURL(pkg)) { - if (!(Home = fileGetURL(NULL, pkg, KeepPackage))) { + if (!(where_to = fileGetURL(NULL, pkg, KeepPackage))) { warnx("unable to fetch '%s' by URL", pkg); return 1; } - where_to = Home; strcpy(pkg_fullname, pkg); cfile = fopen(CONTENTS_FNAME, "r"); if (!cfile) { @@ -135,13 +135,11 @@ pkg_do(char *pkg) extract = NULL; sb.st_size = 100000; /* Make up a plausible average size */ } - Home = make_playpen(playpen, sb.st_size * 4); - if (!Home) + if (!(where_to = make_playpen(playpen, sb.st_size * 4))) errx(1, "unable to make playpen for %lld bytes", (long long)sb.st_size * 4); - where_to = Home; /* Since we can call ourselves recursively, keep notes on where we came from */ if (!getenv("_TOP")) - setenv("_TOP", Home, 1); + setenv("_TOP", where_to, 1); if (unpack(pkg_fullname, extract)) { warnx( "unable to extract table of contents file from '%s' - not a package?", @@ -280,6 +278,42 @@ pkg_do(char *pkg) warnx("-f specified; proceeding anyway"); } + /* + * Before attempting to do the slave mode bit, ensure that we've + * downloaded & processed everything we need. + * It's possible that we haven't already installed all of our + * dependencies if the dependency list was misgenerated due to + * other dynamic dependencies or if a dependency was added to a + * package without all REQUIRED_BY packages being regenerated. + */ + for (p = pkg ? Plist.head : NULL; p; p = p->next) { + const char *ext; + char *deporigin; + + if (p->type != PLIST_PKGDEP) + continue; + deporigin = (p->next->type == PLIST_DEPORIGIN) ? p->next->name : NULL; + + if (isinstalledpkg(p->name) <= 0 && + !(deporigin != NULL && matchbyorigin(deporigin, NULL) != NULL)) { + char subpkg[FILENAME_MAX], *sep; + + strlcpy(subpkg, pkg, sizeof subpkg); + if ((sep = strrchr(subpkg, '/')) != NULL) { + *sep = '\0'; + if ((sep = strrchr(subpkg, '/')) != NULL) { + *sep = '\0'; + strlcat(subpkg, "/All/", sizeof subpkg); + strlcat(subpkg, p->name, sizeof subpkg); + if ((ext = strrchr(pkg, '.')) == NULL) + ext = ".tbz"; + strlcat(subpkg, ext, sizeof subpkg); + pkg_do(subpkg); + } + } + } + } + /* Now check the packing list for dependencies */ for (p = Plist.head; p ; p = p->next) { char *deporigin; @@ -295,7 +329,8 @@ pkg_do(char *pkg) } if (isinstalledpkg(p->name) <= 0 && !(deporigin != NULL && matchbyorigin(deporigin, NULL) != NULL)) { - char path[FILENAME_MAX], *cp = NULL; + char path[FILENAME_MAX]; + const char *cp = NULL; if (!Fake) { char prefixArg[2 + MAXPATHLEN]; /* "-P" + Prefix */ @@ -333,7 +368,7 @@ pkg_do(char *pkg) } else if ((cp = fileGetURL(pkg, p->name, KeepPackage)) != NULL) { if (Verbose) - printf("Finished loading %s over FTP.\n", p->name); + printf("Finished loading %s via a URL\n", p->name); if (!fexists("+CONTENTS")) { warnx("autoloaded package %s has no +CONTENTS file?", p->name); @@ -645,7 +680,8 @@ cleanup(int sig) printf("Signal %d received, cleaning up..\n", sig); if (!Fake && zapLogDir && LogDir[0]) vsystem("%s -rf %s", REMOVE_CMD, LogDir); - leave_playpen(); + while (leave_playpen()) + ; } if (sig) exit(1); diff --git a/usr.sbin/pkg_install/create/perform.c b/usr.sbin/pkg_install/create/perform.c index 505826e..e4f0d2e 100644 --- a/usr.sbin/pkg_install/create/perform.c +++ b/usr.sbin/pkg_install/create/perform.c @@ -39,11 +39,10 @@ static void make_dist(const char *, const char *, const char *, Package *); static int create_from_installed_recursive(const char *, const char *); static int create_from_installed(const char *, const char *, const char *); -static char *home; - int pkg_perform(char **pkgs) { + static const char *home; char *pkg = *pkgs; /* Only one arg to create */ char *cp; FILE *pkg_in, *fp; diff --git a/usr.sbin/pkg_install/info/perform.c b/usr.sbin/pkg_install/info/perform.c index 3803d64..09cad78 100644 --- a/usr.sbin/pkg_install/info/perform.c +++ b/usr.sbin/pkg_install/info/perform.c @@ -85,8 +85,6 @@ pkg_perform(char **pkgs) return err_cnt; } -static char *Home; - static int pkg_do(char *pkg) { @@ -96,7 +94,7 @@ pkg_do(char *pkg) Package plist; FILE *fp; struct stat sb; - char *cp = NULL; + const char *cp = NULL; int code = 0; if (isURL(pkg)) { @@ -138,7 +136,7 @@ pkg_do(char *pkg) code = 1; goto bail; } - Home = make_playpen(PlayPen, sb.st_size / 2); + make_playpen(PlayPen, sb.st_size / 2); if (unpack(fname, "'+*'")) { warnx("error during unpacking, no info for '%s' available", pkg); code = 1; diff --git a/usr.sbin/pkg_install/lib/lib.h b/usr.sbin/pkg_install/lib/lib.h index aef772b..acbd017 100644 --- a/usr.sbin/pkg_install/lib/lib.h +++ b/usr.sbin/pkg_install/lib/lib.h @@ -159,9 +159,9 @@ STAILQ_HEAD(reqr_by_head, reqr_by_entry); int vsystem(const char *, ...); char *vpipe(const char *, ...); void cleanup(int); -char *make_playpen(char *, off_t); +const char *make_playpen(char *, off_t); char *where_playpen(void); -void leave_playpen(void); +int leave_playpen(void); off_t min_free(const char *); /* String */ @@ -183,7 +183,7 @@ Boolean isfile(const char *); Boolean isempty(const char *); Boolean issymlink(const char *); Boolean isURL(const char *); -char *fileGetURL(const char *, const char *, int); +const char *fileGetURL(const char *, const char *, int); char *fileFindByPath(const char *, const char *); char *fileGetContents(const char *); void write_file(const char *, const char *); diff --git a/usr.sbin/pkg_install/lib/pen.c b/usr.sbin/pkg_install/lib/pen.c index fef3f9d..2f7e917 100644 --- a/usr.sbin/pkg_install/lib/pen.c +++ b/usr.sbin/pkg_install/lib/pen.c @@ -31,7 +31,6 @@ __FBSDID("$FreeBSD$"); /* For keeping track of where we are */ static char PenLocation[FILENAME_MAX]; -static char Previous[FILENAME_MAX]; char * where_playpen(void) @@ -76,12 +75,14 @@ find_play_pen(char *pen, off_t sz) static char *pstack[MAX_STACK]; static int pdepth = -1; -static void +static const char * pushPen(const char *pen) { if (++pdepth == MAX_STACK) errx(2, "%s: stack overflow.\n", __func__); pstack[pdepth] = strdup(pen); + + return pstack[pdepth]; } static void @@ -99,10 +100,11 @@ popPen(char *pen) * Make a temporary directory to play in and chdir() to it, returning * pathname of previous working directory. */ -char * +const char * make_playpen(char *pen, off_t sz) { char humbuf1[6], humbuf2[6]; + char cwd[FILENAME_MAX]; if (!find_play_pen(pen, sz)) return NULL; @@ -134,7 +136,7 @@ make_playpen(char *pen, off_t sz) "with more space and\ntry the command again", __func__, pen); } - if (!getcwd(Previous, FILENAME_MAX)) { + if (!getcwd(cwd, FILENAME_MAX)) { upchuck("getcwd"); return NULL; } @@ -144,34 +146,35 @@ make_playpen(char *pen, off_t sz) errx(2, "%s: can't chdir to '%s'", __func__, pen); } - if (PenLocation[0]) - pushPen(PenLocation); - strcpy(PenLocation, pen); - return Previous; + return pushPen(cwd); } /* Convenience routine for getting out of playpen */ -void +int leave_playpen() { + static char left[FILENAME_MAX]; void (*oldsig)(int); + if (!PenLocation[0]) + return 0; + /* Don't interrupt while we're cleaning up */ oldsig = signal(SIGINT, SIG_IGN); - if (Previous[0]) { - if (chdir(Previous) == FAIL) { - cleanup(0); - errx(2, "%s: can't chdir back to '%s'", __func__, Previous); - } - Previous[0] = '\0'; - } - if (PenLocation[0]) { - if (PenLocation[0] == '/' && vsystem("/bin/rm -rf %s", PenLocation)) - warnx("couldn't remove temporary dir '%s'", PenLocation); - popPen(PenLocation); + strcpy(left, PenLocation); + popPen(PenLocation); + + if (chdir(PenLocation) == FAIL) { + cleanup(0); + errx(2, "%s: can't chdir back to '%s'", __func__, PenLocation); } + + if (left[0] == '/' && vsystem("/bin/rm -rf %s", left)) + warnx("couldn't remove temporary dir '%s'", left); signal(SIGINT, oldsig); + + return 1; } off_t diff --git a/usr.sbin/pkg_install/lib/url.c b/usr.sbin/pkg_install/lib/url.c index 1cf5d31..8121283 100644 --- a/usr.sbin/pkg_install/lib/url.c +++ b/usr.sbin/pkg_install/lib/url.c @@ -32,10 +32,11 @@ __FBSDID("$FreeBSD$"); * Try and fetch a file by URL, returning the directory name for where * it's unpacked, if successful. */ -char * +const char * fileGetURL(const char *base, const char *spec, int keep_package) { - char *cp, *rp, *tmp; + const char *rp; + char *cp, *tmp; char fname[FILENAME_MAX]; char pen[FILENAME_MAX]; char pkg[FILENAME_MAX]; |