PERFORCE change 177902 for review

Garrett Cooper gcooper at FreeBSD.org
Fri May 7 14:31:14 UTC 2010


http://p4web.freebsd.org/@@177902?ac=10

Change 177902 by gcooper at gcooper-bayonetta on 2010/05/07 14:30:31

	Checkpoint archive_write(3) skeleton support for pkg_create.

Affected files ...

.. //depot/projects/soc2007/gcooper-pkg_install-enhancements-simplified/usr.sbin/pkg_install/create/perform.c#4 edit

Differences ...

==== //depot/projects/soc2007/gcooper-pkg_install-enhancements-simplified/usr.sbin/pkg_install/create/perform.c#4 (text+ko) ====

@@ -21,19 +21,18 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD: src/usr.sbin/pkg_install/create/perform.c,v 1.85 2010/04/23 11:07:43 flz Exp $");
 
-#include <pkg.h>
-#include "create.h"
-
 #include <err.h>
 #include <libgen.h>
+#include <limits.h>
 #include <signal.h>
 #include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/syslimits.h>
-#include <sys/wait.h>
 #include <unistd.h>
 
+#include <archive.h>
+
+#include <pkg.h>
+#include "create.h"
+
 static void sanity_check(void);
 static void make_dist(const char *, const char *, const char *, Package *);
 static int create_from_installed_recursive(const char *, const char *);
@@ -340,134 +339,174 @@
     return TRUE;	/* Success */
 }
 
