From owner-p4-projects@FreeBSD.ORG Fri May 7 14:31:14 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 07B0D1065675; Fri, 7 May 2010 14:31:14 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id B48CB1065672 for ; Fri, 7 May 2010 14:31:13 +0000 (UTC) (envelope-from gcooper@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id A23B88FC1D for ; Fri, 7 May 2010 14:31:13 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o47EVDqG016478 for ; Fri, 7 May 2010 14:31:13 GMT (envelope-from gcooper@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o47EVDmK016476 for perforce@freebsd.org; Fri, 7 May 2010 14:31:13 GMT (envelope-from gcooper@FreeBSD.org) Date: Fri, 7 May 2010 14:31:13 GMT Message-Id: <201005071431.o47EVDmK016476@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to gcooper@FreeBSD.org using -f From: Garrett Cooper To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 177902 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 07 May 2010 14:31:14 -0000 http://p4web.freebsd.org/@@177902?ac=10 Change 177902 by gcooper@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 __FBSDID("$FreeBSD: src/usr.sbin/pkg_install/create/perform.c,v 1.85 2010/04/23 11:07:43 flz Exp $"); -#include -#include "create.h" - #include #include +#include #include #include -#include -#include -#include -#include #include +#include + +#include +#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 /<@cwd dir> + * to archive. + */ + if (BaseDir != NULL && + p->name[0] == '/') ; + /* else, + * chdir() . */ - 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(). + * 2. Add the + * /<@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