PERFORCE change 181342 for review
Julien Laffaye
jlaffaye at FreeBSD.org
Thu Jul 22 21:30:04 UTC 2010
http://p4web.freebsd.org/@@181342?ac=10
Change 181342 by jlaffaye at jlaffaye-chulak on 2010/07/22 21:30:01
Refactor to welcome (on an other iteration):
* on the fly installation from an URL
* complete package support
Affected files ...
.. //depot/projects/soc2010/pkg_complete/usr.sbin/pkg_install/add/add.h#3 edit
.. //depot/projects/soc2010/pkg_complete/usr.sbin/pkg_install/add/extract.c#5 edit
.. //depot/projects/soc2010/pkg_complete/usr.sbin/pkg_install/add/perform.c#4 edit
Differences ...
==== //depot/projects/soc2010/pkg_complete/usr.sbin/pkg_install/add/add.h#3 (text+ko) ====
@@ -38,11 +38,11 @@
extern char *Directory;
extern char *PkgName;
extern char *PkgAddCmd;
-extern char FirstPen[];
extern add_mode_t AddMode;
-int make_hierarchy(char *);
-void apply_perms(const char *, const char *);
-int extract_package(const char *pkg);
+int make_hierarchy(char *);
+void apply_perms(const char *, const char *);
+int extract_package(struct archive *, Package *);
+int extract_plist(struct archive *, struct archive_entry *, Package *);
#endif /* _INST_ADD_H_INCLUDE */
==== //depot/projects/soc2010/pkg_complete/usr.sbin/pkg_install/add/extract.c#5 (text+ko) ====
@@ -31,16 +31,39 @@
#include "add.h"
-int extract_package(const char *fname)
+int
+extract_plist(struct archive *a, struct archive_entry *entry, Package *pkg) {
+ char *plist_buf;
+ ssize_t s;
+ int retcode;
+
+ assert(strcmp(archive_entry_pathname(entry), CONTENTS_FNAME) == 0);
+
+ s = archive_entry_size(entry);
+ if ((plist_buf = malloc(s+1)) == NULL)
+ err(EXIT_FAILURE, "malloc()");
+ if (archive_read_data(a, plist_buf, s) != s) {
+ warnx("Can not extract plist: %s", archive_error_string(a));
+ return (1);
+ }
+ plist_buf[s] = '\0';
+
+ pkg->head = pkg->tail = NULL;
+ retcode = read_plist_from_buffer(pkg, plist_buf, s);
+ free(plist_buf);
+ if (retcode != 0) {
+ warnx("Unable to parse plist!");
+ return (1);
+ }
+
+ return (0);
+}
+
+int
+extract_package(struct archive *a, Package *pkg)
{
- Package pkg;
PackingList p;
- struct archive *a;
struct archive_entry *entry;
- ssize_t sz;
- char *plist_buf;
- int retcode;
-
char **matched;
char *conflict[2];
Boolean conflictsfound = FALSE;
@@ -59,80 +82,39 @@
int fd;
struct stat sb;
- a = archive_read_new();
- archive_read_support_compression_all(a);
- archive_read_support_format_tar(a);
- if (archive_read_open_filename(a, fname, 10240) != ARCHIVE_OK) {
- warnx("Can not open archive: %s", archive_error_string(a));
- return (1);
- }
-
- /* Extract the plist in memory */
- if ((retcode = archive_read_next_header(a, &entry)) == ARCHIVE_OK) {
- if (strcmp(archive_entry_pathname(entry), CONTENTS_FNAME) == 0){
- sz = archive_entry_size(entry);
- if ((plist_buf = malloc(sz+1)) == NULL)
- err(EXIT_FAILURE, NULL);
- if (archive_read_data(a, plist_buf, sz) != sz) {
- warnx("Can not read plist: %s", archive_error_string(a));
- return (1);
- }
- plist_buf[sz] = '\0';
- } else {
- warnx(CONTENTS_FNAME " not found - bad package!");
- return (1);
- }
- } else if (retcode == ARCHIVE_EOF) {
- warnx("Archive is empty - bad package!");
- return (1);
- } else {
- warnx("Can not read archive: %s - aborting",
- archive_error_string(a));
- return (1);
- }
-
- /* Parse the plist now so we can check the depends, etc */
- pkg.head = pkg.tail = NULL;
- retcode = read_plist_from_buffer(&pkg, plist_buf, sz);
- free(plist_buf);
- if (retcode != 0) {
- warnx("Unable to parse plist");
- return (1);
- }
-
/*
* If we have a prefix, delete the first one we see and add this
* one in place of it.
*/
if (Prefix) {
- delete_plist(&pkg, FALSE, PLIST_CWD, NULL);
- if (add_plist_top(&pkg, PLIST_CWD, Prefix) == -1)
+ delete_plist(pkg, FALSE, PLIST_CWD, NULL);
+ if (add_plist_top(pkg, PLIST_CWD, Prefix) == -1)
err(EXIT_FAILURE, "%s: add_plist_top failed", __func__);
}
- setenv(PKG_PREFIX_VNAME, (p = find_plist(&pkg, PLIST_CWD)) ? p->name :
+ setenv(PKG_PREFIX_VNAME, (p = find_plist(pkg, PLIST_CWD)) ? p->name :
".", 1);
/* Protect against old packages with bogus @name and origin fields */
- if (pkg.name == NULL)
- pkg.name = "anonymous";
- if (pkg.origin == NULL)
- pkg.origin = "anonymous/anonymous";
+ if (pkg->name == NULL)
+ pkg->name = "anonymous";
+ if (pkg->origin == NULL)
+ pkg->origin = "anonymous/anonymous";
/*
* See if we're already registered either with the same name (the same
* version) or some other version with the same origin.
*/
- if ((isinstalledpkg(pkg.name) > 0 ||
- matchbyorigin(pkg.origin, NULL) != NULL) && !Force) {
+ if ((isinstalledpkg(pkg->name) > 0 ||
+ matchbyorigin(pkg->origin, NULL) != NULL) && !Force) {
warnx("package '%s' or its older version already installed%s",
- pkg.name, FailOnAlreadyInstalled ? "" : " (ignored)");
+ pkg->name, FailOnAlreadyInstalled ? "" : " (ignored)");
if (FailOnAlreadyInstalled == TRUE)
return (1);
}
/* Now check the packing list for conflicts */
if (!IgnoreDeps) {
- for (p = pkg.head; p != NULL; p = p->next) {
+ for (p = pkg->head; p != NULL; p = p->next) {
if (p->type == PLIST_CONFLICTS) {
int i;
conflict[0] = strdup(p->name);
@@ -143,7 +125,7 @@
for (i = 0; matched[i] != NULL; i++)
if (isinstalledpkg(matched[i]) > 0) {
warnx("package '%s' conflicts with %s",
- pkg.name, matched[i]);
+ pkg->name, matched[i]);
conflictsfound = TRUE;
}
}
@@ -166,7 +148,7 @@
* other dynamic dependencies or if a dependency was added to a
* package without all REQUIRED_BY packages being regenerated.
*/
- for (p = pkg ? pkg.head : NULL; p; p = p->next) {
+ for (p = pkg ? pkg->head : NULL; p; p = p->next) {
const char *ext;
char *deporigin;
@@ -200,14 +182,14 @@
#endif
/* Now check the packing list for dependencies */
- for (p = pkg.head; p ; p = p->next) {
+ 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);
+ printf("Package '%s' depends on '%s'", pkg->name, p->name);
if (deporigin != NULL)
printf(" with '%s' origin", deporigin);
printf(".\n");
@@ -315,8 +297,8 @@
* Extract the meta files into it now.
* Later, we will rename(2) the directory to validate the installation.
*/
- snprintf(db_dir_tmp, sizeof(db_dir_tmp), "%s/.%s", LOG_DIR, pkg.name);
- snprintf(db_dir, sizeof(db_dir), "%s/%s", LOG_DIR, pkg.name);
+ snprintf(db_dir_tmp, sizeof(db_dir_tmp), "%s/.%s", LOG_DIR, pkg->name);
+ snprintf(db_dir, sizeof(db_dir), "%s/%s", LOG_DIR, pkg->name);
if (make_hierarchy(db_dir_tmp) == -1) {
warnx("Can not create '%s' directory - aborting", db_dir_tmp);
return (1);
@@ -326,7 +308,7 @@
vsystem("%s -rf %s", REMOVE_CMD, db_dir_tmp);
return (1);
}
- for (p = pkg.head; p; p = p->next)
+ for (p = pkg->head; p; p = p->next)
if (p->type == PLIST_IGNORE) {
if (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
/* XXX: temporary assert */
@@ -348,9 +330,9 @@
close(fd);
if (Verbose)
printf("Running requirements file first for %s..\n",
- pkg.name);
- if (!Fake && vsystem("./%s %s INSTALL", REQUIRE_FNAME, pkg.name)){
- warnx("package %s fails requirements %s", pkg.name,
+ pkg->name);
+ if (!Fake && vsystem("./%s %s INSTALL", REQUIRE_FNAME, pkg->name)){
+ warnx("package %s fails requirements %s", pkg->name,
Force ? "installing anyway" : "- not installed");
if (!Force) {
vsystem("%s -rf %s", REMOVE_CMD, db_dir_tmp);
@@ -380,8 +362,8 @@
fchmod(fd, sb.st_mode | S_IXALL); /* be sure, chmod a+x */
close(fd);
if (Verbose)
- printf("Running pre-install for %s..\n", pkg.name);
- if (!Fake && vsystem("./%s %s %s", pre_script, pkg.name, pre_arg)) {
+ printf("Running pre-install for %s..\n", pkg->name);
+ if (!Fake && vsystem("./%s %s %s", pre_script, pkg->name, pre_arg)){
warnx("install script returned error status - aborting");
vsystem("%s -rf %s", REMOVE_CMD, db_dir_tmp);
return (1);
@@ -389,7 +371,7 @@
}
/* Install it, yay! */
- for (p = pkg.head; p; p = p->next) {
+ for (p = pkg->head; p; p = p->next) {
switch (p->type) {
case PLIST_NAME:
if (Verbose)
@@ -464,15 +446,15 @@
*/
if (chdir(db_dir_tmp) == -1) {
warn("Can not chdir to '%s' - aborting", db_dir_tmp);
- delete_package(FALSE, FALSE, &pkg);
+ delete_package(FALSE, FALSE, pkg);
vsystem("%s -rf %s", REMOVE_CMD, db_dir_tmp);
return (1);
}
if (!Fake && fexists(MTREE_FNAME)) {
if (Verbose)
- printf("Running mtree for %s..\n", pkg.name);
- p = find_plist(&pkg, PLIST_CWD);
+ printf("Running mtree for %s..\n", pkg->name);
+ p = find_plist(pkg, PLIST_CWD);
if (Verbose)
printf("mtree -U -f %s -d -e -p %s >%s\n",
MTREE_FNAME, p ? p->name : "/", _PATH_DEVNULL);
@@ -489,11 +471,11 @@
fchmod(fd, sb.st_mode | S_IXALL); /* be sure, chmod a+x */
close(fd);
if (Verbose)
- printf("Running post-install for %s..\n", pkg.name);
- if (!Fake && vsystem("./%s %s %s", post_script, pkg.name,
+ printf("Running post-install for %s..\n", pkg->name);
+ if (!Fake && vsystem("./%s %s %s", post_script, pkg->name,
post_arg)) {
warnx("install script returned error status - aborting");
- delete_package(FALSE, FALSE, &pkg);
+ delete_package(FALSE, FALSE, pkg);
vsystem("%s -rf %s", REMOVE_CMD, db_dir_tmp);
}
}
@@ -512,11 +494,11 @@
contents);
return (1); /* can't log, but still keep pkg */
}
- rc = write_plist(&pkg, contfile);
+ rc = write_plist(pkg, contfile);
fclose(contfile);
if (rc != 0)
return (1);
- for (p = pkg.head; p ; p = p->next) {
+ for (p = pkg->head; p ; p = p->next) {
char *deporigin;
if (p->type != PLIST_PKGDEP)
@@ -556,7 +538,7 @@
"dependency registration is incomplete",
contents);
} else {
- fprintf(contfile, "%s\n", pkg.name);
+ fprintf(contfile, "%s\n", pkg->name);
if (fclose(contfile) == EOF) {
warnx("cannot properly close file %s", contents);
}
@@ -578,7 +560,7 @@
if (depnames[i] && strcmp(depnames[i], tmp[j])
!= 0)
warnx("warning: package '%s' requires '%s',"
- " but '%s' is installed", pkg.name,
+ " but '%s' is installed", pkg->name,
depnames[i], tmp[j]);
contfile = fopen(contents, "a");
if (!contfile) {
@@ -586,7 +568,7 @@
"dependency registration is "
"incomplete", contents);
} else {
- fprintf(contfile, "%s\n", pkg.name);
+ fprintf(contfile, "%s\n", pkg->name);
if (fclose(contfile) == EOF)
warnx("cannot properly close file %s",
contents);
@@ -605,7 +587,7 @@
"dependency registration is incomplete",
contents);
} else {
- fprintf(contfile, "%s\n", pkg.name);
+ fprintf(contfile, "%s\n", pkg->name);
if (fclose(contfile) == EOF) {
warnx("cannot properly close file %s",
contents);
@@ -619,10 +601,10 @@
if (rename(db_dir_tmp, db_dir) == -1)
warn("Can not rename '%s' to '%s'", db_dir_tmp, db_dir);
else if (Verbose)
- printf("Package %s registered in %s\n", pkg.name, db_dir);
+ printf("Package %s registered in %s\n", pkg->name, db_dir);
}
- if ((p = find_plist(&pkg, PLIST_DISPLAY)) != NULL) {
+ if ((p = find_plist(pkg, PLIST_DISPLAY)) != NULL) {
FILE *fp;
char buf[BUFSIZ];
@@ -638,7 +620,5 @@
warnx("cannot open %s as display file", buf);
}
- archive_read_finish(a);
- free_plist(&pkg);
return (0);
}
==== //depot/projects/soc2010/pkg_complete/usr.sbin/pkg_install/add/perform.c#4 (text+ko) ====
@@ -22,6 +22,8 @@
__FBSDID("$FreeBSD: src/usr.sbin/pkg_install/add/perform.c,v 1.90 2010/04/23 11:07:43 flz Exp $");
#include <sys/wait.h>
+#include <archive.h>
+#include <archive_entry.h>
#include <err.h>
#include <libgen.h>
#include <paths.h>
@@ -51,20 +53,72 @@
}
/*
- * This is seriously ugly code following. Written very fast!
- * [And subsequently made even worse.. Sigh! This code was just born
- * to be hacked, I guess.. :) -jkh]
+ * pkg_do() takes a package filename (on local disk, or an url scheme)
+ * as first parameter and install it.
+ * Returns 0 on success, 1 otherwise.
*/
static int
-pkg_do(char *pkg)
+pkg_do(char *fname)
{
+ Package pkg;
+ struct archive *a = NULL;
+ struct archive_entry *entry;
+ const char *pathname;
+ int retcode = 0;
+
+ a = archive_read_new();
+ archive_read_support_compression_all(a);
+ archive_read_support_format_tar(a);
+
/*
* TODO:
* dowload the package if it is an URL, read from stdin if "-"
* Deal with master/slave modes.
* add support for complete packages
*/
- return extract_package(pkg);
+ if (isURL(fname)) {
+ /* TODO: add support */
+ return (1);
+ } else {
+ if (archive_read_open_filename(a, fname, 10240) != ARCHIVE_OK) {
+ warnx("Can not open '%s' archive: %s", fname,
+ archive_error_string(a));
+ retcode = 1;
+ goto cleanup;
+ }
+ }
+
+ if (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
+ pathname = archive_entry_pathname(entry);
+ if (strcmp(pathname, CONTENTS_FNAME) == 0) {
+ if (extract_plist(a, entry, &pkg) != 0) {
+ warnx("Can not extract & parse " CONTENTS_FNAME);
+ retcode = 1;
+ goto cleanup;
+ }
+ extract_package(a, &pkg);
+ } else if (strcmp(pathname, "+PKG_COMPLETE") == 0) {
+ if (Verbose)
+ printf("'%s' is a complete package...\n", fname);
+ /* TODO: add support */
+ } else {
+ warnx("Unknown package type!");
+ retcode = 1;
+ goto cleanup;
+ }
+ } else {
+ warnx("Can not read '%s' archive: %s", fname,
+ archive_error_string(a));
+ retcode = 1;
+ goto cleanup;
+ }
+
+ cleanup:
+ if (a != NULL)
+ archive_read_finish(a);
+ if (pkg.head != NULL)
+ free_plist(&pkg);
+ return (retcode);
# if 0
/* Are we coming in for a second pass, everything already extracted? */
More information about the p4-projects
mailing list