I am trying to using libzip to create a zip file directly in memory, not to a file on disk. My code is quite basic at the moment as I am getting stuck on creating the necessary zip_t struct from a zip_source_buffer:
#include <stdio.h>
#include <string.h>
#include <zip.h>
int main(int argc, char *arrv[])
{
char buffer[65536] = {};
zip_error_t error;
zip_source_t *zs = zip_source_buffer_create(buffer, sizeof(buffer), 0, &error);
int err = zip_source_begin_write(zs);
printf("%p %d '%s'\n", zs, err, zip_error_strerror(&error));
zip_error_fini(&error);
zip_t * zip = zip_open_from_source(zs, ZIP_CREATE, &error);
printf("%p '%s'\n", zip, zip_error_strerror(&error));
zip_error_fini(&error);
}
the code compiles and runs, but thows an error:
$ ./ztest
0xdd50a0 0 'No error'
(nil) 'Not a zip archive'
It's not clear if the begin_write() is needed, but it doesn't generate an error and I get the same result without it.
What am I missing? Thanks
My 2 cent if anybody yet has interest in question.
Do not forget to zip_source_keep
before zip_open_from_source
, as zip_close
will free source, but we want to use its content.
int flags = 0;
zip_error_t error;
zip_source_t *zsmem = zip_source_buffer_create(0, 0, 0, &error);
//we can fill up new zip with an old one (some template, for example)
if (exdata){
zip_source_begin_write(zsmem);
zip_source_write(zsmem, exdata, exdata_sz);
zip_source_commit_write(zsmem);
}else
flags |= ZIP_TRUNCATE;
zip_source_keep(zsmem); //!!
struct zip* arc = zip_open_from_source(zsmem, flags, &error);
//do more stuff adding, removing files , comments, etc
zip_close(arc);
zip_source_open(zsmem);
zip_source_seek(zsmem, 0, SEEK_END);
zip_int64_t sz = zip_source_tell(zsmem);
zip_source_seek(zsmem, 0, SEEK_SET);
zip_source_read(zsmem, outbuffer, sz);
zip_source_close(zsmem);
zip_source_free(zsmem);
send_over_network(outbuffer);
Use ZIP_TRUNCATE instead of ZIP_CREATE
. The archive always exists in the case of a buffer source, so ZIP_CREATE
has no effect, but a stream of '0's is not a valid zip file. ZIP_TRUNCATE
tells libzip to ignore the buffer's current contents (i.e. override all the '0's with the new archive).
zip_source_begin_write()
is called internally by libzip. It's not necessary for it to be called in this kind of situation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With