summaryrefslogtreecommitdiff
path: root/tar/bsdtar.c
diff options
context:
space:
mode:
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>2012-10-21 17:05:28 +0900
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>2012-10-22 19:57:20 +0900
commitd06fc9e5e4a47d022188d4b10202873c5d995b6e (patch)
tree759c5fc5ec8e4a5fc1b35e8867ecb160100596d8 /tar/bsdtar.c
parent877654feb4ebc4cfd3da33fb0582d1147a21e6d1 (diff)
downloadlibarchive-d06fc9e5e4a47d022188d4b10202873c5d995b6e.tar.gz
Introduce -a/--auto-compress option into bsdtar.
This automatically decides on a creation format and filters by the archive suffix.
Diffstat (limited to 'tar/bsdtar.c')
-rw-r--r--tar/bsdtar.c126
1 files changed, 91 insertions, 35 deletions
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,