From: Sergey Poznyakoff Date: Thu, 31 Oct 2024 17:09:28 +0000 (+0200) Subject: Don't assume archive read from stdin starts at offset 0 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=647cafff9657be46d76026d0ddd977abbad6711f;p=thirdparty%2Ftar.git Don't assume archive read from stdin starts at offset 0 * src/buffer.c (start_offset): New variable. (get_archive_status): If reading from seekable stdin, store the position in the stream corresponding to record_start in start_offset. (seek_archive): Compute current offset relative to start_offset. --- diff --git a/src/buffer.c b/src/buffer.c index 570c8666..6550e798 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -65,6 +65,7 @@ union block *current_block; /* current block of archive */ enum access_mode access_mode; /* how do we handle the archive */ off_t records_read; /* number of records read from this archive */ off_t records_written; /* likewise, for records written */ +off_t start_offset; /* start offset in the archive */ /* When file status was last computed. */ static struct timespec last_stat_time; @@ -710,7 +711,20 @@ get_archive_status (enum access_mode wanted_access, bool backed_up_flag) || S_ISBLK (archive_stat.st_mode)) : seek_option)); - if (wanted_access != ACCESS_READ) + if (wanted_access == ACCESS_READ) + { + if (archive == STDIN_FILENO && seekable_archive) + { + start_offset = lseek (archive, 0, SEEK_CUR); + if (start_offset == -1) + seekable_archive = false; + else + start_offset -= (record_end - record_start) * BLOCKSIZE; + } + else + start_offset = 0; + } + else sys_detect_dev_null_output (); SET_BINARY_MODE (archive); @@ -1096,6 +1110,8 @@ seek_archive (off_t size) if (offset < 0) return offset; + offset -= start_offset; + if (offset % record_size) paxfatal (0, _("rmtlseek not stopped at a record boundary"));