// Based on libarchive's public example code. // https://github.com/libarchive/libarchive/wiki/Examples#wiki-A_Basic_Write_Example void GuiZipper::packageFiles(const char *outputFile, const char *baseDir, char **filenames, int numFiles, bool binary, const char *absMetaFilename, const char *metaFilename) throw (ZipperException*) { int r; struct archive *a = archive_write_new(); r = archive_write_add_filter_gzip(a); checkForErrors("Error adding filter gzip", a, r); r = archive_write_set_format_pax_restricted(a); checkForErrors("Error setting format pax restricted", a, r); r = archive_write_open_filename(a, outputFile); checkForErrors("Error opening file", a, r); packageSingleFile(absMetaFilename, metaFilename, a, false); for (int x = 0; x < numFiles; x++) { char *filename = filenames[x]; char *filePath = fileManager_->getFilePath(baseDir, filename); try { packageSingleFile(filePath, filename, a, binary); } catch (ZipperException *ze) { delete filePath; throw ze; } delete filePath; } r = archive_write_close(a); checkForErrors("Error writing close", a, r); r = archive_write_free(a); checkForErrors("Error writing free", a, r); }
int write_archive_from_mem(char *outname, MagickWand *wand) { int archiveSize = 0; int pageNumber = 1; struct archive *a; struct archive_entry *entry; a = archive_write_new(); archive_write_set_format_ustar(a); archive_write_open_filename(a, outname); char filename[13]; MagickResetIterator(wand); MagickNextImage(wand); // Has to be called after MagickResetIterator to set the first picture as the current do { unsigned char *data; size_t size; data = MagickWriteImageBlob(wand, &size); entry = archive_entry_new(); snprintf(filename, 13, "page_%d", pageNumber++); archive_entry_set_pathname(entry, filename); archive_entry_set_size(entry, size); archive_entry_set_filetype(entry, AE_IFREG); archive_entry_set_perm(entry, 0644); archive_write_header(a, entry); archiveSize += archive_write_data(a, data, size); archive_entry_free(entry); } while (MagickNextImage(wand)); archive_write_close(a); archive_write_free(a); return archiveSize; }
void write_archive(const char *outname, const char **filename) { struct archive *a; struct archive_entry *entry; struct stat st; char buff[8192]; int len; FILE* fd; a = archive_write_new(); //archive_write_add_filter_gzip(a); //archive_write_set_format_pax_restricted(a); // Note 1 archive_write_set_format_zip(a); //archive_write_add_filter_none(a); archive_write_open_filename(a, outname); while (*filename) { stat(*filename, &st); entry = archive_entry_new(); // Note 2 myarch_set_entry( *filename, st.st_size, entry); archive_write_header(a, entry); fd = fopen(*filename, "rb"); printf("Read File %s return fd %p\n", *filename, fd); while ((len = fread(buff, 1, sizeof(buff), fd)) > 0) { printf(" len %d\n", len); archive_write_data(a, buff, len); } fclose(fd); archive_entry_free(entry); filename++; } archive_write_close(a); // Note 4 archive_write_finish(a); // Note 5 }
void write_archive(const char *outname, const char **filename) { struct archive *a; struct archive_entry *entry; struct stat st; char buff[8192]; int len; int fd; a = archive_write_new(); archive_write_set_compression_gzip(a); archive_write_set_format_pax_restricted(a); // Note 1 archive_write_open_filename(a, outname, 10240); while (*filename) { stat(*filename, &st); entry = archive_entry_new(); // Note 2 archive_entry_set_pathname(entry, *filename); archive_entry_set_size(entry, st.st_size); // Note 3 archive_entry_set_filetype(entry, AE_IFREG); archive_entry_set_perm(entry, 0644); archive_write_header(a, entry); fd = open(*filename, O_RDONLY); len = read(fd, buff, sizeof(buff)); while ( len > 0 ) { archive_write_data(a, buff, len); len = read(fd, buff, sizeof(buff)); } close(fd); archive_entry_free(entry); filename++; } archive_write_close(a); // Note 4 archive_write_free(a); // Note 5 }
int StudioFrame::CreateZip(std::string zfile, std::vector<std::string> files) { struct archive *zip; zip = archive_write_new(); if (zip == NULL) { wxMessageBox(_("archive_write_new error")); return -1; } archive_write_set_format_zip(zip); // archive_write_zip_set_compression_store(zip); archive_write_open_filename(zip, zfile.c_str()); if (WriteDefsToZip(zip)) { archive_write_close(zip); archive_write_finish(zip); return -1; } for (size_t i=0; i<files.size(); i++) { if (WriteFileToZip(zip, files[i])) { archive_write_close(zip); archive_write_finish(zip); return -1; } } archive_write_close(zip); archive_write_finish(zip); return 0; }
int packing_init(struct packing **pack, const char *path, pkg_formats format) { char archive_path[MAXPATHLEN]; const char *ext; assert(pack != NULL); if ((*pack = calloc(1, sizeof(struct packing))) == NULL) { pkg_emit_errno("calloc", "packing"); return (EPKG_FATAL); } (*pack)->aread = archive_read_disk_new(); archive_read_disk_set_standard_lookup((*pack)->aread); archive_read_disk_set_symlink_physical((*pack)->aread); if (!is_dir(path)) { (*pack)->pass = false; (*pack)->awrite = archive_write_new(); archive_write_set_format_pax_restricted((*pack)->awrite); ext = packing_set_format((*pack)->awrite, format); if (ext == NULL) { archive_read_close((*pack)->aread); archive_read_free((*pack)->aread); archive_write_close((*pack)->awrite); archive_write_free((*pack)->awrite); *pack = NULL; return EPKG_FATAL; /* error set by _set_format() */ } snprintf(archive_path, sizeof(archive_path), "%s.%s", path, ext); pkg_debug(1, "Packing to file '%s'", archive_path); if (archive_write_open_filename( (*pack)->awrite, archive_path) != ARCHIVE_OK) { pkg_emit_errno("archive_write_open_filename", archive_path); archive_read_close((*pack)->aread); archive_read_free((*pack)->aread); archive_write_close((*pack)->awrite); archive_write_free((*pack)->awrite); *pack = NULL; return EPKG_FATAL; } } else { /* pass mode directly write to the disk */ pkg_debug(1, "Packing to directory '%s' (pass mode)", path); (*pack)->pass = true; (*pack)->awrite = archive_write_disk_new(); archive_write_disk_set_options((*pack)->awrite, EXTRACT_ARCHIVE_FLAGS); } (*pack)->resolver = archive_entry_linkresolver_new(); archive_entry_linkresolver_set_strategy((*pack)->resolver, ARCHIVE_FORMAT_TAR_PAX_RESTRICTED); return (EPKG_OK); }
int createArchiveofFilesPC(char** files, unsigned long * size, unsigned int fileCount, const char* filename, const char* tarHostDir) { unsigned int ctr = 0; struct timespec ts; struct archive_entry* entry; struct archive* archive = archive_write_new(); int dirlen = strlen(tarHostDir); if ((archive_write_set_compression_gzip(archive) != ARCHIVE_OK) || (archive_write_set_format_ustar(archive) != ARCHIVE_OK) || (archive_write_open_filename(archive, filename) != ARCHIVE_OK)) { printf("%s\n", archive_error_string(archive)); return -1; } int tarHostDirLen = strlen(tarHostDir); for (ctr = 0; ctr < fileCount; ctr++) { entry = archive_entry_new(); clock_gettime(CLOCK_REALTIME, &ts); //Set entry to be stored under the tarHostDir directory const char* path = files[ctr]; int pathlength = dirlen + strlen(path) + 2; //One for / and the other for '\0' char newPath[pathlength]; if(tarHostDirLen>0) snprintf(newPath, pathlength, "%s/%s", tarHostDir, boost::filesystem::path(path).filename().c_str()); else snprintf(newPath, pathlength, "%s", boost::filesystem::path(path).filename().c_str()); archive_entry_set_pathname(entry, newPath); archive_entry_set_size(entry, size[ctr]); archive_entry_set_filetype(entry, AE_IFREG); archive_entry_set_perm(entry, 0444); archive_entry_set_atime(entry, ts.tv_sec, ts.tv_nsec); archive_entry_set_birthtime(entry, ts.tv_sec, ts.tv_nsec); archive_entry_set_ctime(entry, ts.tv_sec, ts.tv_nsec); archive_entry_set_mtime(entry, ts.tv_sec, ts.tv_nsec); int rc = archive_write_header(archive, entry); char *contents = new char[size[ctr]+1]; FILE* fp = fopen(files[ctr],"rb"); fread((void *)contents, size[ctr], 1, fp); fclose(fp); archive_write_data(archive, contents, size[ctr]); archive_entry_free(entry); entry = NULL; delete[] contents; if (ARCHIVE_OK != rc) { printf("%s\n", archive_error_string(archive)); return -1; } } archive_write_finish(archive); }
static gboolean asb_utils_write_archive (const gchar *filename, const gchar *path_orig, GPtrArray *files, GError **error) { const gchar *tmp; gboolean ret = TRUE; gsize len; guint i; struct archive *a; struct archive_entry *entry; struct stat st; a = archive_write_new (); if (g_str_has_suffix (filename, ".gz")) { archive_write_add_filter_gzip (a); archive_write_set_filter_option (a, "gzip", "timestamp", NULL); } if (g_str_has_suffix (filename, ".bz2")) archive_write_add_filter_bzip2 (a); if (g_str_has_suffix (filename, ".xz")) archive_write_add_filter_xz (a); archive_write_set_format_pax_restricted (a); archive_write_open_filename (a, filename); for (i = 0; i < files->len; i++) { g_autofree gchar *data = NULL; g_autofree gchar *filename_full = NULL; tmp = g_ptr_array_index (files, i); filename_full = g_build_filename (path_orig, tmp, NULL); if (stat (filename_full, &st) != 0) continue; entry = archive_entry_new (); archive_entry_set_pathname (entry, tmp); archive_entry_set_size (entry, st.st_size); archive_entry_set_filetype (entry, AE_IFREG); archive_entry_set_perm (entry, 0644); archive_write_header (a, entry); ret = g_file_get_contents (filename_full, &data, &len, error); if (!ret) { archive_entry_free (entry); break; } archive_write_data (a, data, len); archive_entry_free (entry); } archive_write_close (a); archive_write_free (a); return ret; }
void write_archive(const char *outname, const char **filename) { struct archive *a; a = archive_write_new(); archive_write_set_format_zip(a); archive_write_open_filename(a, outname); while(*filename) { file_to_archive(a, *filename); filename++; } archive_write_close(a); archive_write_free(a); }
void tar_mode_c(struct bsdtar *bsdtar) { struct archive *a; const void *filter_name; int r; if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL) lafe_errc(1, 0, "no files or directories specified"); a = archive_write_new(); /* Support any format that the library supports. */ if (cset_get_format(bsdtar->cset) == NULL) { r = archive_write_set_format_pax_restricted(a); cset_set_format(bsdtar->cset, "pax restricted"); } else { r = archive_write_set_format_by_name(a, cset_get_format(bsdtar->cset)); } if (r != ARCHIVE_OK) { fprintf(stderr, "Can't use format %s: %s\n", cset_get_format(bsdtar->cset), archive_error_string(a)); usage(); } archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block); archive_write_set_bytes_in_last_block(a, bsdtar->bytes_in_last_block); r = cset_write_add_filters(bsdtar->cset, a, &filter_name); if (r < ARCHIVE_WARN) { lafe_errc(1, 0, "Unsupported compression option --%s", (const char *)filter_name); } set_writer_options(bsdtar, a); if (bsdtar->passphrase != NULL) r = archive_write_set_passphrase(a, bsdtar->passphrase); else r = archive_write_set_passphrase_callback(a, bsdtar, &passphrase_callback); if (r != ARCHIVE_OK) lafe_errc(1, 0, "%s", archive_error_string(a)); if (ARCHIVE_OK != archive_write_open_filename(a, bsdtar->filename)) lafe_errc(1, 0, "%s", archive_error_string(a)); write_archive(a, bsdtar); }
static int archive_conv_open(struct archive_conv *conv, const struct repo_t *repo) { int r; /* generally, repo files are gzip compressed, but there's no guarantee of * this. in order to be compression-agnostic, use libarchive's reader/writer * methods. this also gives us an opportunity to rewrite the archive as CPIO, * which is marginally faster given our staunch sequential access. */ conv->reponame = repo->name; stpcpy(stpcpy(conv->tmpfile, repo->diskfile), "~"); conv->in = archive_read_new(); conv->out = archive_write_new(); if (conv->in == NULL || conv->out == NULL) { fputs("error: failed to allocate memory for archive objects\n", stderr); return -ENOMEM; } archive_read_support_format_tar(conv->in); archive_read_support_filter_all(conv->in); r = archive_read_open_fd(conv->in, repo->tmpfile.fd, BUFSIZ); if (r != ARCHIVE_OK) { fprintf(stderr, "error: failed to create archive reader for %s: %s\n", repo->name, strerror(archive_errno(conv->in))); r = archive_errno(conv->in); goto open_error; } archive_write_set_format_cpio_newc(conv->out); archive_write_add_filter(conv->out, repo->config->compress); r = archive_write_open_filename(conv->out, conv->tmpfile); if (r != ARCHIVE_OK) { fprintf(stderr, "error: failed to open file for writing: %s: %s\n", conv->tmpfile, strerror(archive_errno(conv->out))); r = archive_errno(conv->out); goto open_error; } return 0; open_error: archive_write_free(conv->out); archive_read_free(conv->in); return -r; }
int packing_init(struct packing **pack, const char *path, pkg_formats format) { char archive_path[MAXPATHLEN]; const char *ext; assert(pack != NULL); *pack = xcalloc(1, sizeof(struct packing)); (*pack)->aread = archive_read_disk_new(); archive_read_disk_set_standard_lookup((*pack)->aread); archive_read_disk_set_symlink_physical((*pack)->aread); (*pack)->awrite = archive_write_new(); archive_write_set_format_pax_restricted((*pack)->awrite); ext = packing_set_format((*pack)->awrite, format); if (ext == NULL) { archive_read_close((*pack)->aread); archive_read_free((*pack)->aread); archive_write_close((*pack)->awrite); archive_write_free((*pack)->awrite); *pack = NULL; return EPKG_FATAL; /* error set by _set_format() */ } snprintf(archive_path, sizeof(archive_path), "%s.%s", path, ext); pkg_debug(1, "Packing to file '%s'", archive_path); if (archive_write_open_filename( (*pack)->awrite, archive_path) != ARCHIVE_OK) { pkg_emit_errno("archive_write_open_filename", archive_path); archive_read_close((*pack)->aread); archive_read_free((*pack)->aread); archive_write_close((*pack)->awrite); archive_write_free((*pack)->awrite); *pack = NULL; return EPKG_FATAL; } (*pack)->resolver = archive_entry_linkresolver_new(); archive_entry_linkresolver_set_strategy((*pack)->resolver, archive_format((*pack)->awrite)); return (EPKG_OK); }
Writer *Writer::write_open_filename(const char *filename, int compression, int format) { std::string error_msg; struct archive *ar = archive_write_new(); try { switch(compression) { case Archive::COMPRESSION_BZIP2: archive_write_add_filter_bzip2(ar); break; case Archive::COMPRESSION_COMPRESS: archive_write_add_filter_compress(ar); break; case Archive::COMPRESSION_GZIP: archive_write_add_filter_gzip(ar); break; case Archive::COMPRESSION_LZMA: archive_write_add_filter_lzma(ar); break; case Archive::COMPRESSION_NONE: archive_write_add_filter_none(ar); break; case Archive::COMPRESSION_XZ: archive_write_add_filter_xz(ar); break; default: error_msg = "unknown or unsupported compression scheme"; throw Error(error_msg); } set_format_helper(ar, format); if(archive_write_open_filename(ar, filename) != ARCHIVE_OK) { error_msg = archive_error_string(ar); throw Error(error_msg); } } catch(...) { archive_write_free(ar); throw; } return new Writer(ar); }
void errorReporterClose(ErrorReporter self) { #if HAVE_LIBARCHIVE struct archive* outArchive; CharString outputFilename = newCharString(); LinkedList reportContents = newLinkedList(); #endif // Always do this, just in case flushErrorLog(); #if HAVE_LIBARCHIVE // In case any part of the error report causes a segfault, this function will // be called recursively. A mutex would really be a better solution here, but // this will also work just fine. if(!self->completed) { self->completed = true; buildAbsolutePath(self->desktopPath, self->reportName, "tar.gz", outputFilename); listDirectory(self->reportDirPath->data, reportContents); if(self != NULL) { outArchive = archive_write_new(); archive_write_set_compression_gzip(outArchive); archive_write_set_format_pax_restricted(outArchive); archive_write_open_filename(outArchive, outputFilename->data); linkedListForeach(reportContents, _remapFileToErrorReportRelativePath, self); chdir(self->desktopPath->data); linkedListForeach(reportContents, _addFileToArchive, outArchive); archive_write_close(outArchive); archive_write_free(outArchive); } // Remove original error report removeDirectory(self->reportDirPath); } #endif printf("\n=== Error report complete ===\n"); printf("Created error report at %s\n", self->reportDirPath->data); #if HAVE_LIBARCHIVE printf("Please email the report to: %s\n", SUPPORT_EMAIL); #else printf("Please compress and email the report to: %s\n", SUPPORT_EMAIL); #endif printf("Thanks!\n"); }
Status Carver::compress(const std::set<boost::filesystem::path>& paths) { auto arch = archive_write_new(); if (arch == nullptr) { return Status(1, "Failed to create tar archive"); } // Zipping doesn't seem to be working currently // archive_write_set_format_zip(arch); archive_write_set_format_pax_restricted(arch); auto ret = archive_write_open_filename(arch, archivePath_.string().c_str()); if (ret == ARCHIVE_FATAL) { archive_write_free(arch); return Status(1, "Failed to open tar archive for writing"); } for (const auto& f : paths) { PlatformFile pFile(f.string(), PF_OPEN_EXISTING | PF_READ); auto entry = archive_entry_new(); archive_entry_set_pathname(entry, f.leaf().string().c_str()); archive_entry_set_size(entry, pFile.size()); archive_entry_set_filetype(entry, AE_IFREG); archive_entry_set_perm(entry, 0644); // archive_entry_set_atime(); // archive_entry_set_ctime(); // archive_entry_set_mtime(); archive_write_header(arch, entry); // TODO: Chunking or a max file size. std::ifstream in(f.string(), std::ios::binary); std::stringstream buffer; buffer << in.rdbuf(); archive_write_data(arch, buffer.str().c_str(), buffer.str().size()); in.close(); archive_entry_free(entry); } archive_write_free(arch); PlatformFile archFile(archivePath_.string(), PF_OPEN_EXISTING | PF_READ); updateCarveValue(carveGuid_, "size", std::to_string(archFile.size())); updateCarveValue( carveGuid_, "sha256", hashFromFile(HashType::HASH_TYPE_SHA256, archivePath_.string())); return Status(0, "Ok"); };
static void create_archive(const char *filepath, const char *tarfile) { struct archive *a; struct archive_entry *entry; struct stat st; char buff[8192]; int len; int fd; char **filenames, **filename; filenames = list_filenames(filepath); filename = filenames; a = archive_write_new(); archive_write_set_compression_bzip2(a); archive_write_set_format_ustar(a); archive_write_open_filename(a, tarfile); while (*filename) { stat(*filename, &st); entry = archive_entry_new(); archive_entry_set_pathname(entry, *filename); archive_entry_set_size(entry, st.st_size); archive_entry_set_filetype(entry, AE_IFREG); archive_entry_set_perm(entry, 0644); archive_write_header(a, entry); fd = open(*filename, O_RDONLY); len = read(fd, buff, sizeof(buff)); while ( len > 0 ) { archive_write_data(a, buff, len); len = read(fd, buff, sizeof(buff)); } close(fd); archive_entry_free(entry); filename++; } free_str_array(filenames); archive_write_close(a); #if ARCHIVE_VERSION_NUMBER < 4000000 archive_write_finish(a); #else archive_write_free(a); #endif }
void Package::pack() { struct archive *a; char buf[8192]; std::string package_base_filename(mManifest.packageName() + "-" + std::to_string(mManifest.packageVersion()) + "-" + mManifest.targetArch()); std::string tbz2_path = mWorkDir.string() + "/" + package_base_filename + ".rps"; a = archive_write_new(); archive_write_add_filter_bzip2(a); archive_write_set_format_pax_restricted(a); archive_write_open_filename(a, tbz2_path.c_str()); struct stat st; struct archive_entry *entry; for (auto &f: mManifest.files()) { std::string source = mUnpackedDir.string() + std::string("/data/") + f.name(); std::string dest = std::string("data/") + f.name(); stat(source.c_str(), &st); entry = archive_entry_new(); archive_entry_set_pathname(entry, dest.c_str()); archive_entry_set_size(entry, st.st_size); archive_entry_set_filetype(entry, AE_IFREG); archive_entry_set_perm(entry, 0644); archive_write_header(a, entry); int fd = open(source.c_str(), O_RDONLY); int len = read(fd, buf, sizeof(buf)); while (len > 0) { archive_write_data(a, buf, len); len = read(fd, buf, sizeof(buf)); } close(fd); archive_entry_free(entry); } archive_write_close(a); archive_write_free(a); }
/* * Initialize archive structure and create a shar archive. */ static struct archive * shar_create(void) { struct archive *a; if ((a = archive_write_new()) == NULL) errx(EXIT_FAILURE, "%s", archive_error_string(a)); if (b_opt) archive_write_set_format_shar_dump(a); else archive_write_set_format_shar(a); archive_write_set_compression_none(a); if (archive_write_open_filename(a, o_arg) != ARCHIVE_OK) errx(EX_CANTCREAT, "%s", archive_error_string(a)); return (a); }
int createArchiveofFiles(char** files, unsigned long * size, unsigned int fileCount, const char* filename) { unsigned int ctr = 0; struct timespec ts; struct archive_entry* entry; struct archive* archive = archive_write_new(); if ((archive_write_set_compression_gzip(archive) != ARCHIVE_OK) || (archive_write_set_format_ustar(archive) != ARCHIVE_OK) || (archive_write_open_filename(archive, filename) != ARCHIVE_OK)) { printf("%s\n", archive_error_string(archive)); return -1; } for (ctr = 0; ctr < fileCount; ctr++) { entry = archive_entry_new(); clock_gettime(CLOCK_REALTIME, &ts); archive_entry_set_pathname(entry, files[ctr]); archive_entry_set_size(entry, size[ctr]); archive_entry_set_filetype(entry, AE_IFREG); archive_entry_set_perm(entry, 0444); archive_entry_set_atime(entry, ts.tv_sec, ts.tv_nsec); archive_entry_set_birthtime(entry, ts.tv_sec, ts.tv_nsec); archive_entry_set_ctime(entry, ts.tv_sec, ts.tv_nsec); archive_entry_set_mtime(entry, ts.tv_sec, ts.tv_nsec); int rc = archive_write_header(archive, entry); char *contents = new char[size[ctr]+1]; FILE* fp = fopen(files[ctr],"rb"); fread((void *)contents, size[ctr], 1, fp); fclose(fp); archive_write_data(archive, contents, size[ctr]); archive_entry_free(entry); entry = NULL; delete[] contents; if (ARCHIVE_OK != rc) { printf("%s\n", archive_error_string(archive)); return -1; } } archive_write_finish(archive); }
Writer *Writer::write_open_filename(const char *filename, const char *cmd, int format) { std::string error_msg; struct archive *ar = archive_write_new(); archive_write_add_filter_program(ar, cmd); try { set_format_helper(ar, format); if(archive_write_open_filename(ar, filename) != ARCHIVE_OK) { error_msg = archive_error_string(ar); throw Error(error_msg); } } catch(...) { archive_write_free(ar); throw; } return new Writer(ar); }
// This function will create a gzipped tar file (outname) // which contains the files matched by the function pattern_match. // Pattern_match should return 0 on no match and 1 on match. int create_archive(char *outname, char *path, const std::vector<std::string> &filenames) { struct archive *a; struct archive_entry *entry; struct stat st; char buff[BUFFER_SIZE]; int len; int fd; a = archive_write_new(); archive_write_set_compression_gzip(a); archive_write_set_format_pax_restricted(a); archive_write_open_filename(a, outname); for (unsigned int i=0;i<filenames.size();i++) { stat(filenames[i].c_str(), &st); entry = archive_entry_new(); archive_entry_set_pathname(entry, filenames[i].c_str()); archive_entry_set_size(entry, st.st_size); archive_entry_set_filetype(entry, AE_IFREG); archive_entry_set_perm(entry, 0644); archive_write_header(a, entry); fd = open(filenames[i].c_str(), O_RDONLY); len = read(fd, buff, sizeof(buff)); while (len > 0) { archive_write_data(a, buff, len); len = read(fd, buff, sizeof(buff)); } close(fd); } archive_write_close(a); archive_write_finish(a); return 0; }
int packing_init(struct packing **pack, const char *path, pkg_formats format) { char archive_path[MAXPATHLEN]; const char *ext; if ((*pack = calloc(1, sizeof(struct packing))) == NULL) { pkg_emit_event(PKG_EVENT_MALLOC_ERROR, /*argc*/1, strerror(errno)); } (*pack)->aread = archive_read_disk_new(); archive_read_disk_set_standard_lookup((*pack)->aread); archive_read_disk_set_symlink_physical((*pack)->aread); (*pack)->entry = archive_entry_new(); if (!is_dir(path)) { (*pack)->awrite = archive_write_new(); archive_write_set_format_pax_restricted((*pack)->awrite); if ((ext = packing_set_format((*pack)->awrite, format)) == NULL) { archive_read_finish((*pack)->aread); archive_write_finish((*pack)->awrite); archive_entry_free((*pack)->entry); return EPKG_FATAL; /* error set by _set_format() */ } snprintf(archive_path, sizeof(archive_path), "%s.%s", path, ext); archive_write_open_filename((*pack)->awrite, archive_path); } else { /* pass mode directly write to the disk */ (*pack)->awrite = archive_write_disk_new(); archive_write_disk_set_options((*pack)->awrite, EXTRACT_ARCHIVE_FLAGS); } return (EPKG_OK); }
int archive_write_open_file(struct archive *a, const char *filename) { return (archive_write_open_filename(a, filename)); }
static int process_package(rpmts ts, char * filename) { FD_t fdi; FD_t gzdi; Header h; int rc = 0; char * rpmio_flags = NULL; struct archive *a; struct archive_entry *entry; if (!strcmp(filename, "-")) { fdi = fdDup(STDIN_FILENO); } else { fdi = Fopen(filename, "r.ufdio"); } if (Ferror(fdi)) { fprintf(stderr, "rpm2archive: %s: %s\n", filename, Fstrerror(fdi)); exit(EXIT_FAILURE); } rc = rpmReadPackageFile(ts, fdi, "rpm2cpio", &h); switch (rc) { case RPMRC_OK: case RPMRC_NOKEY: case RPMRC_NOTTRUSTED: break; case RPMRC_NOTFOUND: fprintf(stderr, _("argument is not an RPM package\n")); exit(EXIT_FAILURE); break; case RPMRC_FAIL: default: fprintf(stderr, _("error reading header from package\n")); exit(EXIT_FAILURE); break; } /* Retrieve payload size and compression type. */ { const char *compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR); rpmio_flags = rstrscat(NULL, "r.", compr ? compr : "gzip", NULL); } gzdi = Fdopen(fdi, rpmio_flags); /* XXX gzdi == fdi */ free(rpmio_flags); if (gzdi == NULL) { fprintf(stderr, _("cannot re-open payload: %s\n"), Fstrerror(gzdi)); exit(EXIT_FAILURE); } rpmfiles files = rpmfilesNew(NULL, h, 0, RPMFI_KEEPHEADER); rpmfi fi = rpmfiNewArchiveReader(gzdi, files, RPMFI_ITER_READ_ARCHIVE_CONTENT_FIRST); /* create archive */ a = archive_write_new(); archive_write_add_filter_gzip(a); archive_write_set_format_pax_restricted(a); if (!strcmp(filename, "-")) { if (isatty(STDOUT_FILENO)) { fprintf(stderr, "Error: refusing to output archive data to a terminal.\n"); exit(EXIT_FAILURE); } archive_write_open_fd(a, STDOUT_FILENO); } else { char * outname = rstrscat(NULL, filename, ".tgz", NULL); archive_write_open_filename(a, outname); _free(outname); // XXX error handling } entry = archive_entry_new(); char * buf = xmalloc(BUFSIZE); char * hardlink = NULL; rc = 0; while (rc >= 0) { rc = rpmfiNext(fi); if (rc == RPMERR_ITER_END) { break; } rpm_mode_t mode = rpmfiFMode(fi); int nlink = rpmfiFNlink(fi); fill_archive_entry(a, entry, fi); if (nlink > 1) { if (rpmfiArchiveHasContent(fi)) { _free(hardlink); hardlink = rstrscat(NULL, ".", rpmfiFN(fi), NULL); } else { archive_entry_set_hardlink(entry, hardlink); } } archive_write_header(a, entry); if (S_ISREG(mode) && (nlink == 1 || rpmfiArchiveHasContent(fi))) { write_file_content(a, buf, fi); } } /* End of iteration is not an error */ if (rc == RPMERR_ITER_END) { rc = 0; } _free(hardlink); Fclose(gzdi); /* XXX gzdi == fdi */ archive_entry_free(entry); archive_write_close(a); archive_write_free(a); buf = _free(buf); rpmfilesFree(files); rpmfiFree(fi); headerFree(h); return rc; }
//******************************************************************************************************** void write_archive(const char* const outname, char** filename, int nFiles) { // Adapted from // https://github.com/libarchive/libarchive/wiki/Examples#A_Basic_Write_Example struct archive *a; struct archive_entry *entry; struct stat st; int err; char buff[8192]; int len; FILE* fd; //printf("Writing outname='%s'\n",outname); a = archive_write_new(); //Constructs the archive in memory? If so, may be problematic for large archives. //For tar.gz: // archive_write_add_filter_gzip(a); // archive_write_set_format_pax_restricted(a); // Note 1 //For .zip: archive_write_set_format_zip(a); archive_write_open_filename(a, outname); entry = archive_entry_new(); for (int i=0;i<nFiles;i++){ //printf("Compressing filename='%s'... ",filename[i]); //Write the header #ifdef __WIN32 LARGE_INTEGER filesize_union; HANDLE hFile = CreateFile(filename[i], GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) continue; if(!GetFileSizeEx(hFile, &filesize_union)) { fprintf(stderr, "CRITICAL ERROR in write_archive(): GetFileSizeEx failed."); exit(EXIT_FAILURE); } CloseHandle(hFile); LONGLONG filesize = filesize_union.QuadPart; #else off_t filesize = 0; err = stat(filename[i], &st); //printf("stat reported err=%i\n", err); if(err != 0) continue; filesize = st.st_size; #endif archive_entry_set_pathname(entry, filename[i]); archive_entry_set_size(entry, filesize); archive_entry_set_filetype(entry, AE_IFREG); archive_entry_set_perm(entry, 0644); archive_write_header(a, entry); //Write the data int len_total = 0; fd = fopen(filename[i], "rb"); len = fread(buff, 1,sizeof(buff), fd); len_total = len; while ( len > 0 ) { err=archive_write_data(a, buff, len); if (err < 0){ fprintf(stderr, "CRITICAL ERROR in write_archive(): When writing file, got err=%i\n",err); fprintf(stderr, "CRITICAL ERROR in write_archive(): %s\n",archive_error_string(a)); exit(EXIT_FAILURE); } len = fread(buff, 1,sizeof(buff), fd); len_total += len; } fclose(fd); archive_entry_clear(entry); //printf("Wrote file '%s', len_total = %i, filesize = %i\n", filename[i], len_total, filesize); if (len_total != filesize) { fprintf(stderr, "CRITICAL ERROR in write_archive(): When writing file '%s', got len_total = %i but filesize = %i\n", filename[i], len_total, filesize); } } archive_entry_free(entry); //printf("Complete!\n"); archive_write_close(a); // Note 4 archive_write_free(a); // called archive_write_finish() in old versions of libarchive }
RESULTCODE ArchiveProcessorImpl::Compress() { const char* tpath = GetArchivePath(); if(tpath==NULL) { return AG_FAILURE; } struct archive *a; struct archive_entry *entry; struct stat st; char buff[AUGE_BUFFER_MAX]; int len; int fd; a = archive_write_new(); if(a==NULL) { return AG_FAILURE; } //archive_write_add_filter_gzip(a); archive_write_set_format_zip(a); archive_write_set_format_pax_restricted(a); archive_write_open_filename(a,tpath); const char* fpath = NULL; char name[AUGE_NAME_MAX]; char ext[AUGE_EXT_MAX]; char fname[AUGE_NAME_MAX]; std::vector<std::string>::iterator iter; for(iter=m_paths.begin(); iter!=m_paths.end();iter++) { fpath = (*iter).c_str(); memset(fname,0,AUGE_NAME_MAX); memset(name,0,AUGE_NAME_MAX); memset(name,0,AUGE_EXT_MAX); auge_split_path(fpath, NULL, NULL, name, ext); auge_make_path(fname, NULL, NULL, name, ext); if(strlen(fname)==0) { continue; } stat(fpath,&st); entry = archive_entry_new(); archive_entry_set_pathname(entry,fname); archive_entry_set_size(entry,st.st_size); archive_entry_set_filetype(entry, AE_IFREG); archive_entry_set_perm(entry,0644); archive_write_header(a,entry); fd = open(fpath,O_RDONLY); len = read(fd,buff,sizeof(buff)); while(len>0) { archive_write_data(a,buff, len); len = read(fd,buff,sizeof(buff)); } close(fd); archive_entry_free(entry); } archive_write_close(a); archive_write_free(a); return AG_SUCCESS; }
void pkg_sign_gpg(const char *name, const char *output) { struct archive *pkg; struct archive_entry *entry, *hash_entry, *sign_entry; int fd; struct stat sb; char *hash_file, *signature_file, *tmp, *pkgname, hash[SHA512_DIGEST_STRING_LENGTH]; unsigned char block[65536]; off_t i, size; size_t block_len, signature_len; if ((fd = open(name, O_RDONLY)) == -1) err(EXIT_FAILURE, "Cannot open binary package %s", name); if (fstat(fd, &sb) == -1) err(EXIT_FAILURE, "Cannot stat %s", name); entry = archive_entry_new(); archive_entry_copy_stat(entry, &sb); pkgname = extract_pkgname(fd); hash_file = xasprintf(hash_template, pkgname, (long long)archive_entry_size(entry)); free(pkgname); for (i = 0; i < archive_entry_size(entry); i += block_len) { if (i + (off_t)sizeof(block) < archive_entry_size(entry)) block_len = sizeof(block); else block_len = archive_entry_size(entry) % sizeof(block); if (read(fd, block, block_len) != (ssize_t)block_len) err(2, "short read"); hash_block(block, block_len, hash); tmp = xasprintf("%s%s\n", hash_file, hash); free(hash_file); hash_file = tmp; } tmp = xasprintf("%s%s", hash_file, hash_trailer); free(hash_file); hash_file = tmp; if (detached_gpg_sign(hash_file, strlen(hash_file), &signature_file, &signature_len, gpg_keyring_sign, gpg_sign_as)) err(EXIT_FAILURE, "Cannot sign hash file"); lseek(fd, 0, SEEK_SET); sign_entry = archive_entry_clone(entry); hash_entry = archive_entry_clone(entry); pkgname = strrchr(name, '/'); archive_entry_set_pathname(entry, pkgname != NULL ? pkgname + 1 : name); archive_entry_set_pathname(hash_entry, HASH_FNAME); archive_entry_set_pathname(sign_entry, GPG_SIGNATURE_FNAME); archive_entry_set_size(hash_entry, strlen(hash_file)); archive_entry_set_size(sign_entry, signature_len); pkg = archive_write_new(); archive_write_set_compression_none(pkg); archive_write_set_format_ar_bsd(pkg); archive_write_open_filename(pkg, output); archive_write_header(pkg, hash_entry); archive_write_data(pkg, hash_file, strlen(hash_file)); archive_write_finish_entry(pkg); archive_entry_free(hash_entry); archive_write_header(pkg, sign_entry); archive_write_data(pkg, signature_file, signature_len); archive_write_finish_entry(pkg); archive_entry_free(sign_entry); size = archive_entry_size(entry); archive_write_header(pkg, entry); for (i = 0; i < size; i += block_len) { if (i + (off_t)sizeof(block) < size) block_len = sizeof(block); else block_len = size % sizeof(block); if (read(fd, block, block_len) != (ssize_t)block_len) err(2, "short read"); archive_write_data(pkg, block, block_len); } archive_write_finish_entry(pkg); archive_entry_free(entry); archive_write_finish(pkg); close(fd); exit(0); }
/*! * \brief Create pax archive with all metadata * * \param filename Target archive path * \param base_dir Base directory for \a paths * \param paths List of paths to add to the archive * * \return Whether the archive creation was successful */ bool libarchive_tar_create(const std::string &filename, const std::string &base_dir, const std::vector<std::string> &paths) { if (base_dir.empty() && paths.empty()) { LOGE("%s: No base directory or paths specified", filename.c_str()); return false; } autoclose::archive in(archive_read_disk_new(), archive_read_free); if (!in) { LOGE("%s: Out of memory when creating disk reader", __FUNCTION__); return false; } autoclose::archive out(archive_write_new(), archive_write_free); if (!out) { LOGE("%s: Out of memory when creating archive writer", __FUNCTION__); return false; } autoclose::archive_entry_linkresolver resolver(archive_entry_linkresolver_new(), archive_entry_linkresolver_free); if (!resolver) { LOGE("%s: Out of memory when creating link resolver", __FUNCTION__); return false; } // Set up disk reader parameters archive_read_disk_set_symlink_physical(in.get()); archive_read_disk_set_metadata_filter_callback( in.get(), metadata_filter, nullptr); archive_read_disk_set_behavior(in.get(), LIBARCHIVE_DISK_READER_FLAGS); // We don't want to look up usernames and group names on Android //archive_read_disk_set_standard_lookup(in.get()); // Set up archive writer parameters // NOTE: We are creating POSIX pax archives instead of GNU tar archives // because libarchive's GNU tar writer is very limited. In particular, // it does not support storing sparse file information, xattrs, or // ACLs. Since this information is stored as extended attributes in // the pax archive, the GNU tar tool will not be able to extract any // of this additional metadata. In other words, extracting and // repacking a backup on a Linux machine with GNU tar will render the // backup useless. //archive_write_set_format_gnutar(out.get()); archive_write_set_format_pax_restricted(out.get()); //archive_write_set_compression_bzip2(out.get()); //archive_write_set_compression_gzip(out.get()); //archive_write_set_compression_xz(out.get()); archive_write_set_bytes_per_block(out.get(), 10240); // Set up link resolver parameters archive_entry_linkresolver_set_strategy(resolver.get(), archive_format(out.get())); // Open output file if (archive_write_open_filename(out.get(), filename.c_str()) != ARCHIVE_OK) { LOGE("%s: Failed to open file: %s", filename.c_str(), archive_error_string(out.get())); return false; } archive_entry *entry = nullptr; archive_entry *sparse_entry = nullptr; int ret; std::string full_path; // Add hierarchies for (const std::string &path : paths) { if (path.empty()) { LOGE("%s: Cannot add empty path to the archive", filename.c_str()); return false; } // If the path is absolute, don't append it to the base directory if (path[0] == '/') { full_path = path; } else { full_path = base_dir; if (!full_path.empty() && full_path.back() != '/' && path[0] != '/') { full_path += '/'; } full_path += path; } ret = archive_read_disk_open(in.get(), full_path.c_str()); if (ret != ARCHIVE_OK) { LOGE("%s: %s", full_path.c_str(), archive_error_string(in.get())); return false; } while (true) { archive_entry_free(entry); entry = archive_entry_new(); ret = archive_read_next_header2(in.get(), entry); if (ret == ARCHIVE_EOF) { break; } else if (ret != ARCHIVE_OK) { LOGE("%s: Failed to read next header: %s", full_path.c_str(), archive_error_string(in.get())); archive_entry_free(entry); return false; } if (archive_entry_filetype(entry) != AE_IFREG) { archive_entry_set_size(entry, 0); } // If our current directory tree path is not an absolute path, set // the archive path to the relative path starting at base_dir const char *curpath = archive_entry_pathname(entry); if (curpath && path[0] != '/' && !base_dir.empty()) { std::string relpath; if (!util::relative_path(curpath, base_dir, &relpath)) { LOGE("Failed to compute relative path of %s starting at %s: %s", curpath, base_dir.c_str(), strerror(errno)); archive_entry_free(entry); return false; } if (relpath.empty()) { // If the relative path is empty, then the current path is // the root of the directory tree. We don't need that, so // skip it. continue; } archive_entry_set_pathname(entry, relpath.c_str()); } switch (archive_entry_filetype(entry)) { case AE_IFSOCK: LOGW("%s: Skipping socket", archive_entry_pathname(entry)); continue; default: LOGV("%s", archive_entry_pathname(entry)); break; } archive_entry_linkify(resolver.get(), &entry, &sparse_entry); if (entry) { if (!write_file(in.get(), out.get(), entry)) { archive_entry_free(entry); return false; } archive_entry_free(entry); entry = nullptr; } if (sparse_entry) { if (!write_file(in.get(), out.get(), sparse_entry)) { archive_entry_free(sparse_entry); return false; } archive_entry_free(sparse_entry); sparse_entry = nullptr; } } archive_entry_free(entry); entry = nullptr; archive_read_close(in.get()); } archive_read_disk_set_metadata_filter_callback(in.get(), nullptr, nullptr); entry = nullptr; archive_entry_linkify(resolver.get(), &entry, &sparse_entry); while (entry) { // This tricky code here is to correctly read the contents of the entry // because the disk reader 'in' is pointing at does not have any // information about the entry by this time and using // archive_read_data_block() with the disk reader consequently must // fail. And we hae to re-open the entry to read the contents. ret = archive_read_disk_open(in.get(), archive_entry_sourcepath(entry)); if (ret != ARCHIVE_OK) { LOGE("%s: %s", archive_entry_sourcepath(entry), archive_error_string(in.get())); return false; } // Invoke archive_read_next_header2() to work archive_read_data_block(), // which is called via write_file() without failure. archive_entry *entry2 = archive_entry_new(); ret = archive_read_next_header2(in.get(), entry2); archive_entry_free(entry2); if (ret != ARCHIVE_OK) { LOGE("%s: %s", archive_entry_sourcepath(entry), archive_error_string(in.get())); archive_entry_free(entry); return false; } if (!write_file(in.get(), out.get(), entry)) { archive_entry_free(entry); return false; } archive_entry_free(entry); archive_read_close(in.get()); entry = nullptr; archive_entry_linkify(resolver.get(), &entry, &sparse_entry); } if (archive_write_close(out.get()) != ARCHIVE_OK) { LOGE("%s: %s", filename.c_str(), archive_error_string(out.get())); return false; } return true; }
static int rb_libarchive_writer_s_open_filename0(struct rb_libarchive_archive_container *p, void *arg) { const char *filename = (const char *) arg; return archive_write_open_filename(p->ar, filename); }
static void create(const char *filename, int compress, const char **argv) { struct archive *a; struct archive *disk; struct archive_entry *entry; ssize_t len; int fd; a = archive_write_new(); switch (compress) { #ifndef NO_BZIP2_CREATE case 'j': case 'y': archive_write_add_filter_bzip2(a); break; #endif #ifndef NO_COMPRESS_CREATE case 'Z': archive_write_add_filter_compress(a); break; #endif #ifndef NO_GZIP_CREATE case 'z': archive_write_add_filter_gzip(a); break; #endif default: archive_write_add_filter_none(a); break; } archive_write_set_format_ustar(a); if (filename != NULL && strcmp(filename, "-") == 0) filename = NULL; archive_write_open_filename(a, filename); disk = archive_read_disk_new(); #ifndef NO_LOOKUP archive_read_disk_set_standard_lookup(disk); #endif while (*argv != NULL) { struct archive *disk = archive_read_disk_new(); int r; r = archive_read_disk_open(disk, *argv); if (r != ARCHIVE_OK) { errmsg(archive_error_string(disk)); errmsg("\n"); exit(1); } for (;;) { int needcr = 0; entry = archive_entry_new(); r = archive_read_next_header2(disk, entry); if (r == ARCHIVE_EOF) break; if (r != ARCHIVE_OK) { errmsg(archive_error_string(disk)); errmsg("\n"); exit(1); } archive_read_disk_descend(disk); if (verbose) { msg("a "); msg(archive_entry_pathname(entry)); needcr = 1; } r = archive_write_header(a, entry); if (r < ARCHIVE_OK) { errmsg(": "); errmsg(archive_error_string(a)); needcr = 1; } if (r == ARCHIVE_FATAL) exit(1); if (r > ARCHIVE_FAILED) { #if 0 /* Ideally, we would be able to use * the same code to copy a body from * an archive_read_disk to an * archive_write that we use for * copying data from an archive_read * to an archive_write_disk. * Unfortunately, this doesn't quite * work yet. */ copy_data(disk, a); #else /* For now, we use a simpler loop to copy data * into the target archive. */ fd = open(archive_entry_sourcepath(entry), O_RDONLY); len = read(fd, buff, sizeof(buff)); while (len > 0) { archive_write_data(a, buff, len); len = read(fd, buff, sizeof(buff)); } close(fd); #endif } archive_entry_free(entry); if (needcr) msg("\n"); } archive_read_close(disk); archive_read_free(disk); argv++; } archive_write_close(a); archive_write_free(a); }