summaryrefslogtreecommitdiffstats
path: root/usr.sbin/pkg_install/add
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>2009-06-19 17:07:38 +0000
committerbrian <brian@FreeBSD.org>2009-06-19 17:07:38 +0000
commit020220234336a0527c3a4eb5fe739a256bd31981 (patch)
tree7a28f52b43e5a7153d8f58917ed64d7cc7d49968 /usr.sbin/pkg_install/add
parentda4e70cf9ab3e05f67d77de37a7c6c335a5f7e4b (diff)
downloadFreeBSD-src-020220234336a0527c3a4eb5fe739a256bd31981.zip
FreeBSD-src-020220234336a0527c3a4eb5fe739a256bd31981.tar.gz
When running pkg_add -r, check & install our dependencies for each
package rather than expecting our top level package to get all of the dependencies correct. Previously, the code depended on the top level package having all of the pkgdep lines in +CONTENTS correct and in the right order, but that doesn't always happen due to code such as this (in security/gnutls/Makefile): .if (defined(WITH_LZO) || exists(${LOCALBASE}/lib/liblzo2.so)) && !defined(WITHOUT_LZO) LIB_DEPENDS+= lzo2:${PORTSDIR}/archivers/lzo2 .... With such conditional dependencies, my 'sophox-packages' package won't install. The dependency tree looks like this: sophox-packages ... x11/gnome2 x11/gnome-applets net/libgweather devel/libsoup security/gnutls security/libgcrypt security/libgpg-error ... x11/gnome2 archivers/file-roller archivers/gtar archivers/lzop archivers/lzo2 ... gnutls doesn't depend on lzo2 initially, but lzo2 is dragged into the mix via other dependencies and is built by the initial 'make'. The subsequent package generation for gnutls adds a pkgdep line for lzo2 to gnutls' +CONTENTS but the pkgdeps in sophox-packages' +CONTENTS has gnutls *before* lzo2. As a result, sophox-packages cannot install; gnutls fails because lzo2 is missing, 82 more packages fail because gnutls is missing and the whole thing spirals into a super-confusing mess! MFC after: 3 weeks
Diffstat (limited to 'usr.sbin/pkg_install/add')
-rw-r--r--usr.sbin/pkg_install/add/perform.c62
1 files changed, 49 insertions, 13 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);
OpenPOWER on IntegriCloud