static void test_macpolicy(const char *polname, const char *trylabel) { char fn[64]; char mac1[512], mac2[512]; struct archive *ar, *aw; struct archive_entry *ae; int i, found; /* Create a file with the given label */ strcpy(fn, "test_"); strncat(fn, polname, 54); fn[59] = '\0'; if (!create_labeled_file(fn, trylabel)) return; /* Get the actual label. Note that it may be different than * our original argument if multiple policies are loaded. */ failure("Cannot get MAC label from file"); if (!assert(get_file_maclabel(fn, mac1, 512))) return; /* Read the file data into archive */ assert((ar = archive_read_disk_new()) != NULL); ae = archive_entry_new(); assert(ae != NULL); archive_entry_copy_pathname(ae, fn); failure("Reading disk entry failed."); assertEqualIntA(ar, ARCHIVE_OK, archive_read_disk_entry_from_file(ar, ae, -1, NULL)); /* Check that there is a matching xattr */ i = archive_entry_xattr_reset(ae); found = 0; while (i--) { const char *name; const void *value; size_t size; archive_entry_xattr_next(ae, &name, &value, &size); if (name != NULL) { if (strncmp(name, "system.mac", 10) == 0) { if (strncmp(value, mac1, (size > 512 ? 512 : size)) == 0) { found = 1; break; } } } } failure("No matching label in archive"); assert(found); /* Write the file back to disk. Note that the file contained * no data so we're only concerned with the header. */ assert((aw = archive_write_disk_new()) != NULL); archive_write_disk_set_options(aw, ARCHIVE_EXTRACT_XATTR); strncat(fn, "_out", 4); /* New name for extraction */ fn[63] = '\0'; archive_entry_copy_pathname(ae, fn); assertEqualIntA(aw, ARCHIVE_OK, archive_write_header(aw, ae)); assertEqualIntA(aw, ARCHIVE_OK, archive_write_finish_entry(aw)); /* Clean up */ assertEqualInt(ARCHIVE_OK, archive_write_free(aw)); assertEqualInt(ARCHIVE_OK, archive_read_free(ar)); archive_entry_free(ae); /* Finally, verify the label of the created file */ failure("Cannot get MAC label from file"); if (!assert(get_file_maclabel(fn, mac2, 512))) return; failure("Original and extracted MAC labels do not match"); assert(strncmp(mac1, mac2, 512) == 0); }
emb_ruby_error_t emb_ruby_uncompress(){ struct archive *input_archive; struct archive *output_archive; struct archive_entry* entry; int result; int output_flags; unsigned char buff[2048]; int buffsize = 2048; int size; output_flags = ARCHIVE_EXTRACT_TIME; output_flags |= ARCHIVE_EXTRACT_PERM; output_flags |= ARCHIVE_EXTRACT_ACL; output_flags |= ARCHIVE_EXTRACT_FFLAGS; input_archive = archive_read_new(); output_archive = archive_write_disk_new(); archive_read_support_filter_gzip(input_archive); archive_read_support_format_tar(input_archive); //archive_read_support_format_raw(a); archive_write_disk_set_options(output_archive, output_flags); archive_write_disk_set_standard_lookup(output_archive); result = archive_read_open_memory(input_archive, (void*)binary_data, binary_size); if (result != ARCHIVE_OK) { fprintf(stderr, "%s\n", archive_error_string(input_archive)); return E_UNCOMPRESS_ERROR; } for (;;) { /** * Read new header from memory */ result = archive_read_next_header(input_archive, &entry); // EOF if (result == ARCHIVE_EOF) { break; } // error handling if (result != ARCHIVE_OK) { fprintf(stderr, "%s\n", archive_error_string(input_archive)); emd_ruby_uncompress_cleanup(input_archive, output_archive); return E_UNCOMPRESS_ERROR; } /** * Write new header into disk */ result = archive_write_header(output_archive, entry); // error handling if (result != ARCHIVE_OK) { fprintf(stderr, "%s\n", archive_error_string(output_archive)); emd_ruby_uncompress_cleanup(input_archive, output_archive); return E_UNCOMPRESS_ERROR; } /** * copy the data */ result = emb_ruby_uncompress_copy_data(input_archive, output_archive); if (result != ARCHIVE_OK) { fprintf(stderr, "%s\n", archive_error_string(output_archive)); emd_ruby_uncompress_cleanup(input_archive, output_archive); return E_UNCOMPRESS_ERROR; } /** * Write the trailing */ result = archive_write_finish_entry(output_archive); if (result != ARCHIVE_OK) { fprintf(stderr, "%s\n", archive_error_string(output_archive)); emd_ruby_uncompress_cleanup(input_archive, output_archive); return E_UNCOMPRESS_ERROR; } } emd_ruby_uncompress_cleanup(input_archive, output_archive); return E_SUCCESS; }
static bool ExtractArchive(const char *zip_file, const char *out_dir) { struct archive *input = archive_read_new(); archive_read_support_format_all(input); archive_read_support_compression_all(input); struct archive *output = archive_write_disk_new(); archive_write_disk_set_options(output, ARCHIVE_EXTRACT_TIME); archive_write_disk_set_standard_lookup(output); int hRes; const int BLOCK_SIZE = 65536; int r = archive_read_open_filename(input, zip_file, BLOCK_SIZE); if (r != ARCHIVE_OK) { extraction_error = IDS_BADARCHIVE; return false; } // libarchive can only extract into the current directory, so we // need to set it and restore it. char original_dir[MAX_PATH]; char *cRet = getcwd(original_dir, sizeof(original_dir)); hRes = chdir(out_dir); bool retval = true; while (true) { struct archive_entry *entry; r = archive_read_next_header(input, &entry); if (r == ARCHIVE_EOF) break; if (r != ARCHIVE_OK) { extraction_error = IDS_BADARCHIVE; retval = false; break; } r = archive_write_header(output, entry); if (r != ARCHIVE_OK) { const char *msg = archive_error_string(output); extraction_error = IDS_UNKNOWNERROR; retval = false; break; } if (archive_entry_size(entry) > 0) { r = CopyArchiveData(input, output); if (r != ARCHIVE_OK) { const char *msg = archive_error_string(output); extraction_error = IDS_UNKNOWNERROR; retval = false; break; } } r = archive_write_finish_entry(output); if (r != ARCHIVE_OK) { extraction_error = IDS_UNKNOWNERROR; retval = false; break; } // Extraction went OK; process Windows messages ClearMessageQueue(); } archive_read_close(input); archive_read_free(input); archive_write_close(output); archive_write_free(output); // Go back to original working directory hRes = chdir(original_dir); return retval; }
// ----------------------------------------------------------------------------- bool extract(const char* spath, const char* dpath) { DEBUGLOGB; int retc; bool okay = false; archive* sorc = archive_read_new(); archive* dest = archive_write_disk_new(); if( !sorc || !dest ) { DEBUGLOGE; DEBUGLOGS(" (1) - unable to create new read & write archive objects"); return okay; } archive_read_support_filter_all(sorc); archive_read_support_format_all(sorc); archive_write_disk_set_options(dest, ARCHIVE_EXTRACT_TIME); if( (retc = archive_read_open_filename(sorc, spath, 64*1024)) != ARCHIVE_OK ) { int errn = archive_errno(sorc); const char* errs = archive_error_string(sorc); DEBUGLOGE; DEBUGLOGP(" (2) - unable to open archive (%d:%d)\n%s\n%s\n", retc, errn, errs, spath); return okay; } archive_entry* entry; while( true ) { if( (retc = archive_read_next_header(sorc, &entry)) == ARCHIVE_EOF ) { DEBUGLOGS("archive_read_next_header returned 'eof'"); okay = true; break; } if( retc != ARCHIVE_OK ) { DEBUGLOGS("archive_read_next_header returned 'archive not ok' error"); break; } char destPath[PATH_MAX]; strvcpy(destPath, dpath); strvcat(destPath, archive_entry_pathname(entry)); DEBUGLOGP("extracting %s\n", destPath); archive_entry_set_pathname(entry, destPath); if( (retc = archive_write_header(dest, entry)) != ARCHIVE_OK ) { DEBUGLOGS("archive_write_header returned 'archive not ok' error"); break; } copyData(sorc, dest); if( (retc = archive_write_finish_entry(dest)) != ARCHIVE_OK ) { DEBUGLOGS("archive_write_finish returned 'archive not ok' error"); break; } } archive_write_free(dest); archive_read_free(sorc); DEBUGLOGE; return okay; }
int extractArchive(const char* filename, const char* directory) { struct archive *a; struct archive *ext; struct archive_entry *entry; int r; int flags = ARCHIVE_EXTRACT_TIME; int warnCount = 0; int dirlen = strlen(directory); 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_compression_gzip(a); 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_file(a, filename, 10240))) { printf("%s\n", archive_error_string(a)); return -1; } while (true) { r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) break; if (r != ARCHIVE_OK) { printf("%s\n", archive_error_string(a)); return -1; } //Set entry to be extracted under the given directory const char* path = archive_entry_pathname(entry); int pathlength = dirlen + strlen(path) + 2; //One for / and the other for '\0' char newPath[pathlength]; snprintf(newPath, pathlength, "%s/%s", directory, path); archive_entry_set_pathname(entry, newPath); r = archive_write_header(ext, entry); if (r != ARCHIVE_OK) { printf("%s\n", archive_error_string(ext)); warnCount++; } else { copy_data(a, ext); r = archive_write_finish_entry(ext); if (r != ARCHIVE_OK) { printf("%s\n", archive_error_string(ext)); warnCount++; } } } archive_read_close(a); //archive_read_free(a); return warnCount; }
/* * The main archive extract function, loops over the archive entries and unpack * them at the right place. */ void extract(const char *extname, const char *filename) { struct archive *a; struct archive *ext; struct archive_entry *entry; int flags = ARCHIVE_EXTRACT_TIME; int r; char *control_filename = psprintf("%s.control", extname); int cflen = strlen(control_filename); a = archive_read_new(); ext = archive_write_disk_new(); archive_write_disk_set_options(ext, flags); /* * Do we care enough about the .so size to limit ourselves here? We might * want to reconsider and use archive_read_support_format_all() and * archive_read_support_filter_all() rather than just tar.gz. */ archive_read_support_format_tar(a); archive_read_support_filter_gzip(a); if ((archive_read_open_filename(a, filename, 10240))) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Failed to open archive \"%s\"", filename), errdetail("%s", archive_error_string(a)))); elog(DEBUG1, "Unpacking archive \"%s\"", filename); for (;;) { char *path; struct archive_entry *target; r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) break; if (r != ARCHIVE_OK) ereport(ERROR, (errcode(ERRCODE_UNDEFINED_FILE), errmsg("%s", archive_error_string(a)))); target = archive_entry_clone(entry); path = (char *)archive_entry_pathname(target); path = (char *)compute_target_path(path, control_filename, cflen); archive_entry_set_pathname(target, path); elog(DEBUG1, "Extracting \"%s\" to \"%s\"", archive_entry_pathname(entry), path); r = archive_write_header(ext, target); if (r != ARCHIVE_OK) ereport(WARNING, (errcode(ERRCODE_IO_ERROR), errmsg("%s", archive_error_string(ext)))); else { copy_data(a, ext); r = archive_write_finish_entry(ext); if (r != ARCHIVE_OK) ereport(ERROR, (errcode(ERRCODE_IO_ERROR), errmsg("%s", archive_error_string(ext)))); } archive_entry_free(target); } archive_read_close(a); archive_read_free(a); }
bool ExtractArchive(const char *zip_file, const char *out_dir) { struct archive *input = archive_read_new(); archive_read_support_format_all(input); archive_read_support_compression_all(input); struct archive *output = archive_write_disk_new(); archive_write_disk_set_options(output, ARCHIVE_EXTRACT_TIME); archive_write_disk_set_standard_lookup(output); const int BLOCK_SIZE = 65536; int r = archive_read_open_filename(input, zip_file, BLOCK_SIZE); if (r != ARCHIVE_OK) { debug(("Error opening archive %s: %s\n", zip_file, archive_error_string(input))); extraction_error = IDS_BADARCHIVE; return false; } // libarchive can only extract into the current directory, so we // need to set it and restore it. char original_dir[MAX_PATH]; getcwd(original_dir, sizeof(original_dir)); chdir(out_dir); bool retval = true; while (true) { struct archive_entry *entry; r = archive_read_next_header(input, &entry); if (r == ARCHIVE_EOF) break; if (r != ARCHIVE_OK) { debug(("Error reading archive header: %s\n", archive_error_string(input))); extraction_error = IDS_BADARCHIVE; retval = false; break; } r = archive_write_header(output, entry); if (r != ARCHIVE_OK) { debug(("Error writing archive header: %s\n", archive_error_string(input))); extraction_error = IDS_UNKNOWNERROR; retval = false; break; } if (archive_entry_size(entry) > 0) { r = CopyArchiveData(input, output); if (r != ARCHIVE_OK) { debug(("CopyArchiveData error: %s\n", archive_error_string(input))); extraction_error = IDS_UNKNOWNERROR; retval = false; break; } } r = archive_write_finish_entry(output); if (r != ARCHIVE_OK) { debug(("write_finish_entry error: %s\n", archive_error_string(input))); extraction_error = IDS_UNKNOWNERROR; retval = false; break; } debug(("Archive file %s extracted\n", archive_entry_pathname(entry))); // Extraction went OK; process Windows messages ClearMessageQueue(); // Check for user hitting abort button // Check for user abort if (abort_download) { retval = false; break; } } archive_read_close(input); archive_read_free(input); archive_write_close(output); archive_write_free(output); // Go back to original working directory chdir(original_dir); return retval; }
static void * extract(void *p) { struct archive *a; struct archive *ext; struct archive_entry *entry; int r; int flags; struct extract_data *data = (struct extract_data *)p; flags = data->flags; 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_all(a); archive_read_support_filter_all(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. */ char* FIFO = alloca(strlen(get_tmpdir())+strlen(FIFO_FILE_NAME)+1); sprintf(FIFO, "%s%s", get_tmpdir(), FIFO_FILE_NAME); if ((r = archive_read_open_filename(a, FIFO, 4096))) { ERROR("archive_read_open_filename(): %s %d", archive_error_string(a), r); pthread_exit((void *)-1); } for (;;) { r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) break; if (r != ARCHIVE_OK) { ERROR("archive_read_next_header(): %s %d", archive_error_string(a), 1); pthread_exit((void *)-1); } if (debug) TRACE("Extracting %s", archive_entry_pathname(entry)); r = archive_write_header(ext, entry); if (r != ARCHIVE_OK) TRACE("archive_write_header(): %s", archive_error_string(ext)); else { copy_data(a, ext); r = archive_write_finish_entry(ext); if (r != ARCHIVE_OK) { ERROR("archive_write_finish_entry(): %s", archive_error_string(ext)); pthread_exit((void *)-1); } } } archive_read_close(a); archive_read_free(a); pthread_exit((void *)0); }