static void extract (int fd) { struct archive *a; struct archive *ext; struct archive_entry *entry; int r; a = archive_read_new (); ext = archive_write_disk_new (); archive_read_support_format_tar (a); archive_read_support_filter_xz (a); archive_read_support_filter_gzip (a); if ((r = archive_read_open_fd (a, fd, 16*1024))) die_with_libarchive (a, "archive_read_open_fd: %s"); while (1) { r = archive_read_next_header (a, &entry); if (r == ARCHIVE_EOF) break; if (r != ARCHIVE_OK) die_with_libarchive (a, "archive_read_next_header: %s"); if (!should_extract (entry)) continue; r = archive_write_header (ext, entry); if (r != ARCHIVE_OK) die_with_libarchive (ext, "archive_write_header: %s"); else { copy_archive (a, ext); r = archive_write_finish_entry (ext); if (r != ARCHIVE_OK) die_with_libarchive (ext, "archive_write_finish_entry: %s"); } } archive_read_close (a); archive_read_free (a); archive_write_close (ext); archive_write_free (ext); }
int do_extract_mtree(char *mtree, const char *prefix) { struct archive *a = NULL; struct archive_entry *ae; char path[MAXPATHLEN]; const char *fpath; int retcode = EPKG_OK; int ret; if (mtree == NULL || *mtree == '\0') return EPKG_OK; a = archive_read_new(); archive_read_support_filter_none(a); archive_read_support_format_mtree(a); if (archive_read_open_memory(a, mtree, strlen(mtree)) != ARCHIVE_OK) { pkg_emit_error("Fail to extract the mtree: %s", archive_error_string(a)); retcode = EPKG_FATAL; goto cleanup; } while ((ret = archive_read_next_header(a, &ae)) != ARCHIVE_EOF) { if (ret != ARCHIVE_OK) { pkg_emit_error("Skipping unsupported mtree line: %s", archive_error_string(a)); continue; } fpath = archive_entry_pathname(ae); if (*fpath != '/') { snprintf(path, sizeof(path), "%s/%s", prefix, fpath); archive_entry_set_pathname(ae, path); } /* Ignored failed extraction on purpose */ archive_read_extract(a, ae, EXTRACT_ARCHIVE_FLAGS); } cleanup: if (a != NULL) archive_read_free(a); return (retcode); }
GBytes *file_type_archive_data_loader(file_t *file, GError **error_pointer) {/*{{{*/ const file_loader_delegate_archive_t *archive_data = g_bytes_get_data(file->file_data, NULL); GBytes *data = buffered_file_as_bytes(archive_data->source_archive, NULL, error_pointer); if(!data) { g_printerr("Failed to load archive %s: %s\n", file->display_name, error_pointer && *error_pointer ? (*error_pointer)->message : "Unknown error"); g_clear_error(error_pointer); return NULL; } struct archive *archive = file_type_archive_gen_archive(data); if(!archive) { buffered_file_unref(file); return NULL; } // Find the proper entry size_t entry_size = 0; void *entry_data = NULL; struct archive_entry *entry; while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) { if(archive_data->entry_name && strcmp(archive_data->entry_name, archive_entry_pathname(entry)) == 0) { entry_size = archive_entry_size(entry); entry_data = g_malloc(entry_size); if(archive_read_data(archive, entry_data, entry_size) != (ssize_t)entry_size) { archive_read_free(archive); buffered_file_unref(file); *error_pointer = g_error_new(g_quark_from_static_string("pqiv-archive-error"), 1, "The file had an unexpected size"); return NULL; } break; } } archive_read_free(archive); buffered_file_unref(archive_data->source_archive); if(!entry_size) { *error_pointer = g_error_new(g_quark_from_static_string("pqiv-archive-error"), 1, "The file has gone within the archive"); return NULL; } return g_bytes_new_take(entry_data, entry_size); }/*}}}*/
static int append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina) { struct archive_entry *in_entry; int e; while (ARCHIVE_OK == (e = archive_read_next_header(ina, &in_entry))) { if (archive_match_excluded(bsdtar->matching, in_entry)) continue; if (bsdtar->option_interactive && !yes("copy '%s'", archive_entry_pathname(in_entry))) continue; if (bsdtar->verbose > 1) { safe_fprintf(stderr, "a "); list_item_verbose(bsdtar, stderr, in_entry); } else if (bsdtar->verbose > 0) safe_fprintf(stderr, "a %s", archive_entry_pathname(in_entry)); if (need_report()) report_write(bsdtar, a, in_entry, 0); e = archive_write_header(a, in_entry); if (e != ARCHIVE_OK) { if (!bsdtar->verbose) lafe_warnc(0, "%s: %s", archive_entry_pathname(in_entry), archive_error_string(a)); else fprintf(stderr, ": %s", archive_error_string(a)); } if (e == ARCHIVE_FATAL) exit(1); if (e >= ARCHIVE_WARN) { if (archive_entry_size(in_entry) == 0) archive_read_data_skip(ina); else if (copy_file_data_block(bsdtar, a, ina, in_entry)) exit(1); } if (bsdtar->verbose) fprintf(stderr, "\n"); } return (e == ARCHIVE_EOF ? ARCHIVE_OK : e); }
static void verifyEmpty(void) { struct archive_entry *ae; struct archive *a; assert((a = archive_read_new()) != NULL); assertA(0 == archive_read_support_filter_all(a)); assertA(0 == archive_read_support_format_all(a)); assertA(0 == archive_read_open_memory(a, archiveEmpty, 512)); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE); assertEqualString(archive_filter_name(a, 0), "none"); failure("512 zero bytes should be recognized as a tar archive."); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR); assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }
std::string next_with_data(char** data_out, size_t* data_size) { if (archive_read_next_header(mArchive, &mEntry) == ARCHIVE_OK) { std::string entryName = archive_entry_pathname(mEntry); size_t size = archive_entry_size(mEntry); if (size > mSize) { mSize = size; mData = (char*)realloc(mData, mSize); } archive_read_data(mArchive, mData, size); *data_out = mData; *data_size = size; return entryName; } return std::string(""); }
static xbps_dictionary_t repo_get_dict(struct xbps_repo *repo) { struct archive_entry *entry; int rv; if (repo->ar == NULL) return NULL; rv = archive_read_next_header(repo->ar, &entry); if (rv != ARCHIVE_OK) { xbps_dbg_printf(repo->xhp, "%s: read_next_header %s\n", repo->uri, archive_error_string(repo->ar)); return NULL; } return xbps_archive_get_dictionary(repo->ar, entry); }
static void mode_list(struct cpio *cpio) { struct archive *a; struct archive_entry *entry; int r; a = archive_read_new(); if (a == NULL) lafe_errc(1, 0, "Couldn't allocate archive object"); archive_read_support_filter_all(a); archive_read_support_format_all(a); if (archive_read_open_filename(a, cpio->filename, cpio->bytes_per_block)) lafe_errc(1, archive_errno(a), "%s", archive_error_string(a)); for (;;) { r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) break; if (r != ARCHIVE_OK) { lafe_errc(1, archive_errno(a), "%s", archive_error_string(a)); } if (archive_match_path_excluded(cpio->matching, entry)) continue; if (cpio->verbose) list_item_verbose(cpio, entry); else fprintf(stdout, "%s\n", archive_entry_pathname(entry)); } r = archive_read_close(a); if (r != ARCHIVE_OK) lafe_errc(1, 0, "%s", archive_error_string(a)); if (!cpio->quiet) { int64_t blocks = (archive_filter_bytes(a, 0) + 511) / 512; fprintf(stderr, "%lu %s\n", (unsigned long)blocks, blocks == 1 ? "block" : "blocks"); } archive_read_free(a); exit(0); }
// Iterate entries. The first call establishes the first entry. Returns false // if no entry found, otherwise returns true and sets mpa->entry/entry_filename. bool mp_archive_next_entry(struct mp_archive *mpa) { mpa->entry = NULL; talloc_free(mpa->entry_filename); mpa->entry_filename = NULL; if (!mpa->arch) return false; locale_t oldlocale = uselocale(mpa->locale); bool success = false; while (!mp_cancel_test(mpa->primary_src->cancel)) { struct archive_entry *entry; int r = archive_read_next_header(mpa->arch, &entry); if (r == ARCHIVE_EOF) break; if (r < ARCHIVE_OK) MP_ERR(mpa, "%s\n", archive_error_string(mpa->arch)); if (r < ARCHIVE_WARN) { MP_FATAL(mpa, "could not read archive entry\n"); mp_archive_check_fatal(mpa, r); break; } if (archive_entry_filetype(entry) != AE_IFREG) continue; // Some archives may have no filenames, or libarchive won't return some. const char *fn = archive_entry_pathname(entry); char buf[64]; if (!fn || bstr_validate_utf8(bstr0(fn)) < 0) { snprintf(buf, sizeof(buf), "mpv_unknown#%d", mpa->entry_num); fn = buf; } mpa->entry = entry; mpa->entry_filename = talloc_strdup(mpa, fn); mpa->entry_num += 1; success = true; break; } uselocale(oldlocale); return success; }
static void mode_list(struct cpio *cpio) { struct archive *a; struct archive_entry *entry; unsigned long blocks; int r; a = archive_read_new(); if (a == NULL) cpio_errc(1, 0, "Couldn't allocate archive object"); archive_read_support_compression_all(a); archive_read_support_format_all(a); if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block)) cpio_errc(1, archive_errno(a), archive_error_string(a)); for (;;) { r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) break; if (r != ARCHIVE_OK) { cpio_errc(1, archive_errno(a), archive_error_string(a)); } if (excluded(cpio, archive_entry_pathname(entry))) continue; if (cpio->verbose) list_item_verbose(cpio, entry); else fprintf(stdout, "%s\n", archive_entry_pathname(entry)); } r = archive_read_close(a); if (r != ARCHIVE_OK) cpio_errc(1, 0, archive_error_string(a)); if (!cpio->quiet) { blocks = (archive_position_uncompressed(a) + 511) / 512; fprintf(stderr, "%lu %s\n", blocks, blocks == 1 ? "block" : "blocks"); } archive_read_finish(a); exit(0); }
int pkg_full_signature_check(const char *archive_name, struct archive **archive) { struct archive_entry *entry = NULL; char *pkgname; int r; if (pkg_verify_signature(archive_name, archive, &entry, &pkgname)) return -1; if (pkgname == NULL) return 0; /* XXX read PLIST and compare pkgname */ while ((r = archive_read_next_header(*archive, &entry)) == ARCHIVE_OK) archive_read_data_skip(*archive); free(pkgname); return r == ARCHIVE_EOF ? 0 : -1; }
size_t LIBARCHIVEgetEntry(char *name, char *contentFile, char **ptr) { struct mydata *mydata; struct archive *a; struct archive_entry *entry; char *buf; size_t size = 0; mydata = (struct mydata*)malloc(sizeof(struct mydata)); a = archive_read_new(); mydata->name = name; archive_read_support_format_all(a); archive_read_support_compression_all(a); if (archive_read_open(a, mydata, myopen, myread, myclose) == ARCHIVE_FATAL) { fprintf(stderr, "failed to open %s\n", mydata->name); free(mydata->name); free(mydata); return 0; } while (archive_read_next_header(a, &entry) == ARCHIVE_OK) { if( 0 == strcmp(archive_entry_pathname(entry), contentFile)) { o_log(DEBUGM, "%s", (char *)archive_compression_name(a)); o_log(DEBUGM, "%s", (char *)archive_format_name(a)); o_log(DEBUGM, "%s", (char *)archive_entry_pathname(entry)); size = archive_entry_size(entry); if(size <= 0) o_log(DEBUGM, "zero size"); if ((buf = (char *)malloc(size+1)) == NULL) o_log(ERROR, "cannot allocate memory"); if ((size_t)archive_read_data(a, buf, size) != size) o_log(DEBUGM, "cannot read data"); buf[size] = '\0'; *ptr = buf; } else archive_read_data_skip(a); } archive_read_close(a); archive_read_finish(a); free(mydata); return size; }
int load_package(pkg_t *pkg, int fd) { struct archive *archive; struct file_t file; if (file_from_fd(&file, fd) < 0) { return -1; } archive = archive_read_new(); archive_read_support_filter_all(archive); archive_read_support_format_all(archive); if (archive_read_open_memory(archive, file.mmap, file.st.st_size) != ARCHIVE_OK) { archive_read_free(archive); return -1; } bool found_pkginfo = false; struct archive_entry *entry; while (archive_read_next_header(archive, &entry) == ARCHIVE_OK && !found_pkginfo) { const char *entry_name = archive_entry_pathname(entry); const mode_t mode = archive_entry_mode(entry); if (S_ISREG(mode) && streq(entry_name, ".PKGINFO")) { read_pkginfo(archive, pkg); found_pkginfo = true; } } archive_read_close(archive); archive_read_free(archive); if (found_pkginfo) { pkg->size = file.st.st_size; pkg->mtime = file.st.st_mtime; pkg->name_hash = _alpm_hash_sdbm(pkg->name); return 0; } return -1; }
static DEB_RESULT process_meta_file_contents(struct archive *controlarchive, DEB_FILE *file) { struct archive_entry *entry = NULL; int control_file_found = 0; while(archive_read_next_header(controlarchive, &entry) == ARCHIVE_OK) { /* +2 because all file names start with './' */ const char *filename = archive_entry_pathname(entry) + 2; if(strstartswith(filename, DEB_CONTROL_FILE_NAME)) { parse_control_file(controlarchive, entry, file); control_file_found = 1; } else { } } return DEB_RESULT_OK; }
static struct pkg_vulnerabilities * read_pkg_vulnerabilities_archive(struct archive *a, int check_sum) { struct archive_entry *ae; struct pkg_vulnerabilities *pv; char *buf; size_t buf_len, off; ssize_t r; if (archive_read_next_header(a, &ae) != ARCHIVE_OK) errx(EXIT_FAILURE, "Cannot read pkg_vulnerabilities: %s", archive_error_string(a)); off = 0; buf_len = 65536; buf = xmalloc(buf_len + 1); for (;;) { r = archive_read_data(a, buf + off, buf_len - off); if (r <= 0) break; off += r; if (off == buf_len) { buf_len *= 2; if (buf_len < off) errx(EXIT_FAILURE, "pkg_vulnerabilties too large"); buf = xrealloc(buf, buf_len + 1); } } if (r != ARCHIVE_OK) errx(EXIT_FAILURE, "Cannot read pkg_vulnerabilities: %s", archive_error_string(a)); archive_read_close(a); buf[off] = '\0'; pv = parse_pkg_vuln(buf, off, check_sum); free(buf); return pv; }
/* Read a header from the given archive object and handle all possible outcomes. * The returned pointer is managed by libarchive and should not be freed by the * caller. * * If the caller needs to know whether EOF was hit without an error, they can * pass an eof pointer which will be set to 1 in this case or 0 otherwise. */ static struct archive_entry *read_header(struct archive *ar, int *eof) { struct archive_entry *entry; int r; int retries = 0; if (eof) *eof = 0; retry: r = archive_read_next_header(ar, &entry); switch (r) { case ARCHIVE_OK: break; case ARCHIVE_WARN: opkg_msg(NOTICE, "Warning when reading ar archive header: %s\n", archive_error_string(ar)); break; case ARCHIVE_EOF: if (eof) *eof = 1; return NULL; case ARCHIVE_RETRY: opkg_msg(ERROR, "Failed to read archive header: %s\n", archive_error_string(ar)); if (retries++ < 3) goto retry; else return NULL; default: opkg_msg(ERROR, "Failed to read archive header: %s\n", archive_error_string(ar)); return NULL; } return entry; }
bool archive_exists(const std::string &filename, std::vector<exists_info> &files) { if (files.empty()) { return false; } autoclose::archive in(archive_read_new(), archive_read_free); if (!in) { LOGE("Out of memory"); return false; } archive_entry *entry; int ret; for (exists_info &info : files) { info.exists = false; } if (!set_up_input(in.get(), filename)) { return false; } while ((ret = archive_read_next_header(in.get(), &entry)) == ARCHIVE_OK) { for (exists_info &info : files) { if (info.path == archive_entry_pathname(entry)) { info.exists = true; } } } if (ret != ARCHIVE_EOF) { LOGE("Archive extraction ended without reaching EOF: %s", archive_error_string(in.get())); return false; } return true; }
static gboolean http_archive_read_callback (gpointer user_data) { FetchData *fetch_data = (FetchData *) user_data; gint r; struct archive_entry *entry; gchar *newPath = NULL; r = archive_read_next_header(fetch_data->a, &entry); if (r == ARCHIVE_EOF) { g_idle_add (archive_finish_callback, fetch_data); return FALSE; } if (r != ARCHIVE_OK) { g_set_error(&fetch_data->error, RESTRAINT_FETCH_LIBARCHIVE_ERROR, r, "archive_read_next_header failed: %s", archive_error_string(fetch_data->a)); g_idle_add (archive_finish_callback, fetch_data); return FALSE; } if (fetch_data->archive_entry_callback) { fetch_data->archive_entry_callback (archive_entry_pathname (entry), fetch_data->user_data); } // Update pathname newPath = g_build_filename (fetch_data->base_path, archive_entry_pathname( entry ), NULL); archive_entry_set_pathname( entry, newPath ); g_free(newPath); r = archive_read_extract2(fetch_data->a, entry, fetch_data->ext); if (r != ARCHIVE_OK) { g_set_error(&fetch_data->error, RESTRAINT_FETCH_LIBARCHIVE_ERROR, r, "archive_read_extract2 failed: %s", archive_error_string(fetch_data->ext)); g_idle_add (archive_finish_callback, fetch_data); return FALSE; } return TRUE; }
static void test_empty_tarfile(void) { struct archive* a = archive_read_new(); struct archive_entry* e; /* Try opening an empty file with raw and empty handlers. */ assertEqualInt(ARCHIVE_OK, archive_read_support_format_tar(a)); assertEqualInt(0, archive_errno(a)); assertEqualString(NULL, archive_error_string(a)); assertEqualInt(ARCHIVE_OK, archive_read_open_filename(a, "empty.tar", 0)); assertEqualInt(0, archive_errno(a)); assertEqualString(NULL, archive_error_string(a)); assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &e)); assertEqualInt(0, archive_errno(a)); assertEqualString(NULL, archive_error_string(a)); archive_read_free(a); }
static void verifyEmpty(void) { struct archive_entry *ae; struct archive *a; assert((a = archive_read_new()) != NULL); assertA(0 == archive_read_support_compression_all(a)); assertA(0 == archive_read_support_format_all(a)); assertA(0 == archive_read_open_memory(a, archiveEmpty, 512)); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_NONE); failure("512 zero bytes should be recognized as a tar archive."); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR); assert(0 == archive_read_close(a)); #if ARCHIVE_API_VERSION > 1 assert(0 == archive_read_finish(a)); #else archive_read_finish(a); #endif }
int main() { struct archive *a = archive_read_new(); archive_read_support_filter_all(a); archive_read_support_format_all(a); int r = archive_read_open_filename(a, "test.tar", 10240); if (r != ARCHIVE_OK) return 1; struct archive_entry *entry; while (archive_read_next_header(a, &entry) == ARCHIVE_OK) { printf("%s\\n",archive_entry_pathname(entry)); int64_t offset = archive_read_current_position(a); archive_read_data_skip(a); } r = archive_read_free(a); if (r != ARCHIVE_OK) return 1; return 0; }
static int ReadDir( stream_directory_t* p_directory, input_item_node_t* p_node ) { private_sys_t* p_sys = p_directory->p_sys; libarchive_t* p_arc = p_sys->p_archive; struct vlc_readdir_helper rdh; vlc_readdir_helper_init( &rdh, p_directory, p_node); struct archive_entry* entry; int archive_status; while( !( archive_status = archive_read_next_header( p_arc, &entry ) ) ) { if( archive_entry_filetype( entry ) == AE_IFDIR ) continue; char const* path = archive_entry_pathname( entry ); if( unlikely( !path ) ) break; char* mrl = vlc_stream_extractor_CreateMRL( p_directory, path ); if( unlikely( !mrl ) ) break; if( vlc_readdir_helper_additem( &rdh, mrl, path, NULL, ITEM_TYPE_FILE, ITEM_LOCAL ) ) { free( mrl ); break; } free( mrl ); if( archive_read_data_skip( p_arc ) ) break; } vlc_readdir_helper_finish( &rdh, archive_status == ARCHIVE_EOF ); return archive_status == ARCHIVE_EOF ? VLC_SUCCESS : VLC_EGENERIC; }
static int repack_repo_data(const struct repo_t *repo) { struct archive_conv conv = {}; int r = 0; if (archive_conv_open(&conv, repo) < 0) { return -1; } while (archive_read_next_header(conv.in, &conv.ae) == ARCHIVE_OK) { const char *entryname = archive_entry_pathname(conv.ae); /* ignore everything but the /files metadata */ if (endswith(entryname, "/files")) { r = write_cpio_entry(&conv, entryname); if (r < 0) { break; } } } archive_conv_close(&conv); if (r < 0) { /* oh noes! */ if (unlink(conv.tmpfile) < 0 && errno != ENOENT) { fprintf(stderr, "error: failed to unlink temporary file: %s: %s\n", conv.tmpfile, strerror(errno)); } return -1; } if (rename(conv.tmpfile, repo->diskfile) != 0) { fprintf(stderr, "error: failed to rotate new repo for %s into place: %s\n", repo->name, strerror(errno)); return -1; } return 0; }
static VALUE rb_libarchive_reader_next_header(VALUE self) { struct rb_libarchive_archive_container *p; struct archive_entry *ae; int r; Data_Get_Struct(self, struct rb_libarchive_archive_container, p); Check_Archive(p); if (p->eof) { return Qnil; } r = archive_read_next_header(p->ar, &ae); if (r == ARCHIVE_EOF) { p->eof = 1; return Qnil; } else if (r != ARCHIVE_OK) { rb_raise(rb_eArchiveError, "Fetch entry failed: %s", archive_error_string(p->ar)); } return rb_libarchive_entry_new(ae, 0); }
bool next_frame() { png_structp png_ptr; png_infop info_ptr; struct archive_entry *ae; int res; read_data: res = archive_read_next_header(this->archive, &ae); if (res != ARCHIVE_OK || res == ARCHIVE_EOF) { if (play_mode == LOOP) { /* Go to the first archive entry and read it. */ close(); open(); goto read_data; } else { printf("Animation finished.\n"); return false; } } else if (res == ARCHIVE_FATAL || res == ARCHIVE_WARN || res == ARCHIVE_RETRY) { printf("Failed to read next header.\n"); return false; } else if (res == 0) { /* At the end of the archive check the loop flag to see if we * restart. */ if (read_png(&png_ptr, &info_ptr, this->archive) == 1) { fprintf(stderr, "Problem reading PNG.\n"); return false; } /* Store the image data into the framebuffer. */ set_framebuffer(png_ptr, info_ptr, framebuffer); png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL); } else { fprintf(stderr, "archive_read_next_header resulted in an unknown error.\n"); return false; } return true; }
extern int lparchive_extract(lparchive_t *handle, char *path) { char cwd[1024]; unsigned int i; struct archive_entry *entry; struct archive *archive = handle->archive; if ( getcwd(cwd, 1024) == NULL ) return -1; if ( chdir(path) == -1 ) return -1; for (i=0; archive_read_next_header(archive, &entry) == ARCHIVE_OK; ++i) { if ( archive_read_extract(archive, entry, 0) != ARCHIVE_OK ) return -1; } if ( chdir(cwd) == -1 ) return -1; return 0; }
int pkg_archive_file_count(const char *path){ struct archive *a; struct archive_entry *entry; int files, r; a = pkg_archive_open(path); if(a == NULL) return -1; for(files = 0;;files++){ r = archive_read_next_header(a, &entry); if(r == ARCHIVE_EOF) break; if(r != ARCHIVE_OK){ RETURN_P_LARCHIVE(-1, a); } } pkg_archive_close(a); return files; }
static void test1(void) { struct archive_entry *ae; struct archive *a; const char *name = "test_read_format_iso.iso.Z"; extract_reference_file(name); assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 512)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660); assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); }
Installer::ProceedState RomInstaller::on_checked_device() { // /sbin is not going to be populated with anything useful in a normal boot // image. We can almost guarantee that a recovery image is going to be // installed though, so we'll open the recovery partition with libmbp and // extract its /sbin with libarchive into the chroot's /sbin. std::string block_dev(_recovery_block_dev); mbp::BootImage bi; mbp::CpioFile innerCpio; const unsigned char *ramdisk_data; std::size_t ramdisk_size; bool using_boot = false; // Check if the device has a combined boot/recovery partition. If the // FOTAKernel partition is listed, it will be used instead of the combined // ramdisk from the boot image bool combined = mb_device_flags(_device) & FLAG_HAS_COMBINED_BOOT_AND_RECOVERY; if (combined && block_dev.empty()) { block_dev = _boot_block_dev; using_boot = true; } if (block_dev.empty()) { display_msg("Could not determine the recovery block device"); return ProceedState::Fail; } if (!bi.loadFile(block_dev)) { display_msg("Failed to load recovery partition image"); return ProceedState::Fail; } // Load ramdisk bi.ramdiskImageC(&ramdisk_data, &ramdisk_size); if (using_boot) { if (!innerCpio.load(ramdisk_data, ramdisk_size)) { display_msg("Failed to load ramdisk from combined boot image"); return ProceedState::Fail; } if (!innerCpio.contentsC("sbin/ramdisk-recovery.cpio", &ramdisk_data, &ramdisk_size)) { display_msg("Could not find recovery ramdisk in combined boot image"); return ProceedState::Fail; } } autoclose::archive in(archive_read_new(), archive_read_free); autoclose::archive out(archive_write_disk_new(), archive_write_free); if (!in || !out) { LOGE("Out of memory"); return ProceedState::Fail; } archive_entry *entry; // Set up input archive_read_support_filter_gzip(in.get()); archive_read_support_filter_lzop(in.get()); archive_read_support_filter_lz4(in.get()); archive_read_support_filter_lzma(in.get()); archive_read_support_filter_xz(in.get()); archive_read_support_format_cpio(in.get()); int ret = archive_read_open_memory(in.get(), const_cast<unsigned char *>(ramdisk_data), ramdisk_size); if (ret != ARCHIVE_OK) { LOGW("Failed to open recovery ramdisk: %s", archive_error_string(in.get())); return ProceedState::Fail; } // Set up output archive_write_disk_set_options(out.get(), ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_SECURE_NODOTDOT | ARCHIVE_EXTRACT_SECURE_SYMLINKS | ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_UNLINK | ARCHIVE_EXTRACT_XATTR); while ((ret = archive_read_next_header(in.get(), &entry)) == ARCHIVE_OK) { std::string path = archive_entry_pathname(entry); if (path == "default.prop") { path = "default.recovery.prop"; } else if (!util::starts_with(path, "sbin/")) { continue; } LOGE("Copying from recovery: %s", path.c_str()); archive_entry_set_pathname(entry, in_chroot(path).c_str()); if (util::libarchive_copy_header_and_data( in.get(), out.get(), entry) != ARCHIVE_OK) { return ProceedState::Fail; } archive_entry_set_pathname(entry, path.c_str()); } if (ret != ARCHIVE_EOF) { LOGE("Archive extraction ended without reaching EOF: %s", archive_error_string(in.get())); return ProceedState::Fail; } // Create fake /etc/fstab file to please installers that read the file std::string etc_fstab(in_chroot("/etc/fstab")); if (access(etc_fstab.c_str(), R_OK) < 0 && errno == ENOENT) { autoclose::file fp(autoclose::fopen(etc_fstab.c_str(), "w")); if (fp) { auto system_devs = mb_device_system_block_devs(_device); auto cache_devs = mb_device_cache_block_devs(_device); auto data_devs = mb_device_data_block_devs(_device); // Set block device if it's provided and non-empty const char *system_dev = system_devs && system_devs[0] && system_devs[0][0] ? system_devs[0] : "dummy"; const char *cache_dev = cache_devs && cache_devs[0] && cache_devs[0][0] ? cache_devs[0] : "dummy"; const char *data_dev = data_devs && data_devs[0] && data_devs[0][0] ? data_devs[0] : "dummy"; fprintf(fp.get(), "%s /system ext4 rw 0 0\n", system_dev); fprintf(fp.get(), "%s /cache ext4 rw 0 0\n", cache_dev); fprintf(fp.get(), "%s /data ext4 rw 0 0\n", data_dev); } } // Load recovery properties util::file_get_all_properties( in_chroot("/default.recovery.prop"), &_recovery_props); return ProceedState::Continue; }
static void test_filename(const char *prefix, int dlen, int flen) { char buff[8192]; char filename[400]; char dirname[400]; struct archive_entry *ae; struct archive *a; size_t used; int separator = 0; int i = 0; if (prefix != NULL) { strcpy(filename, prefix); i = (int)strlen(prefix); } if (dlen > 0) { for (; i < dlen; i++) filename[i] = 'a'; filename[i++] = '/'; separator = 1; } for (; i < dlen + flen + separator; i++) filename[i] = 'b'; filename[i] = '\0'; strcpy(dirname, filename); /* Create a new archive in memory. */ assert((a = archive_write_new()) != NULL); assertA(0 == archive_write_set_format_ustar(a)); assertA(0 == archive_write_add_filter_none(a)); assertA(0 == archive_write_set_bytes_per_block(a,0)); assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used)); /* * Write a file to it. */ assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, filename); archive_entry_set_mode(ae, S_IFREG | 0755); failure("dlen=%d, flen=%d", dlen, flen); if (flen > 100) { assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); } else { assertEqualIntA(a, 0, archive_write_header(a, ae)); } archive_entry_free(ae); /* * Write a dir to it (without trailing '/'). */ assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, dirname); archive_entry_set_mode(ae, S_IFDIR | 0755); failure("dlen=%d, flen=%d", dlen, flen); if (flen >= 100) { assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); } else { assertEqualIntA(a, 0, archive_write_header(a, ae)); } archive_entry_free(ae); /* Tar adds a '/' to directory names. */ strcat(dirname, "/"); /* * Write a dir to it (with trailing '/'). */ assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, dirname); archive_entry_set_mode(ae, S_IFDIR | 0755); failure("dlen=%d, flen=%d", dlen, flen); if (flen >= 100) { assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae)); } else { assertEqualIntA(a, 0, archive_write_header(a, ae)); } archive_entry_free(ae); /* Close out the archive. */ assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); assertEqualInt(ARCHIVE_OK, archive_write_free(a)); /* * Now, read the data back. */ assert((a = archive_read_new()) != NULL); assertA(0 == archive_read_support_format_all(a)); assertA(0 == archive_read_support_filter_all(a)); assertA(0 == archive_read_open_memory(a, buff, used)); if (flen <= 100) { /* Read the file and check the filename. */ assertA(0 == archive_read_next_header(a, &ae)); failure("dlen=%d, flen=%d", dlen, flen); assertEqualString(filename, archive_entry_pathname(ae)); assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae)); } /* * Read the two dirs and check the names. * * Both dirs should read back with the same name, since * tar should add a trailing '/' to any dir that doesn't * already have one. */ if (flen <= 99) { assertA(0 == archive_read_next_header(a, &ae)); assert((S_IFDIR | 0755) == archive_entry_mode(ae)); failure("dlen=%d, flen=%d", dlen, flen); assertEqualString(dirname, archive_entry_pathname(ae)); } if (flen <= 99) { assertA(0 == archive_read_next_header(a, &ae)); assert((S_IFDIR | 0755) == archive_entry_mode(ae)); assertEqualString(dirname, archive_entry_pathname(ae)); } /* Verify the end of the archive. */ failure("This fails if entries were written that should not have been written. dlen=%d, flen=%d", dlen, flen); assertEqualInt(1, archive_read_next_header(a, &ae)); assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }