-
Notifications
You must be signed in to change notification settings - Fork 2
/
zip_helper.c
119 lines (95 loc) · 3.13 KB
/
zip_helper.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <err.h>
#include <zip.h>
#include "zip_helper.h"
/*
This is zip_helper, a small wrapper around libzip for lazy people like me.
(c) 2022 by kittennbfive
AGPLv3+ and NO WARRANTY!
*/
zip_t * open_zip_file(char const * const filename)
{
zip_t * zip;
int err;
zip=zip_open(filename, ZIP_RDONLY, &err);
if(!zip)
errx(1, "open_zip_file(%s): zip_open failed with error %d", filename, err);
return zip;
}
void close_zip_file(zip_t * zip)
{
zip_close(zip);
}
bool get_file_size_from_zip(zip_t * zip, char const * const fname, zip_uint64_t * const filesize)
{
zip_stat_t stat;
if(zip_stat(zip, fname, 0, &stat))
{
zip_error_t * error=zip_get_error(zip);
if(error->zip_err==ZIP_ER_NOENT)
{
*filesize=0;
zip_error_fini(error);
return false;
}
else
errx(1, "get_file_size_from_zip(%s): zip_stat failed: %s", fname, zip_error_strerror(error));
}
if(!(stat.valid&ZIP_STAT_SIZE))
errx(1, "get_file_size_from_zip(%s): zip_stat did not return a valid filesize", fname);
*filesize=stat.size;
return true;
}
zip_uint64_t get_file_from_zip(zip_t * zip, char const * const fname, uint8_t **buffer, const bool c_string)
{
zip_uint64_t sz;
if(!get_file_size_from_zip(zip, fname, &sz))
return false;
if(sz>SZ_MALLOC_MAX)
errx(1, "get_file_from_zip: file %s is bigger than hardcoded limit SZ_MALLOC_MAX", fname);
zip_file_t * file=zip_fopen(zip, fname, 0);
if(!file)
errx(1, "get_file_from_zip(%s): zip_open failed: %s", fname, zip_strerror(zip));
*buffer=malloc(sz+(c_string?1:0));
if(!(*buffer))
err(1, "get_file_from_zip: malloc failed for %s", fname);
zip_int64_t bytes_read=zip_fread(file, *buffer, sz);
if(bytes_read<0 || (zip_uint64_t)bytes_read!=sz)
errx(1, "get_file_from_zip(%s): zip_fread failed: %s", fname, zip_strerror(zip));
if(zip_fclose(file))
errx(1, "get_file_from_zip(%s): zip_fclose failed: %s", fname, zip_strerror(zip));
if(c_string)
(*buffer)[sz]='\0';
return sz;
}
zip_t * create_zip_file(char const * const filename)
{
zip_t * zip;
int err;
zip=zip_open(filename, ZIP_CREATE|ZIP_EXCL, &err);
if(!zip)
{
if(err==ZIP_ER_EXISTS)
errx(1, "create_zip_file(%s): file already exists, not overwriting", filename);
else
errx(1, "create_zip_file(%s) failed with error %d", filename, err);
}
return zip;
}
void add_buffer_to_zip_file(zip_t * zip, char const * const filename, void const * const buffer, const zip_uint64_t buffersize, const uint8_t compression_level)
{
zip_source_t * zip_source;
zip_error_t * err=NULL;
zip_source=zip_source_buffer_create(buffer, buffersize, 0, err);
if(!zip_source)
errx(1, "add_buffer_to_zip_file(%s): zip_source_buffer_create failed: %s", filename, zip_error_strerror(err));
zip_int64_t index=zip_file_add(zip, filename, zip_source, ZIP_FL_ENC_CP437);
if(index==-1)
errx(1, "add_buffer_to_zip_file(%s): zip_file_add failed: %s", filename, zip_strerror(zip));
if(zip_set_file_compression(zip, index, ZIP_CM_DEFLATE, compression_level)<0)
errx(1, "add_buffer_to_zip_file(%s): zip_set_file_compression failed: %s", filename, zip_strerror(zip));
}