+#define EXTRACT_ARCHIVE_FLAGS	(ARCHIVE_EXTRACT_OWNER |ARCHIVE_EXTRACT_PERM| \
+				 ARCHIVE_EXTRACT_TIME  |ARCHIVE_EXTRACT_ACL | \
+				 ARCHIVE_EXTRACT_FFLAGS|ARCHIVE_EXTRACT_XATTR)
+
 static void
 make_dist(const char *homedir, const char *pkg, const char *suff, Package *plist)
 {
-    struct stat sb;
-    char tball[FILENAME_MAX];
-    PackingList p;
-    int ret;
-    const char *args[50];	/* Much more than enough. */
-    int nargs = 0;
-    int pipefds[2];
-    FILE *totar;
-    pid_t pid;
-    const char *cname;
-    char *prefix = NULL;
+
+#ifdef NOTYET
+	PackingList p;
+#endif
+	struct archive *archive = NULL;
+	char tball[PATH_MAX];
+#ifdef NOTYET
+	char *prefix = NULL;
+#endif
+	const char *cname = NULL;
+	const char *error = NULL;
+	int archive_fd = -1, open_flags;
+	Boolean passed = FALSE;
+
+	if (*pkg == '/')
+		snprintf(tball, sizeof(tball), "%s.%s", pkg, suff);
+	else
+		snprintf(tball, sizeof(tball), "%s/%s.%s", homedir, pkg, suff);
+
+	open_flags = O_WRONLY;
+
+	if (Regenerate == FALSE)
+		open_flags |= O_CREAT;
+
+	/*
+	 * If the package tarball exists already, and we are running in
+	 * `no clobber' mode, skip this package.
+	 */
+	if ((archive_fd = open(tball, open_flags)) == -1) {
+		if (Verbose)
+			warn("Skipping package creation for: '%s'", tball);
+	} else {
+
+		if ((archive = archive_write_new()) == NULL) {
+			error = archive_error_string(archive);
+			warnx("%s: unable to create the package '%s': %s",
+			    __func__, tball, error);
+		} else {
+
+			if (archive_write_set_format_ustar(archive) !=
+			    ARCHIVE_OK) {
+				error = archive_error_string(archive);
+			} else if (strncmp(suff, "tbz", 3) == 0) {
+				if (archive_write_set_compression_bzip2(archive)
+				    == ARCHIVE_OK)
+					cname = "bzipp";
+				else
+					error = archive_error_string(archive);
+			} else if (strncmp(suff, "tgz", 3) == 0) {
+				if (archive_write_set_compression_gzip(archive)
+				    == ARCHIVE_OK)
+					cname = "gzipp";
+				else
+					error = archive_error_string(archive);
+			} else {
+				if (archive_write_set_compression_none(archive)
+				    == ARCHIVE_OK)
+					cname = "uncompress";
+				else
+					error = archive_error_string(archive);
+			}
+
+			if (error != NULL) {
+
+				/* XXX (gcooper): fill this stuff in. */
+#ifdef NOTYET
+				if (Dereference == TRUE) ;
+
+				if (ExcludeFrom != NULL) ;
+
+				if (Verbose)
+					printf("Creating %sed tar ball in '%s'\n", cname, tball);
+
+				//fprintf(totar, "%s\n", CONTENTS_FNAME);
+				//fprintf(totar, "%s\n", COMMENT_FNAME);
+				//fprintf(totar, "%s\n", DESC_FNAME);
+
+				if (Install) ;
+					//fprintf(totar, "%s\n", INSTALL_FNAME);
+				if (PostInstall) ;
+					//fprintf(totar, "%s\n", POST_INSTALL_FNAME);
+				if (DeInstall) ;
+					//fprintf(totar, "%s\n", DEINSTALL_FNAME);
+				if (PostDeInstall) ;
+					//fprintf(totar, "%s\n", POST_DEINSTALL_FNAME);
+				if (Require) ;
+					//fprintf(totar, "%s\n", REQUIRE_FNAME);
+				if (Display) ;
+					//fprintf(totar, "%s\n", DISPLAY_FNAME);
+				if (Mtree) ;
+					//fprintf(totar, "%s\n", MTREE_FNAME);
+
+				passed = TRUE;
+
+				for (p = plist->head; p != NULL; p = p->next) {
 
+					switch(p->type) {
+					case PLIST_FILE:
+						/* Add p->name to archive. */
+						break;
+					case PLIST_CWD:
 
-    args[nargs++] = "tar";	/* argv[0] */
+						if (p->name != NULL) {
+							/*
+							 * Add <base>/<@cwd dir>
+							 * to archive.
+							 */
+							if (BaseDir != NULL &&
+							    p->name[0] == '/') ;
+							/* else,
+							 * chdir(<prefix>) . */
 
-    if (*pkg == '/')
-	snprintf(tball, FILENAME_MAX, "%s.%s", pkg, suff);
-    else
-	snprintf(tball, FILENAME_MAX, "%s/%s.%s", homedir, pkg, suff);
+							if (prefix == NULL)
+								prefix = p->name;
 
-    /*
-     * If the package tarball exists already, and we are running in `no
-     * clobber' mode, skip this package.
-     */
-    if (stat(tball, &sb) == 0 && Regenerate == FALSE) {
-	if (Verbose)
-	    printf("Skipping package '%s'.  It already exists.\n", tball);
-	return;
-    }
+						}
 
-    args[nargs++] = "-c";
-    args[nargs++] = "-f";
-    args[nargs++] = tball;
-    if (strchr(suff, 'z')) {	/* Compress/gzip/bzip2? */
-	if (Zipper == BZIP2) {
-	    args[nargs++] = "-j";
-	    cname = "bzip'd ";
-	}
-	else {
-	    args[nargs++] = "-z";
-	    cname = "gzip'd ";
-	}
-    } else {
-	cname = "";
-    }
-    if (Dereference)
-	args[nargs++] = "-h";
-    if (ExcludeFrom) {
-	args[nargs++] = "-X";
-	args[nargs++] = ExcludeFrom;
-    }
-    args[nargs++] = "-T";	/* Take filenames from file instead of args. */
-    args[nargs++] = "-";	/* Use stdin for the file. */
-    args[nargs] = NULL;
+						/* FALLTHROUGH */
+					case PLIST_SRC:
+						/*
+						 * 1. chdir(<base>).
+						 * 2. Add the
+						 *    <base>/<@cwd-dir>.
+						 */
+						break;
+					default:
+						/* 
+						 * Catch-all for the rest of
+						 * the cases.
+						 */
+						break;
+					}
 
-    if (Verbose)
-	printf("Creating %star ball in '%s'\n", cname, tball);
+					/*
+					 * if the file operation is invalid,
+					 * set passed to FALSE .
+					 */
 
-    /* Set up a pipe for passing the filenames, and fork off a tar process. */
-    if (pipe(pipefds) == -1) {
-	cleanup(0);
-	errx(2, "%s: cannot create pipe", __func__);
-    }
-    if ((pid = fork()) == -1) {
-	cleanup(0);
-	errx(2, "%s: cannot fork process for tar", __func__);
-    }
-    if (pid == 0) {	/* The child */
-	dup2(pipefds[0], 0);
-	close(pipefds[0]);
-	close(pipefds[1]);
-	execv("/usr/bin/tar", (char * const *)(uintptr_t)args);
-	cleanup(0);
-	errx(2, "%s: failed to execute tar command", __func__);
-    }
+				}
 
-    /* Meanwhile, back in the parent process ... */
-    close(pipefds[0]);
-    if ((totar = fdopen(pipefds[1], "w")) == NULL) {
-	cleanup(0);
-	errx(2, "%s: fdopen failed", __func__);
-    }
+#endif
 
-    fprintf(totar, "%s\n", CONTENTS_FNAME);
-    fprintf(totar, "%s\n", COMMENT_FNAME);
-    fprintf(totar, "%s\n", DESC_FNAME);
+			}
 
-    if (Install)
-	fprintf(totar, "%s\n", INSTALL_FNAME);
-    if (PostInstall)
-	fprintf(totar, "%s\n", POST_INSTALL_FNAME);
-    if (DeInstall)
-	fprintf(totar, "%s\n", DEINSTALL_FNAME);
-    if (PostDeInstall)
-	fprintf(totar, "%s\n", POST_DEINSTALL_FNAME);
-    if (Require)
-	fprintf(totar, "%s\n", REQUIRE_FNAME);
-    if (Display)
-	fprintf(totar, "%s\n", DISPLAY_FNAME);
-    if (Mtree)
-	fprintf(totar, "%s\n", MTREE_FNAME);
+		}
 
-    for (p = plist->head; p; p = p->next) {
-	if (p->type == PLIST_FILE)
-	    fprintf(totar, "%s\n", p->name);
-	else if (p->type == PLIST_CWD && p->name == NULL)
-	    fprintf(totar, "-C\n%s\n", prefix);
-	else if (p->type == PLIST_CWD && BaseDir && p->name && p->name[0] == '/')
-	    fprintf(totar, "-C\n%s%s\n", BaseDir, p->name);
-	else if (p->type == PLIST_CWD || p->type == PLIST_SRC)
-	    fprintf(totar, "-C\n%s\n", p->name);
-	else if (p->type == PLIST_IGNORE)
-	     p = p->next;
-	if (p->type == PLIST_CWD && !prefix)
-	    prefix = p->name;
+	}
 
-    }
+	if (archive != NULL)
+		archive_write_finish(archive);
+	if (error != NULL) {
+		passed = FALSE;
+		warnx("%s: unable to create the package '%s': %s",
+		    __func__, tball, error);
+	}
+	if (0 <= archive_fd)
+		close(archive_fd);
+	if (passed == FALSE && unlink(tball) == -1)
+		warn("%s: failed to remove incomplete package - '%s'",
+		    __func__, tball);
 
-    fclose(totar);
-    wait(&ret);
-    /* assume either signal or bad exit is enough for us */
-    if (ret) {
-	cleanup(0);
-	errx(2, "%s: tar command failed with code %d", __func__, ret);
-    }
 }
 
 static void


More information about the p4-projects mailing list