Unzip a zip file using zlib
Asked Answered
C

4

13

I have an archive.zip which contains two crypted ".txt" files. I would like to decompress the archive in order to retrieve those 2 files.

Here's what I've done so far:

FILE *FileIn = fopen("./archive.zip", "rb");
if (FileIn)
    printf("file opened\n");
else
    printf("unable to open file\n");

fseek(FileIn, 0, SEEK_END);
unsigned long FileInSize = ftell(FileIn);
printf("size of input compressed file : %u\n", FileInSize);

void *CompDataBuff = malloc(FileInSize);
void *UnCompDataBuff = NULL;

int fd = open ("archive.zip", O_RDONLY);
CompDataBuff = mmap(NULL, FileInSize, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
printf("buffer read : %s\n", (char *)CompDataBuff);

uLongf UnCompSize = (FileInSize * 11/10 + 12);
UnCompDataBuff = malloc(UnCompSize);

int ret_uncp ;

ret_uncp = uncompress((Bytef*)UnCompDataBuff, &UnCompSize, (const Bytef*)CompDataBuff,FileInSize);
printf("size of uncompressed data : %u\n", UnCompSize);

if (ret_uncp == Z_OK){
    printf("uncompression ok\n");
    printf("uncompressed data : %s\n",(char *)UnCompDataBuff);
    }
if (ret_uncp == Z_MEM_ERROR)
    printf("uncompression memory error\n");
if (ret_uncp == Z_BUF_ERROR)
    printf("uncompression buffer error\n");
if (ret_uncp == Z_DATA_ERROR)
    printf("uncompression data error\n");

I always get "uncompression data error" and I don't know why. And then I would like to know how to retrieve the 2 files with my data uncompressed.

Cloistered answered 23/7, 2012 at 11:49 Comment(0)
S
22

zip is a file format that wraps header and trailer information around compressed data streams in order to represent a set of files and directories. The compressed data streams are almost always deflate data streams, which can in fact be generated and decoded by zlib. zlib also provides the crc32 function which can be used to generate and check the crc values in the zip wrapper information.

What zlib does not do by itself is decode and deconstruct the zip structure. You can either write your own code to do that using the specification (not very hard to do), or you can use the minizip routines in the contrib/minizip directory of the zlib distribution, which provides functions to open, access, and close zip files.

Sixty answered 23/7, 2012 at 23:29 Comment(1)
Thanks. I added the contrib/minizip headers and was able to read files from a zip (in an application that was already using zlib). I just had to write some simple functions to wrap calls to the interface in unzip.hMalenamalet
B
10

Zlib is not a library for handling .zip files. It supports decompressing zlib and gzip streams, both of which work on the level of a single stream of data, rather than an "archive" format like .zip.

You would need a different library (for one example, libzip; there are many others) to open and manipulate .zip archives.

Bechuana answered 23/7, 2012 at 12:20 Comment(2)
Oh really, i was sure that zlib would deal with .zip .. anyway thanks for information ! :)Cloistered
zlib can in fact help with zip processing, and the source distribution comes with contributed code to process zip files. See my answer.Sixty
S
5

As mentioned, zlib only handles compression, it doesn't archive. When you want to zip or unzip what you are doing is extracting files from an archive which happens to be in a zip format (there are other formats like rar, 7zip and so on)

If you want to create zips or unzip files you have to handle the zip format and minizip is a nice library, robust and has been there for quite a long time.

There is a contrib for minizip https://github.com/nmoinvaz/minizip with examples on how to use it. Is not that hard, and you can check the minizip.c and miniunz.c for code on how to use it. (Minizip uses zlib for the compression)

Also i ended up building a library that wraps minizip and adds a bunch of nice features to it and makes it easier to use and more object oriented. Lets you do things like zip entire folders, streams, vectors, etc. As well as doing everything entirely in memory.

Repo with examples here: https://github.com/sebastiandev/zipper

Beta pre-release: https://github.com/sebastiandev/zipper/releases/

Code looks something like:

Zipper zipper("ziptest.zip");
zipper.add("somefile.txt");
zipper.add("myFolder");
zipper.close();
Solanaceous answered 26/7, 2015 at 18:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.