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