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); }
static void pack_extract(const char *pack, const char *dbname, const char *dbpath) { struct archive *a = NULL; struct archive_entry *ae = NULL; if (access(pack, F_OK) != 0) return; a = archive_read_new(); archive_read_support_filter_all(a); archive_read_support_format_tar(a); if (archive_read_open_filename(a, pack, 4096) != ARCHIVE_OK) { /* if we can't unpack it it won't be useful for us */ unlink(pack); archive_read_free(a); return; } while (archive_read_next_header(a, &ae) == ARCHIVE_OK) { if (strcmp(archive_entry_pathname(ae), dbname) == 0) { archive_entry_set_pathname(ae, dbpath); archive_read_extract(a, ae, EXTRACT_ARCHIVE_FLAGS); break; } } archive_read_free(a); }
int main(int argc, const char **argv) { if (argc > 2) { fprintf(stderr, "Usage: %s [file]\n", argv[0]); exit(1); } struct archive *a = archive_read_new(); archive_read_support_compression_all(a); archive_read_support_format_raw(a); int err; if (argc == 2) err = archive_read_open_filename(a, argv[1], BS); else err = archive_read_open_fd(a, 0, BS); if (err != ARCHIVE_OK) { fprintf(stderr, "Broken archive (1)\n"); exit(1); } struct archive_entry *ae; err = archive_read_next_header(a, &ae); if (err != ARCHIVE_OK) { fprintf(stderr, "Broken archive (2)\n"); exit(1); } (void) archive_read_data_into_fd(a, 1); archive_read_finish(a); exit(0); }
static void extract(const char *filename, int do_extract, int flags) { struct archive *a; struct archive *ext; struct archive_entry *entry; int r; a = archive_read_new(); ext = archive_write_disk_new(); archive_write_disk_set_options(ext, flags); /* * Note: archive_write_disk_set_standard_lookup() is useful * here, but it requires library routines that can add 500k or * more to a static executable. */ archive_read_support_format_tar(a); /* * On my system, enabling other archive formats adds 20k-30k * each. Enabling gzip decompression adds about 20k. * Enabling bzip2 is more expensive because the libbz2 library * isn't very well factored. */ if (filename != NULL && strcmp(filename, "-") == 0) filename = NULL; if ((r = archive_read_open_filename(a, filename, 10240))) fail("archive_read_open_filename()", archive_error_string(a), r); for (;;) { r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) break; if (r != ARCHIVE_OK) fail("archive_read_next_header()", archive_error_string(a), 1); if (verbose && do_extract) msg("x "); if (verbose || !do_extract) msg(archive_entry_pathname(entry)); if (do_extract) { r = archive_write_header(ext, entry); if (r != ARCHIVE_OK) warn("archive_write_header()", archive_error_string(ext)); else { copy_data(a, ext); r = archive_write_finish_entry(ext); if (r != ARCHIVE_OK) fail("archive_write_finish_entry()", archive_error_string(ext), 1); } } if (verbose || !do_extract) msg("\n"); } archive_read_close(a); archive_read_free(a); exit(0); }
/* * An archive file has one empty file. It means there is no content * in the archive file except for a header. */ static void test_empty_file() { const char *refname = "test_read_format_7zip_empty_file.7z"; struct archive_entry *ae; struct archive *a; extract_reference_file(refname); assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); /* Verify regular empty. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae)); assertEqualString("empty", archive_entry_pathname(ae)); assertEqualInt(86401, archive_entry_mtime(ae)); assertEqualInt(0, archive_entry_size(ae)); assertEqualInt(1, archive_file_count(a)); /* End of archive. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); /* Verify archive format. */ assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a)); assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); /* Close the archive. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }
/* * Copy from specified archive to current archive. Returns non-zero * for write errors (which force us to terminate the entire archiving * operation). If there are errors reading the input archive, we set * bsdtar->return_value but return zero, so the overall archiving * operation will complete and return non-zero. */ static int append_archive_filename(struct bsdtar *bsdtar, struct archive *a, const char *raw_filename) { struct archive *ina; const char *filename = raw_filename; int rc; if (strcmp(filename, "-") == 0) filename = NULL; /* Library uses NULL for stdio. */ ina = archive_read_new(); archive_read_support_format_all(ina); archive_read_support_filter_all(ina); set_reader_options(bsdtar, a); if (archive_read_open_filename(ina, filename, bsdtar->bytes_per_block)) { lafe_warnc(0, "%s", archive_error_string(ina)); bsdtar->return_value = 1; return (0); } rc = append_archive(bsdtar, a, ina); if (rc != ARCHIVE_OK) { lafe_warnc(0, "Error reading archive %s: %s", raw_filename, archive_error_string(ina)); bsdtar->return_value = 1; } archive_read_free(ina); return (rc); }
/* Open an outer archive with the given filename. */ static struct archive *open_outer(const char *filename) { struct archive *outer; int r; outer = archive_read_new(); if (!outer) { opkg_msg(ERROR, "Failed to create outer archive object.\n"); return NULL; } /* Outer package is in 'ar' format, uncompressed. */ r = archive_read_support_format_ar(outer); if (r != ARCHIVE_OK) { opkg_msg(ERROR, "Ar format not supported: %s\n", archive_error_string(outer)); goto err_cleanup; } r = archive_read_open_filename(outer, filename, EXTRACT_BUFFER_LEN); if (r != ARCHIVE_OK) { opkg_msg(ERROR, "Failed to open package '%s': %s\n", filename, archive_error_string(outer)); goto err_cleanup; } return outer; err_cleanup: archive_read_free(outer); return NULL; }
//******************************************************************************************************** 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); } }
/* * Extract an archive (optionally compressed). * Args: * filename Full path to archive to unpack. * dest Directory to unpack in, or NULL for current dir. * Returns ARCHIVE_OK on success, or appropriate ARCHIVE_* value * on failure (see /usr/include/archive.h). */ int unpack_archive_file(char *filename, char *dest) { int rc = 0; struct archive *a = NULL; if (filename == NULL || access(filename, R_OK) == -1) { logMessage(ERROR, "unable to read %s (%s:%d): %m", filename, __func__, __LINE__); return ARCHIVE_FATAL; } if ((rc = unpack_init(&a)) != ARCHIVE_OK) { logMessage(ERROR, "unable to initialize libarchive"); return rc; } rc = archive_read_open_filename(a, filename, ARCHIVE_DEFAULT_BYTES_PER_BLOCK); if (rc != ARCHIVE_OK) { logMessage(ERROR, "error opening %s (%s:%d): %s", filename, __func__, __LINE__, archive_error_string(a)); return rc; } return unpack_members_and_finish(a, dest, NULL, NULL); }
static void test_extract_length_at_end(void) { const char *refname = "test_read_format_zip_length_at_end.zip"; char *p; size_t s; struct archive *a; extract_reference_file(refname); /* Verify extraction with seeking reader. */ assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); verify_extract_length_at_end(a, 1); /* Verify extraction with streaming reader. */ p = slurpfile(&s, refname); assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108)); verify_extract_length_at_end(a, 0); free(p); }
int Tarball::install () { archive_entry *entry; int r; archive* a = archive_read_new(); archive_read_support_format_all(a); archive_read_support_filter_all(a); archive* ext = archive_write_disk_new(); const int flags = ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS; archive_write_disk_set_options(ext, flags); archive_write_disk_set_standard_lookup(ext); const std::string subdir = "deps"; const std::string filename = subdir + "/" + basename(this->location); printf("Unpacking archive %s\n", filename.c_str()); if ((r = archive_read_open_filename(a,filename.c_str(), 10240))) { fprintf(stderr, "Error opening archive:\n%s\n", archive_error_string(a)); return -1; } for (;;) { r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) { break; } if (r < ARCHIVE_OK) { fprintf(stderr, "%s\n", archive_error_string(a)); } if (r < ARCHIVE_WARN) { return -1; } rewrite_subdir(entry, subdir); r = archive_write_header(ext, entry); if (r < ARCHIVE_OK) { fprintf(stderr, "%s\n", archive_error_string(ext)); } else if (archive_entry_size(entry) > 0) { r = copy_data(a, ext); if (r < ARCHIVE_OK) { fprintf(stderr, "%s\n", archive_error_string(ext)); } if (r < ARCHIVE_WARN) { return -1; } } r = archive_write_finish_entry(ext); if (r < ARCHIVE_OK) { fprintf(stderr, "%s\n", archive_error_string(ext)); } if (r < ARCHIVE_WARN) { return -1; } } archive_read_close(a); archive_read_free(a); archive_write_close(ext); archive_write_free(ext); return 0; };
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; }
/* * For each entry in the archive, it checks "entry + len" pointer against searched string. * Len is always the offset of the current dir inside archive, eg: foo.tgz/bar/x, * while checking x, len will be strlen("bar/") */ static int search_inside_archive(const char *path) { char *ptr; int len = 0, ret = FTW_CONTINUE, r = 0, string_length; struct archive_entry *entry; struct archive *a = archive_read_new(); archive_read_support_filter_all(a); archive_read_support_format_all(a); string_length = strlen(sv.searched_string); if ((a) && (archive_read_open_filename(a, path, BUFF_SIZE) == ARCHIVE_OK)) { while ((!quit) && (ret == FTW_CONTINUE) && (archive_read_next_header(a, &entry) == ARCHIVE_OK)) { if (!sv.search_lazy) { r = !strncmp(archive_entry_pathname(entry) + len, sv.searched_string, string_length); } else if (strcasestr(archive_entry_pathname(entry) + len, sv.searched_string)) { r = 1; } if (r) { snprintf(sv.found_searched[sv.found_cont], PATH_MAX, "%s/%s", path, archive_entry_pathname(entry)); sv.found_cont++; if (sv.found_cont == MAX_NUMBER_OF_FOUND) { ret = FTW_STOP; } } ptr = strrchr(archive_entry_pathname(entry), '/'); if ((ptr) && (strlen(ptr) == 1)) { len = strlen(archive_entry_pathname(entry)); } } } archive_read_free(a); return quit ? FTW_STOP : ret; }
/* * Verify that we skip junk between entries. The compat_zip_2.zip file * has several bytes of junk between 'file1' and 'file2'. Such * junk is routinely introduced by some Zip writers when they manipulate * existing zip archives. */ static void test_compat_zip_2(void) { char name[] = "test_compat_zip_2.zip"; struct archive_entry *ae; struct archive *a; assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); extract_reference_file(name); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240)); /* Read first entry. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("file1", archive_entry_pathname(ae)); /* Read first entry. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("file2", archive_entry_pathname(ae)); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }
/* * An archive file has no entry. */ static void test_empty_archive() { const char *refname = "test_read_format_7zip_empty_archive.7z"; struct archive_entry *ae; struct archive *a; extract_reference_file(refname); assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); /* End of archive. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); assertEqualInt(0, archive_file_count(a)); /* Verify archive format. */ assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0)); assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a)); /* Close the archive. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }
/* * file to file */ int archive_extract_file( char *arch_file, const char *src, char *dest ) { int flags; const char *filename; struct archive *arch_r = NULL, *arch_w = NULL; struct archive_entry *entry; if( !arch_file || !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_filename( arch_r, arch_file, 10240 ) != 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; }
struct archive *uniso_open(uniso_status_t *s, const char *src) { struct archive *iso = archive_read_new(); archive_read_support_format_iso9660(iso); if(archive_read_open_filename(iso, src, 10240) != ARCHIVE_OK) { s->error = strdup2("Could not open ISO file."); return NULL; } return iso; }
void PictureBank::loadArchive(const std::string &filename) { std::cout << "reading image archive: " << filename << std::endl; struct archive *a; struct archive_entry *entry; int rc; a = archive_read_new(); archive_read_support_compression_all(a); archive_read_support_format_all(a); rc = archive_read_open_filename(a, filename.c_str(), 16384); // block size if (rc != ARCHIVE_OK) { THROW("Cannot open archive " << filename); } SDL_Surface *surface; SDL_RWops *rw; const Uint32 bufferSize = 10000000; // allocated buffer std::auto_ptr< Uint8 > buffer( new Uint8[ bufferSize ] ); if( buffer.get() == 0 ) THROW("Memory error, cannot allocate buffer size " << bufferSize); std::string entryname; while( archive_read_next_header(a, &entry) == ARCHIVE_OK ) { // for all entries in archive entryname = archive_entry_pathname(entry); if ((archive_entry_stat(entry)->st_mode & S_IFREG) == 0) { // not a regular file (maybe a directory). skip it. continue; } if (archive_entry_stat(entry)->st_size >= bufferSize) { THROW("Cannot load archive: file is too big " << entryname << " in archive " << filename); } int size = archive_read_data(a, buffer.get(), bufferSize); // read data into buffer rw = SDL_RWFromMem(buffer.get(), size); surface = IMG_Load_RW(rw, 0); SDL_SetAlpha( surface, 0, 0 ); setPicture(entryname, *surface); SDL_FreeRW(rw); } rc = archive_read_finish(a); if (rc != ARCHIVE_OK) { THROW("Error while reading archive " << filename); } }
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; }
int extract_archive(char *filename) { struct archive *a; struct archive_entry *entry; int r; size_t size; char buff[BUFFER_SIZE]; FILE *fd; a = archive_read_new(); archive_read_support_compression_gzip(a); archive_read_support_format_tar(a); r = archive_read_open_filename(a, filename, 10240); if (r != ARCHIVE_OK) { return 1; } for (;;) { if ((r = archive_read_next_header(a, &entry))) { if (r != ARCHIVE_OK) { if (r == ARCHIVE_EOF) { return 0; }else{ return 1; } } } fd = fopen(archive_entry_pathname(entry),"wb"); if (fd == NULL) { fprintf(stderr, "problem extracting archive: %s: %s\n", filename, strerror(errno)); return 1; } for (;;) { size = archive_read_data(a, buff, BUFFER_SIZE); if (size < 0) { return 1; } if (size == 0) { break; } fwrite(buff, 1, size, fd); } fclose(fd); } r = archive_read_finish(a); if (r != ARCHIVE_OK) { return 4; } return 0; }
/* * this one takes a filename and an extension we expect is an archive, * and attempts to open it up. it returns -1 on error, 0 if it's not * an archive, or 1 if the archive was successfully loaded */ static int archive_fopen(struct epic_loadfile *elf, char *filename, const char *ext, int do_error) { int ret; int pos; char * fname; char * extra; char * safet; fname = LOCAL_COPY(filename); safet = LOCAL_COPY(filename); extra = fname; if ((pos=stristr(fname, ext))!=-1) { /* * Here we make fname actually point to a real * file, instead of virtual files/directories * inside the archive.. and check if we're * supposed to load a file by default.. */ extra+=pos; while (*extra!='/') { if (*extra==0) break; extra++; pos++; } safet+=pos; *extra++ = 0; elf->a = archive_read_new(); if (!archive_read_support_format_all(elf->a)) { if ( !(ret = archive_read_open_filename(elf->a, fname, 10240)) ) { if ( (strstr(safet, "/"))!=NULL ) { /* specific file provided */ if (!find_in_archive(elf->a, &elf->entry, extra, do_error)) return 0; } else { if (!find_in_archive(elf->a, &elf->entry, ".ircrc", do_error)) { /* bootstrap */ if (do_error) yell("No .ircrc in the zip file specified"); return -1; } } /* * Our archive should now be open and pointing to the * beginning of the specified file */ return 1; } /* <-- we can fall off the end */ } } return 0; }
static void test_compat_tar_hardlink_1(void) { char name[] = "test_compat_tar_hardlink_1.tar"; struct archive_entry *ae; struct archive *a; 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)); extract_reference_file(name); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240)); /* Read first entry, which is a regular file. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("xmcd-3.3.2/docs_d/READMf", archive_entry_pathname(ae)); assertEqualString(NULL, archive_entry_hardlink(ae)); assertEqualInt(321, archive_entry_size(ae)); assertEqualInt(1082575645, archive_entry_mtime(ae)); assertEqualInt(1851, archive_entry_uid(ae)); assertEqualInt(3, archive_entry_gid(ae)); assertEqualInt(0100444, archive_entry_mode(ae)); /* Read second entry, which is a hard link at the end of archive. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("xmcd-3.3.2/README", archive_entry_pathname(ae)); assertEqualString( "xmcd-3.3.2/docs_d/READMf", archive_entry_hardlink(ae)); assertEqualInt(0, archive_entry_size(ae)); assertEqualInt(1082575645, archive_entry_mtime(ae)); assertEqualInt(1851, archive_entry_uid(ae)); assertEqualInt(3, archive_entry_gid(ae)); assertEqualInt(0100444, archive_entry_mode(ae)); /* Verify the end-of-archive. */ /* * This failed in libarchive 2.4.12 because the tar reader * tried to obey the size field for the hard link and ended * up running past the end of the file. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); /* Verify that the format detection worked. */ assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_NONE); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR); assertEqualInt(ARCHIVE_OK, archive_read_close(a)); #if ARCHIVE_VERSION_NUMBER < 2000000 archive_read_finish(a); #else assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); #endif }
/* * test_compat_cpio_1.cpio checks heuristics for avoiding false * hardlinks. foo1 and foo2 are files that have nlinks=1 and so * should not be marked as hardlinks even though they have identical * ino values. bar1 and bar2 have nlinks=2 so should be marked * as hardlinks. */ static void test_compat_cpio_1(void) { char name[] = "test_compat_cpio_1.cpio"; struct archive_entry *ae; struct archive *a; assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); extract_reference_file(name); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 17)); /* Read first entry. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("foo1", archive_entry_pathname(ae)); assertEqualString(NULL, archive_entry_hardlink(ae)); assertEqualInt(1260250228, archive_entry_mtime(ae)); assertEqualInt(1000, archive_entry_uid(ae)); assertEqualInt(1000, archive_entry_gid(ae)); assertEqualInt(0100644, archive_entry_mode(ae)); /* Read second entry. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("foo2", archive_entry_pathname(ae)); assertEqualString(NULL, archive_entry_hardlink(ae)); assertEqualInt(1260250228, archive_entry_mtime(ae)); assertEqualInt(1000, archive_entry_uid(ae)); assertEqualInt(1000, archive_entry_gid(ae)); assertEqualInt(0100644, archive_entry_mode(ae)); /* Read third entry. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("bar1", archive_entry_pathname(ae)); assertEqualString(NULL, archive_entry_hardlink(ae)); assertEqualInt(1260250228, archive_entry_mtime(ae)); assertEqualInt(1000, archive_entry_uid(ae)); assertEqualInt(1000, archive_entry_gid(ae)); assertEqualInt(0100644, archive_entry_mode(ae)); /* Read fourth entry. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("bar2", archive_entry_pathname(ae)); assertEqualString("bar1", archive_entry_hardlink(ae)); assertEqualInt(1260250228, archive_entry_mtime(ae)); assertEqualInt(1000, archive_entry_uid(ae)); assertEqualInt(1000, archive_entry_gid(ae)); assertEqualInt(0100644, archive_entry_mode(ae)); /* Verify that the format detection worked. */ assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_SVR4_NOCRC); assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }
static void extract_recovery(char *ramdisk_path) { // Delete everything in the current root DIR *root = opendir("/"); struct dirent *dp; while ((dp = readdir(root)) != NULL) { unlink(dp->d_name); } closedir(root); // Open the ramdisk struct archive *a = archive_read_new(); archive_read_support_filter_lzma(a); archive_read_support_format_cpio(a); if (archive_read_open_filename(a, ramdisk_path, 4096) == ARCHIVE_OK) { // Set up the writer struct archive *ext = archive_write_disk_new(); archive_write_disk_set_options(ext, ARCHIVE_EXTRACT_UNLINK | ARCHIVE_EXTRACT_PERM); chdir("/"); while (1) { struct archive_entry *entry; // Read the next file if (archive_read_next_header(a, &entry) == ARCHIVE_EOF) break; // Create the file archive_write_header(ext, entry); // If the file has data to write... if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) > 0) { const void *block; size_t size; int64_t offset; // Write the blocks until EOF while (1) { if (archive_read_data_block(a, &block, &size, &offset) == ARCHIVE_EOF) break; archive_write_data_block(ext, block, size, offset); } } } archive_write_free(ext); } archive_read_free(a); }
/* * file to memory */ int archive_extract_file2( char *arch_file, const char *src, void **dest_buff, size_t *dest_len ) { const char *filename; struct archive *arch_r = NULL; struct archive_entry *entry; if( !arch_file || !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_filename( arch_r, arch_file, 10240 ) != 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 + 10 ); memset( *dest_buff, 0, *dest_len + 10 ); } 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, "errno:%d, error:%s\n", archive_errno( arch_r ), archive_error_string( arch_r ) ); #endif if( arch_r ) archive_read_finish( arch_r ); return -1; }
static void test_read_format_ustar_filename_KOI8R_CP1251(const char *refname) { struct archive *a; struct archive_entry *ae; /* * Read KOI8-R filename in CP1251 with "hdrcharset=KOI8-R" option. */ if (NULL == setlocale(LC_ALL, "Russian_Russia") && NULL == setlocale(LC_ALL, "ru_RU.CP1251")) { skipping("CP1251 locale not available on this system."); return; } assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) { skipping("This system cannot convert character-set" " from KOI8-R to CP1251."); goto cleanup; } assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); /* Verify regular file. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2", archive_entry_pathname(ae)); assertEqualInt(6, archive_entry_size(ae)); assertEqualInt(archive_entry_is_encrypted(ae), 0); assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); /* Verify regular file. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2", archive_entry_pathname(ae)); assertEqualInt(6, archive_entry_size(ae)); assertEqualInt(archive_entry_is_encrypted(ae), 0); assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); /* End of archive. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); /* Verify archive format. */ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a)); /* Close the archive. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); cleanup: assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }
bool open() { /* Open the animation file. */ this->archive = archive_read_new(); archive_read_support_format_all(this->archive); if (archive_read_open_filename(this->archive, this->path, 10240) != ARCHIVE_OK) { fprintf(stderr, "Failed to open animation archive.\n"); return false; } return true; }
static void test_read_format_ustar_filename_CP866_UTF8(const char *refname) { struct archive *a; struct archive_entry *ae; /* * Read CP866 filename in en_US.UTF-8 with "hdrcharset=CP866" option. */ if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) { skipping("en_US.UTF-8 locale not available on this system."); return; } assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) { skipping("This system cannot convert character-set" " from CP866 to UTF-8."); goto cleanup; } assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); /* Verify regular file. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2", archive_entry_pathname(ae)); assertEqualInt(6, archive_entry_size(ae)); assertEqualInt(archive_entry_is_encrypted(ae), 0); assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); /* Verify regular file. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82", archive_entry_pathname(ae)); assertEqualInt(6, archive_entry_size(ae)); assertEqualInt(archive_entry_is_encrypted(ae), 0); assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); /* End of archive. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); /* Verify archive format. */ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a)); /* Close the archive. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); cleanup: assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }
static void test_read_format_ustar_filename_eucJP_CP932(const char *refname) { struct archive *a; struct archive_entry *ae; /* * Read eucJP filename in CP932/SJIS with "hdrcharset=eucJP" option. */ if (NULL == setlocale(LC_ALL, "Japanese_Japan") && NULL == setlocale(LC_ALL, "ja_JP.SJIS")) { skipping("CP932 locale not available on this system."); return; } assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=eucJP")) { skipping("This system cannot convert character-set" " from eucJP."); goto cleanup; } assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); /* Verify regular file. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("\x8a\xbf\x8e\x9a.txt", archive_entry_pathname(ae)); assertEqualInt(8, archive_entry_size(ae)); assertEqualInt(archive_entry_is_encrypted(ae), 0); assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); /* Verify regular file. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("\x95\x5c.txt", archive_entry_pathname(ae)); assertEqualInt(4, archive_entry_size(ae)); assertEqualInt(archive_entry_is_encrypted(ae), 0); assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED); /* End of archive. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); /* Verify archive format. */ assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0)); assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a)); /* Close the archive. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); cleanup: assertEqualInt(ARCHIVE_OK, archive_read_free(a)); }