PERFORCE change 181486 for review
Julien Laffaye
jlaffaye at FreeBSD.org
Wed Jul 28 08:21:54 UTC 2010
http://p4web.freebsd.org/@@181486?ac=10
Change 181486 by jlaffaye at jlaffaye-chulak on 2010/07/27 22:04:27
- Re-implemented the automatic installation of packages dependencies.
- While I'm here, do not call pkg_add recursively but use pkg_do()
- Moved the 'URL guess' logic from fetch_archive() to find_package_url().
- While I'm here, do not use a hard-coded value of '.tbz' for the
archive extension but find it dynamically.
Affected files ...
.. //depot/projects/soc2010/pkg_complete/lib/libpkg/pkg.h#8 edit
.. //depot/projects/soc2010/pkg_complete/lib/libpkg/url.c#4 edit
.. //depot/projects/soc2010/pkg_complete/usr.sbin/pkg_install/add/add.h#4 edit
.. //depot/projects/soc2010/pkg_complete/usr.sbin/pkg_install/add/extract.c#8 edit
.. //depot/projects/soc2010/pkg_complete/usr.sbin/pkg_install/add/perform.c#8 edit
Differences ...
==== //depot/projects/soc2010/pkg_complete/lib/libpkg/pkg.h#8 (text+ko) ====
@@ -180,8 +180,8 @@
Boolean issymlink(const char *);
Boolean isURL(const char *);
const char *fileGetURL(const char *, const char *, int);
-int fetch_archive(struct archive *, const char *, const char *,
- Boolean);
+int find_package_url(char * restrict, const char *, const char *);
+int fetch_archive(struct archive *, const char *, Boolean);
char *fileFindByPath(const char *, const char *);
char *fileGetContents(const char *);
ssize_t write_file(const char *, const char *);
==== //depot/projects/soc2010/pkg_complete/lib/libpkg/url.c#4 (text+ko) ====
@@ -24,6 +24,7 @@
#include <sys/param.h>
#include <sys/wait.h>
#include <archive.h>
+#include <assert.h>
#include <err.h>
#include <errno.h>
#include <libgen.h>
@@ -192,70 +193,76 @@
}
/*
- * Setup the archive `a' callbacks to read data from an URL `spec' via fetch(3).
- * If `spec' is not an URL, the function try to find the location of the file
- * via `base' or via the environment variable `PKG_ADD_BASE'.
+ * Given a know-good URL `base', construct the URL to fetch `pkgname'.
+ * If the environment variable `PKG_ADD_BASE' (setted by sysinstall) exist,
+ * it is used to construct the URL ($PKG_ADD_BASE concatened with pkgname),
+ * and `base' is only used to find the file extension.
+ * The resulting URL string is stored at the memory of size FILENAME_MAX
+ * pointed by `p'.
+ * Returns 0 on success, 1 otherwise.
+ */
+int
+find_package_url(char * restrict p, const char *base, const char *pkgname)
+{
+ char *cp;
+ char *ext;
+
+ assert(p != NULL);
+ assert(base != NULL);
+ assert(pkgname != NULL);
+
+ if ((ext = strrchr(base, '.')) == NULL)
+ ext = ".tbz";
+
+ /* Special tip that sysinstall left for us */
+ if ((cp = getenv("PKG_ADD_BASE")) != NULL) {
+ strlcpy(p, cp, FILENAME_MAX);
+ strlcat(p, pkgname, FILENAME_MAX);
+ strlcat(p, ext, FILENAME_MAX);
+ } else {
+ strlcpy(p, base, FILENAME_MAX);
+ /*
+ * Advance back two slashes to get to the root of the
+ * package hierarchy, then append pkgname.
+ */
+ cp = strrchr(p, '/');
+ if (cp != NULL) {
+ *cp = '\0'; /* chop name */
+ cp = strrchr(p, '/');
+ }
+ if (cp != NULL) {
+ *(cp + 1) = '\0';
+ strlcat(p, "All/", FILENAME_MAX);
+ strlcat(p, pkgname, FILENAME_MAX);
+ strlcat(p, ext, FILENAME_MAX);
+ } else
+ return (1);
+ }
+
+ return (0);
+}
+
+/*
+ * Setup the archive `a' callbacks to read data from an URL `url' via fetch(3).
* Returns 0 on success, 1 otherwise.
*/
int
-fetch_archive(struct archive *a, const char *base, const char *spec,
- Boolean keep_package)
+fetch_archive(struct archive *a, const char *url, Boolean keep_package)
{
struct fetch_data *data = NULL;
- char *cp, *hint, *tmp;
+ char *tmp;
char fname[FILENAME_MAX];
char pkg[FILENAME_MAX];
int retcode = 0;
+ if (!isURL(url)) {
+ warnx("fetch_archive(): '%s' is not an URL!", url);
+ return (1);
+ }
+
if ((data = malloc(sizeof(struct fetch_data))) == NULL)
err(EXIT_FAILURE, "malloc()");
- if (!isURL(spec)) {
- /*
- * 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.
- */
- if (base != NULL) {
- strcpy(fname, base);
- /*
- * Advance back two slashes to get to the root of the
- * package hierarchy
- */
- cp = strrchr(fname, '/');
- if (cp) {
- *cp = '\0'; /* chop name */
- cp = strrchr(fname, '/');
- }
- if (cp != NULL) {
- *(cp + 1) = '\0';
- strcat(cp, "All/");
- strcat(cp, spec);
- strcat(cp, ".tbz");
- } else {
- retcode = 1;
- goto cleanup;
- }
- }
- /* Special tip that sysinstall left for us */
- else if ((hint = getenv("PKG_ADD_BASE")) != NULL) {
- /*
- * Otherwise, we've been given an environment variable
- * hinting at the right location from sysinstall
- */
- strcpy(fname, hint);
- strcat(fname, spec);
- strcat(fname, ".tbz");
- }
- /* We dont have an url and are unable to guess one */
- else {
- retcode = 1;
- goto cleanup;
- }
- }
- else
- strcpy(fname, spec);
-
if (keep_package) {
tmp = getenv("PKGDIR");
strlcpy(pkg, tmp ? tmp : ".", sizeof(pkg));
==== //depot/projects/soc2010/pkg_complete/usr.sbin/pkg_install/add/add.h#4 (text+ko) ====
@@ -42,7 +42,8 @@
int make_hierarchy(char *);
void apply_perms(const char *, const char *);
-int extract_package(struct archive *, Package *);
+int extract_package(struct archive *, Package *, const char *);
int extract_plist(struct archive *, struct archive_entry *, Package *);
+int pkg_do(const char *);
#endif /* _INST_ADD_H_INCLUDE */
==== //depot/projects/soc2010/pkg_complete/usr.sbin/pkg_install/add/extract.c#8 (text+ko) ====
@@ -66,7 +66,7 @@
}
int
-extract_package(struct archive *a, Package *pkg)
+extract_package(struct archive *a, Package *pkg, const char *fname)
{
PackingList p;
struct archive_entry *entry;
@@ -188,113 +188,108 @@
}
#endif
- /* Now check the packing list for dependencies */
- for (p = pkg->head; p ; p = p->next) {
- char *deporigin;
+ /* Now check the packing list for dependencies */
+ for (p = pkg->head; p ; p = p->next) {
+ char *deporigin;
- if (p->type != PLIST_PKGDEP)
- continue;
- deporigin = (p->next->type == PLIST_DEPORIGIN) ? p->next->name : NULL;
- if (Verbose) {
- printf("Package '%s' depends on '%s'", pkg->name, p->name);
- if (deporigin != NULL)
- printf(" with '%s' origin", deporigin);
- printf(".\n");
- }
-#if 0
- if (isinstalledpkg(p->name) <= 0 &&
- !(deporigin != NULL && matchbyorigin(deporigin, NULL) != NULL)) {
- char path[FILENAME_MAX];
- const char *cp = NULL;
+ if (p->type != PLIST_PKGDEP)
+ continue;
- if (!Fake) {
- char prefixArg[2 + MAXPATHLEN]; /* "-P" + Prefix */
- if (PrefixRecursive) {
- strlcpy(prefixArg, "-P", sizeof(prefixArg));
- strlcat(prefixArg, Prefix, sizeof(prefixArg));
+ if (p->next->type == PLIST_DEPORIGIN)
+ deporigin = p->next->name;
+ else
+ deporigin = NULL;
+ if (Verbose) {
+ printf("Package '%s' depends on '%s'", pkg->name, p->name);
+ if (deporigin != NULL)
+ printf(" with '%s' origin", deporigin);
+ printf(".\n");
}
- if (!isURL(pkg) && !getenv("PKG_ADD_BASE")) {
- const char *ext;
+
+ if (isinstalledpkg(p->name) <= 0 &&
+ !(deporigin != NULL && matchbyorigin(deporigin, NULL) !=
+ NULL)) {
+ char path[FILENAME_MAX];
+ const char *cp = NULL;
+
+ if (!Fake) {
+ /*
+ * Since we are calling pkg_do() recursively,
+ * set the global variable `Prefix' to NULL.
+ * It is safe to do so because we are already done
+ * with it at this level.
+ */
+ if (PrefixRecursive == FALSE)
+ Prefix = NULL;
+
+ if (!isURL(fname) && !getenv("PKG_ADD_BASE")) {
+ const char *ext;
+
+ ext = strrchr(fname, '.');
+ if (ext == NULL)
+ ext = ".tbz";
+ snprintf(path, FILENAME_MAX, "%s/%s%s",
+ getenv("_TOP"), p->name, ext);
+ if (fexists(path))
+ cp = path;
+ else
+ cp = fileFindByPath(fname, p->name);
+
+ if (cp) {
+ if (Verbose)
+ printf("Loading it from %s.\n", cp);
+ if (pkg_do(cp) != 0) {
+ warnx("autoload of dependency '%s' "
+ "failed%s", cp,
+ Force ? " (proceeding anyway)" : "!");
+ if (!Force)
+ ++code;
+ }
+ }
+ else {
+ warnx("could not find package %s %s", p->name,
+ Force ? "(proceeding anyway)" : "!");
+ if (!Force)
+ ++code;
+ }
+ }
+ else {
+ char dep_url[FILENAME_MAX];
+ if (find_package_url(dep_url, fname, p->name) != 1)
+ errx(1, "Can not make an URL to get %s",
+ p->name);
- ext = strrchr(pkg, '.');
- if (ext == NULL)
- ext = ".tbz";
- snprintf(path, FILENAME_MAX, "%s/%s%s", getenv("_TOP"),
- p->name, ext);
- if (fexists(path))
- cp = path;
- else
- cp = fileFindByPath(pkg, p->name);
- if (cp) {
- if (Verbose)
- printf("Loading it from %s.\n", cp);
- if (vsystem("%s %s %s '%s'", PkgAddCmd, Verbose ? "-v "
-: "", PrefixRecursive ? prefixArg : "", cp)) {
- warnx("autoload of dependency '%s' failed%s",
- cp, Force ? " (proceeding anyway)" : "!");
- if (!Force)
- ++code;
+ if (pkg_do(dep_url) != 0) {
+ warnx("pkg_add of dependency %s failed%s",
+ p->name,
+ Force ? " (proceeding anyway)" : "!");
+ if (!Force)
+ ++code;
+ } else
+ if (Verbose)
+ printf("%s added successfully\n", p->name);
}
+ /* pkg_do() modified this global, so reset it */
+ extract_state = 0;
}
+ /* XXX: WTF is this logic ? */
else {
- warnx("could not find package %s %s",
- p->name, Force ? " (proceeding anyway)" : "!");
+ 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->name,
+ Force ? " (proceeding anyway)" : "!");
if (!Force)
++code;
}
}
- else {
-
- if ((cp = fileGetURL(pkg, p->name, KeepPackage)) == NULL) {
- cleanup();
- warnx("Getting pkg '%s' by URL failed", pkg);
- goto bomb;
- } else {
-
- if (Verbose)
- printf("Finished loading %s via a URL\n", p->name);
- if (!fexists(CONTENTS_FNAME)) {
- warnx("autoloaded package %s has no %s file?",
- p->name, CONTENTS_FNAME);
- if (!Force)
- ++code;
- }
- else if (vsystem("(pwd; /bin/cat " CONTENTS_FNAME
- ") | %s %s %s %s -S", PkgAddCmd,
- Verbose ? "-v" : "",
- PrefixRecursive ? prefixArg : "",
- KeepPackage ? "-K" : "")) {
- warnx("pkg_add 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();
-
- }
-
- }
+ else if (Verbose)
+ printf(" - already installed.\n");
}
- 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");
-#endif
- }
- } /* if (!IgnoreDeps) */
+ } /* if (!IgnoreDeps) */
if (code != 0)
return (1);
==== //depot/projects/soc2010/pkg_complete/usr.sbin/pkg_install/add/perform.c#8 (text+ko) ====
@@ -33,7 +33,6 @@
#include "cleanup.h"
void cleanup(void);
-static int pkg_do(char *);
extern int extract_state;
extern char db_dir_tmp[FILENAME_MAX];
@@ -61,8 +60,8 @@
* as first parameter and install it.
* Returns 0 on success, 1 otherwise.
*/
-static int
-pkg_do(char *fname)
+int
+pkg_do(const char *fname)
{
Package pkg;
struct archive *a = NULL;
@@ -81,7 +80,7 @@
* add support for complete packages
*/
if (isURL(fname)) {
- if (fetch_archive(a, NULL, fname, KeepPackage) != 0) {
+ if (fetch_archive(a, fname, KeepPackage) != 0) {
warnx("Can not fetch '%s' - aborting", fname);
retcode = 1;
goto cleanup;
@@ -113,7 +112,7 @@
retcode = 1;
goto cleanup;
}
- retcode = extract_package(a, &pkg);
+ retcode = extract_package(a, &pkg, fname);
free_plist(&pkg);
} else if (strcmp(pathname, "+PKG_COMPLETE") == 0) {
if (Verbose)
More information about the p4-projects
mailing list