summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/pkg_install/add/perform.c62
-rw-r--r--usr.sbin/pkg_install/create/perform.c3
-rw-r--r--usr.sbin/pkg_install/info/perform.c6
-rw-r--r--usr.sbin/pkg_install/lib/lib.h6
-rw-r--r--usr.sbin/pkg_install/lib/pen.c43
-rw-r--r--usr.sbin/pkg_install/lib/url.c5
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];
OpenPOWER on IntegriCloud