I am trying out libarchive to try to find out whether it is useful for my purpose.
I have a .zip file, with few files encrypted (PKzip) and few other files un-encrypted. I am able to successfully extract my .zip file using libarchive without a problem.
But when I try to create such an archive, I am not able to do it. Any guidance is appreciated.
[Working Fine] Extraction
void Extract()
{
// In
archive *ina = archive_read_new();
archive_entry *entry;
archive_read_support_format_zip(ina);
archive_read_set_passphrase_callback(ina, &count, ReadPasswordCallback); // ReadPasswordCallback - Supplies nullptr/emptry string for extracting files with no password, and give appropriate password for extracting files with password
archive_read_open_filename(ina, "test.zip", 10240); // ARCHIVE_OK received here
// Out
archive *ext = archive_write_disk_new();
archive_write_disk_set_options(ext, flags);
// Extraction
for(;;)
{
archive_read_next_header(ina, &entry); // ARCHIEVE_OK received here
archive_write_header(ext, entry); // ARCHIEVE_OK received here
copy_data(ina, ext); // copy_data ** defined at the bottom **
// Completion of write entry
archive_write_finish_entry(ext);
}
// Close and Cleanup
archive_read_close(ina);
archive_read_free(ina);
archive_write_close(ext);
archive_write_free(ext);
}
**[NOT WORKING] Cloning - Read the same zip file and create a copy (with few files as encrypted, few others as un-encrypted as per the original zip file) and **
void Clone()
{
// In
archive *ina = archive_read_new();
archive_entry *entry;
archive_read_support_format_zip(ina);
archive_read_set_passphrase_callback(ina, &count, ReadPasswordCallback); // ReadPasswordCallback - Supplies nullptr/emptry string for extracting files with no password, and give appropriate password for extracting files with password
archive_read_open_filename(ina, "test.zip", 10240); // ARCHIVE_OK received here
// Out
archive *oua = archive_write_new();
archive_write_set_format_zip(oua);
archive_write_set_options(oua, "zip:encryption=traditional");
archive_write_set_passphrase_callback(oua, nullptr, WritePasswordCallback); // WritePasswordCallback - Supplies nullptr/empty string for writing files with no password, and give appropriate password for writings files with password
archive_write_open_filename(oua, "testNEW.zip");
// Cloning
for(;;)
{
archive_read_next_header(ina, &entry); // ARCHIEVE_OK received here
archive_write_header(oua, entry); // ARCHIEVE_OK received here
copy_data(ina, oua); // copy_data ** defined at the bottom **
// Completion of write entry
archive_write_finish_entry(oua);
}
// Close and Cleanup
archive_read_close(ina);
archive_read_free(ina);
archive_write_close(oua);
archive_write_free(oua);
}
ReadPasswordCallback is called once per entry, hence I am able to decrypt files independently by supplying the file's corresponding password. For non-encrypted files, supplying nullptr works fine.
Whereas, with the write, the behaviour is different with the WritePasswordCallback invocation. The WritePasswordCallback is getting called "only once", not once per entry as ReadPasswordCallback. Hence I am not able to supply independent encryption key for the files. Also supplying a nullptr throws an error saying encryption key is necessary for encryption, hence I am not able to have few files as unencrypted
Is this a limitation of Libarchive library? Please help, and thanks in advance!
static int
copy_data(struct archive *ar, struct archive *aw)
{
int r;
char buff[1024];
do
{
r = archive_read_data(ar, buff, sizeof(buff)); // Receives 0/EOF at the last read
if (r == 0 || r == ARCHIVE_EOF)
return (ARCHIVE_OK);
// Copy
r = archive_write_data(aw, buff, r); // Receive ARCHIVE_OK
} while (r > 0);
return ARCHIVE_FATAL;
}