read.c revision 311041
1228753Smm/*- 2228753Smm * Copyright (c) 2003-2007 Tim Kientzle 3228753Smm * All rights reserved. 4228753Smm * 5228753Smm * Redistribution and use in source and binary forms, with or without 6228753Smm * modification, are permitted provided that the following conditions 7228753Smm * are met: 8228753Smm * 1. Redistributions of source code must retain the above copyright 9228753Smm * notice, this list of conditions and the following disclaimer. 10228753Smm * 2. Redistributions in binary form must reproduce the above copyright 11228753Smm * notice, this list of conditions and the following disclaimer in the 12228753Smm * documentation and/or other materials provided with the distribution. 13228753Smm * 14228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17228753Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24228753Smm */ 25228753Smm 26228753Smm#include "bsdtar_platform.h" 27228763Smm__FBSDID("$FreeBSD: stable/11/contrib/libarchive/tar/read.c 311041 2017-01-02 01:41:31Z mm $"); 28228753Smm 29228753Smm#ifdef HAVE_SYS_TYPES_H 30228753Smm#include <sys/types.h> 31228753Smm#endif 32228753Smm#ifdef HAVE_SYS_PARAM_H 33228753Smm#include <sys/param.h> 34228753Smm#endif 35228753Smm#ifdef HAVE_SYS_STAT_H 36228753Smm#include <sys/stat.h> 37228753Smm#endif 38228753Smm 39228753Smm#ifdef HAVE_ERRNO_H 40228753Smm#include <errno.h> 41228753Smm#endif 42299529Smm 43299529Smm#ifdef HAVE_FCNTL_H 44299529Smm#include <fcntl.h> 45299529Smm#endif 46299529Smm 47228753Smm#ifdef HAVE_GRP_H 48228753Smm#include <grp.h> 49228753Smm#endif 50299529Smm 51299529Smm#ifdef HAVE_IO_H 52299529Smm#include <io.h> 53299529Smm#endif 54299529Smm 55228753Smm#ifdef HAVE_LIMITS_H 56228753Smm#include <limits.h> 57228753Smm#endif 58228753Smm#ifdef HAVE_PWD_H 59228753Smm#include <pwd.h> 60228753Smm#endif 61228753Smm#ifdef HAVE_STDINT_H 62228753Smm#include <stdint.h> 63228753Smm#endif 64228753Smm#include <stdio.h> 65228753Smm#ifdef HAVE_STDLIB_H 66228753Smm#include <stdlib.h> 67228753Smm#endif 68228753Smm#ifdef HAVE_STRING_H 69228753Smm#include <string.h> 70228753Smm#endif 71228753Smm#ifdef HAVE_TIME_H 72228753Smm#include <time.h> 73228753Smm#endif 74228753Smm#ifdef HAVE_UNISTD_H 75228753Smm#include <unistd.h> 76228753Smm#endif 77228753Smm 78228753Smm#include "bsdtar.h" 79228753Smm#include "err.h" 80228753Smm 81228753Smmstruct progress_data { 82228753Smm struct bsdtar *bsdtar; 83228753Smm struct archive *archive; 84228753Smm struct archive_entry *entry; 85228753Smm}; 86228753Smm 87232153Smmstatic void read_archive(struct bsdtar *bsdtar, char mode, struct archive *); 88238856Smmstatic int unmatched_inclusions_warn(struct archive *matching, const char *); 89228753Smm 90238856Smm 91228753Smmvoid 92228753Smmtar_mode_t(struct bsdtar *bsdtar) 93228753Smm{ 94232153Smm read_archive(bsdtar, 't', NULL); 95238856Smm if (unmatched_inclusions_warn(bsdtar->matching, 96238856Smm "Not found in archive") != 0) 97228753Smm bsdtar->return_value = 1; 98228753Smm} 99228753Smm 100228753Smmvoid 101228753Smmtar_mode_x(struct bsdtar *bsdtar) 102228753Smm{ 103232153Smm struct archive *writer; 104228753Smm 105232153Smm writer = archive_write_disk_new(); 106232153Smm if (writer == NULL) 107232153Smm lafe_errc(1, ENOMEM, "Cannot allocate disk writer object"); 108232153Smm if (!bsdtar->option_numeric_owner) 109232153Smm archive_write_disk_set_standard_lookup(writer); 110232153Smm archive_write_disk_set_options(writer, bsdtar->extract_flags); 111232153Smm 112232153Smm read_archive(bsdtar, 'x', writer); 113232153Smm 114238856Smm if (unmatched_inclusions_warn(bsdtar->matching, 115238856Smm "Not found in archive") != 0) 116228753Smm bsdtar->return_value = 1; 117232153Smm archive_write_free(writer); 118228753Smm} 119228753Smm 120228753Smmstatic void 121228753Smmprogress_func(void *cookie) 122228753Smm{ 123299529Smm struct progress_data *progress_data = (struct progress_data *)cookie; 124228753Smm struct bsdtar *bsdtar = progress_data->bsdtar; 125228753Smm struct archive *a = progress_data->archive; 126228753Smm struct archive_entry *entry = progress_data->entry; 127228753Smm uint64_t comp, uncomp; 128228776Smm int compression; 129228753Smm 130228753Smm if (!need_report()) 131228753Smm return; 132228753Smm 133228753Smm if (bsdtar->verbose) 134228753Smm fprintf(stderr, "\n"); 135228753Smm if (a != NULL) { 136248616Smm comp = archive_filter_bytes(a, -1); 137248616Smm uncomp = archive_filter_bytes(a, 0); 138228776Smm if (comp > uncomp) 139228776Smm compression = 0; 140228776Smm else 141228776Smm compression = (int)((uncomp - comp) * 100 / uncomp); 142228753Smm fprintf(stderr, 143228753Smm "In: %s bytes, compression %d%%;", 144228776Smm tar_i64toa(comp), compression); 145228753Smm fprintf(stderr, " Out: %d files, %s bytes\n", 146228753Smm archive_file_count(a), tar_i64toa(uncomp)); 147228753Smm } 148228753Smm if (entry != NULL) { 149228753Smm safe_fprintf(stderr, "Current: %s", 150228753Smm archive_entry_pathname(entry)); 151228753Smm fprintf(stderr, " (%s bytes)\n", 152228753Smm tar_i64toa(archive_entry_size(entry))); 153228753Smm } 154228753Smm} 155228753Smm 156228753Smm/* 157228753Smm * Handle 'x' and 't' modes. 158228753Smm */ 159228753Smmstatic void 160232153Smmread_archive(struct bsdtar *bsdtar, char mode, struct archive *writer) 161228753Smm{ 162228753Smm struct progress_data progress_data; 163228753Smm FILE *out; 164228753Smm struct archive *a; 165228753Smm struct archive_entry *entry; 166248616Smm const char *reader_options; 167228753Smm int r; 168228753Smm 169228753Smm while (*bsdtar->argv) { 170238856Smm if (archive_match_include_pattern(bsdtar->matching, 171238856Smm *bsdtar->argv) != ARCHIVE_OK) 172238856Smm lafe_errc(1, 0, "Error inclusion pattern: %s", 173238856Smm archive_error_string(bsdtar->matching)); 174228753Smm bsdtar->argv++; 175228753Smm } 176228753Smm 177228753Smm if (bsdtar->names_from_file != NULL) 178238856Smm if (archive_match_include_pattern_from_file( 179238856Smm bsdtar->matching, bsdtar->names_from_file, 180238856Smm bsdtar->option_null) != ARCHIVE_OK) 181238856Smm lafe_errc(1, 0, "Error inclusion pattern: %s", 182238856Smm archive_error_string(bsdtar->matching)); 183228753Smm 184228753Smm a = archive_read_new(); 185248616Smm if (cset_read_support_filter_program(bsdtar->cset, a) == 0) 186232153Smm archive_read_support_filter_all(a); 187228753Smm archive_read_support_format_all(a); 188248616Smm 189248616Smm reader_options = getenv(ENV_READER_OPTIONS); 190248616Smm if (reader_options != NULL) { 191311041Smm size_t module_len = sizeof(IGNORE_WRONG_MODULE_NAME) - 1; 192311041Smm size_t opt_len = strlen(reader_options) + 1; 193248616Smm char *p; 194248616Smm /* Set default read options. */ 195311041Smm if ((p = malloc(module_len + opt_len)) == NULL) 196248616Smm lafe_errc(1, errno, "Out of memory"); 197248616Smm /* Prepend magic code to ignore options for 198248616Smm * a format or modules which are not added to 199248616Smm * the archive read object. */ 200311041Smm memcpy(p, IGNORE_WRONG_MODULE_NAME, module_len); 201311041Smm memcpy(p + module_len, reader_options, opt_len); 202248616Smm r = archive_read_set_options(a, p); 203248616Smm free(p); 204248616Smm if (r == ARCHIVE_FATAL) 205248616Smm lafe_errc(1, 0, "%s", archive_error_string(a)); 206248616Smm else 207248616Smm archive_clear_error(a); 208248616Smm } 209228753Smm if (ARCHIVE_OK != archive_read_set_options(a, bsdtar->option_options)) 210228753Smm lafe_errc(1, 0, "%s", archive_error_string(a)); 211299529Smm if (bsdtar->option_ignore_zeros) 212299529Smm if (archive_read_set_options(a, 213299529Smm "read_concatenated_archives") != ARCHIVE_OK) 214299529Smm lafe_errc(1, 0, "%s", archive_error_string(a)); 215299529Smm if (bsdtar->passphrase != NULL) 216299529Smm r = archive_read_add_passphrase(a, bsdtar->passphrase); 217299529Smm else 218299529Smm r = archive_read_set_passphrase_callback(a, bsdtar, 219299529Smm &passphrase_callback); 220299529Smm if (r != ARCHIVE_OK) 221299529Smm lafe_errc(1, 0, "%s", archive_error_string(a)); 222248616Smm if (archive_read_open_filename(a, bsdtar->filename, 223248616Smm bsdtar->bytes_per_block)) 224228753Smm lafe_errc(1, 0, "Error opening archive: %s", 225228753Smm archive_error_string(a)); 226228753Smm 227228753Smm do_chdir(bsdtar); 228228753Smm 229228753Smm if (mode == 'x') { 230228753Smm /* Set an extract callback so that we can handle SIGINFO. */ 231228753Smm progress_data.bsdtar = bsdtar; 232228753Smm progress_data.archive = a; 233228753Smm archive_read_extract_set_progress_callback(a, progress_func, 234228753Smm &progress_data); 235228753Smm } 236228753Smm 237228753Smm if (mode == 'x' && bsdtar->option_chroot) { 238228753Smm#if HAVE_CHROOT 239228753Smm if (chroot(".") != 0) 240228753Smm lafe_errc(1, errno, "Can't chroot to \".\""); 241228753Smm#else 242228753Smm lafe_errc(1, 0, 243228753Smm "chroot isn't supported on this platform"); 244228753Smm#endif 245228753Smm } 246228753Smm 247299529Smm#if defined(_WIN32) && !defined(__CYGWIN__) 248299529Smm if (mode == 'x' && bsdtar->option_stdout) { 249299529Smm _setmode(1, _O_BINARY); 250299529Smm } 251299529Smm#endif 252299529Smm 253228753Smm for (;;) { 254228753Smm /* Support --fast-read option */ 255299529Smm const char *p; 256228753Smm if (bsdtar->option_fast_read && 257238856Smm archive_match_path_unmatched_inclusions(bsdtar->matching) == 0) 258228753Smm break; 259228753Smm 260228753Smm r = archive_read_next_header(a, &entry); 261228753Smm progress_data.entry = entry; 262228753Smm if (r == ARCHIVE_EOF) 263228753Smm break; 264228753Smm if (r < ARCHIVE_OK) 265228753Smm lafe_warnc(0, "%s", archive_error_string(a)); 266228753Smm if (r <= ARCHIVE_WARN) 267228753Smm bsdtar->return_value = 1; 268228753Smm if (r == ARCHIVE_RETRY) { 269228753Smm /* Retryable error: try again */ 270228753Smm lafe_warnc(0, "Retrying..."); 271228753Smm continue; 272228753Smm } 273228753Smm if (r == ARCHIVE_FATAL) 274228753Smm break; 275299529Smm p = archive_entry_pathname(entry); 276299529Smm if (p == NULL || p[0] == '\0') { 277299529Smm lafe_warnc(0, "Archive entry has empty or unreadable filename ... skipping."); 278299529Smm bsdtar->return_value = 1; 279299529Smm continue; 280299529Smm } 281228753Smm 282228753Smm if (bsdtar->uid >= 0) { 283228753Smm archive_entry_set_uid(entry, bsdtar->uid); 284228753Smm archive_entry_set_uname(entry, NULL); 285228753Smm } 286228753Smm if (bsdtar->gid >= 0) { 287228753Smm archive_entry_set_gid(entry, bsdtar->gid); 288228753Smm archive_entry_set_gname(entry, NULL); 289228753Smm } 290228753Smm if (bsdtar->uname) 291228753Smm archive_entry_set_uname(entry, bsdtar->uname); 292228776Smm if (bsdtar->gname) 293228753Smm archive_entry_set_gname(entry, bsdtar->gname); 294228753Smm 295228753Smm /* 296228753Smm * Note that pattern exclusions are checked before 297228753Smm * pathname rewrites are handled. This gives more 298228753Smm * control over exclusions, since rewrites always lose 299228753Smm * information. (For example, consider a rewrite 300228753Smm * s/foo[0-9]/foo/. If we check exclusions after the 301228753Smm * rewrite, there would be no way to exclude foo1/bar 302228753Smm * while allowing foo2/bar.) 303228753Smm */ 304238856Smm if (archive_match_excluded(bsdtar->matching, entry)) 305228753Smm continue; /* Excluded by a pattern test. */ 306228753Smm 307228753Smm if (mode == 't') { 308228753Smm /* Perversely, gtar uses -O to mean "send to stderr" 309228753Smm * when used with -t. */ 310228753Smm out = bsdtar->option_stdout ? stderr : stdout; 311228753Smm 312228753Smm /* 313228753Smm * TODO: Provide some reasonable way to 314228753Smm * preview rewrites. gtar always displays 315228753Smm * the unedited path in -t output, which means 316228753Smm * you cannot easily preview rewrites. 317228753Smm */ 318228753Smm if (bsdtar->verbose < 2) 319228753Smm safe_fprintf(out, "%s", 320228753Smm archive_entry_pathname(entry)); 321228753Smm else 322228753Smm list_item_verbose(bsdtar, out, entry); 323228753Smm fflush(out); 324228753Smm r = archive_read_data_skip(a); 325228753Smm if (r == ARCHIVE_WARN) { 326228753Smm fprintf(out, "\n"); 327228753Smm lafe_warnc(0, "%s", 328228753Smm archive_error_string(a)); 329228753Smm } 330228753Smm if (r == ARCHIVE_RETRY) { 331228753Smm fprintf(out, "\n"); 332228753Smm lafe_warnc(0, "%s", 333228753Smm archive_error_string(a)); 334228753Smm } 335228753Smm if (r == ARCHIVE_FATAL) { 336228753Smm fprintf(out, "\n"); 337228753Smm lafe_warnc(0, "%s", 338228753Smm archive_error_string(a)); 339228753Smm bsdtar->return_value = 1; 340228753Smm break; 341228753Smm } 342228753Smm fprintf(out, "\n"); 343228753Smm } else { 344228753Smm /* Note: some rewrite failures prevent extraction. */ 345228753Smm if (edit_pathname(bsdtar, entry)) 346228753Smm continue; /* Excluded by a rewrite failure. */ 347228753Smm 348228753Smm if (bsdtar->option_interactive && 349228753Smm !yes("extract '%s'", archive_entry_pathname(entry))) 350228753Smm continue; 351228753Smm 352299529Smm if (bsdtar->verbose > 1) { 353299529Smm /* GNU tar uses -tv format with -xvv */ 354299529Smm safe_fprintf(stderr, "x "); 355299529Smm list_item_verbose(bsdtar, stderr, entry); 356299529Smm fflush(stderr); 357299529Smm } else if (bsdtar->verbose > 0) { 358299529Smm /* Format follows SUSv2, including the 359299529Smm * deferred '\n'. */ 360228753Smm safe_fprintf(stderr, "x %s", 361228753Smm archive_entry_pathname(entry)); 362228753Smm fflush(stderr); 363228753Smm } 364228753Smm 365232153Smm /* TODO siginfo_printinfo(bsdtar, 0); */ 366228753Smm 367228753Smm if (bsdtar->option_stdout) 368228753Smm r = archive_read_data_into_fd(a, 1); 369228753Smm else 370232153Smm r = archive_read_extract2(a, entry, writer); 371228753Smm if (r != ARCHIVE_OK) { 372228753Smm if (!bsdtar->verbose) 373228753Smm safe_fprintf(stderr, "%s", 374228753Smm archive_entry_pathname(entry)); 375228753Smm safe_fprintf(stderr, ": %s", 376228753Smm archive_error_string(a)); 377228753Smm if (!bsdtar->verbose) 378228753Smm fprintf(stderr, "\n"); 379228753Smm bsdtar->return_value = 1; 380228753Smm } 381228753Smm if (bsdtar->verbose) 382228753Smm fprintf(stderr, "\n"); 383228753Smm if (r == ARCHIVE_FATAL) 384228753Smm break; 385228753Smm } 386228753Smm } 387228753Smm 388228753Smm 389228753Smm r = archive_read_close(a); 390228753Smm if (r != ARCHIVE_OK) 391228753Smm lafe_warnc(0, "%s", archive_error_string(a)); 392228753Smm if (r <= ARCHIVE_WARN) 393228753Smm bsdtar->return_value = 1; 394228753Smm 395228753Smm if (bsdtar->verbose > 2) 396228753Smm fprintf(stdout, "Archive Format: %s, Compression: %s\n", 397248616Smm archive_format_name(a), archive_filter_name(a, 0)); 398228753Smm 399232153Smm archive_read_free(a); 400228753Smm} 401228753Smm 402228753Smm 403238856Smmstatic int 404238856Smmunmatched_inclusions_warn(struct archive *matching, const char *msg) 405238856Smm{ 406238856Smm const char *p; 407238856Smm int r; 408238856Smm 409238856Smm if (matching == NULL) 410238856Smm return (0); 411238856Smm 412238856Smm while ((r = archive_match_path_unmatched_inclusions_next( 413238856Smm matching, &p)) == ARCHIVE_OK) 414238856Smm lafe_warnc(0, "%s: %s", p, msg); 415238856Smm if (r == ARCHIVE_FATAL) 416238856Smm lafe_errc(1, errno, "Out of memory"); 417238856Smm 418238856Smm return (archive_match_path_unmatched_inclusions(matching)); 419238856Smm} 420