1 #ifndef ZCK_PRIVATE_H
2 #define ZCK_PRIVATE_H
3 
4 #include <stdarg.h>
5 #include <stdint.h>
6 #include <stdbool.h>
7 #include <stddef.h>
8 #include <regex.h>
9 #include "buzhash/buzhash.h"
10 #include "uthash.h"
11 #include "zck.h"
12 
13 #define BUF_SIZE 32768
14 /* Maximum string length for a compressed size_t */
15 #define MAX_COMP_SIZE (((sizeof(size_t) * 8) / 7) + 1)
16 
17 #define ZCK_MODE_READ 0
18 #define ZCK_MODE_WRITE 1
19 
20 #define DEFAULT_BUZHASH_WIDTH 48
21 #define DEFAULT_BUZHASH_BITS 15
22 #define CHUNK_DEFAULT_MIN 1
23 #define CHUNK_DEFAULT_MAX 10485760 // 10MB
24 
25 #define PUBLIC __attribute__((visibility("default")))
26 
27 #define zck_log(...) zck_log_wf(__func__, __VA_ARGS__)
28 
29 #define set_error(zck, ...) set_error_wf(zck, 0, __func__, __VA_ARGS__)
30 #define set_fatal_error(zck, ...) set_error_wf(zck, 1, __func__, __VA_ARGS__)
31 
32 #define ALLOCD_BOOL(z, f)   if(!f) { \
33                                 set_error(z, \
34                                         "Object not initialized"); \
35                                 return false; \
36                             }
37 #define ALLOCD_INT(z, f)    if(!f) { \
38                                 set_error(z, \
39                                         "Object not initialized"); \
40                                 return -1; \
41                             }
42 #define ALLOCD_PTR(z, f)    if(!f) { \
43                                 set_error(z, \
44                                         "Object not initialized"); \
45                                 return NULL; \
46                             }
47 #define VALIDATE_BOOL(f)    ALLOCD_BOOL(f, f) \
48                             if((f)->error_state > 0) return false;
49 #define VALIDATE_INT(f)     ALLOCD_INT(f, f) \
50                             if((f)->error_state > 0) return -1;
51 #define VALIDATE_PTR(f)     ALLOCD_PTR(f, f) \
52                             if((f)->error_state > 0) return NULL;
53 
54 #define VALIDATE_READ_BOOL(f)   VALIDATE_BOOL(f); \
55                                 if(f->mode != ZCK_MODE_READ) { \
56                                     set_error(f, \
57                                         "zckCtx not opened for reading"); \
58                                     return false; \
59                                 }
60 #define VALIDATE_READ_INT(f)    VALIDATE_INT(f); \
61                                 if(f->mode != ZCK_MODE_READ) { \
62                                     set_error(f, \
63                                         "zckCtx not opened for reading"); \
64                                     return -1; \
65                                 }
66 #define VALIDATE_READ_PTR(f)    VALIDATE_PTR(f); \
67                                 if(f->mode != ZCK_MODE_READ) { \
68                                     set_error(f, \
69                                         "zckCtx not opened for reading"); \
70                                     return NULL; \
71                                 }
72 
73 #define VALIDATE_WRITE_BOOL(f)  VALIDATE_BOOL(f); \
74                                 if(f->mode != ZCK_MODE_WRITE) { \
75                                     set_error(f, \
76                                         "zckCtx not opened for writing"); \
77                                     return false; \
78                                 }
79 #define VALIDATE_WRITE_INT(f)   VALIDATE_INT(f); \
80                                 if(f->mode != ZCK_MODE_WRITE) { \
81                                     set_error(f, \
82                                         "zckCtx not opened for writing"); \
83                                     return -1; \
84                                 }
85 #define VALIDATE_WRITE_PTR(f)   VALIDATE_PTR(f); \
86                                 if(f->mode != ZCK_MODE_WRITE) { \
87                                     set_error(f, \
88                                         "zckCtx not opened for writing"); \
89                                     return NULL; \
90                                 }
91 
92 typedef struct zckComp zckComp;
93 
94 typedef bool (*finit)(zckCtx *zck, zckComp *comp);
95 typedef bool (*fparam)(zckCtx *zck,zckComp *comp, int option, const void *value);
96 typedef bool (*fccompend)(zckCtx *zck, zckComp *comp, char **dst,
97                           size_t *dst_size, bool use_dict);
98 typedef ssize_t (*fcomp)(zckCtx *zck, zckComp *comp, const char *src,
99                          const size_t src_size, char **dst, size_t *dst_size,
100                          bool use_dict);
101 typedef bool (*fdecomp)(zckCtx *zck, zckComp *comp, const bool use_dict);
102 typedef bool (*fdcompend)(zckCtx *zck, zckComp *comp, const bool use_dict,
103                           const size_t fd_size);
104 typedef bool (*fcclose)(zckCtx *zck, zckComp *comp);
105 
106 typedef struct zckHashType {
107     int type;
108     int digest_size;
109 } zckHashType;
110 
111 struct zckHash {
112     zckHashType *type;
113     void *ctx;
114 };
115 
116 typedef void CURL;
117 
118 typedef struct zckMP {
119     int state;
120     size_t length;
121     char *buffer;
122     size_t buffer_len;
123 } zckMP;
124 
125 struct zckDL {
126     struct zckCtx *zck;
127     size_t dl;
128     size_t ul;
129     zckRange *range;
130     zckMP *mp;
131     char *boundary;
132     int parser_started;
133     int is_chunk;
134     size_t write_in_chunk;
135     size_t dl_chunk_data;
136     regex_t *dl_regex;
137     regex_t *end_regex;
138     regex_t *hdr_regex;
139     zckChunk *tgt_check;
140     int tgt_number;
141 
142     /* Callbacks */
143     zck_wcb write_cb;
144     void *write_data;
145     zck_wcb header_cb;
146     void *header_data;
147 };
148 
149 /* Contains an index item pointing to a chunk */
150 struct zckChunk {
151     char *digest;
152     int digest_size;
153     int valid;
154     size_t number;
155     size_t start;
156     size_t comp_length;
157     size_t length;
158     struct zckChunk *next;
159     struct zckChunk *src;
160     zckCtx *zck;
161     UT_hash_handle hh;
162 };
163 
164 /* Contains everything about an index and a pointer to the first index item */
165 struct zckIndex {
166     size_t count;
167     size_t length;
168     int hash_type;
169     size_t digest_size;
170     zckChunk *first;
171     zckChunk *last;
172     zckChunk *current;
173     zckChunk *ht;
174 };
175 
176 /* Contains a single range */
177 typedef struct zckRangeItem {
178     size_t start;
179     size_t end;
180     struct zckRangeItem *next;
181     struct zckRangeItem *prev;
182 } zckRangeItem;
183 
184 /* Contains a series of ranges, information about them, a link to the first
185  * range item, and an index describing what information is in the ranges */
186 struct zckRange {
187     unsigned int count;
188     zckRangeItem *first;
189     zckIndex index;
190 };
191 
192 struct zckComp {
193     int started;
194 
195     uint8_t type;
196     int level;
197 
198     void *cctx;
199     void *dctx;
200     void *cdict_ctx;
201     void *ddict_ctx;
202     void *dict;
203     size_t dict_size;
204 
205     char *data;
206     size_t data_size;
207     size_t data_loc;
208     zckChunk *data_idx;
209     int data_eof;
210     char *dc_data;
211     size_t dc_data_size;
212     size_t dc_data_loc;
213 
214     finit init;
215     fparam set_parameter;
216     fcomp compress;
217     fccompend end_cchunk;
218     fdecomp decompress;
219     fdcompend end_dchunk;
220     fcclose close;
221 };
222 
223 typedef struct zckSig {
224     zckHashType hash_type;
225     size_t length;
226     char *signature;
227     void *ctx;
228 } zckSig;
229 
230 typedef struct zckSigCollection {
231     int count;
232     zckSig *sig;
233 } zckSigCollection;
234 
235 struct zckCtx {
236     int temp_fd;
237     int fd;
238     int mode;
239 
240     char *full_hash_digest;
241     char *header_digest;
242     size_t data_offset;
243     size_t header_length;
244 
245     char *header;
246     size_t header_size;
247     size_t hdr_digest_loc;
248     char *lead_string;
249     size_t lead_size;
250     char *preface_string;
251     size_t preface_size;
252     char *index_string;
253     size_t index_size;
254     char *sig_string;
255     size_t sig_size;
256 
257 
258     char *prep_digest;
259     int prep_hash_type;
260     ssize_t prep_hdr_size;
261 
262     zckIndex index;
263     zckChunk *work_index_item;
264     zckHash work_index_hash;
265     size_t stream;
266     int has_streams;
267     int has_optional_elems;
268 
269     char *read_buf;
270     size_t read_buf_size;
271 
272     zckHash full_hash;
273     zckHash check_full_hash;
274     zckHash check_chunk_hash;
275     zckComp comp;
276     zckHashType hash_type;
277     zckHashType chunk_hash_type;
278     zckSigCollection sigs;
279 
280     char *data;
281     size_t data_size;
282 
283     buzHash buzhash;
284     int buzhash_width;
285     int buzhash_match_bits;
286     int buzhash_bitmask;
287     int chunk_auto_min;
288     int chunk_auto_max;
289     int chunk_min_size;
290     int chunk_max_size;
291     int manual_chunk;
292 
293     char *msg;
294     int error_state;
295 };
296 
297 int get_tmp_fd()
298     __attribute__ ((warn_unused_result));
299 bool import_dict(zckCtx *zck)
300     __attribute__ ((warn_unused_result));
301 void *zmalloc(size_t size)
302     __attribute__ ((warn_unused_result));
303 void *zrealloc(void *ptr, size_t size)
304     __attribute__ ((warn_unused_result));
305 
306 
307 /* hash/hash.h */
308 bool hash_setup(zckCtx *zck, zckHashType *ht, int h)
309     __attribute__ ((warn_unused_result));
310 bool hash_init(zckCtx *zck, zckHash *hash, zckHashType *hash_type)
311     __attribute__ ((warn_unused_result));
312 bool hash_update(zckCtx *zck, zckHash *hash, const char *message,
313                  const size_t size)
314     __attribute__ ((warn_unused_result));
315 char *hash_finalize(zckCtx *zck, zckHash *hash)
316     __attribute__ ((warn_unused_result));
317 void hash_close(zckHash *hash);
318 void hash_reset(zckHashType *ht);
319 int validate_chunk(zckChunk *idx, zck_log_type bad_checksum)
320     __attribute__ ((warn_unused_result));
321 int validate_file(zckCtx *zck, zck_log_type bad_checksums)
322     __attribute__ ((warn_unused_result));
323 int validate_current_chunk(zckCtx *zck)
324     __attribute__ ((warn_unused_result));
325 int validate_header(zckCtx *zck)
326     __attribute__ ((warn_unused_result));
327 bool set_full_hash_type(zckCtx *zck, int hash_type)
328     __attribute__ ((warn_unused_result));
329 bool set_chunk_hash_type(zckCtx *zck, int hash_type)
330     __attribute__ ((warn_unused_result));
331 int get_max_hash_size()
332     __attribute__ ((warn_unused_result));
333 char *get_digest_string(const char *digest, int size)
334     __attribute__ ((warn_unused_result));
335 
336 
337 /* index/index.c */
338 bool index_read(zckCtx *zck, char *data, size_t size, size_t max_length)
339     __attribute__ ((warn_unused_result));
340 bool index_create(zckCtx *zck)
341     __attribute__ ((warn_unused_result));
342 bool index_new_chunk(zckCtx *zck, zckIndex *index, char *digest, int digest_size,
343                      size_t comp_size, size_t orig_size, zckChunk *src, bool valid)
344     __attribute__ ((warn_unused_result));
345 bool index_add_to_chunk(zckCtx *zck, char *data, size_t comp_size,
346                         size_t orig_size)
347     __attribute__ ((warn_unused_result));
348 bool index_finish_chunk(zckCtx *zck)
349     __attribute__ ((warn_unused_result));
350 void index_clean(zckIndex *index);
351 void index_free(zckCtx *zck);
352 void clear_work_index(zckCtx *zck);
353 bool write_index(zckCtx *zck)
354     __attribute__ ((warn_unused_result));
355 
356 
357 /* io.c */
358 int seek_data(zckCtx *zck, off_t offset, int whence)
359     __attribute__ ((warn_unused_result));
360 ssize_t tell_data(zckCtx *zck)
361     __attribute__ ((warn_unused_result));
362 ssize_t read_data(zckCtx *zck, char *data, size_t length)
363     __attribute__ ((warn_unused_result));
364 int write_data(zckCtx *zck, int fd, const char *data, size_t length)
365     __attribute__ ((warn_unused_result));
366 int chunks_from_temp(zckCtx *zck)
367     __attribute__ ((warn_unused_result));
368 
369 /* header.c */
370 bool header_create(zckCtx *zck)
371     __attribute__ ((warn_unused_result));
372 bool write_header(zckCtx *zck)
373     __attribute__ ((warn_unused_result));
374 
375 /* comp/comp.c */
376 bool comp_init(zckCtx *zck)
377     __attribute__ ((warn_unused_result));
378 bool comp_close(zckCtx *zck)
379     __attribute__ ((warn_unused_result));
380 bool comp_reset(zckCtx *zck)
381     __attribute__ ((warn_unused_result));
382 bool comp_add_to_dc(zckCtx *zck, zckComp *comp, const char *src, size_t src_size)
383     __attribute__ ((warn_unused_result));
384 ssize_t comp_read(zckCtx *zck, char *dst, size_t dst_size, bool use_dict)
385     __attribute__ ((warn_unused_result));
386 bool comp_ioption(zckCtx *zck, zck_ioption option, ssize_t value)
387     __attribute__ ((warn_unused_result));
388 bool comp_soption(zckCtx *zck, zck_soption option, const void *value,
389                   size_t length)
390     __attribute__ ((warn_unused_result));
391 
392 /* dl/range.c */
393 char *range_get_char(zckRangeItem **range, int max_ranges)
394     __attribute__ ((warn_unused_result));
395 
396 /* dl/multipart.c */
397 size_t multipart_extract(zckDL *dl, char *b, size_t l)
398     __attribute__ ((warn_unused_result));
399 size_t multipart_get_boundary(zckDL *dl, char *b, size_t size)
400     __attribute__ ((warn_unused_result));
401 void reset_mp(zckMP *mp);
402 
403 /* dl/dl.c */
404 int dl_write_range(zckDL *dl, const char *at, size_t length)
405     __attribute__ ((warn_unused_result));
406 
407 /* compint.c */
408 int compint_from_int(zckCtx *zck, char *compint, int val, size_t *length)
409     __attribute__ ((warn_unused_result));
410 void compint_from_size(char *compint, size_t val, size_t *length);
411 int compint_to_int(zckCtx *zck, int *val, const char *compint, size_t *length,
412                    size_t max_length)
413     __attribute__ ((warn_unused_result));
414 int compint_to_size(zckCtx *zck, size_t *val, const char *compint,
415                     size_t *length, size_t max_length)
416     __attribute__ ((warn_unused_result));
417 
418 /* log.c */
419 void zck_log_v(const char *function, zck_log_type lt, const char *format,
420      va_list args);
421 void zck_log_wf(const char *function, zck_log_type lt, const char *format, ...);
422 
423 /* error.c */
424 void set_error_wf(zckCtx *zck, int fatal, const char *function,
425                   const char *format, ...);
426 
427 #endif
428