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 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; }