From 6fc0ea8474e616cacbc73576b315de3390b6b0f0 Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Mon, 16 Apr 2007 04:04:50 +0000 Subject: [PATCH] In libarchive: Downgrade ARCHIVE_FATAL and ARCHIVE_FAILED errors which occur on the write side of extracting a file to ARCHIVE_WARN errors when returning them from archive_read_extract. In bsdtar: Use the return code from archive_read_data_into_fd and archive_read_extract to determine whether we should continue trying to extract an archive after one of the entries fails. This commit makes extracting a truncated tarball complain once about the archive being truncated, instead of complaining twice (once when trying to extract an entry, and once when trying to seek to the next entry). Discussed with: kientzle --- lib/libarchive/archive_read_extract.c | 6 ++++++ usr.bin/tar/read.c | 17 ++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/libarchive/archive_read_extract.c b/lib/libarchive/archive_read_extract.c index 8828ec6a801..464ebe9bef3 100644 --- a/lib/libarchive/archive_read_extract.c +++ b/lib/libarchive/archive_read_extract.c @@ -95,6 +95,8 @@ archive_read_extract(struct archive *_a, struct archive_entry *entry, int flags) archive_write_disk_set_skip_file(a->extract->ad, a->skip_file_dev, a->skip_file_ino); r = archive_write_header(a->extract->ad, entry); + if (r < ARCHIVE_WARN) + r = ARCHIVE_WARN; if (r != ARCHIVE_OK) /* If _write_header failed, copy the error. */ archive_set_error(&a->archive, @@ -104,6 +106,8 @@ archive_read_extract(struct archive *_a, struct archive_entry *entry, int flags) /* Otherwise, pour data into the entry. */ r = copy_data(_a, a->extract->ad); r2 = archive_write_finish_entry(a->extract->ad); + if (r2 < ARCHIVE_WARN) + r2 = ARCHIVE_WARN; /* Use the first message. */ if (r2 != ARCHIVE_OK && r == ARCHIVE_OK) archive_set_error(&a->archive, @@ -142,6 +146,8 @@ copy_data(struct archive *ar, struct archive *aw) if (r != ARCHIVE_OK) return (r); r = archive_write_data_block(aw, buff, size, offset); + if (r < ARCHIVE_WARN) + r = ARCHIVE_WARN; if (r != ARCHIVE_OK) { archive_set_error(ar, archive_errno(aw), "%s", archive_error_string(aw)); diff --git a/usr.bin/tar/read.c b/usr.bin/tar/read.c index 65074871e6c..2e44c9ee519 100644 --- a/usr.bin/tar/read.c +++ b/usr.bin/tar/read.c @@ -223,11 +223,12 @@ read_archive(struct bsdtar *bsdtar, char mode) archive_entry_pathname(entry)); fflush(stderr); } - if (bsdtar->option_stdout) { - /* TODO: Catch/recover any errors here. */ - archive_read_data_into_fd(a, 1); - } else if (archive_read_extract(a, entry, - bsdtar->extract_flags)) { + if (bsdtar->option_stdout) + r = archive_read_data_into_fd(a, 1); + else + r = archive_read_extract(a, entry, + bsdtar->extract_flags); + if (r != ARCHIVE_OK) { if (!bsdtar->verbose) safe_fprintf(stderr, "%s", archive_entry_pathname(entry)); @@ -235,14 +236,12 @@ read_archive(struct bsdtar *bsdtar, char mode) archive_error_string(a)); if (!bsdtar->verbose) fprintf(stderr, "\n"); - /* - * TODO: Decide how to handle - * extraction error... - */ bsdtar->return_value = 1; } if (bsdtar->verbose) fprintf(stderr, "\n"); + if (r == ARCHIVE_FATAL) + break; } }