How to use libzip
// Compile:
// g++ libzipplayground.cpp -I<path to libzip include> libarchive-rw.a -lz
#include<iostream>
#include<string>
#include <zip.h>
#include <cstdlib>
using namespace std;
char *readfile(string filename, size_t *size) {
char * buffer;
size_t result;
FILE* pFile = fopen (filename.c_str(), "rb" );
if (pFile==NULL) {fputs ("File error",stderr); exit (1);}
// obtain file size:
fseek (pFile , 0 , SEEK_END);
unsigned int lSize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
buffer = (char*) malloc (sizeof(char)*lSize);
if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}
// copy the file into the buffer:
result = fread (buffer,1,lSize,pFile);
if (result != lSize) {fputs ("Reading error",stderr); exit (3);}
/* the whole file is now loaded in the memory buffer. */
// terminate
fclose (pFile);
*size = lSize;
return buffer;
}
void dump(zip *archive) {
int files_total = zip_get_num_entries(archive, 0);
printf("Note: we have only %d files in ZIP\n",files_total);
struct zip_stat sb;
int r, len;
long long sum;
char buffer[10000];
for (int i = 0; i < zip_get_num_entries(archive, 0); i++) {
if (zip_stat_index(archive, i, 0, &sb) == 0) {
printf("==================\n");
printf("Name: [%s], ", sb.name);
printf("Size: [%llu], ", sb.size);
printf("Index: [%llu], ", sb.index);
printf("Valid: [%llu], ", sb.valid);
printf("mtime: [%u]\n", (unsigned int)sb.mtime);
zip_file *zf = zip_fopen_index(archive, i, 0);
if (!zf) {
fprintf(stderr, "boese, boese\n");
cout << "failed to opne entry of archive. " << zip_strerror(archive) << endl;
zip_close(archive);
}
sum = 0;
while (sum != sb.size) {
len = zip_fread(zf, buffer, 100);
if (len < 0) {
fprintf(stderr, "boese, boese\n");
exit(102);
}
printf("%s",buffer, len);
sum += len;
}
zip_fclose(zf);
printf("==================\n");
}
}
printf("\n\n");
}
zip * get_archive(string path, int flags) {
int error = 0;
zip *archive = zip_open(path.c_str(), flags , &error);
if(!archive) {
cout << "could not open or create archive" << path << endl;
exit(1) ;
}
cout << "Done : creating archieve" << path << endl;
return archive;
}
void add(zip *archive, string file) {
int index;
size_t len;
char *data = readfile(file, &len);
cout << "File content \n" << "Name " << file << "\nSize " << len << "\n" << data << "\n";
zip_source *source = zip_source_buffer(archive, data, len, 0);
if(source == NULL) {
cout << "failed to create source buffer. " << zip_strerror(archive) << endl;
return ;
}
//index = (int)zip_file_add(archive, file.c_str(), source, ZIP_FL_ENC_UTF_8);
index = (int)zip_add(archive, file.c_str(), source);
if(index < 0) {
zip_source_free(source);
cout << "failed to add file to archive. " << zip_strerror(archive) << endl;
return ;
}
}
void
createfromexisting(string path) {
zip *oldarchive = get_archive(path, ZIP_CREATE);
dump(oldarchive);
std::string new_path = "/home/sdasgup3/Junk/LIBZIP/ref_new.zip";
int err;
int flags = ZIP_CREATE;
zip_t *archive = zip_open(new_path.c_str(), flags, &err);
char buffer[10000];
for (int i = 0; i < zip_get_num_entries(oldarchive, 0); i++) {
zip_stat_t sb;;
if (zip_stat_index(oldarchive, i, 0, &sb) == 0) {
size_t s = sb.size;
const char* name = sb.name;
zip_file *zf = zip_fopen_index(oldarchive, i, 0);
if (!zf) {
fprintf(stderr, "boese, boese\n");
cout << "failed to open entry of archive. " << zip_strerror(archive) << endl;
zip_close(archive);
}
size_t len = zip_fread(zf, buffer, s);
if (len < 0) {
fprintf(stderr, "boese, boese\n");
exit(102);
}
zip_fclose(zf);
zip_source *zipBuffer = zip_source_buffer(archive, buffer, s, 0 /*don't free*/);
if(zip_file_add(archive, name, zipBuffer, ZIP_FL_ENC_UTF_8) < 0 ) {
cout << "zip_file_add problem " << zip_strerror(archive) << endl;
}
}
}
dump(archive);
zip_close(oldarchive);
zip_close(archive);
}
int main () {
std::string path1 = "/home/sdasgup3/Junk/LIBZIP/archive.zip";
std::string path2 = "/home/sdasgup3/Junk/LIBZIP/ref.zip";
std::string file1 = "message1.txt";
std::string file2 = "Makefile.rules";
//std::string file1 = "/home/sdasgup3/Junk/LIBZIP/message1.txt";
//std::string file2 = "/home/sdasgup3/Junk/LIBZIP/Makefile.rules";
//Read
zip *archive1 = get_archive(path2, ZIP_CREATE);
dump(archive1);
zip_close(archive1);
//create from existing
createfromexisting(path2);
return 0;
}