From d06fc9e5e4a47d022188d4b10202873c5d995b6e Mon Sep 17 00:00:00 2001 From: Michihiro NAKAJIMA Date: Sun, 21 Oct 2012 17:05:28 +0900 Subject: Introduce -a/--auto-compress option into bsdtar. This automatically decides on a creation format and filters by the archive suffix. --- tar/bsdtar.c | 126 ++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 91 insertions(+), 35 deletions(-) (limited to 'tar/bsdtar.c') diff --git a/tar/bsdtar.c b/tar/bsdtar.c index 7f19d837..99ce7644 100644 --- a/tar/bsdtar.c +++ b/tar/bsdtar.c @@ -134,7 +134,10 @@ main(int argc, char **argv) { struct bsdtar *bsdtar, bsdtar_storage; int opt, t; - char option_o; + char compression, compression2; + const char *compression_name, *compression2_name; + const char *compress_program; + char option_a, option_o; char possible_help_request; char buff[16]; @@ -147,7 +150,10 @@ main(int argc, char **argv) bsdtar->fd = -1; /* Mark as "unused" */ bsdtar->gid = -1; bsdtar->uid = -1; - option_o = 0; + option_a = option_o = 0; + compression = compression2 = '\0'; + compression_name = compression2_name = NULL; + compress_program = NULL; #if defined(HAVE_SIGACTION) { /* Set up signal handling. */ @@ -243,6 +249,9 @@ main(int argc, char **argv) bsdtar->matching = archive_match_new(); if (bsdtar->matching == NULL) lafe_errc(1, errno, "Out of memory"); + bsdtar->cset = cset_new(); + if (bsdtar->cset == NULL) + lafe_errc(1, errno, "Out of memory"); bsdtar->argv = argv; bsdtar->argc = argc; @@ -255,6 +264,9 @@ main(int argc, char **argv) */ while ((opt = bsdtar_getopt(bsdtar)) != -1) { switch (opt) { + case 'a': /* GNU tar */ + option_a = 1; /* Record it and resolve it later. */ + break; case 'B': /* GNU tar */ /* libarchive doesn't need this; just ignore it. */ break; @@ -268,11 +280,12 @@ main(int argc, char **argv) bsdtar->bytes_in_last_block = bsdtar->bytes_per_block; break; case OPTION_B64ENCODE: - if (bsdtar->add_filter != '\0') + if (compression2 != '\0') lafe_errc(1, 0, "Can't specify both --uuencode and " "--b64encode"); - bsdtar->add_filter = opt; + compression2 = opt; + compression2_name = "b64encode"; break; case 'C': /* GNU tar */ if (strlen(bsdtar->argument) == 0) @@ -300,7 +313,7 @@ main(int argc, char **argv) "Couldn't exclude %s\n", bsdtar->argument); break; case OPTION_FORMAT: /* GNU tar, others */ - bsdtar->create_format = bsdtar->argument; + cset_set_format(bsdtar->cset, bsdtar->argument); break; case 'f': /* SUSv2 */ bsdtar->filename = bsdtar->argument; @@ -316,11 +329,12 @@ main(int argc, char **argv) bsdtar->gname = bsdtar->argument; break; case OPTION_GRZIP: - if (bsdtar->create_compression != '\0') + if (compression != '\0') lafe_errc(1, 0, "Can't specify both -%c and -%c", opt, - bsdtar->create_compression); - bsdtar->create_compression = opt; + compression); + compression = opt; + compression_name = "grzip"; break; case 'H': /* BSD convention */ bsdtar->symlink_mode = 'H'; @@ -360,18 +374,20 @@ main(int argc, char **argv) bsdtar->argument); break; case 'j': /* GNU tar */ - if (bsdtar->create_compression != '\0') + if (compression != '\0') lafe_errc(1, 0, "Can't specify both -%c and -%c", opt, - bsdtar->create_compression); - bsdtar->create_compression = opt; + compression); + compression = opt; + compression_name = "bzip2"; break; case 'J': /* GNU tar 1.21 and later */ - if (bsdtar->create_compression != '\0') + if (compression != '\0') lafe_errc(1, 0, "Can't specify both -%c and -%c", opt, - bsdtar->create_compression); - bsdtar->create_compression = opt; + compression); + compression = opt; + compression_name = "xz"; break; case 'k': /* GNU tar */ bsdtar->extract_flags |= ARCHIVE_EXTRACT_NO_OVERWRITE; @@ -390,11 +406,17 @@ main(int argc, char **argv) case OPTION_LZIP: /* GNU tar beginning with 1.23 */ case OPTION_LZMA: /* GNU tar beginning with 1.20 */ case OPTION_LZOP: /* GNU tar beginning with 1.21 */ - if (bsdtar->create_compression != '\0') + if (compression != '\0') lafe_errc(1, 0, "Can't specify both -%c and -%c", opt, - bsdtar->create_compression); - bsdtar->create_compression = opt; + compression); + compression = opt; + switch (opt) { + case OPTION_LRZIP: compression_name = "lrzip"; break; + case OPTION_LZIP: compression_name = "lzip"; break; + case OPTION_LZMA: compression_name = "lzma"; break; + case OPTION_LZOP: compression_name = "lzop"; break; + } break; case 'm': /* SUSv2 */ bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_TIME; @@ -527,7 +549,7 @@ main(int argc, char **argv) bsdtar->extract_flags |= ARCHIVE_EXTRACT_MAC_METADATA; break; case OPTION_POSIX: /* GNU tar */ - bsdtar->create_format = "pax"; + cset_set_format(bsdtar->cset, "pax"); break; case 'q': /* FreeBSD GNU tar --fast-read, NetBSD -q */ bsdtar->option_fast_read = 1; @@ -587,11 +609,12 @@ main(int argc, char **argv) bsdtar->uname = bsdtar->argument; break; case OPTION_UUENCODE: - if (bsdtar->add_filter != '\0') + if (compression2 != '\0') lafe_errc(1, 0, "Can't specify both --uuencode and " "--b64encode"); - bsdtar->add_filter = opt; + compression2 = opt; + compression2_name = "uuencode"; break; case 'v': /* SUSv2 */ bsdtar->verbose++; @@ -621,28 +644,31 @@ main(int argc, char **argv) set_mode(bsdtar, opt); break; case 'y': /* FreeBSD version of GNU tar */ - if (bsdtar->create_compression != '\0') + if (compression != '\0') lafe_errc(1, 0, "Can't specify both -%c and -%c", opt, - bsdtar->create_compression); - bsdtar->create_compression = opt; + compression); + compression = opt; + compression_name = "bzip2"; break; case 'Z': /* GNU tar */ - if (bsdtar->create_compression != '\0') + if (compression != '\0') lafe_errc(1, 0, "Can't specify both -%c and -%c", opt, - bsdtar->create_compression); - bsdtar->create_compression = opt; + compression); + compression = opt; + compression_name = "compress"; break; case 'z': /* GNU tar, star, many others */ - if (bsdtar->create_compression != '\0') + if (compression != '\0') lafe_errc(1, 0, "Can't specify both -%c and -%c", opt, - bsdtar->create_compression); - bsdtar->create_compression = opt; + compression); + compression = opt; + compression_name = "gzip"; break; case OPTION_USE_COMPRESS_PROGRAM: - bsdtar->compress_program = bsdtar->argument; + compress_program = bsdtar->argument; break; default: usage(); @@ -665,6 +691,8 @@ main(int argc, char **argv) "Must specify one of -c, -r, -t, -u, -x"); /* Check boolean options only permitted in certain modes. */ + if (option_a) + only_mode(bsdtar, "-a", "c"); if (bsdtar->readdisk_flags & ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS) only_mode(bsdtar, "--one-file-system", "cru"); if (bsdtar->option_fast_read) @@ -679,7 +707,7 @@ main(int argc, char **argv) * "ustar" format is the closest thing * supported by libarchive. */ - bsdtar->create_format = "ustar"; + cset_set_format(bsdtar->cset, "ustar"); /* TODO: bsdtar->create_format = "v7"; */ break; case 'x': @@ -701,13 +729,40 @@ main(int argc, char **argv) if (bsdtar->option_warn_links) only_mode(bsdtar, "--check-links", "cr"); + if (option_a && cset_auto_compress(bsdtar->cset, bsdtar->filename)) { + /* Ignore specified compressions if auto-compress works. */ + compression = '\0'; + compression2 = '\0'; + } /* Check other parameters only permitted in certain modes. */ - if (bsdtar->create_compression != '\0') { - strcpy(buff, "-?"); - buff[1] = bsdtar->create_compression; + if (compress_program != NULL) { + only_mode(bsdtar, "--use-compress-program", "cxt"); + cset_add_filter_program(bsdtar->cset, compress_program); + /* Ignore specified compressions. */ + compression = '\0'; + compression2 = '\0'; + } + if (compression != '\0') { + switch (compression) { + case 'J': case 'j': case 'y': case 'Z': case 'z': + strcpy(buff, "-?"); + buff[1] = compression; + break; + default: + strcpy(buff, "--"); + strcat(buff, compression_name); + break; + } + only_mode(bsdtar, buff, "cxt"); + cset_add_filter(bsdtar->cset, compression_name); + } + if (compression2 != '\0') { + strcpy(buff, "--"); + strcat(buff, compression2_name); only_mode(bsdtar, buff, "cxt"); + cset_add_filter(bsdtar->cset, compression2_name); } - if (bsdtar->create_format != NULL) + if (cset_get_format(bsdtar->cset) != NULL) only_mode(bsdtar, "--format", "cru"); if (bsdtar->symlink_mode != '\0') { strcpy(buff, "-?"); @@ -741,6 +796,7 @@ main(int argc, char **argv) #if HAVE_REGEX_H cleanup_substitution(bsdtar); #endif + cset_free(bsdtar->cset); if (bsdtar->return_value != 0) lafe_warnc(0, -- cgit v1.2.1