Reader *Reader::read_open_filename(const char *filename, const char *cmd, bool raw) { struct archive *ar = archive_read_new(); try { if(cmd) { if(archive_read_support_filter_program(ar, cmd) != ARCHIVE_OK) throw 0; } else { if(archive_read_support_filter_all(ar) != ARCHIVE_OK) throw 0; } if(raw) { if(archive_read_support_format_raw(ar) != ARCHIVE_OK) throw 0; } else { if(archive_read_support_format_all(ar) != ARCHIVE_OK) throw 0; } if(archive_read_open_filename(ar, filename, 1024) != ARCHIVE_OK) throw 0; } catch(...) { std::string error_msg = archive_error_string(ar); archive_read_free(ar); throw Error(error_msg); } return new Reader(ar); }
int cset_read_support_filter_program(struct creation_set *cset, struct archive *a) { int cnt = 0, i; for (i = 0; i < cset->filter_count; i++) { if (cset->filters[i].program) { archive_read_support_filter_program(a, cset->filters[i].filter_name); ++cnt; } } return (cnt); }
Reader *Reader::read_open_memory(const char *string, size_t length, const char *cmd, bool raw) { struct archive *ar = archive_read_new(); if (!ar) { throw Error("Unable to allocate libarchive handle!"); } char *content = (char*) malloc(length); if (!content) { archive_read_free(ar); throw Error("Unable to allocate memory when duplicating buffer"); } memcpy((void*) content, (void*) string, length); try { if(cmd) { if(archive_read_support_filter_program(ar, cmd) != ARCHIVE_OK) throw 0; } else { if(archive_read_support_filter_all(ar) != ARCHIVE_OK) throw 0; } if(raw) { if(archive_read_support_format_raw(ar) != ARCHIVE_OK) throw 0; } else { if(archive_read_support_format_all(ar) != ARCHIVE_OK) throw 0; } if(archive_read_open_memory(ar, (void*) content, length) != ARCHIVE_OK) throw 0; } catch(...) { std::string error_msg = archive_error_string(ar); archive_read_free(ar); free(content); throw Error(error_msg); } Reader *reader_obj = new Reader(ar); reader_obj->_archive_content = content; return reader_obj; }
/* Deprecated; remove in libarchive 4.0 */ int archive_read_support_compression_program(struct archive *a, const char *cmd) { return archive_read_support_filter_program(a, cmd); }
/* * Handle 'x' and 't' modes. */ static void read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer) { struct progress_data progress_data; FILE *out; struct archive *a; struct archive_entry *entry; int r; time_t sec; long nsec; while (*bsdtar->argv) { lafe_include(&bsdtar->matching, *bsdtar->argv); bsdtar->argv++; } if (bsdtar->names_from_file != NULL) lafe_include_from_file(&bsdtar->matching, bsdtar->names_from_file, bsdtar->option_null); a = archive_read_new(); if (bsdtar->compress_program != NULL) archive_read_support_filter_program(a, bsdtar->compress_program); else 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)) lafe_errc(1, 0, "Error opening archive: %s", archive_error_string(a)); do_chdir(bsdtar); if (mode == 'x') { /* Set an extract callback so that we can handle SIGINFO. */ progress_data.bsdtar = bsdtar; progress_data.archive = a; archive_read_extract_set_progress_callback(a, progress_func, &progress_data); } if (mode == 'x' && bsdtar->option_chroot) { #if HAVE_CHROOT if (chroot(".") != 0) lafe_errc(1, errno, "Can't chroot to \".\""); #else lafe_errc(1, 0, "chroot isn't supported on this platform"); #endif } for (;;) { /* Support --fast-read option */ if (bsdtar->option_fast_read && lafe_unmatched_inclusions(bsdtar->matching) == 0) break; r = archive_read_next_header(a, &entry); progress_data.entry = entry; if (r == ARCHIVE_EOF) break; if (r < ARCHIVE_OK) lafe_warnc(0, "%s", archive_error_string(a)); if (r <= ARCHIVE_WARN) bsdtar->return_value = 1; if (r == ARCHIVE_RETRY) { /* Retryable error: try again */ lafe_warnc(0, "Retrying..."); continue; } if (r == ARCHIVE_FATAL) break; if (bsdtar->uid >= 0) { archive_entry_set_uid(entry, bsdtar->uid); archive_entry_set_uname(entry, NULL); } if (bsdtar->gid >= 0) { archive_entry_set_gid(entry, bsdtar->gid); archive_entry_set_gname(entry, NULL); } if (bsdtar->uname) archive_entry_set_uname(entry, bsdtar->uname); if (bsdtar->gname) archive_entry_set_gname(entry, bsdtar->gname); /* * Exclude entries that are too old. */ 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 (sec == bsdtar->newer_ctime_sec && nsec <= bsdtar->newer_ctime_nsec) continue; /* Too old, skip it. */ } 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 (sec == bsdtar->newer_mtime_sec && nsec <= bsdtar->newer_mtime_nsec) continue; /* Too old, skip it. */ } /* * Note that pattern exclusions are checked before * pathname rewrites are handled. This gives more * control over exclusions, since rewrites always lose * information. (For example, consider a rewrite * s/foo[0-9]/foo/. If we check exclusions after the * rewrite, there would be no way to exclude foo1/bar * while allowing foo2/bar.) */ if (lafe_excluded(bsdtar->matching, archive_entry_pathname(entry))) continue; /* Excluded by a pattern test. */ if (mode == 't') { /* Perversely, gtar uses -O to mean "send to stderr" * when used with -t. */ out = bsdtar->option_stdout ? stderr : stdout; /* * TODO: Provide some reasonable way to * preview rewrites. gtar always displays * the unedited path in -t output, which means * you cannot easily preview rewrites. */ if (bsdtar->verbose < 2) safe_fprintf(out, "%s", archive_entry_pathname(entry)); else list_item_verbose(bsdtar, out, entry); fflush(out); r = archive_read_data_skip(a); if (r == ARCHIVE_WARN) { fprintf(out, "\n"); lafe_warnc(0, "%s", archive_error_string(a)); } if (r == ARCHIVE_RETRY) { fprintf(out, "\n"); lafe_warnc(0, "%s", archive_error_string(a)); } if (r == ARCHIVE_FATAL) { fprintf(out, "\n"); lafe_warnc(0, "%s", archive_error_string(a)); bsdtar->return_value = 1; break; } fprintf(out, "\n"); } else { /* Note: some rewrite failures prevent extraction. */ if (edit_pathname(bsdtar, entry)) continue; /* Excluded by a rewrite failure. */ if (bsdtar->option_interactive && !yes("extract '%s'", archive_entry_pathname(entry))) continue; /* * Format here is from SUSv2, including the * deferred '\n'. */ if (bsdtar->verbose) { safe_fprintf(stderr, "x %s", archive_entry_pathname(entry)); fflush(stderr); } /* TODO siginfo_printinfo(bsdtar, 0); */ if (bsdtar->option_stdout) r = archive_read_data_into_fd(a, 1); else r = archive_read_extract2(a, entry, writer); if (r != ARCHIVE_OK) { if (!bsdtar->verbose) safe_fprintf(stderr, "%s", archive_entry_pathname(entry)); safe_fprintf(stderr, ": %s", archive_error_string(a)); if (!bsdtar->verbose) fprintf(stderr, "\n"); bsdtar->return_value = 1; } if (bsdtar->verbose) fprintf(stderr, "\n"); if (r == ARCHIVE_FATAL) break; } } r = archive_read_close(a); if (r != ARCHIVE_OK) lafe_warnc(0, "%s", archive_error_string(a)); if (r <= ARCHIVE_WARN) bsdtar->return_value = 1; if (bsdtar->verbose > 2) fprintf(stdout, "Archive Format: %s, Compression: %s\n", archive_format_name(a), archive_compression_name(a)); archive_read_free(a); }