diff options
author | mm <mm@FreeBSD.org> | 2013-03-22 13:36:03 +0000 |
---|---|---|
committer | mm <mm@FreeBSD.org> | 2013-03-22 13:36:03 +0000 |
commit | 5ee0a7b76c4addc27bb45864cb4e0ce790a4b80e (patch) | |
tree | e741e3532b574e7c25aa9bb07c18cdb16139824f /contrib/libarchive/tar/bsdtar.c | |
parent | af89cb16bfde2fc8e93708b89daff55026d3b216 (diff) | |
parent | 366f42737cba40ceb2e83af8d17c61c0242703c5 (diff) | |
download | FreeBSD-src-5ee0a7b76c4addc27bb45864cb4e0ce790a4b80e.zip FreeBSD-src-5ee0a7b76c4addc27bb45864cb4e0ce790a4b80e.tar.gz |
MFV r248590,248594:
Update libarchive to 3.1.2
Some of new features:
- support for lrzip and grzip compression
- support for writing tar v7 format
- b64encode and uuencode filters
- support for __MACOSX directory in Zip archives
- support for lzop compresion (external utility)
Diffstat (limited to 'contrib/libarchive/tar/bsdtar.c')
-rw-r--r-- | contrib/libarchive/tar/bsdtar.c | 187 |
1 files changed, 156 insertions, 31 deletions
diff --git a/contrib/libarchive/tar/bsdtar.c b/contrib/libarchive/tar/bsdtar.c index 50f9c99..194d798 100644 --- a/contrib/libarchive/tar/bsdtar.c +++ b/contrib/libarchive/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; @@ -267,6 +279,14 @@ main(int argc, char **argv) /* Explicit -b forces last block size. */ bsdtar->bytes_in_last_block = bsdtar->bytes_per_block; break; + case OPTION_B64ENCODE: + if (compression2 != '\0') + lafe_errc(1, 0, + "Can't specify both --uuencode and " + "--b64encode"); + compression2 = opt; + compression2_name = "b64encode"; + break; case 'C': /* GNU tar */ if (strlen(bsdtar->argument) == 0) lafe_errc(1, 0, @@ -293,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; @@ -308,6 +328,14 @@ main(int argc, char **argv) case OPTION_GNAME: /* cpio */ bsdtar->gname = bsdtar->argument; break; + case OPTION_GRZIP: + if (compression != '\0') + lafe_errc(1, 0, + "Can't specify both -%c and -%c", opt, + compression); + compression = opt; + compression_name = "grzip"; + break; case 'H': /* BSD convention */ bsdtar->symlink_mode = 'H'; break; @@ -320,6 +348,10 @@ main(int argc, char **argv) long_help(); exit(0); break; + case OPTION_HFS_COMPRESSION: /* Mac OS X v10.6 or later */ + bsdtar->extract_flags |= + ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED; + break; case 'I': /* GNU tar */ /* * TODO: Allow 'names' to come from an archive, @@ -346,18 +378,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; @@ -372,13 +406,21 @@ main(int argc, char **argv) /* GNU tar 1.13 used -l for --one-file-system */ bsdtar->option_warn_links = 1; break; + case OPTION_LRZIP: case OPTION_LZIP: /* GNU tar beginning with 1.23 */ case OPTION_LZMA: /* GNU tar beginning with 1.20 */ - if (bsdtar->create_compression != '\0') + case OPTION_LZOP: /* GNU tar beginning with 1.21 */ + 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; @@ -391,7 +433,6 @@ main(int argc, char **argv) * --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 */ if (archive_match_include_date(bsdtar->matching, @@ -424,6 +465,11 @@ main(int argc, char **argv) case OPTION_NODUMP: /* star */ bsdtar->readdisk_flags |= ARCHIVE_READDISK_HONOR_NODUMP; break; + case OPTION_NOPRESERVE_HFS_COMPRESSION: + /* Mac OS X v10.6 or later */ + bsdtar->extract_flags |= + ARCHIVE_EXTRACT_NO_HFS_COMPRESSION; + break; case OPTION_NO_SAME_OWNER: /* GNU tar */ bsdtar->extract_flags &= ~ARCHIVE_EXTRACT_OWNER; break; @@ -448,6 +494,40 @@ main(int argc, char **argv) case 'o': /* SUSv2 and GNU conflict here, but not fatally */ option_o = 1; /* Record it and resolve it later. */ break; + /* + * Selecting files by time: + * --older-?time='date' Only files older than 'date' + * --older-?time-than='file' Only files older than time + * on specified file + */ + case OPTION_OLDER_CTIME: + if (archive_match_include_date(bsdtar->matching, + ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, + bsdtar->argument) != ARCHIVE_OK) + lafe_errc(1, 0, "Error : %s", + archive_error_string(bsdtar->matching)); + break; + case OPTION_OLDER_CTIME_THAN: + if (archive_match_include_file_time(bsdtar->matching, + ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, + bsdtar->argument) != ARCHIVE_OK) + lafe_errc(1, 0, "Error : %s", + archive_error_string(bsdtar->matching)); + break; + case OPTION_OLDER_MTIME: + if (archive_match_include_date(bsdtar->matching, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, + bsdtar->argument) != ARCHIVE_OK) + lafe_errc(1, 0, "Error : %s", + archive_error_string(bsdtar->matching)); + break; + case OPTION_OLDER_MTIME_THAN: + if (archive_match_include_file_time(bsdtar->matching, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, + bsdtar->argument) != ARCHIVE_OK) + lafe_errc(1, 0, "Error : %s", + archive_error_string(bsdtar->matching)); + break; case OPTION_ONE_FILE_SYSTEM: /* GNU tar */ bsdtar->readdisk_flags |= ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS; @@ -478,7 +558,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; @@ -490,7 +570,7 @@ main(int argc, char **argv) bsdtar->extract_flags |= ARCHIVE_EXTRACT_SPARSE; break; case 's': /* NetBSD pax-as-tar */ -#if HAVE_REGEX_H +#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H) add_substitution(bsdtar, bsdtar->argument); #else lafe_warnc(0, @@ -537,6 +617,14 @@ main(int argc, char **argv) case OPTION_UNAME: /* cpio */ bsdtar->uname = bsdtar->argument; break; + case OPTION_UUENCODE: + if (compression2 != '\0') + lafe_errc(1, 0, + "Can't specify both --uuencode and " + "--b64encode"); + compression2 = opt; + compression2_name = "uuencode"; + break; case 'v': /* SUSv2 */ bsdtar->verbose++; break; @@ -565,28 +653,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(); @@ -609,10 +700,16 @@ 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) only_mode(bsdtar, "--fast-read", "xt"); + if (bsdtar->extract_flags & ARCHIVE_EXTRACT_HFS_COMPRESSION_FORCED) + only_mode(bsdtar, "--hfsCompression", "x"); + if (bsdtar->extract_flags & ARCHIVE_EXTRACT_NO_HFS_COMPRESSION) + only_mode(bsdtar, "--nopreserveHFSCompression", "x"); if (bsdtar->readdisk_flags & ARCHIVE_READDISK_HONOR_NODUMP) only_mode(bsdtar, "--nodump", "cru"); if (option_o > 0) { @@ -623,7 +720,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': @@ -645,13 +742,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, "-?"); @@ -682,9 +806,10 @@ main(int argc, char **argv) } archive_match_free(bsdtar->matching); -#if HAVE_REGEX_H +#if defined(HAVE_REGEX_H) || defined(HAVE_PCREPOSIX_H) cleanup_substitution(bsdtar); #endif + cset_free(bsdtar->cset); if (bsdtar->return_value != 0) lafe_warnc(0, |