Пример #1
0
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;
}
Пример #2
0
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;
}