/* * Issue 226: Try to reproduce hang when reading archives where the * length-at-end marker ends exactly on a block boundary. */ static void test_compat_zip_7(void) { const char *refname = "test_compat_zip_7.xps"; struct archive *a; struct archive_entry *ae; void *p; size_t s; int i; extract_reference_file(refname); p = slurpfile(&s, refname); for (i = 1; i < 1000; ++i) { assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); assertEqualIntA(a, ARCHIVE_OK, read_open_memory_minimal(a, p, s, i)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); } free(p); }
inline void genSafariExtension(const std::string& path, QueryData& results) { Row r; r["path"] = path; // Loop through (Plist key -> table column name) in kSafariExtensionKeys. struct archive* ext = archive_read_new(); if (ext == nullptr) { return; } // Use open_file, instead of the preferred open_filename for OS X 10.9. archive_read_support_format_xar(ext); if (archive_read_open_file(ext, path.c_str(), 10240) != ARCHIVE_OK) { archive_read_finish(ext); return; } struct archive_entry* entry = nullptr; while (archive_read_next_header(ext, &entry) == ARCHIVE_OK) { auto item_path = archive_entry_pathname(entry); // Documentation for libarchive mentions these APIs may return NULL. if (item_path == nullptr) { archive_read_data_skip(ext); continue; } // Assume there is no non-root Info. if (std::string(item_path).find("Info.plist") == std::string::npos) { archive_read_data_skip(ext); continue; } // Read the decompressed Info.plist content. auto content = std::string(archive_entry_size(entry), '\0'); archive_read_data_into_buffer(ext, &content[0], content.size()); // If the Plist can be parsed, extract important keys into columns. pt::ptree tree; if (parsePlistContent(content, tree).ok()) { for (const auto& it : kSafariExtensionKeys) { r[it.second] = tree.get(it.first, ""); } } break; } archive_read_close(ext); archive_read_finish(ext); results.push_back(std::move(r)); }
/* * Extract a directory. */ static void extract_dir(struct archive *a, struct archive_entry *e, const char *path) { int mode; mode = archive_entry_mode(e) & 0777; if (mode == 0) mode = 0755; /* * Some zipfiles contain directories with weird permissions such * as 0644 or 0444. This can cause strange issues such as being * unable to extract files into the directory we just created, or * the user being unable to remove the directory later without * first manually changing its permissions. Therefore, we whack * the permissions into shape, assuming that the user wants full * access and that anyone who gets read access also gets execute * access. */ mode |= 0700; if (mode & 0040) mode |= 0010; if (mode & 0004) mode |= 0001; info("d %s\n", path); make_dir(path, mode); ac(archive_read_data_skip(a)); }
static foreign_t archive_next_header(term_t archive, term_t name) { archive_wrapper *ar; int rc; if ( !get_archive(archive, &ar) ) return FALSE; if ( ar->status == AR_NEW_ENTRY ) archive_read_data_skip(ar->archive); if ( ar->status == AR_OPENED_ENTRY ) return PL_permission_error("next_header", "archive", archive); while ( (rc=archive_read_next_header(ar->archive, &ar->entry)) == ARCHIVE_OK ) { if ( PL_unify_wchars(name, PL_ATOM, -1, archive_entry_pathname_w(ar->entry)) ) { ar->status = AR_NEW_ENTRY; return TRUE; } if ( PL_exception(0) ) return FALSE; } if ( rc == ARCHIVE_EOF ) return FALSE; /* simply at the end */ return archive_error(ar); }
/* * Extract to memory to check CRC */ static int test(struct archive *a, struct archive_entry *e) { ssize_t len; int error_count; error_count = 0; if (S_ISDIR(archive_entry_filetype(e))) return 0; info(" testing: %s\t", archive_entry_pathname(e)); while ((len = archive_read_data(a, buffer, sizeof buffer)) > 0) /* nothing */; if (len < 0) { info(" %s\n", archive_error_string(a)); ++error_count; } else { info(" OK\n"); } /* shouldn't be necessary, but it doesn't hurt */ ac(archive_read_data_skip(a)); return error_count; }
static void test(int skip_explicitely) { struct archive* a = archive_read_new(); struct archive_entry* e; assertEqualInt(ARCHIVE_OK, archive_read_support_format_raw(a)); assertEqualInt(0, archive_errno(a)); assertEqualString(NULL, archive_error_string(a)); assertEqualInt(ARCHIVE_OK, archive_read_open_memory(a, (void*) data, sizeof(data))); assertEqualString(NULL, archive_error_string(a)); assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &e)); assertEqualInt(0, archive_errno(a)); assertEqualString(NULL, archive_error_string(a)); if (skip_explicitely) assertEqualInt(ARCHIVE_OK, archive_read_data_skip(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); }
//******************************************************************************************************** void list_archive(const char* const infile) { // Adapted from: // https://github.com/libarchive/libarchive/wiki/Examples#List_contents_of_Archive_stored_in_File // Note - this function will always be "chatty"; make sure to flush the stdout before using it... // TODO: Write a function which *returns* the list of files // (by writing it into a char** supplied by the caller) fprintf(stderr, "Opening archive '%s' for listing...\n",infile); struct archive* a = archive_read_new(); archive_read_support_format_zip(a); int err = archive_read_open_filename(a, infile,10240);//Note: Blocksize isn't neccessarilly adhered to if (err != ARCHIVE_OK) { fprintf(stderr, "CRITICAL ERROR in list_archive(): When opening archive '%s', err=%i\n",infile,err); fprintf(stderr, "CRITICAL ERROR in list_archive(): %s\n",archive_error_string(a)); exit(EXIT_FAILURE); } struct archive_entry* entry; while (archive_read_next_header(a,&entry)==ARCHIVE_OK){ printf("Found file: '%s'\n",archive_entry_pathname(entry)); archive_read_data_skip(a); } archive_read_close(a); err = archive_read_free(a); if (err != ARCHIVE_OK){ fprintf(stderr, "CRITICAL ERROR in list_archive(): Error when calling archive_read_free(), '%s', err=%i\n",infile,err); fprintf(stderr, "CRITICAL ERROR in list_archive(): %s\n",archive_error_string(a)); exit(EXIT_FAILURE); } }
/* * Print the name of an entry to stdout. */ static void list(struct archive *a, struct archive_entry *e) { char buf[20]; time_t mtime; mtime = archive_entry_mtime(e); strftime(buf, sizeof(buf), "%m-%d-%g %R", localtime(&mtime)); if (!zipinfo_mode) { if (v_opt == 1) { printf(" %8ju %s %s\n", (uintmax_t)archive_entry_size(e), buf, archive_entry_pathname(e)); } else if (v_opt == 2) { printf("%8ju Stored %7ju 0%% %s %08x %s\n", (uintmax_t)archive_entry_size(e), (uintmax_t)archive_entry_size(e), buf, 0U, archive_entry_pathname(e)); } } else { if (Z1_opt) printf("%s\n",archive_entry_pathname(e)); } ac(archive_read_data_skip(a)); }
void verify_read_positions(struct archive *a) { struct archive_entry *ae; intmax_t read_position = 0; size_t j; /* Initial header position is zero. */ assert(read_position == (intmax_t)archive_read_header_position(a)); for (j = 0; j < sizeof(data_sizes)/sizeof(data_sizes[0]); ++j) { assertA(0 == archive_read_next_header(a, &ae)); assertEqualInt(read_position, (intmax_t)archive_read_header_position(a)); /* Every other entry: read, then skip */ if (j & 1) assertEqualInt(1, archive_read_data(a, tmp, 1)); assertA(0 == archive_read_data_skip(a)); /* read_data_skip() doesn't change header_position */ assertEqualInt(read_position, (intmax_t)archive_read_header_position(a)); read_position += 512; /* Size of header. */ read_position += (data_sizes[j] + 511) & ~511; } assertA(1 == archive_read_next_header(a, &ae)); assertEqualInt(read_position, (intmax_t)archive_read_header_position(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualInt(read_position, (intmax_t)archive_read_header_position(a)); }
int main(int argc, char* argv[]) { // setup the archive object struct archive* a = archive_read_new(); archive_read_support_filter_all(a); archive_read_support_format_all(a); // actually open the archive file int r = archive_read_open_filename(a, argv[1], 10240); // Note 1 if (r != ARCHIVE_OK) return 1; // read through the entries struct archive_entry *entry; while (archive_read_next_header(a, &entry) == ARCHIVE_OK) { // output the path to the archived file puts(archive_entry_pathname(entry)); // move over the data part of the archive entry archive_read_data_skip(a); } // close it up r = archive_read_close(a); if (r != ARCHIVE_OK) return 1; return 0; }
/* * memory to file */ int archive_extract_file3( void *arch_buff, size_t arch_size, const char *src, char *dest ) { int flags; const char *filename; struct archive *arch_r = NULL, *arch_w = NULL; struct archive_entry *entry; if( !src || !dest ) return -1; arch_r = archive_read_new(); archive_read_support_format_all( arch_r ); archive_read_support_compression_all( arch_r ); if( archive_read_open_memory( arch_r, arch_buff, arch_size ) != ARCHIVE_OK ) goto errout; while( archive_read_next_header( arch_r, &entry ) == ARCHIVE_OK ) { filename = archive_entry_pathname( entry ); if( fnmatch( src, filename, FNM_PATHNAME | FNM_PERIOD ) ) { if( archive_read_data_skip( arch_r ) != ARCHIVE_OK ) { goto errout; } } else { #ifdef DEBUG printf("extract:%s\n", filename ); #endif flags = ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS; arch_w = archive_write_disk_new(); archive_write_disk_set_options( arch_w, flags ); archive_write_disk_set_standard_lookup( arch_w ); archive_entry_set_pathname( entry, dest ); if( archive_read_extract2( arch_r, entry, arch_w ) != ARCHIVE_OK ) goto errout; archive_write_finish( arch_w ); } } archive_read_finish( arch_r ); return 0; errout: #ifdef DEBUG fprintf( stderr, "%s\n", archive_error_string( arch_r ) ); #endif if( arch_r ) archive_read_finish( arch_r ); if( arch_w ) archive_write_finish( arch_w ); return -1; }
static char * file_get_zipped_contents (const char *filename, GCompareFunc func, gpointer user_data, gsize *length) { struct archive *a; struct archive_entry *entry; char *ret = NULL; int r; *length = 0; a = archive_read_new (); archive_read_support_format_zip (a); r = archive_read_open_filename (a, filename, 10240); if (r != ARCHIVE_OK) { g_print ("Failed to open archive %s\n", filename); return NULL; } while (1) { const char *name; r = archive_read_next_header(a, &entry); if (r != ARCHIVE_OK) { if (r != ARCHIVE_EOF && r == ARCHIVE_FATAL) g_warning ("Fatal error handling archive: %s", archive_error_string (a)); break; } name = archive_entry_pathname (entry); if (func (name, user_data) == 0) { size_t size = archive_entry_size (entry); char *buf; ssize_t read; buf = g_malloc (size); read = archive_read_data (a, buf, size); if (read <= 0) { g_free (buf); if (read < 0) g_warning ("Fatal error reading '%s' in archive: %s", name, archive_error_string (a)); else g_warning ("Read an empty file from the archive"); } else { ret = buf; *length = size; } break; } archive_read_data_skip(a); } archive_read_free(a); return ret; }
bool Decompress(const std::string & file, const std::string & output_path, std::ostream & info_output, std::ostream & error_output) { // Ensure the output path exists. PathManager::MakeDir(output_path); struct archive * a = archive_read_new(); archive_read_support_filter_all(a); archive_read_support_format_all(a); if (archive_read_open_filename(a, file.c_str(), BUFFSIZE) != ARCHIVE_OK) { error_output << "Unable to open " << file << std::endl; return false; } char buff[BUFFSIZE]; struct archive_entry *entry; while (archive_read_next_header(a, &entry) == ARCHIVE_OK) { std::string filename = archive_entry_pathname(entry); std::string fullpath = output_path + "/" + filename; if (archive_entry_filetype(entry) == AE_IFDIR) PathManager::MakeDir(fullpath); else { std::fstream f(fullpath.c_str(), std::ios_base::out | std::ios_base::binary | std::ios_base::trunc); if (!f) { error_output << "Unable to open file for write (permissions issue?): " << fullpath << std::endl; return false; } int size = -1; while (size != 0) { size = archive_read_data(a, buff, BUFFSIZE); if (size < 0) { error_output << "Encountered corrupt file: " << filename << std::endl; return false; } else if (size != 0) f.write(buff, size); } } archive_read_data_skip(a); } if (archive_read_free(a) != ARCHIVE_OK) { error_output << "Unable to finish read of " << file << std::endl; return false; } info_output << "Successfully decompressed " << file << std::endl; return true; }
/* * memory to memory */ int archive_extract_file4( void *arch_buff, size_t arch_size, const char *src, void **dest_buff, size_t *dest_len ) { const char *filename; struct archive *arch_r = NULL; struct archive_entry *entry; if( !src ) return -1; arch_r = archive_read_new(); archive_read_support_format_all( arch_r ); archive_read_support_compression_all( arch_r ); if( archive_read_open_memory( arch_r, arch_buff, arch_size ) != ARCHIVE_OK ) goto errout; while( archive_read_next_header( arch_r, &entry ) == ARCHIVE_OK ) { filename = archive_entry_pathname( entry ); if( fnmatch( src, filename, FNM_PATHNAME | FNM_PERIOD ) ) { if( archive_read_data_skip( arch_r ) != ARCHIVE_OK ) { goto errout; } } else { #ifdef DEBUG printf("extract:%s\n", filename ); #endif *dest_len = archive_entry_size( entry ); if( *dest_len > 0 ) { *dest_buff = malloc( *dest_len + 1 ); memset( *dest_buff, 0, *dest_len + 1 ); } if( archive_read_data( arch_r, *dest_buff, *dest_len) < 0 ) goto errout; } } archive_read_finish( arch_r ); return 0; errout: #ifdef DEBUG fprintf( stderr, "%s\n", archive_error_string( arch_r ) ); #endif if( arch_r ) archive_read_finish( arch_r ); return -1; }
std::string next() { if (archive_read_next_header(mArchive, &mEntry) == ARCHIVE_OK) { std::string entryName = archive_entry_pathname(mEntry); archive_read_data_skip(mArchive); return entryName; } return std::string(""); }
static int read_file_from_archive(const char *archive_name, struct archive *archive, struct archive_entry **entry, const char *fname, char **content, size_t *len) { int r; *content = NULL; *len = 0; retry: if (*entry == NULL && (r = archive_read_next_header(archive, entry)) != ARCHIVE_OK) { if (r == ARCHIVE_FATAL) { warnx("Cannot read from archive `%s': %s", archive_name, archive_error_string(archive)); } else { warnx("Premature end of archive `%s'", archive_name); } *entry = NULL; return -1; } if (strcmp(archive_entry_pathname(*entry), "//") == 0) { archive_read_data_skip(archive); *entry = NULL; goto retry; } if (strcmp(fname, archive_entry_pathname(*entry)) != 0) return 1; /* if (archive_entry_size(*entry) > SSIZE_MAX - 1) { warnx("Signature of archive `%s' too large to process", archive_name); return 1; } */ *len = archive_entry_size(*entry); *content = xmalloc(*len + 1); if (archive_read_data(archive, *content, *len) != (ssize_t)*len) { warnx("Cannot read complete %s from archive `%s'", fname, archive_name); free(*content); *len = 0; *content = NULL; return 1; } (*content)[*len] = '\0'; *entry = NULL; return 0; }
bool LibArchiveInterface::list() { kDebug(); ArchiveRead arch_reader(archive_read_new()); if (!(arch_reader.data())) { return false; } if (archive_read_support_compression_all(arch_reader.data()) != ARCHIVE_OK) { return false; } if (archive_read_support_format_all(arch_reader.data()) != ARCHIVE_OK) { return false; } if (archive_read_open_filename(arch_reader.data(), QFile::encodeName(filename()), 10240) != ARCHIVE_OK) { emit error(i18nc("@info", "Could not open the archive <filename>%1</filename>, libarchive cannot handle it.", filename())); return false; } m_cachedArchiveEntryCount = 0; m_extractedFilesSize = 0; struct archive_entry *aentry; int result; while (!m_abortOperation && (result = archive_read_next_header(arch_reader.data(), &aentry)) == ARCHIVE_OK) { if (!m_emitNoEntries) { emitEntryFromArchiveEntry(aentry); } m_extractedFilesSize += (qlonglong)archive_entry_size(aentry); m_cachedArchiveEntryCount++; archive_read_data_skip(arch_reader.data()); } m_abortOperation = false; if (result != ARCHIVE_EOF) { emit error(i18nc("@info", "The archive reading failed with the following error: <message>%1</message>", QLatin1String( archive_error_string(arch_reader.data())))); return false; } return archive_read_close(arch_reader.data()) == ARCHIVE_OK; }
bool LibarchivePlugin::list() { qCDebug(ARK) << "Listing archive contents"; if (!initializeReader()) { return false; } qDebug(ARK) << "Detected compression filter:" << archive_filter_name(m_archiveReader.data(), 0); QString compMethod = convertCompressionName(QString::fromUtf8(archive_filter_name(m_archiveReader.data(), 0))); if (!compMethod.isEmpty()) { emit compressionMethodFound(compMethod); } m_cachedArchiveEntryCount = 0; m_extractedFilesSize = 0; m_numberOfEntries = 0; auto compressedArchiveSize = QFileInfo(filename()).size(); struct archive_entry *aentry; int result = ARCHIVE_RETRY; bool firstEntry = true; while (!QThread::currentThread()->isInterruptionRequested() && (result = archive_read_next_header(m_archiveReader.data(), &aentry)) == ARCHIVE_OK) { if (firstEntry) { qDebug(ARK) << "Detected format for first entry:" << archive_format_name(m_archiveReader.data()); firstEntry = false; } if (!m_emitNoEntries) { emitEntryFromArchiveEntry(aentry); } m_extractedFilesSize += (qlonglong)archive_entry_size(aentry); emit progress(float(archive_filter_bytes(m_archiveReader.data(), -1))/float(compressedArchiveSize)); m_cachedArchiveEntryCount++; archive_read_data_skip(m_archiveReader.data()); } if (result != ARCHIVE_EOF) { qCWarning(ARK) << "Could not read until the end of the archive:" << QLatin1String(archive_error_string(m_archiveReader.data())); return false; } return archive_read_close(m_archiveReader.data()) == ARCHIVE_OK; }
static int append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina) { struct archive_entry *in_entry; int e; while (0 == archive_read_next_header(ina, &in_entry)) { if (!new_enough(bsdtar, archive_entry_pathname(in_entry), archive_entry_stat(in_entry))) continue; if (excluded(bsdtar, archive_entry_pathname(in_entry))) continue; if (bsdtar->option_interactive && !yes("copy '%s'", archive_entry_pathname(in_entry))) continue; if (bsdtar->verbose) safe_fprintf(stderr, "a %s", archive_entry_pathname(in_entry)); siginfo_setinfo(bsdtar, "copying", archive_entry_pathname(in_entry), archive_entry_size(in_entry)); siginfo_printinfo(bsdtar, 0); e = archive_write_header(a, in_entry); if (e != ARCHIVE_OK) { if (!bsdtar->verbose) bsdtar_warnc(bsdtar, 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(bsdtar, a, ina)) exit(1); } if (bsdtar->verbose) fprintf(stderr, "\n"); } /* Note: If we got here, we saw no write errors, so return success. */ return (0); }
static int archive_seek_subentry( private_sys_t* p_sys, char const* psz_subentry ) { libarchive_t* p_arc = p_sys->p_archive; struct archive_entry* entry; int archive_status; while( !( archive_status = archive_read_next_header( p_arc, &entry ) ) ) { char const* entry_path = archive_entry_pathname( entry ); if( strcmp( entry_path, psz_subentry ) == 0 ) { p_sys->p_entry = archive_entry_clone( entry ); if( unlikely( !p_sys->p_entry ) ) return VLC_ENOMEM; break; } archive_read_data_skip( p_arc ); } switch( archive_status ) { case ARCHIVE_WARN: msg_Warn( p_sys->p_obj, "libarchive: %s", archive_error_string( p_arc ) ); /* fall through */ case ARCHIVE_EOF: case ARCHIVE_FATAL: case ARCHIVE_RETRY: archive_set_error( p_arc, ARCHIVE_FATAL, "archive does not contain >>> %s <<<", psz_subentry ); return VLC_EGENERIC; } /* check if seeking is supported */ if( p_sys->b_seekable_source ) { if( archive_seek_data( p_sys->p_archive, 0, SEEK_CUR ) >= 0 ) p_sys->b_seekable_archive = true; } return VLC_SUCCESS; }
void list_archive_get(const char* const infile, char** filenames, int* nfiles, const int buffsize) { //printf("In list_archive_get\n"); //fflush(stdout); struct archive* a = archive_read_new(); archive_read_support_format_zip(a); int err = archive_read_open_filename(a, infile,10240);//Note: Blocksize isn't neccessarilly adhered to if (err != ARCHIVE_OK) { fprintf(stderr, "CRITICAL ERROR in list_archive_get(): When opening archive '%s', err=%i\n",infile,err); fprintf(stderr, "CRITICAL ERROR in list_archive_get(): %s\n",archive_error_string(a)); exit(EXIT_FAILURE); } const int nfiles_max = *nfiles; *nfiles = 0; struct archive_entry* entry; while (archive_read_next_header(a,&entry)==ARCHIVE_OK){ //printf("Found file: '%s'\n",archive_entry_pathname(entry)); //fflush(stdout); int buff_used = 0; buff_used = snprintf(filenames[*nfiles],buffsize,"%s",archive_entry_pathname(entry)); if (buff_used >= buffsize) { fprintf(stderr, "CRITICAL ERROR in list_archive_get(): When reading file '%s' from archive '%s':\n",filenames[*nfiles],infile); fprintf(stderr, "CRITICAL ERROR in list_archive_get(): Buffer too small by %i characters\n",buff_used-buffsize+1); exit(EXIT_FAILURE); } else if (buff_used < 0) { fprintf(stderr, "CRITICAL ERROR in list_archive_get(): When reading file '%s' from archive '%s':\n",filenames[*nfiles],infile); fprintf(stderr, "CRITICAL ERROR in list_archive_get(): Error in snprintf.\n"); exit(EXIT_FAILURE); } archive_read_data_skip(a); if(++(*nfiles) >= nfiles_max) { fprintf(stderr, "CRITICAL ERROR in list_archive_get(): Number of files greater than nfiles_max=%i",nfiles_max); exit(EXIT_FAILURE); } } archive_read_close(a); err = archive_read_free(a); if (err != ARCHIVE_OK){ fprintf(stderr, "CRITICAL ERROR in list_archive_get(): Error when calling archive_read_free(), '%s', err=%i\n",infile,err); fprintf(stderr, "CRITICAL ERROR in list_archive_get(): %s\n",archive_error_string(a)); exit(EXIT_FAILURE); } }
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); }
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 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; }
/* ArchiveReader::skipCurrentEntryData{{{ * */ ZEND_METHOD(ArchiveReader, skipCurrentEntryData){ zval *this = getThis(); archive_file_t *arch; zend_error_handling error_handling; int r; zend_replace_error_handling(EH_THROW, ce_ArchiveException, &error_handling TSRMLS_CC); if (!_archive_get_fd(this, &arch TSRMLS_CC)) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } r = archive_read_data_skip(arch->arch); if(r != ARCHIVE_OK){ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Skip archive entry failed"); zend_restore_error_handling(&error_handling TSRMLS_CC); return; } return; }/*}}}*/
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 extract_db_file(alpm_handle_t *handle, struct archive *archive, struct archive_entry *entry, alpm_pkg_t *newpkg, const char *entryname) { char filename[PATH_MAX]; /* the actual file we're extracting */ const char *dbfile = NULL; if(strcmp(entryname, ".INSTALL") == 0) { dbfile = "install"; } else if(strcmp(entryname, ".CHANGELOG") == 0) { dbfile = "changelog"; } else if(strcmp(entryname, ".MTREE") == 0) { dbfile = "mtree"; } else if(*entryname == '.') { /* reserve all files starting with '.' for future possibilities */ _alpm_log(handle, ALPM_LOG_DEBUG, "skipping extraction of '%s'\n", entryname); archive_read_data_skip(archive); return 0; } archive_entry_set_perm(entry, 0644); snprintf(filename, PATH_MAX, "%s%s-%s/%s", _alpm_db_path(handle->db_local), newpkg->name, newpkg->version, dbfile); return perform_extraction(handle, archive, entry, filename); }
bool OdinPatcher::Impl::processContents() { archive_entry *entry; int laRet; int mzRet; zipFile zf = MinizipUtils::ctxGetZipFile(zOutput); while ((laRet = archive_read_next_header(aInput, &entry)) == ARCHIVE_OK) { if (cancelled) return false; const char *name = archive_entry_pathname(entry); if (!name) { continue; } updateDetails(name); if (strcmp(name, "boot.img") == 0) { LOGD("Handling boot.img"); // Boot images should never be over about 30 MiB. This check is here // so the patcher won't try to read a multi-gigabyte system image // into RAM la_int64_t size = archive_entry_size(entry); if (size > 30 * 1024 * 1024) { LOGE("Boot image exceeds 30 MiB: %" PRId64, size); error = ErrorCode::BootImageTooLargeError; return false; } std::vector<unsigned char> data; if (size > 0) { data.reserve(size); } char buf[10240]; la_ssize_t n; while ((n = archive_read_data(aInput, buf, sizeof(buf))) > 0) { data.insert(data.end(), buf, buf + n); } if (n != 0) { LOGE("libarchive: Failed to read data: %s", archive_error_string(aInput)); error = ErrorCode::ArchiveReadDataError; return false; } if (!MultiBootPatcher::patchBootImage(pc, info, &data, &error)) { return false; } auto errorRet = MinizipUtils::addFile(zf, name, data); if (errorRet != ErrorCode::NoError) { error = errorRet; return false; } continue; } else if (!StringUtils::starts_with(name, "cache.img") && !StringUtils::starts_with(name, "system.img")) { LOGD("Skipping %s", name); if (archive_read_data_skip(aInput) != ARCHIVE_OK) { LOGE("libarchive: Failed to skip data: %s", archive_error_string(aInput)); error = ErrorCode::ArchiveReadDataError; return false; } continue; } LOGD("Handling %s", name); std::string zipName(name); if (StringUtils::ends_with(name, ".ext4")) { zipName.erase(zipName.size() - 5); } zipName += ".sparse"; // Ha! I'll be impressed if a Samsung firmware image does NOT need zip64 int zip64 = archive_entry_size(entry) > ((1ll << 32) - 1); zip_fileinfo zi; memset(&zi, 0, sizeof(zi)); // Open file in output zip mzRet = zipOpenNewFileInZip2_64( zf, // file zipName.c_str(), // filename &zi, // zip_fileinfo nullptr, // extrafield_local 0, // size_extrafield_local nullptr, // extrafield_global 0, // size_extrafield_global nullptr, // comment Z_DEFLATED, // method Z_DEFAULT_COMPRESSION, // level 0, // raw zip64 // zip64 ); if (mzRet != ZIP_OK) { LOGE("minizip: Failed to open new file in output zip: %s", MinizipUtils::zipErrorString(mzRet).c_str()); error = ErrorCode::ArchiveWriteHeaderError; return false; } la_ssize_t nRead; char buf[10240]; while ((nRead = archive_read_data(aInput, buf, sizeof(buf))) > 0) { if (cancelled) return false; mzRet = zipWriteInFileInZip(zf, buf, nRead); if (mzRet != ZIP_OK) { LOGE("minizip: Failed to write %s in output zip: %s", zipName.c_str(), MinizipUtils::zipErrorString(mzRet).c_str()); error = ErrorCode::ArchiveWriteDataError; zipCloseFileInZip(zf); return false; } } if (nRead != 0) { LOGE("libarchive: Failed to read %s: %s", name, archive_error_string(aInput)); error = ErrorCode::ArchiveReadDataError; zipCloseFileInZip(zf); return false; } // Close file in output zip mzRet = zipCloseFileInZip(zf); if (mzRet != ZIP_OK) { LOGE("minizip: Failed to close file in output zip: %s", MinizipUtils::zipErrorString(mzRet).c_str()); error = ErrorCode::ArchiveWriteDataError; return false; } } if (laRet != ARCHIVE_EOF) { LOGE("libarchive: Failed to read header: %s", archive_error_string(aInput)); error = ErrorCode::ArchiveReadHeaderError; return false; } if (cancelled) return false; return true; }
/* * Handle read modes: 'x', 't' and 'p'. */ static void read_archive(struct bsdar *bsdar, char mode) { struct archive *a; struct archive_entry *entry; struct stat sb; struct tm *tp; const char *bname; const char *name; mode_t md; size_t size; time_t mtime; uid_t uid; gid_t gid; char **av; char buf[25]; char find; int flags, r, i; if ((a = archive_read_new()) == NULL) bsdar_errc(bsdar, EX_SOFTWARE, 0, "archive_read_new failed"); archive_read_support_format_ar(a); AC(archive_read_open_filename(a, bsdar->filename, DEF_BLKSZ)); for (;;) { r = archive_read_next_header(a, &entry); if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY || r == ARCHIVE_FATAL) bsdar_warnc(bsdar, archive_errno(a), "%s", archive_error_string(a)); if (r == ARCHIVE_EOF || r == ARCHIVE_FATAL) break; if (r == ARCHIVE_RETRY) { bsdar_warnc(bsdar, 0, "Retrying..."); continue; } if ((name = archive_entry_pathname(entry)) == NULL) break; /* Skip pseudo members. */ if (strcmp(name, "/") == 0 || strcmp(name, "//") == 0 || strcmp(name, "/SYM64/") == 0) continue; if (bsdar->argc > 0) { find = 0; for(i = 0; i < bsdar->argc; i++) { av = &bsdar->argv[i]; if (*av == NULL) continue; if ((bname = basename(*av)) == NULL) bsdar_errc(bsdar, EX_SOFTWARE, errno, "basename failed"); if (strcmp(bname, name) != 0) continue; *av = NULL; find = 1; break; } if (!find) continue; } if (mode == 't') { if (bsdar->options & AR_V) { md = archive_entry_mode(entry); uid = archive_entry_uid(entry); gid = archive_entry_gid(entry); size = archive_entry_size(entry); mtime = archive_entry_mtime(entry); (void)strmode(md, buf); (void)fprintf(stdout, "%s %6d/%-6d %8ju ", buf + 1, uid, gid, (uintmax_t)size); tp = localtime(&mtime); (void)strftime(buf, sizeof(buf), "%b %e %H:%M %Y", tp); (void)fprintf(stdout, "%s %s", buf, name); } else (void)fprintf(stdout, "%s", name); r = archive_read_data_skip(a); if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY || r == ARCHIVE_FATAL) { (void)fprintf(stdout, "\n"); bsdar_warnc(bsdar, archive_errno(a), "%s", archive_error_string(a)); } if (r == ARCHIVE_FATAL) break; (void)fprintf(stdout, "\n"); } else { /* mode == 'x' || mode = 'p' */ if (mode == 'p') { if (bsdar->options & AR_V) { (void)fprintf(stdout, "\n<%s>\n\n", name); fflush(stdout); } r = archive_read_data_into_fd(a, 1); } else { /* mode == 'x' */ if (stat(name, &sb) != 0) { if (errno != ENOENT) { bsdar_warnc(bsdar, 0, "stat %s failed", bsdar->filename); continue; } } else { /* stat success, file exist */ if (bsdar->options & AR_CC) continue; if (bsdar->options & AR_U && archive_entry_mtime(entry) <= sb.st_mtime) continue; } if (bsdar->options & AR_V) (void)fprintf(stdout, "x - %s\n", name); /* Disallow absolute paths. */ if (name[0] == '/') { bsdar_warnc(bsdar, 0, "Absolute path '%s'", name); continue; } /* Basic path security flags. */ flags = ARCHIVE_EXTRACT_SECURE_SYMLINKS | ARCHIVE_EXTRACT_SECURE_NODOTDOT; if (bsdar->options & AR_O) flags |= ARCHIVE_EXTRACT_TIME; r = archive_read_extract(a, entry, flags); } if (r) bsdar_warnc(bsdar, archive_errno(a), "%s", archive_error_string(a)); } } AC(archive_read_close(a)); AC(archive_read_free(a)); }