aboutsummaryrefslogtreecommitdiff
path: root/tar/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'tar/read.c')
-rw-r--r--tar/read.c79
1 files changed, 51 insertions, 28 deletions
diff --git a/tar/read.c b/tar/read.c
index 0470599885c2..2ca7a534cb14 100644
--- a/tar/read.c
+++ b/tar/read.c
@@ -76,12 +76,12 @@ struct progress_data {
static void list_item_verbose(struct bsdtar *, FILE *,
struct archive_entry *);
-static void read_archive(struct bsdtar *bsdtar, char mode);
+static void read_archive(struct bsdtar *bsdtar, char mode, struct archive *);
void
tar_mode_t(struct bsdtar *bsdtar)
{
- read_archive(bsdtar, 't');
+ read_archive(bsdtar, 't', NULL);
if (lafe_unmatched_inclusions_warn(bsdtar->matching, "Not found in archive") != 0)
bsdtar->return_value = 1;
}
@@ -89,10 +89,20 @@ tar_mode_t(struct bsdtar *bsdtar)
void
tar_mode_x(struct bsdtar *bsdtar)
{
- read_archive(bsdtar, 'x');
+ struct archive *writer;
+
+ writer = archive_write_disk_new();
+ if (writer == NULL)
+ lafe_errc(1, ENOMEM, "Cannot allocate disk writer object");
+ if (!bsdtar->option_numeric_owner)
+ archive_write_disk_set_standard_lookup(writer);
+ archive_write_disk_set_options(writer, bsdtar->extract_flags);
+
+ read_archive(bsdtar, 'x', writer);
if (lafe_unmatched_inclusions_warn(bsdtar->matching, "Not found in archive") != 0)
bsdtar->return_value = 1;
+ archive_write_free(writer);
}
static void
@@ -135,14 +145,15 @@ progress_func(void *cookie)
* Handle 'x' and 't' modes.
*/
static void
-read_archive(struct bsdtar *bsdtar, char mode)
+read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
{
struct progress_data progress_data;
FILE *out;
struct archive *a;
struct archive_entry *entry;
- const struct stat *st;
int r;
+ time_t sec;
+ long nsec;
while (*bsdtar->argv) {
lafe_include(&bsdtar->matching, *bsdtar->argv);
@@ -155,15 +166,13 @@ read_archive(struct bsdtar *bsdtar, char mode)
a = archive_read_new();
if (bsdtar->compress_program != NULL)
- archive_read_support_compression_program(a, bsdtar->compress_program);
+ archive_read_support_filter_program(a, bsdtar->compress_program);
else
- archive_read_support_compression_all(a);
+ archive_read_support_filter_all(a);
archive_read_support_format_all(a);
if (ARCHIVE_OK != archive_read_set_options(a, bsdtar->option_options))
lafe_errc(1, 0, "%s", archive_error_string(a));
- if (archive_read_open_file(a, bsdtar->filename,
- bsdtar->bytes_per_block != 0 ? bsdtar->bytes_per_block :
- DEFAULT_BYTES_PER_BLOCK))
+ if (archive_read_open_file(a, bsdtar->filename, bsdtar->bytes_per_block))
lafe_errc(1, 0, "Error opening archive: %s",
archive_error_string(a));
@@ -225,21 +234,36 @@ read_archive(struct bsdtar *bsdtar, char mode)
/*
* Exclude entries that are too old.
*/
- st = archive_entry_stat(entry);
- if (bsdtar->newer_ctime_sec > 0) {
- if (st->st_ctime < bsdtar->newer_ctime_sec)
+ if (bsdtar->newer_ctime_filter) {
+ /* Use ctime if format provides, else mtime. */
+ if (archive_entry_ctime_is_set(entry)) {
+ sec = archive_entry_ctime(entry);
+ nsec = archive_entry_ctime_nsec(entry);
+ } else if (archive_entry_mtime_is_set(entry)) {
+ sec = archive_entry_mtime(entry);
+ nsec = archive_entry_mtime_nsec(entry);
+ } else {
+ sec = 0;
+ nsec = 0;
+ }
+ if (sec < bsdtar->newer_ctime_sec)
continue; /* Too old, skip it. */
- if (st->st_ctime == bsdtar->newer_ctime_sec
- && ARCHIVE_STAT_CTIME_NANOS(st)
- <= bsdtar->newer_ctime_nsec)
+ if (sec == bsdtar->newer_ctime_sec
+ && nsec <= bsdtar->newer_ctime_nsec)
continue; /* Too old, skip it. */
}
- if (bsdtar->newer_mtime_sec > 0) {
- if (st->st_mtime < bsdtar->newer_mtime_sec)
+ if (bsdtar->newer_mtime_filter) {
+ if (archive_entry_mtime_is_set(entry)) {
+ sec = archive_entry_mtime(entry);
+ nsec = archive_entry_mtime_nsec(entry);
+ } else {
+ sec = 0;
+ nsec = 0;
+ }
+ if (sec < bsdtar->newer_mtime_sec)
continue; /* Too old, skip it. */
- if (st->st_mtime == bsdtar->newer_mtime_sec
- && ARCHIVE_STAT_MTIME_NANOS(st)
- <= bsdtar->newer_mtime_nsec)
+ if (sec == bsdtar->newer_mtime_sec
+ && nsec <= bsdtar->newer_mtime_nsec)
continue; /* Too old, skip it. */
}
@@ -310,13 +334,12 @@ read_archive(struct bsdtar *bsdtar, char mode)
fflush(stderr);
}
- // TODO siginfo_printinfo(bsdtar, 0);
+ /* TODO siginfo_printinfo(bsdtar, 0); */
if (bsdtar->option_stdout)
r = archive_read_data_into_fd(a, 1);
else
- r = archive_read_extract(a, entry,
- bsdtar->extract_flags);
+ r = archive_read_extract2(a, entry, writer);
if (r != ARCHIVE_OK) {
if (!bsdtar->verbose)
safe_fprintf(stderr, "%s",
@@ -345,7 +368,7 @@ read_archive(struct bsdtar *bsdtar, char mode)
fprintf(stdout, "Archive Format: %s, Compression: %s\n",
archive_format_name(a), archive_compression_name(a));
- archive_read_finish(a);
+ archive_read_free(a);
}
@@ -427,11 +450,11 @@ list_item_verbose(struct bsdtar *bsdtar, FILE *out, struct archive_entry *entry)
/* Format the time using 'ls -l' conventions. */
tim = archive_entry_mtime(entry);
-#define HALF_YEAR (time_t)365 * 86400 / 2
+#define HALF_YEAR (time_t)365 * 86400 / 2
#if defined(_WIN32) && !defined(__CYGWIN__)
-#define DAY_FMT "%d" /* Windows' strftime function does not support %e format. */
+#define DAY_FMT "%d" /* Windows' strftime function does not support %e format. */
#else
-#define DAY_FMT "%e" /* Day number without leading zeros */
+#define DAY_FMT "%e" /* Day number without leading zeros */
#endif
if (tim < now - HALF_YEAR || tim > now + HALF_YEAR)
fmt = bsdtar->day_first ? DAY_FMT " %b %Y" : "%b " DAY_FMT " %Y";