RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson Root: /v/rpm/cvs Email: [EMAIL PROTECTED] Module: rpm Date: 08-Mar-2008 09:45:55 Branch: HEAD Handle: 2008030808455301 Modified files: rpm/rpmio Makefile.am ar.c cpio.c rpmtar.c rpmtar.h tar.c tdeb.c Log: - jbj: rpmtar: lash up a working rpmtar -tvf through iosm w ar/tar. Summary: Revision Changes Path 1.149 +1 -1 rpm/rpmio/Makefile.am 1.14 +2 -2 rpm/rpmio/ar.c 1.6 +2 -2 rpm/rpmio/cpio.c 1.10 +669 -592 rpm/rpmio/rpmtar.c 1.3 +57 -61 rpm/rpmio/rpmtar.h 1.6 +4 -4 rpm/rpmio/tar.c 1.7 +0 -2 rpm/rpmio/tdeb.c ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/rpmio/Makefile.am ============================================================================ $ cvs diff -u -r1.148 -r1.149 Makefile.am --- rpm/rpmio/Makefile.am 7 Mar 2008 17:55:58 -0000 1.148 +++ rpm/rpmio/Makefile.am 8 Mar 2008 08:45:53 -0000 1.149 @@ -159,7 +159,7 @@ rpmdigest_LDADD = $(RPMIO_LDADD_COMMON) rpmtar_SOURCES = rpmtar.c -rpmtar_LDADD = $(RPMIO_LDADD_COMMON) +rpmtar_LDADD = $(RPM_LDADD_COMMON) tdeb_SOURCES = tdeb.c tdeb_LDFLAGS = $(RPM_LDADD_COMMON) @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/ar.c ============================================================================ $ cvs diff -u -r1.13 -r1.14 ar.c --- rpm/rpmio/ar.c 7 Mar 2008 17:13:49 -0000 1.13 +++ rpm/rpmio/ar.c 8 Mar 2008 08:45:53 -0000 1.14 @@ -171,9 +171,9 @@ st->st_nlink = 1; if (_ar_debug) -fprintf(stderr, "\t %06o%3d (%4d,%4d)%12d %s\n", +fprintf(stderr, "\t %06o%3d (%4d,%4d)%12lu %s\n", (unsigned)st->st_mode, (int)st->st_nlink, - (int)st->st_uid, (int)st->st_gid, (int)st->st_size, + (int)st->st_uid, (int)st->st_gid, (unsigned long)st->st_size, (iosm->path ? iosm->path : "")); return (int) rc; @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/cpio.c ============================================================================ $ cvs diff -u -r1.5 -r1.6 cpio.c --- rpm/rpmio/cpio.c 7 Mar 2008 17:13:49 -0000 1.5 +++ rpm/rpmio/cpio.c 8 Mar 2008 08:45:54 -0000 1.6 @@ -206,9 +206,9 @@ } if (_cpio_debug) -fprintf(stderr, "\t %06o%3d (%4d,%4d)%10d %s\n\t-> %s\n", +fprintf(stderr, "\t %06o%3d (%4d,%4d)%12lu %s\n\t-> %s\n", (unsigned)st->st_mode, (int)st->st_nlink, - (int)st->st_uid, (int)st->st_gid, (int)st->st_size, + (int)st->st_uid, (int)st->st_gid, (unsigned long)st->st_size, (iosm->path ? iosm->path : ""), (iosm->lpath ? iosm->lpath : "")); return rc; @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/rpmtar.c ============================================================================ $ cvs diff -u -r1.9 -r1.10 rpmtar.c --- rpm/rpmio/rpmtar.c 8 Mar 2008 04:41:27 -0000 1.9 +++ rpm/rpmio/rpmtar.c 8 Mar 2008 08:45:54 -0000 1.10 @@ -64,9 +64,6 @@ #include "system.h" __FBSDID("$FreeBSD: src/usr.bin/tar/bsdtar.c,v 1.79 2008/01/22 07:23:44 kientzle Exp $"); -#include <rpmio.h> -#include <argv.h> - #ifdef HAVE_LANGINFO_H #include <langinfo.h> #endif @@ -77,11 +74,45 @@ #include <paths.h> #endif -#include <popt.h> -#include "rpmtar.h" +#include <rpmio_internal.h> +#include <rpmcb.h> +#include <poptIO.h> + +#include "../rpmdb/rpmtag.h" + +typedef /[EMAIL PROTECTED]@*/ /[EMAIL PROTECTED]@*/ struct rpmts_s * rpmts; +typedef /[EMAIL PROTECTED]@*/ struct rpmte_s * rpmte; + +#define _RPMFI_INTERNAL +#include "../lib/rpmfi.h" + +#define _IOSM_INTERNAL +#include <iosm.h> /* XXX CPIO_FOO/FSM_FOO constants */ +#include <ar.h> +#include <cpio.h> +#include <tar.h> + +typedef /[EMAIL PROTECTED]@*/ /[EMAIL PROTECTED]@*/ struct rpmds_s * rpmds; +typedef struct rpmRelocation_s * rpmRelocation; + +typedef /[EMAIL PROTECTED]@*/ /[EMAIL PROTECTED]@*/ struct rpmdb_s * rpmdb; +typedef /[EMAIL PROTECTED]@*/ struct rpmdbMatchIterator_s * rpmdbMatchIterator; +typedef struct rpmPRCO_s * rpmPRCO; +typedef struct Spec_s * Spec; +#include "../lib/rpmts.h" + +typedef /[EMAIL PROTECTED]@*/ /[EMAIL PROTECTED]@*/ struct rpmpsm_s * rpmpsm; +#define _RPMSQ_INTERNAL +#include "../lib/psm.h" + +#include <rpmtar.h> #include "debug.h" +/[EMAIL PROTECTED] FD_t @*/ +/[EMAIL PROTECTED] rpmpsm @*/ +/[EMAIL PROTECTED] IOSM_t @*/ +/[EMAIL PROTECTED] rpmfi @*/ /* * Per POSIX.1-1988, tar defaults to reading/writing archives to/from * the default tape device for the system. Pick something reasonable here. @@ -104,11 +135,11 @@ /[EMAIL PROTECTED]@*/ static struct bsdtar bsdtar_storage = { - .progname = "rpmtar", /* Need bsdtar->progname for bsdtar_warnc. */ - .fd = -1, /* Mark as "unused" */ - /* Default: preserve mod time on extract */ - /* Default: Perform basic security checks. */ - .extract_flags = ARCHIVE_EXTRACT_TIME | SECURITY, + .progname = "rpmtar", /* Need bsdtar->progname for bsdtar_warnc. */ + .fd = -1, /* Mark as "unused" */ + /* Default: preserve mod time on extract */ + /* Default: Perform basic security checks. */ + .extract_flags = ARCHIVE_EXTRACT_TIME | SECURITY, }; @@ -125,32 +156,32 @@ /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] ap, fileSystem @*/ { - fprintf(stderr, "%s: ", bsdtar->progname); - vfprintf(stderr, fmt, ap); - if (code != 0) - fprintf(stderr, ": %s", strerror(code)); - fprintf(stderr, "\n"); + fprintf(stderr, "%s: ", bsdtar->progname); + vfprintf(stderr, fmt, ap); + if (code != 0) + fprintf(stderr, ": %s", strerror(code)); + fprintf(stderr, "\n"); } void bsdtar_warnc(struct bsdtar *bsdtar, int code, const char *fmt, ...) { - va_list ap; + va_list ap; - va_start(ap, fmt); - bsdtar_vwarnc(bsdtar, code, fmt, ap); - va_end(ap); + va_start(ap, fmt); + bsdtar_vwarnc(bsdtar, code, fmt, ap); + va_end(ap); } void bsdtar_errc(struct bsdtar *bsdtar, int eval, int code, const char *fmt, ...) { - va_list ap; + va_list ap; - va_start(ap, fmt); - bsdtar_vwarnc(bsdtar, code, fmt, ap); - va_end(ap); - exit(eval); + va_start(ap, fmt); + bsdtar_vwarnc(bsdtar, code, fmt, ap); + va_end(ap); + exit(eval); } /*- @@ -173,28 +204,24 @@ void set_chdir(struct bsdtar *bsdtar, const char *newdir) { - if (newdir[0] == '/') { - /* The -C /foo -C /bar case; dump first one. */ - free(bsdtar->pending_chdir); - bsdtar->pending_chdir = NULL; - } - if (bsdtar->pending_chdir == NULL) - /* Easy case: no previously-saved dir. */ - bsdtar->pending_chdir = strdup(newdir); - else { - /* The -C /foo -C bar case; concatenate */ - char *old_pending = bsdtar->pending_chdir; - size_t old_len = strlen(old_pending); - bsdtar->pending_chdir = malloc(old_len + strlen(newdir) + 2); - if (old_pending[old_len - 1] == '/') - old_pending[old_len - 1] = '\0'; - if (bsdtar->pending_chdir != NULL) - sprintf(bsdtar->pending_chdir, "%s/%s", - old_pending, newdir); - free(old_pending); - } - if (bsdtar->pending_chdir == NULL) - bsdtar_errc(bsdtar, 1, errno, "No memory"); + if (newdir[0] == '/') { + /* The -C /foo -C /bar case; dump first one. */ + bsdtar->pending_chdir = _free(bsdtar->pending_chdir); + } + if (bsdtar->pending_chdir == NULL) + /* Easy case: no previously-saved dir. */ + bsdtar->pending_chdir = strdup(newdir); + else { + /* The -C /foo -C bar case; concatenate */ + char *old_pending = bsdtar->pending_chdir; + size_t old_len = strlen(old_pending); + bsdtar->pending_chdir = xmalloc(old_len + strlen(newdir) + 2); + if (old_pending[old_len - 1] == '/') + old_pending[old_len - 1] = '\0'; + if (bsdtar->pending_chdir != NULL) + sprintf(bsdtar->pending_chdir, "%s/%s", old_pending, newdir); + old_pending = _free(old_pending); + } } /* @@ -212,13 +239,13 @@ exclude(struct bsdtar *bsdtar, const char *pattern) { #ifdef NOTYET - struct matching *matching; + struct matching *matching; - if (bsdtar->matching == NULL) - initialize_matching(bsdtar); - matching = bsdtar->matching; - add_pattern(bsdtar, &(matching->exclusions), pattern); - matching->exclusions_count++; + if (bsdtar->matching == NULL) + initialize_matching(bsdtar); + matching = bsdtar->matching; + add_pattern(bsdtar, &(matching->exclusions), pattern); + matching->exclusions_count++; #endif return (0); } @@ -227,9 +254,9 @@ exclude_from_file(struct bsdtar *bsdtar, const char *pathname) { #ifdef NOTYET - return (process_lines(bsdtar, pathname, &exclude)); + return (process_lines(bsdtar, pathname, &exclude)); #else - return (0); + return (0); #endif } @@ -237,64 +264,126 @@ include(struct bsdtar *bsdtar, const char *pattern) { #ifdef NOTYET - struct matching *matching; + struct matching *matching; - if (bsdtar->matching == NULL) - initialize_matching(bsdtar); - matching = bsdtar->matching; - add_pattern(bsdtar, &(matching->inclusions), pattern); - matching->inclusions_count++; - matching->inclusions_unmatched_count++; + if (bsdtar->matching == NULL) + initialize_matching(bsdtar); + matching = bsdtar->matching; + add_pattern(bsdtar, &(matching->inclusions), pattern); + matching->inclusions_count++; + matching->inclusions_unmatched_count++; #endif - return (0); + return (0); } void cleanup_exclusions(struct bsdtar *bsdtar) { #ifdef NOTYET - struct match *p, *q; + struct match *p, *q; - if (bsdtar->matching) { - p = bsdtar->matching->inclusions; - while (p != NULL) { - q = p; - p = p->next; - free(q); - } - p = bsdtar->matching->exclusions; - while (p != NULL) { - q = p; - p = p->next; - free(q); - } - free(bsdtar->matching); + if (bsdtar->matching) { + p = bsdtar->matching->inclusions; + while (p != NULL) { + q = p; + p = p->next; + q = _free(q); + } + p = bsdtar->matching->exclusions; + while (p != NULL) { + q = p; + p = p->next; + q = _free(q); } + bsdtar->matching = _free(bsdtar->matching); + } #endif } /*==============================================================*/ -void tar_mode_c(struct bsdtar *bsdtar) +static int rpmIOSM(rpmts ts, const char * fn, int mapflags) + /[EMAIL PROTECTED] rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ + /[EMAIL PROTECTED] ts, rpmGlobalMacroContext, fileSystem, internalState @*/ +{ + rpmpsm psm; + rpmfi fi; + const char * ioflags; + int fsmmode; + int rc = 0; + int xx; + +fprintf(stderr, "--> rpmIOSM(%p, \"%s\", 0x%x)\n", ts, fn, mapflags); + + if (fn != NULL) { + + fi = rpmfiNew(ts, NULL, RPMTAG_BASENAMES, 0); +assert(fi != NULL); + + psm = rpmpsmNew(ts, NULL, fi); +assert(psm != NULL); + + ioflags = (mapflags & IOSM_PAYLOAD_CREATE) ? "w.ufdio" : "r.ufdio"; + psm->cfd = Fopen(fn, ioflags); + if (psm->cfd != NULL && !Ferror(psm->cfd)) { + + fi->mapflags |= mapflags; + fsmmode = (mapflags & IOSM_PAYLOAD_CREATE) ? IOSM_PKGBUILD : IOSM_PKGINSTALL; + rc = iosmSetup(fi->fsm, fsmmode, "tar", ts, fi, + psm->cfd, NULL, &psm->failedFile); + (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_UNCOMPRESS), + fdstat_op(psm->cfd, FDSTAT_READ)); + (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DIGEST), + fdstat_op(psm->cfd, FDSTAT_DIGEST)); + xx = iosmTeardown(fi->fsm); + + xx = Fclose(psm->cfd); + psm->cfd = NULL; + + if (rc != 0 || psm->failedFile != NULL) { + const char * msg = iosmStrerror(rc); + fprintf(stderr, "%s: %s: %s\n", fn, msg, psm->failedFile); + msg = _free(msg); + } + } + + psm = rpmpsmFree(psm); + + fi = rpmfiFree(fi); + } + + return rc; +} + +/*==============================================================*/ + +int tar_mode_c(struct bsdtar *bsdtar) /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] bsdtar, fileSystem @*/ -{ fprintf(stderr, "==> tar_mode_c: %s\n", (bsdtar->filename ?: "")); return; } -void tar_mode_r(struct bsdtar *bsdtar) +{ fprintf(stderr, "==> tar_mode_c: %s\n", (bsdtar->filename ?: "")); return 0; } +int tar_mode_r(struct bsdtar *bsdtar) /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] bsdtar, fileSystem @*/ -{ fprintf(stderr, "==> tar_mode_r: %s\n", (bsdtar->filename ?: "")); return; } -void tar_mode_t(struct bsdtar *bsdtar) +{ fprintf(stderr, "==> tar_mode_r: %s\n", (bsdtar->filename ?: "")); return 0; } + +int tar_mode_t(struct bsdtar *bsdtar) /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] bsdtar, fileSystem @*/ -{ fprintf(stderr, "==> tar_mode_t: %s\n", (bsdtar->filename ?: "")); return; } -void tar_mode_u(struct bsdtar *bsdtar) +{ + rpmts ts = rpmtsCreate(); + int rc = rpmIOSM(ts, (bsdtar->filename ?: "-"), IOSM_PAYLOAD_LIST); + ts = rpmtsFree(ts); + return rc; +} + +int tar_mode_u(struct bsdtar *bsdtar) /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] bsdtar, fileSystem @*/ -{ fprintf(stderr, "==> tar_mode_u: %s\n", (bsdtar->filename ?: "")); return; } -void tar_mode_x(struct bsdtar *bsdtar) +{ fprintf(stderr, "==> tar_mode_u: %s\n", (bsdtar->filename ?: "")); return 0; } +int tar_mode_x(struct bsdtar *bsdtar) /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] bsdtar, fileSystem @*/ -{ fprintf(stderr, "==> tar_mode_x: %s\n", (bsdtar->filename ?: "")); return; } +{ fprintf(stderr, "==> tar_mode_x: %s\n", (bsdtar->filename ?: "")); return 0; } /*==============================================================*/ @@ -321,50 +410,44 @@ /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] *argc, fileSystem @*/ { - char **new_argv, **dest_argv; - const char *p; - char *src, *dest; - - if (src_argv[0] == NULL || - src_argv[1] == NULL || src_argv[1][0] == '-') - return (src_argv); - - *argc += strlen(src_argv[1]) - 1; - new_argv = malloc((*argc + 1) * sizeof(new_argv[0])); - if (new_argv == NULL) - bsdtar_errc(bsdtar, 1, errno, "No Memory"); - - dest_argv = new_argv; - *dest_argv++ = *src_argv++; - - dest = malloc(strlen(*src_argv) * 3); - if (dest == NULL) - bsdtar_errc(bsdtar, 1, errno, "No memory"); - for (src = *src_argv++; *src != '\0'; src++) { - *dest_argv++ = dest; - *dest++ = '-'; - *dest++ = *src; - *dest++ = '\0'; - /* If option takes an argument, insert that into the list. */ - for (p = optstring; p != NULL && *p != '\0'; p++) { - if (*p != *src) - /[EMAIL PROTECTED]@*/ continue; - if (p[1] != ':') /* No arg required, done. */ - /[EMAIL PROTECTED]@*/ break; - if (*src_argv == NULL) /* No arg available? Error. */ - bsdtar_errc(bsdtar, 1, 0, - "Option %c requires an argument", + char **new_argv, **dest_argv; + const char *p; + char *src, *dest; + + if (src_argv[0] == NULL || src_argv[1] == NULL || src_argv[1][0] == '-') + return (src_argv); + + *argc += strlen(src_argv[1]) - 1; + new_argv = xmalloc((*argc + 1) * sizeof(new_argv[0])); + + dest_argv = new_argv; + *dest_argv++ = *src_argv++; + + dest = xmalloc(strlen(*src_argv) * 3); + for (src = *src_argv++; *src != '\0'; src++) { + *dest_argv++ = dest; + *dest++ = '-'; + *dest++ = *src; + *dest++ = '\0'; + /* If option takes an argument, insert that into the list. */ + for (p = optstring; p != NULL && *p != '\0'; p++) { + if (*p != *src) + /[EMAIL PROTECTED]@*/ continue; + if (p[1] != ':') /* No arg required, done. */ + /[EMAIL PROTECTED]@*/ break; + if (*src_argv == NULL) /* No arg available? Error. */ + bsdtar_errc(bsdtar, 1, 0, "Option %c requires an argument", *src); - *dest_argv++ = *src_argv++; - /[EMAIL PROTECTED]@*/ break; - } + *dest_argv++ = *src_argv++; + /[EMAIL PROTECTED]@*/ break; } + } - /* Copy remaining arguments, including trailing NULL. */ - while ((*dest_argv++ = *src_argv++) != NULL) - ; + /* Copy remaining arguments, including trailing NULL. */ + while ((*dest_argv++ = *src_argv++) != NULL) + ; - return (new_argv); + return (new_argv); } /* @@ -392,25 +475,25 @@ /* Fake short equivalents for long options that otherwise lack them. */ enum { - OPTION_CHECK_LINKS=1, - OPTION_EXCLUDE, - OPTION_FAST_READ, - OPTION_FORMAT, - OPTION_INCLUDE, - OPTION_NEWER_CTIME, - OPTION_NEWER_CTIME_THAN, - OPTION_NEWER_MTIME, - OPTION_NEWER_MTIME_THAN, - OPTION_NODUMP, - OPTION_NO_SAME_OWNER, - OPTION_NO_SAME_PERMISSIONS, - OPTION_NULL, - OPTION_ONE_FILE_SYSTEM, - OPTION_POSIX, - OPTION_STRIP_COMPONENTS, - OPTION_TOTALS, - OPTION_USE_COMPRESS_PROGRAM, - OPTION_VERSION + OPTION_CHECK_LINKS=1, + OPTION_EXCLUDE, + OPTION_FAST_READ, + OPTION_FORMAT, + OPTION_INCLUDE, + OPTION_NEWER_CTIME, + OPTION_NEWER_CTIME_THAN, + OPTION_NEWER_MTIME, + OPTION_NEWER_MTIME_THAN, + OPTION_NODUMP, + OPTION_NO_SAME_OWNER, + OPTION_NO_SAME_PERMISSIONS, + OPTION_NULL, + OPTION_ONE_FILE_SYSTEM, + OPTION_POSIX, + OPTION_STRIP_COMPONENTS, + OPTION_TOTALS, + OPTION_USE_COMPRESS_PROGRAM, + OPTION_VERSION }; static void @@ -418,10 +501,10 @@ /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] bsdtar, fileSystem @*/ { - if (bsdtar->mode != '\0' && bsdtar->mode != opt) - bsdtar_errc(bsdtar, 1, 0, - "Can't specify both -%c and -%c", opt, bsdtar->mode); - bsdtar->mode = opt; + if (bsdtar->mode != '\0' && bsdtar->mode != opt) + bsdtar_errc(bsdtar, 1, 0, "Can't specify both -%c and -%c", + opt, bsdtar->mode); + bsdtar->mode = opt; } /[EMAIL PROTECTED]@*/ @@ -433,278 +516,271 @@ void * data) /[EMAIL PROTECTED] *data @*/ { - struct bsdtar * bsdtar = data; - int val = opt->val; - int t; + struct bsdtar * bsdtar = data; + int val = opt->val; + int t; if (_debug) fprintf(stderr, "--> bsdtarArgCallback(%p, %d, %p, %p, %p) val %d\n", con, reason, opt, arg, data, val); + /* + * Comments following each option indicate where that option + * originated: SUSv2, POSIX, GNU tar, star, etc. If there's + * no such comment, then I don't know of anyone else who + * implements that option. + */ + + /* XXX avoid accidental collisions with POPT_BIT_SET for flags */ + if (opt->arg == NULL) + switch (val) { + case 'B': /* GNU tar */ + /* libarchive doesn't need this; just ignore it. */ + break; + case 'b': /* SUSv2 */ + t = atoi(arg); + if (t <= 0 || t > 1024) + bsdtar_errc(bsdtar, 1, 0, + "Argument to -b is out of range (1..1024)"); + bsdtar->bytes_per_block = 512 * t; + break; + case 'C': /* GNU tar */ + set_chdir(bsdtar, arg); + break; + case 'c': /* SUSv2 */ + set_mode(bsdtar, val); + break; + case OPTION_EXCLUDE: /* GNU tar */ + if (exclude(bsdtar, arg)) + bsdtar_errc(bsdtar, 1, 0, "Couldn't exclude %s\n", arg); + break; + case OPTION_FORMAT: /* GNU tar, others */ + bsdtar->create_format = arg; + break; + case 'f': /* SUSv2 */ + bsdtar->filename = arg; + break; + case OPTION_FAST_READ: /* GNU tar */ + bsdtar->option_fast_read = 1; + break; + case 'H': /* BSD convention */ + bsdtar->symlink_mode = 'H'; + break; + case 'h': /* Linux Standards Base, gtar; synonym for -L */ + bsdtar->symlink_mode = 'L'; + break; + case 'I': /* GNU tar */ /* - * Comments following each option indicate where that option - * originated: SUSv2, POSIX, GNU tar, star, etc. If there's - * no such comment, then I don't know of anyone else who - * implements that option. + * TODO: Allow 'names' to come from an archive, + * not just a text file. Design a good UI for + * allowing names and mode/owner to be read + * from an archive, with contents coming from + * disk. This can be used to "refresh" an + * archive or to design archives with special + * permissions without having to create those + * permissions on disk. */ - - /* XXX avoid accidental collisions with POPT_BIT_SET for flags */ - if (opt->arg == NULL) - switch (val) { - case 'B': /* GNU tar */ - /* libarchive doesn't need this; just ignore it. */ - break; - case 'b': /* SUSv2 */ - t = atoi(arg); - if (t <= 0 || t > 1024) - bsdtar_errc(bsdtar, 1, 0, - "Argument to -b is out of range (1..1024)"); - bsdtar->bytes_per_block = 512 * t; - break; - case 'C': /* GNU tar */ - set_chdir(bsdtar, arg); - break; - case 'c': /* SUSv2 */ - set_mode(bsdtar, val); - break; - case OPTION_EXCLUDE: /* GNU tar */ - if (exclude(bsdtar, arg)) - bsdtar_errc(bsdtar, 1, 0, - "Couldn't exclude %s\n", arg); - break; - case OPTION_FORMAT: /* GNU tar, others */ - bsdtar->create_format = arg; - break; - case 'f': /* SUSv2 */ - bsdtar->filename = arg; - break; - case OPTION_FAST_READ: /* GNU tar */ - bsdtar->option_fast_read = 1; - break; - case 'H': /* BSD convention */ - bsdtar->symlink_mode = 'H'; - break; - case 'h': /* Linux Standards Base, gtar; synonym for -L */ - bsdtar->symlink_mode = 'L'; - break; - case 'I': /* GNU tar */ - /* - * TODO: Allow 'names' to come from an archive, - * not just a text file. Design a good UI for - * allowing names and mode/owner to be read - * from an archive, with contents coming from - * disk. This can be used to "refresh" an - * archive or to design archives with special - * permissions without having to create those - * permissions on disk. - */ - bsdtar->names_from_file = arg; - break; - case OPTION_INCLUDE: - /* - * Noone else has the @archive extension, so - * noone else needs this to filter entries - * when transforming archives. - */ - if (include(bsdtar, arg)) - bsdtar_errc(bsdtar, 1, 0, - "Failed to add %s to inclusion list", - arg); + bsdtar->names_from_file = arg; + break; + case OPTION_INCLUDE: + /* + * Noone else has the @archive extension, so + * noone else needs this to filter entries + * when transforming archives. + */ + if (include(bsdtar, arg)) + bsdtar_errc(bsdtar, 1, 0, + "Failed to add %s to inclusion list", arg); break; - case 'j': /* GNU tar */ + case 'j': /* GNU tar */ #if HAVE_LIBBZ2 - if (bsdtar->create_compression != '\0') - bsdtar_errc(bsdtar, 1, 0, - "Can't specify both -%c and -%c", val, + if (bsdtar->create_compression != '\0') + bsdtar_errc(bsdtar, 1, 0, "Can't specify both -%c and -%c", val, bsdtar->create_compression); - bsdtar->create_compression = val; + bsdtar->create_compression = val; #else - bsdtar_warnc(bsdtar, 0, "-j compression not supported by this version of rpmtar"); - poptPrintUsage(con, stderr, 0); - exit(EXIT_FAILURE); + bsdtar_warnc(bsdtar, 0, "-j compression not supported by this version of rpmtar"); + poptPrintUsage(con, stderr, 0); + exit(EXIT_FAILURE); #endif - break; - case 'k': /* GNU tar */ - bsdtar->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE; - break; - case 'L': /* BSD convention */ - bsdtar->symlink_mode = 'L'; - break; - case 'l': /* SUSv2 and GNU tar beginning with 1.16 */ - /* GNU tar 1.13 used -l for --one-file-system */ - bsdtar->option_warn_links = 1; - break; - case 'm': /* SUSv2 */ - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_TIME; - break; - case 'n': /* GNU tar */ - bsdtar->option_no_subdirs = 1; - break; - /* - * Selecting files by time: - * --newer-?time='date' Only files newer than 'date' - * --newer-?time-than='file' Only files newer than time - * on specified file (useful for incremental backups) - * TODO: Add corresponding "older" options to reverse these. - */ - case OPTION_NEWER_CTIME: /* GNU tar */ - bsdtar->newer_ctime_sec = get_date(arg); - break; - case OPTION_NEWER_CTIME_THAN: - { struct stat st; - if (stat(arg, &st) != 0) - bsdtar_errc(bsdtar, 1, 0, "Can't open file %s", arg); - bsdtar->newer_ctime_sec = st.st_ctime; - bsdtar->newer_ctime_nsec = ARCHIVE_STAT_CTIME_NANOS(&st); - } break; - case OPTION_NEWER_MTIME: /* GNU tar */ - bsdtar->newer_mtime_sec = get_date(arg); - break; - case OPTION_NEWER_MTIME_THAN: - { struct stat st; - if (stat(arg, &st) != 0) - bsdtar_errc(bsdtar, 1, 0, "Can't open file %s", arg); - bsdtar->newer_mtime_sec = st.st_mtime; - bsdtar->newer_mtime_nsec = ARCHIVE_STAT_MTIME_NANOS(&st); - } break; - case OPTION_NODUMP: /* star */ - bsdtar->option_honor_nodump = 1; - break; - case OPTION_NO_SAME_OWNER: /* GNU tar */ - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_OWNER; - break; - case OPTION_NO_SAME_PERMISSIONS: /* GNU tar */ - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_PERM; - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_ACL; - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_XATTR; - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_FFLAGS; - break; - case OPTION_NULL: /* GNU tar */ - bsdtar->option_null++; - break; - case 'O': /* GNU tar */ - bsdtar->option_stdout = 1; - break; - case 'o': /* SUSv2 and GNU conflict here, but not fatally */ - option_o = 1; /* Record it and resolve it later. */ - break; - case OPTION_ONE_FILE_SYSTEM: /* GNU tar */ - bsdtar->option_dont_traverse_mounts = 1; - break; + break; + case 'k': /* GNU tar */ + bsdtar->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE; + break; + case 'L': /* BSD convention */ + bsdtar->symlink_mode = 'L'; + break; + case 'l': /* SUSv2 and GNU tar beginning with 1.16 */ + /* GNU tar 1.13 used -l for --one-file-system */ + bsdtar->option_warn_links = 1; + break; + case 'm': /* SUSv2 */ + bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_TIME; + break; + case 'n': /* GNU tar */ + bsdtar->option_no_subdirs = 1; + break; + /* + * Selecting files by time: + * --newer-?time='date' Only files newer than 'date' + * --newer-?time-than='file' Only files newer than time + * on specified file (useful for incremental backups) + * TODO: Add corresponding "older" options to reverse these. + */ + case OPTION_NEWER_CTIME: /* GNU tar */ + bsdtar->newer_ctime_sec = get_date(arg); + break; + case OPTION_NEWER_CTIME_THAN: + { struct stat st; + if (stat(arg, &st) != 0) + bsdtar_errc(bsdtar, 1, 0, "Can't open file %s", arg); + bsdtar->newer_ctime_sec = st.st_ctime; + bsdtar->newer_ctime_nsec = ARCHIVE_STAT_CTIME_NANOS(&st); + } break; + case OPTION_NEWER_MTIME: /* GNU tar */ + bsdtar->newer_mtime_sec = get_date(arg); + break; + case OPTION_NEWER_MTIME_THAN: + { struct stat st; + if (stat(arg, &st) != 0) + bsdtar_errc(bsdtar, 1, 0, "Can't open file %s", arg); + bsdtar->newer_mtime_sec = st.st_mtime; + bsdtar->newer_mtime_nsec = ARCHIVE_STAT_MTIME_NANOS(&st); + } break; + case OPTION_NODUMP: /* star */ + bsdtar->option_honor_nodump = 1; + break; + case OPTION_NO_SAME_OWNER: /* GNU tar */ + bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_OWNER; + break; + case OPTION_NO_SAME_PERMISSIONS: /* GNU tar */ + bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_PERM; + bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_ACL; + bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_XATTR; + bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_FFLAGS; + break; + case OPTION_NULL: /* GNU tar */ + bsdtar->option_null++; + break; + case 'O': /* GNU tar */ + bsdtar->option_stdout = 1; + break; + case 'o': /* SUSv2 and GNU conflict here, but not fatally */ + option_o = 1; /* Record it and resolve it later. */ + break; + case OPTION_ONE_FILE_SYSTEM: /* GNU tar */ + bsdtar->option_dont_traverse_mounts = 1; + break; #if 0 - /* - * The common BSD -P option is not necessary, since - * our default is to archive symlinks, not follow - * them. This is convenient, as -P conflicts with GNU - * tar anyway. - */ - case 'P': /* BSD convention */ - /* Default behavior, no option necessary. */ - break; + /* + * The common BSD -P option is not necessary, since + * our default is to archive symlinks, not follow + * them. This is convenient, as -P conflicts with GNU + * tar anyway. + */ + case 'P': /* BSD convention */ + /* Default behavior, no option necessary. */ + break; #endif - case 'P': /* GNU tar */ - bsdtar->extract_flags &= ~SECURITY; - bsdtar->option_absolute_paths = 1; - break; - case 'p': /* GNU tar, star */ - bsdtar->extract_flags |= ARCHIVE_EXTRACT_PERM; - bsdtar->extract_flags |= ARCHIVE_EXTRACT_ACL; - bsdtar->extract_flags |= ARCHIVE_EXTRACT_XATTR; - bsdtar->extract_flags |= ARCHIVE_EXTRACT_FFLAGS; - break; - case OPTION_POSIX: /* GNU tar */ - bsdtar->create_format = "pax"; - break; - case 'r': /* SUSv2 */ - set_mode(bsdtar, val); - break; - case OPTION_STRIP_COMPONENTS: /* GNU tar 1.15 */ - bsdtar->strip_components = atoi(arg); - break; - case 'T': /* GNU tar */ - bsdtar->names_from_file = arg; - break; - case 't': /* SUSv2 */ - set_mode(bsdtar, val); - bsdtar->verbose++; - break; - case OPTION_TOTALS: /* GNU tar */ - bsdtar->option_totals++; - break; - case 'U': /* GNU tar */ - bsdtar->extract_flags |= ARCHIVE_EXTRACT_UNLINK; - bsdtar->option_unlink_first = 1; - break; - case 'u': /* SUSv2 */ - set_mode(bsdtar, val); - break; - case 'v': /* SUSv2 */ - bsdtar->verbose++; - break; - case OPTION_VERSION: /* GNU convention */ - printf("%s %s (libarchive %s)\n", bsdtar->progname, + case 'P': /* GNU tar */ + bsdtar->extract_flags &= ~SECURITY; + bsdtar->option_absolute_paths = 1; + break; + case 'p': /* GNU tar, star */ + bsdtar->extract_flags |= ARCHIVE_EXTRACT_PERM; + bsdtar->extract_flags |= ARCHIVE_EXTRACT_ACL; + bsdtar->extract_flags |= ARCHIVE_EXTRACT_XATTR; + bsdtar->extract_flags |= ARCHIVE_EXTRACT_FFLAGS; + break; + case OPTION_POSIX: /* GNU tar */ + bsdtar->create_format = "pax"; + break; + case 'r': /* SUSv2 */ + set_mode(bsdtar, val); + break; + case OPTION_STRIP_COMPONENTS: /* GNU tar 1.15 */ + bsdtar->strip_components = atoi(arg); + break; + case 'T': /* GNU tar */ + bsdtar->names_from_file = arg; + break; + case 't': /* SUSv2 */ + set_mode(bsdtar, val); + bsdtar->verbose++; + break; + case OPTION_TOTALS: /* GNU tar */ + bsdtar->option_totals++; + break; + case 'U': /* GNU tar */ + bsdtar->extract_flags |= ARCHIVE_EXTRACT_UNLINK; + bsdtar->option_unlink_first = 1; + break; + case 'u': /* SUSv2 */ + set_mode(bsdtar, val); + break; + case 'v': /* SUSv2 */ + bsdtar->verbose++; + break; + case OPTION_VERSION: /* GNU convention */ + printf("%s %s (libarchive %s)\n", bsdtar->progname, BSDTAR_VERSION_STRING, archive_version()); - exit(EXIT_FAILURE); - break; + exit(EXIT_FAILURE); + break; #if 0 - /* - * The -W longopt feature is handled inside of - * bsdtar_getop(), so -W is not available here. - */ - case 'W': /* Obscure, but useful GNU convention. */ - break; + /* + * The -W longopt feature is handled inside of + * bsdtar_getop(), so -W is not available here. + */ + case 'W': /* Obscure, but useful GNU convention. */ + break; #endif - case 'w': /* SUSv2 */ - bsdtar->option_interactive = 1; - break; - case 'X': /* GNU tar */ - if (exclude_from_file(bsdtar, arg)) - bsdtar_errc(bsdtar, 1, 0, - "failed to process exclusions from file %s", - arg); - break; - case 'x': /* SUSv2 */ - set_mode(bsdtar, val); - break; - case 'y': /* FreeBSD version of GNU tar */ + case 'w': /* SUSv2 */ + bsdtar->option_interactive = 1; + break; + case 'X': /* GNU tar */ + if (exclude_from_file(bsdtar, arg)) + bsdtar_errc(bsdtar, 1, 0, + "failed to process exclusions from file %s", arg); + break; + case 'x': /* SUSv2 */ + set_mode(bsdtar, val); + break; + case 'y': /* FreeBSD version of GNU tar */ #if HAVE_LIBBZ2 - if (bsdtar->create_compression != '\0') - bsdtar_errc(bsdtar, 1, 0, - "Can't specify both -%c and -%c", val, + if (bsdtar->create_compression != '\0') + bsdtar_errc(bsdtar, 1, 0, "Can't specify both -%c and -%c", val, bsdtar->create_compression); - bsdtar->create_compression = val; + bsdtar->create_compression = val; #else - bsdtar_warnc(bsdtar, 0, "-y compression not supported by this version of rpmtar"); - poptPrintUsage(con, stderr, 0); - exit(EXIT_FAILURE); + bsdtar_warnc(bsdtar, 0, "-y compression not supported by this version of rpmtar"); + poptPrintUsage(con, stderr, 0); + exit(EXIT_FAILURE); #endif - break; - case 'Z': /* GNU tar */ - if (bsdtar->create_compression != '\0') - bsdtar_errc(bsdtar, 1, 0, - "Can't specify both -%c and -%c", val, + break; + case 'Z': /* GNU tar */ + if (bsdtar->create_compression != '\0') + bsdtar_errc(bsdtar, 1, 0, "Can't specify both -%c and -%c", val, bsdtar->create_compression); - bsdtar->create_compression = val; - break; - case 'z': /* GNU tar, star, many others */ + bsdtar->create_compression = val; + break; + case 'z': /* GNU tar, star, many others */ #if HAVE_LIBZ - if (bsdtar->create_compression != '\0') - bsdtar_errc(bsdtar, 1, 0, - "Can't specify both -%c and -%c", val, + if (bsdtar->create_compression != '\0') + bsdtar_errc(bsdtar, 1, 0, "Can't specify both -%c and -%c", val, bsdtar->create_compression); - bsdtar->create_compression = val; + bsdtar->create_compression = val; #else - bsdtar_warnc(bsdtar, 0, "-z compression not supported by this version of rpmtar"); - poptPrintUsage(con, stderr, 0); - exit(EXIT_FAILURE); + bsdtar_warnc(bsdtar, 0, "-z compression not supported by this version of rpmtar"); + poptPrintUsage(con, stderr, 0); + exit(EXIT_FAILURE); #endif - break; - case OPTION_USE_COMPRESS_PROGRAM: - bsdtar->compress_program = arg; - break; - default: - poptPrintUsage(con, stderr, 0); - exit(EXIT_FAILURE); - break; - } + break; + case OPTION_USE_COMPRESS_PROGRAM: + bsdtar->compress_program = arg; + break; + default: + poptPrintUsage(con, stderr, 0); + exit(EXIT_FAILURE); + break; + } } static struct poptOption optionsTable[] = { @@ -875,61 +951,61 @@ /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] bsdtar, fileSystem @*/ { - const char *p, *q; - const struct option * option = NULL; - int opt; - size_t option_length; - - /* Support long options through -W longopt=value */ - p = arg; - q = strchr(arg, '='); - if (q != NULL) { - option_length = (size_t)(q - p); - arg = q + 1; - } else { - option_length = strlen(p); - arg = NULL; - } - option = tar_longopts; - while (option->name != NULL && - (strlen(option->name) < option_length || - strncmp(p, option->name, option_length) != 0 )) { - option++; - } - - if (option->name != NULL) { - const struct option * o = option; - opt = o->val; - - /* If the first match was exact, we're done. */ - if (!strncmp(p, o->name, strlen(o->name))) { - while (o->name != NULL) - o++; - } else { - /* Check if there's another match. */ - o++; - while (o->name != NULL && - (strlen(o->name) < option_length || - strncmp(p, o->name, option_length))) { - o++; - } - } - if (o->name != NULL) - bsdtar_errc(bsdtar, 1, 0, - "Ambiguous option %s " - "(matches both %s and %s)", - p, option->name, o->name); - - if (option->has_arg == required_argument && arg == NULL) - bsdtar_errc(bsdtar, 1, 0, - "Option \"%s\" requires argument", p); + const char *p, *q; + const struct option * option = NULL; + int opt; + size_t option_length; + + /* Support long options through -W longopt=value */ + p = arg; + q = strchr(arg, '='); + if (q != NULL) { + option_length = (size_t)(q - p); + arg = q + 1; + } else { + option_length = strlen(p); + arg = NULL; + } + option = tar_longopts; + while (option->name != NULL && + (strlen(option->name) < option_length || + strncmp(p, option->name, option_length) != 0 )) + { + option++; + } + + if (option->name != NULL) { + const struct option * o = option; + opt = o->val; + + /* If the first match was exact, we're done. */ + if (!strncmp(p, o->name, strlen(o->name))) { + while (o->name != NULL) + o++; } else { - opt = '?'; - /* TODO: Set up a fake 'struct option' for - * error reporting... ? ? ? */ - option = NULL; + /* Check if there's another match. */ + o++; + while (o->name != NULL && + (strlen(o->name) < option_length || + strncmp(p, o->name, option_length))) + { + o++; + } } - return option; + if (o->name != NULL) + bsdtar_errc(bsdtar, 1, 0, + "Ambiguous option %s (matches both %s and %s)", + p, option->name, o->name); + + if (option->has_arg == required_argument && arg == NULL) + bsdtar_errc(bsdtar, 1, 0, "Option \"%s\" requires argument", p); + } else { + opt = '?'; + /* TODO: Set up a fake 'struct option' for + * error reporting... ? ? ? */ + option = NULL; + } + return option; } #endif @@ -941,9 +1017,8 @@ /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] fileSystem @*/ { - if (strchr(valid_modes, bsdtar->mode) == NULL) - bsdtar_errc(bsdtar, 1, 0, - "Option %s is not permitted in mode -%c", + if (strchr(valid_modes, bsdtar->mode) == NULL) + bsdtar_errc(bsdtar, 1, 0, "Option %s is not permitted in mode -%c", opt, bsdtar->mode); } @@ -952,154 +1027,156 @@ /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] argc, *argv, fileSystem @*/ { - struct bsdtar *bsdtar = &bsdtar_storage; - poptContext optCon; - char buff[16]; - int rc; - - if (setlocale(LC_ALL, "") == NULL) - bsdtar_warnc(bsdtar, 0, "Failed to set default locale"); - - /* Rewrite traditional-style tar arguments, if used. */ - argv = rewrite_argv(bsdtar, &argc, argv, tar_opts); - - optCon = poptGetContext(bsdtar->progname, argc, (const char **)argv, optionsTable, 0); - - /* Process all options, whine if unknown. */ - while ((rc = poptGetNextOpt(optCon)) > 0) { - const char * optArg = poptGetOptArg(optCon); + poptContext optCon; + struct bsdtar *bsdtar = &bsdtar_storage; + char buff[16]; + int rc; + int xx; + + if (setlocale(LC_ALL, "") == NULL) + bsdtar_warnc(bsdtar, 0, "Failed to set default locale"); + + /* Rewrite traditional-style tar arguments, if used. */ + argv = rewrite_argv(bsdtar, &argc, argv, tar_opts); + + optCon = poptGetContext(bsdtar->progname, argc, (const char **)argv, optionsTable, 0); + + /* Process all options, whine if unknown. */ + while ((rc = poptGetNextOpt(optCon)) > 0) { + const char * optArg = poptGetOptArg(optCon); /[EMAIL PROTECTED] -modobserver -observertrans @*/ - optArg = _free(optArg); + optArg = _free(optArg); /[EMAIL PROTECTED] =modobserver =observertrans @*/ - switch (rc) { - default: - bsdtar_errc(bsdtar, 1, 0, "Option table misconfigured"); - /[EMAIL PROTECTED]@*/ /[EMAIL PROTECTED]@*/ break; - } - } - bsdtar->argv = (char **) poptGetArgs(optCon); - bsdtar->argc = argvCount((ARGV_t)bsdtar->argv); - - /* - * Sanity-check options. - */ - - /* A mode is required. */ - if (bsdtar->mode == '\0') { - poptPrintUsage(optCon, stderr, 0); - bsdtar_errc(bsdtar, 1, 0, - "Must specify one of -c, -r, -t, -u, -x"); - } - - /* Check boolean options only permitted in certain modes. */ - if (bsdtar->option_dont_traverse_mounts) - only_mode(bsdtar, "--one-file-system", "cru"); - if (bsdtar->option_fast_read) - only_mode(bsdtar, "--fast-read", "xt"); - if (bsdtar->option_honor_nodump) - only_mode(bsdtar, "--nodump", "cru"); - if (option_o > 0) { - switch (bsdtar->mode) { - case 'c': - /* - * In GNU tar, -o means "old format." The - * "ustar" format is the closest thing - * supported by libarchive. - */ - bsdtar->create_format = "ustar"; - /* TODO: bsdtar->create_format = "v7"; */ - break; - case 'x': - /* POSIX-compatible behavior. */ - bsdtar->option_no_owner = 1; - bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_OWNER; - break; - default: - only_mode(bsdtar, "-o", "xc"); - break; - } - } - if (bsdtar->option_no_subdirs) - only_mode(bsdtar, "-n", "cru"); - if (bsdtar->option_stdout) - only_mode(bsdtar, "-O", "xt"); - if (bsdtar->option_unlink_first) - only_mode(bsdtar, "-U", "x"); - if (bsdtar->option_warn_links) - only_mode(bsdtar, "--check-links", "cr"); - - /* Check other parameters only permitted in certain modes. */ - if (bsdtar->create_compression == 'Z' && bsdtar->mode == 'c') { - bsdtar_warnc(bsdtar, 0, ".Z compression not supported"); - poptPrintUsage(optCon, stderr, 0); - exit(EXIT_FAILURE); - } - if (bsdtar->create_compression != '\0') { - strcpy(buff, "-?"); - buff[1] = bsdtar->create_compression; - only_mode(bsdtar, buff, "cxt"); - } - if (bsdtar->create_format != NULL) - only_mode(bsdtar, "--format", "c"); - if (bsdtar->symlink_mode != '\0') { - strcpy(buff, "-?"); - buff[1] = bsdtar->symlink_mode; - only_mode(bsdtar, buff, "cru"); + switch (rc) { + default: + bsdtar_errc(bsdtar, 1, 0, "Option table misconfigured"); + /[EMAIL PROTECTED]@*/ /[EMAIL PROTECTED]@*/ break; } - if (bsdtar->strip_components != 0) - only_mode(bsdtar, "--strip-components", "xt"); - - /* Look up uid of current user. */ - /* Defaults for root user: */ - bsdtar->user_uid = geteuid(); - if (bsdtar->user_uid == 0) { - /* --same-owner */ - bsdtar->extract_flags |= ARCHIVE_EXTRACT_OWNER; - /* -p */ - bsdtar->extract_flags |= ARCHIVE_EXTRACT_PERM; - bsdtar->extract_flags |= ARCHIVE_EXTRACT_ACL; - bsdtar->extract_flags |= ARCHIVE_EXTRACT_XATTR; - bsdtar->extract_flags |= ARCHIVE_EXTRACT_FFLAGS; + } + bsdtar->argv = (char **) poptGetArgs(optCon); + bsdtar->argc = argvCount((ARGV_t)bsdtar->argv); + + /* Sanity-check options. */ + + /* A mode is required. */ + if (bsdtar->mode == '\0') { + poptPrintUsage(optCon, stderr, 0); + bsdtar_errc(bsdtar, 1, 0, "Must specify one of -c, -r, -t, -u, -x"); + } + + /* Check boolean options only permitted in certain modes. */ + if (bsdtar->option_dont_traverse_mounts) + only_mode(bsdtar, "--one-file-system", "cru"); + if (bsdtar->option_fast_read) + only_mode(bsdtar, "--fast-read", "xt"); + if (bsdtar->option_honor_nodump) + only_mode(bsdtar, "--nodump", "cru"); + if (option_o > 0) { + switch (bsdtar->mode) { + case 'c': + /* + * In GNU tar, -o means "old format." The "ustar" format is the + * closest thing supported by libarchive. + */ + bsdtar->create_format = "ustar"; + /* TODO: bsdtar->create_format = "v7"; */ + break; + case 'x': + /* POSIX-compatible behavior. */ + bsdtar->option_no_owner = 1; + bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_OWNER; + break; + default: + only_mode(bsdtar, "-o", "xc"); + break; } + } + if (bsdtar->option_no_subdirs) + only_mode(bsdtar, "-n", "cru"); + if (bsdtar->option_stdout) + only_mode(bsdtar, "-O", "xt"); + if (bsdtar->option_unlink_first) + only_mode(bsdtar, "-U", "x"); + if (bsdtar->option_warn_links) + only_mode(bsdtar, "--check-links", "cr"); + + /* Check other parameters only permitted in certain modes. */ + if (bsdtar->create_compression == 'Z' && bsdtar->mode == 'c') { + bsdtar_warnc(bsdtar, 0, ".Z compression not supported"); + poptPrintUsage(optCon, stderr, 0); + exit(EXIT_FAILURE); + } + if (bsdtar->create_compression != '\0') { + strcpy(buff, "-?"); + buff[1] = bsdtar->create_compression; + only_mode(bsdtar, buff, "cxt"); + } + if (bsdtar->create_format != NULL) + only_mode(bsdtar, "--format", "c"); + if (bsdtar->symlink_mode != '\0') { + strcpy(buff, "-?"); + buff[1] = bsdtar->symlink_mode; + only_mode(bsdtar, buff, "cru"); + } + if (bsdtar->strip_components != 0) + only_mode(bsdtar, "--strip-components", "xt"); + + /* Look up uid of current user. */ + /* Defaults for root user: */ + bsdtar->user_uid = geteuid(); + if (bsdtar->user_uid == 0) { + bsdtar->extract_flags |= ARCHIVE_EXTRACT_OWNER; /* --same-owner */ + bsdtar->extract_flags |= ARCHIVE_EXTRACT_PERM; /* -p */ + bsdtar->extract_flags |= ARCHIVE_EXTRACT_ACL; + bsdtar->extract_flags |= ARCHIVE_EXTRACT_XATTR; + bsdtar->extract_flags |= ARCHIVE_EXTRACT_FFLAGS; + } #if defined(HAVE_NL_LANGINFO) && defined(HAVE_D_MD_ORDER) - bsdtar->day_first = (*nl_langinfo(D_MD_ORDER) == 'd'); + bsdtar->day_first = (*nl_langinfo(D_MD_ORDER) == 'd'); #endif - /* Default: open tape drive. */ - if (bsdtar->filename == NULL) { - if ((bsdtar->filename = getenv("TAPE")) == NULL) - bsdtar->filename = _PATH_DEFTAPE; - } else - if (bsdtar->filename[0] == '-' && bsdtar->filename[1] == '\0') - bsdtar->filename = NULL; - - switch(bsdtar->mode) { - case 'c': - tar_mode_c(bsdtar); - break; - case 'r': - tar_mode_r(bsdtar); - break; - case 't': - tar_mode_t(bsdtar); - break; - case 'u': - tar_mode_u(bsdtar); - break; - case 'x': - tar_mode_x(bsdtar); - break; - } - - cleanup_exclusions(bsdtar); - if (bsdtar->return_value != 0) - bsdtar_warnc(bsdtar, 0, - "Error exit delayed from previous errors."); + /* Default: open tape drive. */ + if (bsdtar->filename == NULL) { + if ((bsdtar->filename = getenv("TAPE")) == NULL) + bsdtar->filename = _PATH_DEFTAPE; + } else + if (bsdtar->filename[0] == '-' && bsdtar->filename[1] == '\0') + bsdtar->filename = NULL; + +_iosmNext = &iosmNext; +_iosm_debug = -1; +_ar_debug = 1; +_cpio_debug = 1; +_tar_debug = 1; +rpmIncreaseVerbosity(); +rpmIncreaseVerbosity(); + + switch(bsdtar->mode) { + case 'c': + xx = tar_mode_c(bsdtar); + break; + case 'r': + xx = tar_mode_r(bsdtar); + break; + case 't': + xx = tar_mode_t(bsdtar); + break; + case 'u': + xx = tar_mode_u(bsdtar); + break; + case 'x': + xx = tar_mode_x(bsdtar); + break; + } + + cleanup_exclusions(bsdtar); + if (bsdtar->return_value != 0) + bsdtar_warnc(bsdtar, 0, "Error exit delayed from previous errors."); - optCon = poptFreeContext(optCon); + optCon = poptFreeContext(optCon); /[EMAIL PROTECTED]@*/ - return (bsdtar->return_value); + return (bsdtar->return_value); /[EMAIL PROTECTED]@*/ } @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/rpmtar.h ============================================================================ $ cvs diff -u -r1.2 -r1.3 rpmtar.h --- rpm/rpmio/rpmtar.h 7 Mar 2008 18:28:46 -0000 1.2 +++ rpm/rpmio/rpmtar.h 8 Mar 2008 08:45:54 -0000 1.3 @@ -38,74 +38,73 @@ * functions. */ struct bsdtar { - /* Options */ + /* Options */ /[EMAIL PROTECTED]@*/ /[EMAIL PROTECTED]@*/ - const char *filename; /* -f filename */ + const char *filename; /*!< -f filename */ /[EMAIL PROTECTED]@*/ /[EMAIL PROTECTED]@*/ - const char *create_format; /* -F format */ + const char *create_format; /*!< -F format */ /[EMAIL PROTECTED]@*/ - char *pending_chdir; /* -C dir */ + char *pending_chdir; /*!< -C dir */ /[EMAIL PROTECTED]@*/ - const char *names_from_file; /* -T file */ - time_t newer_ctime_sec; /* --newer/--newer-than */ - long newer_ctime_nsec; /* --newer/--newer-than */ - time_t newer_mtime_sec; /* --newer-mtime */ - long newer_mtime_nsec; /* --newer-mtime-than */ - int bytes_per_block; /* -b block_size */ - int verbose; /* -v */ - int extract_flags; /* Flags for extract operation */ - int strip_components; /* Remove this many leading dirs */ - char mode; /* Program mode: 'c', 't', 'r', 'u', 'x' */ - char symlink_mode; /* H or L, per BSD conventions */ - char create_compression; /* j, y, or z */ + const char *names_from_file;/*!< -T file */ + time_t newer_ctime_sec; /*!< --newer/--newer-than */ + long newer_ctime_nsec; /*!< --newer/--newer-than */ + time_t newer_mtime_sec; /*!< --newer-mtime */ + long newer_mtime_nsec; /*!< --newer-mtime-than */ + int bytes_per_block; /*!< -b block_size */ + int verbose; /*!< -v */ + int extract_flags; /*!< Flags for extract operation */ + int strip_components; /*!< Remove this many leading dirs */ + char mode; /*!< Program mode: 'c', 't', 'r', 'u', 'x' */ + char symlink_mode; /*!< H or L, per BSD conventions */ + char create_compression; /*!< j, y, or z */ /[EMAIL PROTECTED]@*/ /[EMAIL PROTECTED]@*/ - const char *compress_program; - char option_absolute_paths; /* -P */ - char option_dont_traverse_mounts; /* --one-file-system */ - char option_fast_read; /* --fast-read */ - char option_honor_nodump; /* --nodump */ - char option_interactive; /* -w */ - char option_no_owner; /* -o */ - char option_no_subdirs; /* -n */ - char option_null; /* --null */ - char option_stdout; /* -O */ - char option_totals; /* --totals */ - char option_unlink_first; /* -U */ - char option_warn_links; /* --check-links */ - char day_first; /* show day before month in -tv output */ + const char *compress_program; + char option_absolute_paths; /*!< -P */ + char option_dont_traverse_mounts; /*!< --one-file-system */ + char option_fast_read; /*!< --fast-read */ + char option_honor_nodump; /*!< --nodump */ + char option_interactive; /*!< -w */ + char option_no_owner; /*!< -o */ + char option_no_subdirs; /*!< -n */ + char option_null; /*!< --null */ + char option_stdout; /*!< -O */ + char option_totals; /*!< --totals */ + char option_unlink_first; /*!< -U */ + char option_warn_links; /*!< --check-links */ + char day_first; /*!< show day before month in -tv output */ - /* If >= 0, then close this when done. */ - int fd; + int fd; /*!< If fd >= 0, then close this when done. */ - /* Miscellaneous state information */ - struct archive *archive; + /* Miscellaneous state information */ + struct archive *archive; /[EMAIL PROTECTED]@*/ - const char *progname; - int argc; + const char *progname; + int argc; /[EMAIL PROTECTED]@*/ - char **argv; - size_t gs_width; /* For 'list_item' in read.c */ - size_t u_width; /* for 'list_item' in read.c */ - uid_t user_uid; /* UID running this program */ - int return_value; /* Value returned by main() */ - char warned_lead_slash; /* Already displayed warning */ - char next_line_is_dir; /* Used for -C parsing in -cT */ + char **argv; + size_t gs_width; /*!< For 'list_item' in read.c */ + size_t u_width; /*!< for 'list_item' in read.c */ + uid_t user_uid; /*!< UID running this program */ + int return_value; /*!< Value returned by main() */ + char warned_lead_slash; /*!< Already displayed warning */ + char next_line_is_dir; /*!< Used for -C parsing in -cT */ - /* - * Data for various subsystems. Full definitions are located in - * the file where they are used. - */ + /* + * Data for various subsystems. Full definitions are located in + * the file where they are used. + */ /[EMAIL PROTECTED]@*/ - struct archive_dir *archive_dir; /* for write.c */ + struct archive_dir *archive_dir; /* for write.c */ /[EMAIL PROTECTED]@*/ - struct name_cache *gname_cache; /* for write.c */ + struct name_cache *gname_cache; /* for write.c */ /[EMAIL PROTECTED]@*/ - struct links_cache *links_cache; /* for write.c */ + struct links_cache *links_cache; /* for write.c */ /[EMAIL PROTECTED]@*/ - struct matching *matching; /* for matching.c */ - struct security *security; /* for read.c */ + struct matching *matching; /* for matching.c */ + struct security *security; /* for read.c */ /[EMAIL PROTECTED]@*/ - struct name_cache *uname_cache; /* for write.c */ + struct name_cache *uname_cache; /* for write.c */ }; void bsdtar_errc(struct bsdtar *bsdtar, int eval, int code, @@ -149,26 +148,23 @@ void set_chdir(struct bsdtar *bsdtar, const char *newdir) /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] bsdtar, fileSystem @*/; -void tar_mode_c(struct bsdtar *bsdtar) +int tar_mode_c(struct bsdtar *bsdtar) /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] bsdtar, fileSystem @*/; -void tar_mode_r(struct bsdtar *bsdtar) +int tar_mode_r(struct bsdtar *bsdtar) /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] bsdtar, fileSystem @*/; -void tar_mode_t(struct bsdtar *bsdtar) +int tar_mode_t(struct bsdtar *bsdtar) /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] bsdtar, fileSystem @*/; -void tar_mode_u(struct bsdtar *bsdtar) +int tar_mode_u(struct bsdtar *bsdtar) /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] bsdtar, fileSystem @*/; -void tar_mode_x(struct bsdtar *bsdtar) +int tar_mode_x(struct bsdtar *bsdtar) /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] bsdtar, fileSystem @*/; int unmatched_inclusions(struct bsdtar *bsdtar) /[EMAIL PROTECTED]/; -void usage(struct bsdtar *bsdtar) - /[EMAIL PROTECTED] fileSystem @*/ - /[EMAIL PROTECTED] fileSystem @*/; int yes(const char *fmt, ...) /[EMAIL PROTECTED] fileSystem @*/ /[EMAIL PROTECTED] fileSystem @*/; @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/tar.c ============================================================================ $ cvs diff -u -r1.5 -r1.6 tar.c --- rpm/rpmio/tar.c 7 Mar 2008 17:13:49 -0000 1.5 +++ rpm/rpmio/tar.c 8 Mar 2008 08:45:54 -0000 1.6 @@ -248,9 +248,9 @@ } if (_tar_debug) -fprintf(stderr, "\t %06o%3d (%4d,%4d)%10d %s\n\t-> %s\n", +fprintf(stderr, "\t %06o%3d (%4d,%4d)%12lu %s\n\t-> %s\n", (unsigned)st->st_mode, (int)st->st_nlink, - (int)st->st_uid, (int)st->st_gid, (int)st->st_size, + (int)st->st_uid, (int)st->st_gid, (unsigned long)st->st_size, (iosm->path ? iosm->path : ""), (iosm->lpath ? iosm->lpath : "")); return rc; @@ -312,9 +312,9 @@ if (_tar_debug) fprintf(stderr, "\ttarHeaderWriteBlock(%p, %p) type %c\n", iosm, hdr, hdr->typeflag); if (_tar_debug) -fprintf(stderr, "\t %06o%3d (%4d,%4d)%10d %s\n", +fprintf(stderr, "\t %06o%3d (%4d,%4d)%12lu %s\n", (unsigned)st->st_mode, (int)st->st_nlink, - (int)st->st_uid, (int)st->st_gid, (int)st->st_size, + (int)st->st_uid, (int)st->st_gid, (unsigned long)st->st_size, (iosm->path ? iosm->path : "")); @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/tdeb.c ============================================================================ $ cvs diff -u -r1.6 -r1.7 tdeb.c --- rpm/rpmio/tdeb.c 4 Mar 2008 20:04:52 -0000 1.6 +++ rpm/rpmio/tdeb.c 8 Mar 2008 08:45:54 -0000 1.7 @@ -34,9 +34,7 @@ #include "debug.h" /[EMAIL PROTECTED] FD_t @*/ - /[EMAIL PROTECTED] rpmpsm @*/ - /[EMAIL PROTECTED] IOSM_t @*/ /[EMAIL PROTECTED] rpmfi @*/ @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository rpm-cvs@rpm5.org