int copy_data(struct archive *ar, struct archive *aw) { int r; const void *buff; size_t size; int64_t offset; while(true) { r = archive_read_data_block(ar, &buff, &size, &offset); if (r == ARCHIVE_EOF) { return (ARCHIVE_OK); } if (r < ARCHIVE_OK) { return (r); } r = archive_write_data_block(aw, buff, size, offset); if (r < ARCHIVE_OK) { fprintf(stderr, "%s\n", archive_error_string(aw)); return (r); } } }
static void create_reg_file2(struct archive_entry *ae, const char *msg) { const int datasize = 100000; char *data; struct archive *ad; int i; data = malloc(datasize); for (i = 0; i < datasize; i++) data[i] = (char)(i % 256); /* Write the entry to disk. */ assert((ad = archive_write_disk_new()) != NULL); failure("%s", msg); /* * See above for an explanation why this next call * is necessary. */ archive_entry_set_size(ae, datasize); assertEqualIntA(ad, 0, archive_write_header(ad, ae)); for (i = 0; i < datasize - 999; i += 1000) { assertEqualIntA(ad, ARCHIVE_OK, archive_write_data_block(ad, data + i, 1000, i)); } assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); assertEqualInt(0, archive_write_finish(ad)); /* Test the entries on disk. */ assertIsReg(archive_entry_pathname(ae), archive_entry_mode(ae) & 0777); assertFileSize(archive_entry_pathname(ae), i); assertFileContents(data, datasize, archive_entry_pathname(ae)); free(data); }
static void create_reg_file4(struct archive_entry *ae, const char *msg) { static const char data[]="abcdefghijklmnopqrstuvwxyz"; struct archive *ad; struct stat st; /* Write the entry to disk. */ assert((ad = archive_write_disk_new()) != NULL); /* Leave the size unset. The data should not be truncated. */ assertEqualIntA(ad, 0, archive_write_header(ad, ae)); assertEqualInt(ARCHIVE_OK, archive_write_data_block(ad, data, sizeof(data), 0)); assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); #if ARCHIVE_VERSION_NUMBER < 2000000 archive_write_finish(ad); #else assertEqualInt(0, archive_write_finish(ad)); #endif /* Test the entry on disk. */ assert(0 == stat(archive_entry_pathname(ae), &st)); failure("st.st_mode=%o archive_entry_mode(ae)=%o", st.st_mode, archive_entry_mode(ae)); #if !defined(_WIN32) || defined(__CYGWIN__) assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK)); #endif failure(msg); assertEqualInt(st.st_size, sizeof(data)); }
int copy_data(struct archive* ar, struct archive* aw) { int r; const void* buff; size_t size; #if ARCHIVE_VERSION >= 3000000 int64_t offset; #else off_t offset; #endif for(;;) { r = archive_read_data_block(ar, &buff, &size, &offset); if(r == ARCHIVE_EOF) { return ARCHIVE_OK; } if(r != ARCHIVE_OK) { return (r); } r = archive_write_data_block(aw, buff, size, offset); if(r != ARCHIVE_OK) { printf("archive_write_data_block(): %s", archive_error_string(aw)); return r; } } }
/* * Exits if there's a fatal error. Returns ARCHIVE_OK * if everything is kosher. */ static int extract_data(struct archive *ar, struct archive *aw) { int r; size_t size; const void *block; off_t offset; for (;;) { r = archive_read_data_block(ar, &block, &size, &offset); if (r == ARCHIVE_EOF) return (ARCHIVE_OK); if (r != ARCHIVE_OK) { lafe_warnc(archive_errno(ar), "%s", archive_error_string(ar)); exit(1); } r = archive_write_data_block(aw, block, size, offset); if (r != ARCHIVE_OK) { lafe_warnc(archive_errno(aw), "%s", archive_error_string(aw)); return (r); } } }
// ----------------------------------------------------------------------------- bool copyData(archive* sorc, archive* dest) { DEBUGLOGB; int retc; const void* buff; size_t size; int64_t offs; bool okay = false; while( true ) { if( (retc = archive_read_data_block (sorc, &buff, &size, &offs)) == ARCHIVE_EOF ) { okay = true; break; } if( retc != ARCHIVE_OK ) break; if( (retc = archive_write_data_block(dest, buff, size, offs)) != ARCHIVE_OK ) break; } DEBUGLOGE; return okay; }
static int copy_data(struct archive *ar, struct archive *aw) { int r; const void *buff; size_t size; #if ARCHIVE_VERSION_NUMBER >= 3000000 int64_t offset; #else off_t offset; #endif for (;;) { r = archive_read_data_block(ar, &buff, &size, &offset); if (r == ARCHIVE_EOF) { return ARCHIVE_OK; } if (r != ARCHIVE_OK) { return r; } r = archive_write_data_block(aw, buff, size, offset); if (r != ARCHIVE_OK) { return r; } } return ARCHIVE_OK; }
static int copy_data(struct archive *ar, struct archive *aw) { int r; const void *buff; size_t size; #if ARCHIVE_VERSION >= 3000000 int64_t offset; #else off_t offset; #endif for (;;) { r = archive_read_data_block(ar, &buff, &size, &offset); if (r == ARCHIVE_EOF) return ARCHIVE_OK; if (r != ARCHIVE_OK) return r; r = archive_write_data_block(aw, buff, size, offset); if (r != ARCHIVE_OK) { ereport(WARNING, (errcode(ERRCODE_IO_ERROR), errmsg("%s", archive_error_string(aw)))); return r; } } }
static int copy_data(struct archive *ar, struct archive *aw) { int64_t offset; const void *buff; struct archive_read_extract *extract; size_t size; int r; extract = __archive_read_get_extract((struct archive_read *)ar); if (extract == NULL) return (ARCHIVE_FATAL); for (;;) { r = archive_read_data_block(ar, &buff, &size, &offset); if (r == ARCHIVE_EOF) return (ARCHIVE_OK); if (r != ARCHIVE_OK) return (r); r = (int)archive_write_data_block(aw, buff, size, offset); if (r < ARCHIVE_WARN) r = ARCHIVE_WARN; if (r < ARCHIVE_OK) { archive_set_error(ar, archive_errno(aw), "%s", archive_error_string(aw)); return (r); } if (extract->extract_progress) (extract->extract_progress) (extract->extract_progress_user_data); } }
static int copy_data(struct archive *ar, struct archive *aw) { int r; const void *buff; size_t size; #if ARCHIVE_VERSION_NUMBER >= 3000000 int64_t offset; #else off_t offset; #endif for (;;) { r = archive_read_data_block(ar, &buff, &size, &offset); if (r == ARCHIVE_EOF) return (ARCHIVE_OK); if (r != ARCHIVE_OK) return (r); r = archive_write_data_block(aw, buff, size, offset); if (r != ARCHIVE_OK) { warn("archive_write_data_block()", archive_error_string(aw)); return (r); } } }
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); }
static int archive_copy_data(struct archive* in, struct archive* out) { const void* buf; size_t size; off_t offset; int res = ARCHIVE_OK; while (res == ARCHIVE_OK) { res = archive_read_data_block(in, &buf, &size, &offset); if (res == ARCHIVE_OK) { res = archive_write_data_block(out, buf, size, offset); } } return (res == ARCHIVE_EOF) ? ARCHIVE_OK : res; }
static void create_reg_file2(struct archive_entry *ae, const char *msg) { const int datasize = 100000; char *data; char *compare; struct archive *ad; struct stat st; int i, fd; data = malloc(datasize); for (i = 0; i < datasize; i++) data[i] = (char)(i % 256); /* Write the entry to disk. */ assert((ad = archive_write_disk_new()) != NULL); failure("%s", msg); /* * See above for an explanation why this next call * is necessary. */ archive_entry_set_size(ae, datasize); assertEqualIntA(ad, 0, archive_write_header(ad, ae)); for (i = 0; i < datasize - 999; i += 1000) { assertEqualIntA(ad, ARCHIVE_OK, archive_write_data_block(ad, data + i, 1000, i)); } assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); #if ARCHIVE_API_VERSION > 1 assertEqualInt(0, archive_write_finish(ad)); #else archive_write_finish(ad); #endif /* Test the entries on disk. */ assert(0 == stat(archive_entry_pathname(ae), &st)); failure("st.st_mode=%o archive_entry_mode(ae)=%o", st.st_mode, archive_entry_mode(ae)); assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK)); assertEqualInt(st.st_size, i); compare = malloc(datasize); fd = open(archive_entry_pathname(ae), O_RDONLY); assertEqualInt(datasize, read(fd, compare, datasize)); close(fd); assert(memcmp(compare, data, datasize) == 0); free(compare); free(data); }
static int CopyArchiveData(struct archive *ar, struct archive *aw) { const void *buff; size_t size; __int64 offset; while (true) { int r = archive_read_data_block(ar, &buff, &size, &offset); if (r == ARCHIVE_EOF) return ARCHIVE_OK; if (r != ARCHIVE_OK) return r; r = archive_write_data_block(aw, buff, size, offset); if (r != ARCHIVE_OK) return r; } }
// Based on libarchive's public example code. // https://github.com/libarchive/libarchive/wiki/Examples#wiki-Constructing_Objects_On_Disk ssize_t GuiZipper::copyData(struct archive *ar, struct archive *aw, const char *userDirPath) throw (ZipperException*) { ssize_t r; const void *buff; size_t size; int64_t offset; for (;;) { r = archive_read_data_block(ar, &buff, &size, &offset); if (r == ARCHIVE_EOF) { return (ARCHIVE_OK); } if (r != ARCHIVE_OK) { return (r); } r = archive_write_data_block(aw, buff, size, offset); checkForErrors("Error writing archive data block", ar, r); return r; } }
static int emb_ruby_uncompress_copy_data(struct archive *ar, struct archive *aw) { int r; const void *buff; size_t size; off_t offset; for (;;) { r = archive_read_data_block(ar, &buff, &size, &offset); if (r == ARCHIVE_EOF) return (ARCHIVE_OK); if (r < ARCHIVE_OK) return (r); r = archive_write_data_block(aw, buff, size, offset); if (r < ARCHIVE_OK) { fprintf(stderr, "%s\n", archive_error_string(aw)); return (r); } } }
static int copy_data(struct archive *ar, struct archive *aw) { int r; const void *buff; size_t size; off_t offset; for (;;) { r = archive_read_data_block(ar, &buff, &size, &offset); if (r == ARCHIVE_EOF) return (ARCHIVE_OK); if (r != ARCHIVE_OK) return (r); r = archive_write_data_block(aw, buff, size, offset); if (r != ARCHIVE_OK) { die(archive_error_string(aw)); return (r); } } }
static void copy_archive (struct archive *ar, struct archive *aw) { int r; const void *buff; size_t size; int64_t offset; while (1) { r = archive_read_data_block (ar, &buff, &size, &offset); if (r == ARCHIVE_EOF) break; if (r != ARCHIVE_OK) die_with_libarchive (ar, "archive_write_data_block: %s"); r = archive_write_data_block (aw, buff, size, offset); if (r != ARCHIVE_OK) die_with_libarchive (aw, "archive_write_data_block: %s"); } }
static int copy_data(struct archive* ar, struct archive* aw) { const void* buff; size_t size; off_t offset; for (;;) { int r = archive_read_data_block(ar, &buff, &size, &offset); if (r == ARCHIVE_EOF) { return ARCHIVE_OK; } if (r != ARCHIVE_OK) { return r; } r = archive_write_data_block(aw, buff, size, offset); if (r != ARCHIVE_OK) { errmsg(archive_error_string(ar)); return r; } } return 0; }
int libarchive_copy_data(archive *in, archive *out, archive_entry *entry) { const void *buff; size_t size; int64_t offset; int ret; while ((ret = archive_read_data_block( in, &buff, &size, &offset)) == ARCHIVE_OK) { if (archive_write_data_block(out, buff, size, offset) != ARCHIVE_OK) { LOGE("%s: Failed to write data: %s", archive_entry_pathname(entry), archive_error_string(out)); return ARCHIVE_FAILED; } } if (ret != ARCHIVE_EOF) { LOGE("%s: Data copy ended without reaching EOF: %s", archive_entry_pathname(entry), archive_error_string(in)); return ARCHIVE_FAILED; } return ARCHIVE_OK; }
/* * As above, but using the archive_write_data_block() call. */ static void verify_write_data_block(struct archive *a, int sparse) { static const char data[]="abcdefghijklmnopqrstuvwxyz"; struct stat st; struct archive_entry *ae; size_t buff_size = 64 * 1024; char *buff, *p; const char *msg = sparse ? "sparse" : "non-sparse"; FILE *f; buff = malloc(buff_size); assert(buff != NULL); ae = archive_entry_new(); assert(ae != NULL); archive_entry_set_size(ae, 8 * buff_size); archive_entry_set_pathname(ae, "test_write_data_block"); archive_entry_set_mode(ae, AE_IFREG | 0755); assertEqualIntA(a, 0, archive_write_header(a, ae)); /* Use archive_write_data_block() to write three relatively sparse blocks. */ /* First has non-null data at beginning. */ memset(buff, 0, buff_size); memcpy(buff, data, sizeof(data)); failure("%s", msg); assertEqualInt(ARCHIVE_OK, archive_write_data_block(a, buff, buff_size, 100)); /* Second has non-null data in the middle. */ memset(buff, 0, buff_size); memcpy(buff + buff_size / 2 - 3, data, sizeof(data)); failure("%s", msg); assertEqualInt(ARCHIVE_OK, archive_write_data_block(a, buff, buff_size, buff_size + 200)); /* Third has non-null data at the end. */ memset(buff, 0, buff_size); memcpy(buff + buff_size - sizeof(data), data, sizeof(data)); failure("%s", msg); assertEqualInt(ARCHIVE_OK, archive_write_data_block(a, buff, buff_size, buff_size * 2 + 300)); failure("%s", msg); assertEqualIntA(a, 0, archive_write_finish_entry(a)); /* Test the entry on disk. */ assert(0 == stat(archive_entry_pathname(ae), &st)); assertEqualInt(st.st_size, 8 * buff_size); f = fopen(archive_entry_pathname(ae), "rb"); if (!assert(f != NULL)) return; /* Check 100-byte gap at beginning */ assertEqualInt(100, fread(buff, 1, 100, f)); failure("%s", msg); for (p = buff; p < buff + 100; ++p) { failure("offset: %d, %s", (int)(p - buff), msg); if (!assertEqualInt(0, *p)) break; } /* Check first block. */ assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); failure("%s", msg); assertEqualMem(buff, data, sizeof(data)); for (p = buff + sizeof(data); p < buff + buff_size; ++p) { failure("offset: %d, %s", (int)(p - buff), msg); if (!assertEqualInt(0, *p)) break; } /* Check 100-byte gap */ assertEqualInt(100, fread(buff, 1, 100, f)); failure("%s", msg); for (p = buff; p < buff + 100; ++p) { failure("offset: %d, %s", (int)(p - buff), msg); if (!assertEqualInt(0, *p)) break; } /* Check second block. */ assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); for (p = buff; p < buff + buff_size; ++p) { failure("offset: %d, %s", (int)(p - buff), msg); if (p == buff + buff_size / 2 - 3) { assertEqualMem(p, data, sizeof(data)); p += sizeof(data); } else if (!assertEqualInt(0, *p)) break; } /* Check 100-byte gap */ assertEqualInt(100, fread(buff, 1, 100, f)); failure("%s", msg); for (p = buff; p < buff + 100; ++p) { failure("offset: %d, %s", (int)(p - buff), msg); if (!assertEqualInt(0, *p)) break; } /* Check third block. */ assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); for (p = buff; p < buff + buff_size - sizeof(data); ++p) { failure("offset: %d, %s", (int)(p - buff), msg); if (!assertEqualInt(0, *p)) break; } failure("%s", msg); assertEqualMem(buff + buff_size - sizeof(data), data, sizeof(data)); /* Check another block size beyond last we wrote. */ assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); failure("%s", msg); for (p = buff; p < buff + buff_size; ++p) { failure("offset: %d, %s", (int)(p - buff), msg); if (!assertEqualInt(0, *p)) break; } /* XXX more XXX */ assertEqualInt(0, fclose(f)); free(buff); archive_entry_free(ae); }
//******************************************************************************************************** void read_archive(const char* const infile, const char* const extractFolder){ // Strongly inspired by // https://github.com/libarchive/libarchive/wiki/Examples#A_Complete_Extractor //printf("Opening archive '%s' for extracting to folder '%s'...\n",infile,extractFolder); //Check that the archive exists //Check that the folder exists, if not then create it struct archive* a = archive_read_new(); archive_read_support_format_zip(a); struct archive* ext = archive_write_disk_new(); archive_write_disk_set_options(ext,ARCHIVE_EXTRACT_TIME|ARCHIVE_EXTRACT_PERM|ARCHIVE_EXTRACT_ACL|ARCHIVE_EXTRACT_FFLAGS); archive_write_disk_set_standard_lookup(ext); int err; err = archive_read_open_filename(a, infile, 10240); if (err != ARCHIVE_OK) { fprintf(stderr, "CRITICAL ERROR in read_archive(): When opening archive '%s', err=%i\n",infile,err); fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a)); exit(EXIT_FAILURE); } struct archive_entry *entry; const int fcount_max = 1000; char fcompleted=0; //C-Boolean for(int fcount=0; fcount<fcount_max;fcount++){ err = archive_read_next_header(a,&entry); if (err == ARCHIVE_EOF){ fcompleted=1; break; } else if (err != ARCHIVE_OK){ fprintf(stderr, "CRITICAL ERROR in read_archive(): When reading archive, err=%i\n",err); fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a)); exit(EXIT_FAILURE); } //printf("Found file: '%s'\n",archive_entry_pathname(entry)); //Avoid clobbering files in current directory - solution from // http://stackoverflow.com/questions/4496001/libarchive-to-extract-to-a-specified-folder char newPath[PATH_MAX]; int buff_used = snprintf(newPath, PATH_MAX, "%s/%s",extractFolder,archive_entry_pathname(entry)); if (buff_used >= PATH_MAX || buff_used < 0){ fprintf(stderr, "CRITICAL ERROR in read_archive(): Buffer overflow or other error when creating the path.\n"); fprintf(stderr, "CRITICAL ERROR in read_archive(): buff_used=%i\n",buff_used); exit(EXIT_FAILURE); } archive_entry_set_pathname(entry,newPath); err = archive_write_header(ext, entry); if (err != ARCHIVE_OK){ fprintf(stderr, "CRITICAL ERROR in read_archive(): when extracting archive (creating new file), err=%i\n",err); fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(ext)); exit(EXIT_FAILURE); } //Write the data! const void* buff; size_t size; la_int64_t offset; const int bcount_max = 100000000; char bcompleted = 0; //C boolean for (int bcount=0; bcount<bcount_max;bcount++){ err = archive_read_data_block(a,&buff,&size, &offset); if ( err == ARCHIVE_EOF ) { bcompleted=1; break; } else if (err != ARCHIVE_OK){ fprintf(stderr, "CRITICAL ERROR in read_archive(): When extracting archive (reading data), err=%i\n",err); fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a)); exit(EXIT_FAILURE); } err = archive_write_data_block(ext,buff,size,offset); if (err != ARCHIVE_OK){ fprintf(stderr, "CRITICAL ERROR in read_archive(): When extracting archive (writing data), err=%i\n",err); fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a)); exit(EXIT_FAILURE); } } if (!bcompleted){ fprintf(stderr, "CRITICAL ERROR in read_archive(): The file writing block loop was aborted by the infinite loop guard\n"); exit(EXIT_FAILURE); } err=archive_write_finish_entry(ext); if (err != ARCHIVE_OK) { fprintf(stderr, "CRITICAL ERROR in read_archive(): When extracting archive (closing new file), err=%i\n",err); fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(ext)); exit(EXIT_FAILURE); } } archive_read_close(a); err=archive_read_free(a); if (err != ARCHIVE_OK){ fprintf(stderr, "CRITICAL ERROR in read_archive(): When calling archive_read_free(a), err=%i\n",err); fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a)); exit(EXIT_FAILURE); } archive_write_close(ext); err = archive_write_free(ext); if (err != ARCHIVE_OK){ fprintf(stderr, "CRITICAL ERROR in read_archive(): When calling archive_read_free(ext), err=%i\n",err); fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a)); exit(EXIT_FAILURE); } if (!fcompleted) { fprintf(stderr, "CRITICAL ERROR in read_archive(): The file header loop was aborted by the infinite loop guard\n"); exit(EXIT_FAILURE); } }
bool extract_archive(const char *filename, const char *target) { struct archive *in = NULL; struct archive *out = NULL; struct archive_entry *entry; int ret; char *cwd = NULL; if (!(in = archive_read_new())) { LOGE("Out of memory"); goto error; } // Add more as needed //archive_read_support_format_all(in); //archive_read_support_filter_all(in); archive_read_support_format_tar(in); archive_read_support_format_zip(in); archive_read_support_filter_xz(in); if (archive_read_open_filename(in, filename, 10240) != ARCHIVE_OK) { LOGE("%s: Failed to open archive: %s", filename, archive_error_string(in)); goto error; } if (!(out = archive_write_disk_new())) { LOGE("Out of memory"); goto error; } archive_write_disk_set_options(out, 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); if (!(cwd = getcwd(NULL, 0))) { LOGE("Failed to get cwd: %s", strerror(errno)); goto error; } if (chdir(target) < 0) { LOGE("%s: Failed to change to target directory: %s", target, strerror(errno)); goto error; } while ((ret = archive_read_next_header(in, &entry)) == ARCHIVE_OK) { if ((ret = archive_write_header(out, entry)) != ARCHIVE_OK) { LOGE("Failed to write header: %s", archive_error_string(out)); goto error; } const void *buff; size_t size; int64_t offset; int ret; while ((ret = archive_read_data_block( in, &buff, &size, &offset)) == ARCHIVE_OK) { if (archive_write_data_block(out, buff, size, offset) != ARCHIVE_OK) { LOGE("Failed to write data: %s", archive_error_string(out)); goto error; } } if (ret != ARCHIVE_EOF) { LOGE("Data copy ended without reaching EOF: %s", archive_error_string(in)); goto error; } } if (ret != ARCHIVE_EOF) { LOGE("Archive extraction ended without reaching EOF: %s", archive_error_string(in)); goto error; } chdir(cwd); archive_read_free(in); archive_write_free(out); return true; error: if (cwd) { chdir(cwd); } archive_read_free(in); archive_write_free(out); return false; }
int archive_extract_tar_bzip2(void) { struct archive *a; struct archive *ext; int r = 0; int flags = 0; int error = 0; a = archive_read_new(); archive_read_support_format_tar(a); archive_read_support_compression_bzip2(a); ext = archive_write_disk_new(); archive_write_disk_set_options(ext, flags); if ((r = archive_read_open_file(a, NULL, 10240))) { fprintf(stderr, "archiving: %s", archive_error_string(a)); error = r; } else { for (;;) { struct archive_entry *entry; r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) { break; } if (r != ARCHIVE_OK) { fprintf(stderr, "archiving: %s", archive_error_string(a)); error = 1; break; } if (archive_write_header(ext, entry) != ARCHIVE_OK) { fprintf(stderr, "archiving: %s", archive_error_string(ext)); } else { const void *buff; size_t size; off_t offset; for (;;) { r = archive_read_data_block(a, &buff, &size, &offset); if (r == ARCHIVE_EOF) { r = ARCHIVE_OK; break; } if (r != ARCHIVE_OK) { fprintf(stderr, "archiving: %s", archive_error_string(ext)); break; } r = archive_write_data_block(ext, buff, size, offset); if (r != ARCHIVE_OK) { fprintf(stderr, "archiving: %s", archive_error_string(ext)); break; } } if (r != ARCHIVE_OK) { error = 1; break; } r = archive_write_finish_entry(ext); if (r != ARCHIVE_OK) { fprintf(stderr, "archiving: %s", archive_error_string(ext)); error = 1; break; } } } } archive_read_close(a); archive_read_finish(a); return error; }
void Package::readPackageFile(const std::string &package_path) { if (!package_path.empty()) mPackagePath = package_path; boost::filesystem::path unpacked_dir = mWorkDir; unpacked_dir /= mPackagePath.stem(); mUnpackedDir = unpacked_dir; const void *buf; int r; struct archive *a = archive_read_new(); struct archive_entry *entry; archive_read_support_compression_bzip2(a); archive_read_support_format_tar(a); struct archive *ext = archive_write_disk_new(); 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); r = archive_read_open_filename(a, package_path.c_str(), 16384); if (r != ARCHIVE_OK) { archive_read_free(a); archive_write_free(ext); throw Exception(std::string("archive_read_open_filename() failed for file: ") + package_path); } while (true) { r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) { break; } if (r < ARCHIVE_OK) { std::cerr << archive_error_string(ext) << std::endl; } if (r < ARCHIVE_WARN) { archive_read_free(a); archive_write_free(ext); throw Exception(std::string("archive_read_next_header() failed:") + archive_error_string(a)); } std::cout << std::string("extract: ") << archive_entry_pathname(entry) << std::endl; archive_entry_set_pathname(entry, (mUnpackedDir.string() + std::string("/") + archive_entry_pathname(entry)).c_str()); r = archive_write_header(ext, entry); if (r < ARCHIVE_OK) { archive_read_free(a); archive_write_free(ext); throw Exception(std::string("archive_write_header() failed:") + archive_error_string(ext)); } else if (archive_entry_size(entry) > 0) { size_t size; int64_t offset; while (true) { r = archive_read_data_block(a, &buf, &size, &offset); if (r == ARCHIVE_EOF) break; if (r < ARCHIVE_WARN) { archive_read_free(a); archive_write_free(ext); throw Exception(std::string(archive_error_string(ext))); } if (r < ARCHIVE_OK) { std::cerr << archive_error_string(ext) << std::endl; break; } r = archive_write_data_block(ext, buf, size, offset); if (r < ARCHIVE_WARN) { archive_read_free(a); archive_write_free(ext); throw Exception(std::string(archive_error_string(ext))); } if (r < ARCHIVE_OK) { std::cerr << archive_error_string(ext) << std::endl; break; } } r = archive_write_finish_entry(ext); if (r < ARCHIVE_OK) std::cerr << archive_error_string(ext) << std::endl; if (r < ARCHIVE_WARN) { archive_read_free(a); archive_write_free(ext); throw Exception(std::string(archive_error_string(ext))); } } } archive_read_close(a); archive_read_free(a); archive_write_close(ext); archive_write_free(ext); }