From: Jonathan Dieter Date: Tue, 24 Jul 2018 21:29:50 +0000 (+0100) Subject: Update everything to use new error functions X-Git-Tag: archive/raspbian/1.1.9+ds1-1+rpi1~1^2~185 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=d41812cda6dc84340f25db0145246ae37e99af5e;p=zchunk.git Update everything to use new error functions Signed-off-by: Jonathan Dieter --- diff --git a/src/lib/comp/comp.c b/src/lib/comp/comp.c index 9e6b85a..e72cbcb 100644 --- a/src/lib/comp/comp.c +++ b/src/lib/comp/comp.c @@ -38,45 +38,6 @@ #endif #define BLK_SIZE 32768 -#define VALIDATE(f) if(!f) { \ - zck_log(ZCK_LOG_ERROR, \ - "zckCtx not initialized\n"); \ - return False; \ - } - -#define VALIDATE_READ(f) VALIDATE(f); \ - if(f->mode != ZCK_MODE_READ) { \ - zck_log(ZCK_LOG_ERROR, \ - "zckCtx not opened for reading\n"); \ - return False; \ - } - -#define VALIDATE_WRITE(f) VALIDATE(f); \ - if(f->mode != ZCK_MODE_WRITE) { \ - zck_log(ZCK_LOG_ERROR, \ - "zckCtx not opened for writing\n"); \ - return False; \ - } - -#define VALIDATE_SIZE(f) if(!f) { \ - zck_log(ZCK_LOG_ERROR, \ - "zckComp not initialized\n"); \ - return -1; \ - } - -#define VALIDATE_READ_SIZE(f) VALIDATE_SIZE(f); \ - if(f->mode != ZCK_MODE_READ) { \ - zck_log(ZCK_LOG_ERROR, \ - "zckComp not opened for reading\n"); \ - return -1; \ - } - -#define VALIDATE_WRITE_SIZE(f) VALIDATE_SIZE(f); \ - if(f->mode != ZCK_MODE_WRITE) { \ - zck_log(ZCK_LOG_ERROR, \ - "zckComp not opened for writing\n"); \ - return -1; \ - } static char unknown[] = "Unknown(\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; @@ -87,14 +48,13 @@ const static char *COMP_NAME[] = { }; static int set_comp_type(zckCtx *zck, ssize_t type) { - VALIDATE(zck); + VALIDATE_BOOL(zck); zckComp *comp = &(zck->comp); /* Cannot change compression type after compression has started */ if(comp->started) { - zck_log(ZCK_LOG_ERROR, - "Unable to set compression type after initialization\n"); + set_error(zck, "Unable to set compression type after initialization"); return False; } @@ -107,25 +67,27 @@ static int set_comp_type(zckCtx *zck, ssize_t type) { comp->dc_data_loc = dc_data_loc; comp->dc_data_size = dc_data_size; - zck_log(ZCK_LOG_DEBUG, "Setting compression to %s\n", + zck_log(ZCK_LOG_DEBUG, "Setting compression to %s", zck_comp_name_from_type(type)); if(type == ZCK_COMP_NONE) { - return nocomp_setup(comp); + return nocomp_setup(zck, comp); #ifdef ZCHUNK_ZSTD } else if(type == ZCK_COMP_ZSTD) { - return zstd_setup(comp); + return zstd_setup(zck, comp); #endif } else { - zck_log(ZCK_LOG_ERROR, "Unsupported compression type: %s\n", - zck_comp_name_from_type(type)); + set_error(zck, "Unsupported compression type: %s", + zck_comp_name_from_type(type)); return False; } return True; } -static size_t comp_read_from_dc(zckComp *comp, char *dst, size_t dst_size) { - VALIDATE_SIZE(comp); - VALIDATE_SIZE(dst); +static size_t comp_read_from_dc(zckCtx *zck, zckComp *comp, char *dst, + size_t dst_size) { + VALIDATE_TRI(zck); + _VALIDATE_TRI(comp); + _VALIDATE_TRI(dst); size_t dl_size = dst_size; if(dl_size > comp->dc_data_size - comp->dc_data_loc) @@ -133,21 +95,24 @@ static size_t comp_read_from_dc(zckComp *comp, char *dst, size_t dst_size) { memcpy(dst, comp->dc_data+comp->dc_data_loc, dl_size); comp->dc_data_loc += dl_size; if(dl_size > 0) - zck_log(ZCK_LOG_DEBUG, "Reading %lu bytes from decompressed buffer\n", + zck_log(ZCK_LOG_DEBUG, "Reading %lu bytes from decompressed buffer", dl_size); return dl_size; } -static int comp_add_to_data(zckComp *comp, const char *src, size_t src_size) { - VALIDATE(comp); - VALIDATE(src); +static int comp_add_to_data(zckCtx *zck, zckComp *comp, const char *src, + size_t src_size) { + VALIDATE_BOOL(zck); + _VALIDATE_BOOL(comp); + _VALIDATE_BOOL(src); + comp->data = realloc(comp->data, comp->data_size + src_size); if(comp->data == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to reallocate %lu bytes\n", - comp->data_size + src_size); + set_fatal_error(zck, "Unable to reallocate %lu bytes", + comp->data_size + src_size); return False; } - zck_log(ZCK_LOG_DEBUG, "Adding %lu bytes to compressed buffer\n", + zck_log(ZCK_LOG_DEBUG, "Adding %lu bytes to compressed buffer", src_size); memcpy(comp->data + comp->data_size, src, src_size); comp->data_size += src_size; @@ -156,18 +121,20 @@ static int comp_add_to_data(zckComp *comp, const char *src, size_t src_size) { } static ssize_t comp_end_dchunk(zckCtx *zck, int use_dict, size_t fd_size) { - ssize_t rb = zck->comp.end_dchunk(&(zck->comp), use_dict, fd_size); + VALIDATE_READ_TRI(zck); + + ssize_t rb = zck->comp.end_dchunk(zck, &(zck->comp), use_dict, fd_size); if(validate_current_chunk(zck) < 1) return -1; zck->comp.data_loc = 0; zck->comp.data_idx = zck->comp.data_idx->next; - if(!hash_init(&(zck->check_chunk_hash), &(zck->chunk_hash_type))) + if(!hash_init(zck, &(zck->check_chunk_hash), &(zck->chunk_hash_type))) return -1; return rb; } static ssize_t comp_write(zckCtx *zck, const char *src, const size_t src_size) { - VALIDATE_WRITE_SIZE(zck); + VALIDATE_WRITE_TRI(zck); if(!zck->comp.started && !comp_init(zck)) return -1; @@ -177,9 +144,10 @@ static ssize_t comp_write(zckCtx *zck, const char *src, const size_t src_size) { char *dst = NULL; size_t dst_size = 0; - if(zck->comp.compress(&(zck->comp), src, src_size, &dst, &dst_size, 1) < 0) + if(zck->comp.compress(zck, &(zck->comp), src, src_size, &dst, + &dst_size, 1) < 0) return -1; - if(dst_size > 0 && !write_data(zck->temp_fd, dst, dst_size)) { + if(dst_size > 0 && !write_data(zck, zck->temp_fd, dst, dst_size)) { free(dst); return -1; } @@ -192,32 +160,32 @@ static ssize_t comp_write(zckCtx *zck, const char *src, const size_t src_size) { } int comp_init(zckCtx *zck) { - VALIDATE(zck); + VALIDATE_BOOL(zck); zckComp *comp = &(zck->comp); if(zck->comp.started) { - zck_log(ZCK_LOG_ERROR, "Compression already initialized\n"); + set_error(zck, "Compression already initialized"); return False; } if((zck->comp.dict && zck->comp.dict_size == 0) || (zck->comp.dict == NULL && zck->comp.dict_size > 0)) { - zck_log(ZCK_LOG_ERROR, "Invalid dictionary configuration\n"); + set_error(zck, "Invalid dictionary configuration"); return False; } - zck_log(ZCK_LOG_DEBUG, "Initializing %s compression\n", + zck_log(ZCK_LOG_DEBUG, "Initializing %s compression", zck_comp_name_from_type(comp->type)); - if(!zck->comp.init(&(zck->comp))) + if(!zck->comp.init(zck, &(zck->comp))) return False; if(zck->temp_fd) { if(zck->comp.dict) { char *dst = NULL; size_t dst_size = 0; - if(zck->comp.compress(comp, zck->comp.dict, zck->comp.dict_size, - &dst, &dst_size, 0) < 0) + if(zck->comp.compress(zck, comp, zck->comp.dict, + zck->comp.dict_size, &dst, &dst_size, 0) < 0) return False; - if(!write_data(zck->temp_fd, dst, dst_size)) { + if(!write_data(zck, zck->temp_fd, dst, dst_size)) { free(dst); return False; } @@ -230,9 +198,9 @@ int comp_init(zckCtx *zck) { dst = NULL; dst_size = 0; - if(!zck->comp.end_cchunk(comp, &dst, &dst_size, 0)) + if(!zck->comp.end_cchunk(zck, comp, &dst, &dst_size, 0)) return False; - if(!write_data(zck->temp_fd, dst, dst_size)) { + if(!write_data(zck, zck->temp_fd, dst, dst_size)) { free(dst); return False; } @@ -255,7 +223,7 @@ int comp_init(zckCtx *zck) { } int comp_reset(zckCtx *zck) { - VALIDATE(zck); + VALIDATE_BOOL(zck); zck->comp.started = 0; if(zck->comp.dc_data) { @@ -266,12 +234,13 @@ int comp_reset(zckCtx *zck) { } if(zck->comp.close == NULL) return True; - return zck->comp.close(&(zck->comp)); + return zck->comp.close(zck, &(zck->comp)); } int comp_close(zckCtx *zck) { - VALIDATE(zck); - zck_log(ZCK_LOG_DEBUG, "Closing compression\n"); + VALIDATE_BOOL(zck); + + zck_log(ZCK_LOG_DEBUG, "Closing compression"); if(zck->comp.data) { free(zck->comp.data); zck->comp.data = NULL; @@ -283,22 +252,22 @@ int comp_close(zckCtx *zck) { } int comp_ioption(zckCtx *zck, zck_ioption option, ssize_t value) { - VALIDATE(zck); + VALIDATE_BOOL(zck); /* Cannot change compression parameters after compression has started */ if(zck && zck->comp.started) { - zck_log(ZCK_LOG_ERROR, - "Unable to set compression parameters after initialization\n"); + set_error(zck, + "Unable to set compression parameters after initialization"); return False; } if(option == ZCK_COMP_TYPE) { return set_comp_type(zck, value); } else { if(zck && zck->comp.set_parameter) - return zck->comp.set_parameter(&(zck->comp), option, &value); + return zck->comp.set_parameter(zck, &(zck->comp), option, &value); - zck_log(ZCK_LOG_ERROR, "Unsupported compression parameter: %i\n", - option); + set_error(zck, "Unsupported compression parameter: %i", + option); return False; } return True; @@ -306,12 +275,12 @@ int comp_ioption(zckCtx *zck, zck_ioption option, ssize_t value) { int comp_soption(zckCtx *zck, zck_soption option, const void *value, size_t length) { - VALIDATE(zck); + VALIDATE_BOOL(zck); /* Cannot change compression parameters after compression has started */ if(zck && zck->comp.started) { - zck_log(ZCK_LOG_ERROR, - "Unable to set compression parameters after initialization\n"); + set_error(zck, + "Unable to set compression parameters after initialization"); return False; } if(option == ZCK_COMP_DICT) { @@ -319,30 +288,31 @@ int comp_soption(zckCtx *zck, zck_soption option, const void *value, zck->comp.dict_size = length; } else { if(zck && zck->comp.set_parameter) - return zck->comp.set_parameter(&(zck->comp), option, value); + return zck->comp.set_parameter(zck, &(zck->comp), option, value); - zck_log(ZCK_LOG_ERROR, "Unsupported compression parameter: %i\n", - option); + set_error(zck, "Unsupported compression parameter: %i", option); return False; } return True; } -int comp_add_to_dc(zckComp *comp, const char *src, size_t src_size) { - VALIDATE(comp); - VALIDATE(src); +int comp_add_to_dc(zckCtx *zck, zckComp *comp, const char *src, + size_t src_size) { + VALIDATE_BOOL(zck); + _VALIDATE_BOOL(comp); + _VALIDATE_BOOL(src); /* Get rid of any already read data and allocate space for new data */ char *temp = zmalloc(comp->dc_data_size - comp->dc_data_loc + src_size); if(temp == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", - comp->dc_data_size - comp->dc_data_loc + src_size); + set_fatal_error(zck, "Unable to allocate %lu bytes", + comp->dc_data_size - comp->dc_data_loc + src_size); return False; } if(comp->dc_data_loc != 0) - zck_log(ZCK_LOG_DEBUG, "Freeing %lu bytes from decompressed buffer\n", + zck_log(ZCK_LOG_DEBUG, "Freeing %lu bytes from decompressed buffer", comp->dc_data_loc); - zck_log(ZCK_LOG_DEBUG, "Adding %lu bytes to decompressed buffer\n", + zck_log(ZCK_LOG_DEBUG, "Adding %lu bytes to decompressed buffer", src_size); memcpy(temp, comp->dc_data + comp->dc_data_loc, comp->dc_data_size - comp->dc_data_loc); @@ -358,10 +328,10 @@ int comp_add_to_dc(zckComp *comp, const char *src, size_t src_size) { } ssize_t comp_read(zckCtx *zck, char *dst, size_t dst_size, int use_dict) { - VALIDATE_READ_SIZE(zck); + VALIDATE_READ_TRI(zck); if(!zck->comp.started) { - zck_log(ZCK_LOG_ERROR, "Compression hasn't been initialized yet\n"); + set_error(zck, "Compression hasn't been initialized yet"); return -1; } @@ -376,15 +346,15 @@ ssize_t comp_read(zckCtx *zck, char *dst, size_t dst_size, int use_dict) { size_t dc = 0; char *src = zmalloc(dst_size - dc); if(src == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", dst_size-dc); + set_fatal_error(zck, "Unable to allocate %lu bytes", dst_size-dc); return False; } int finished_rd = False; int finished_dc = False; - zck_log(ZCK_LOG_DEBUG, "Trying to read %lu bytes\n", dst_size); + zck_log(ZCK_LOG_DEBUG, "Trying to read %lu bytes", dst_size); while(dc < dst_size) { /* Get bytes from decompressed buffer */ - ssize_t rb = comp_read_from_dc(&(zck->comp), dst+dc, dst_size-dc); + ssize_t rb = comp_read_from_dc(zck, &(zck->comp), dst+dc, dst_size-dc); if(rb < 0) goto read_error; dc += rb; @@ -398,7 +368,7 @@ ssize_t comp_read(zckCtx *zck, char *dst, size_t dst_size, int use_dict) { /* Decompress compressed buffer into decompressed buffer */ size_t dc_data_size = zck->comp.dc_data_size; size_t dc_data_loc = zck->comp.dc_data_loc; - if(!zck->comp.decompress(&(zck->comp), use_dict)) + if(!zck->comp.decompress(zck, &(zck->comp), use_dict)) goto read_error; /* Check whether we decompressed more data */ @@ -412,14 +382,15 @@ ssize_t comp_read(zckCtx *zck, char *dst, size_t dst_size, int use_dict) { /* Skip first chunk if it's an empty dict */ if(zck->comp.data_idx->comp_length == 0) zck->comp.data_idx = zck->comp.data_idx->next; - if(!hash_init(&(zck->check_chunk_hash), &(zck->chunk_hash_type))) + if(!hash_init(zck, &(zck->check_chunk_hash), + &(zck->chunk_hash_type))) goto hash_error; if(zck->comp.data_loc > 0) { - if(!hash_update(&(zck->check_full_hash), zck->comp.data, - zck->comp.data_loc)) + if(!hash_update(zck, &(zck->check_full_hash), zck->comp.data, + zck->comp.data_loc)) goto hash_error; - if(!hash_update(&(zck->check_chunk_hash), zck->comp.data, - zck->comp.data_loc)) + if(!hash_update(zck, &(zck->check_chunk_hash), zck->comp.data, + zck->comp.data_loc)) goto hash_error; } if(zck->comp.data_idx == NULL) { @@ -449,16 +420,16 @@ ssize_t comp_read(zckCtx *zck, char *dst, size_t dst_size, int use_dict) { /* Decompressed buffer is empty, so read data from file and fill * compressed buffer */ - rb = read_data(zck->fd, src, rs); + rb = read_data(zck, src, rs); if(rb < 0) goto read_error; if(rb < rs) { - zck_log(ZCK_LOG_DEBUG, "EOF\n"); + zck_log(ZCK_LOG_DEBUG, "EOF"); finished_rd = True; } - if(!hash_update(&(zck->check_full_hash), src, rb) || - !hash_update(&(zck->check_chunk_hash), src, rb) || - !comp_add_to_data(&(zck->comp), src, rb)) + if(!hash_update(zck, &(zck->check_full_hash), src, rb) || + !hash_update(zck, &(zck->check_chunk_hash), src, rb) || + !comp_add_to_data(zck, &(zck->comp), src, rb)) goto read_error; } free(src); @@ -490,7 +461,7 @@ ssize_t PUBLIC zck_write(zckCtx *zck, const char *src, const size_t src_size) { zck->buzhash_bitmask) == 0) { if(comp_write(zck, loc, i) != i) return -1; - zck_log(ZCK_LOG_DEBUG, "Automatically ending chunk\n"); + zck_log(ZCK_LOG_DEBUG, "Automatically ending chunk"); if(zck_end_chunk(zck) < 0) return -1; loc += i; @@ -507,7 +478,7 @@ ssize_t PUBLIC zck_write(zckCtx *zck, const char *src, const size_t src_size) { } ssize_t PUBLIC zck_end_chunk(zckCtx *zck) { - VALIDATE_WRITE_SIZE(zck); + VALIDATE_WRITE_TRI(zck); if(!zck->comp.started && !comp_init(zck)) return -1; @@ -520,9 +491,9 @@ ssize_t PUBLIC zck_end_chunk(zckCtx *zck) { size_t data_size = zck->comp.dc_data_size; char *dst = NULL; size_t dst_size = 0; - if(!zck->comp.end_cchunk(&(zck->comp), &dst, &dst_size, 1)) + if(!zck->comp.end_cchunk(zck, &(zck->comp), &dst, &dst_size, 1)) return -1; - if(dst_size > 0 && !write_data(zck->temp_fd, dst, dst_size)) { + if(dst_size > 0 && !write_data(zck, zck->temp_fd, dst, dst_size)) { free(dst); return -1; } @@ -534,13 +505,13 @@ ssize_t PUBLIC zck_end_chunk(zckCtx *zck) { free(dst); return -1; } - zck_log(ZCK_LOG_DEBUG, "Finished chunk size: %lu\n", data_size); + zck_log(ZCK_LOG_DEBUG, "Finished chunk size: %lu", data_size); free(dst); return data_size; } ssize_t PUBLIC zck_read(zckCtx *zck, char *dst, size_t dst_size) { - VALIDATE_READ_SIZE(zck); + VALIDATE_READ_TRI(zck); return comp_read(zck, dst, dst_size, 1); } diff --git a/src/lib/comp/nocomp/nocomp.c b/src/lib/comp/nocomp/nocomp.c index 890a857..3ab7db6 100644 --- a/src/lib/comp/nocomp/nocomp.c +++ b/src/lib/comp/nocomp/nocomp.c @@ -31,11 +31,11 @@ #include "zck_private.h" -static int init(zckComp *comp) { +static int init(zckCtx *zck, zckComp *comp) { return True; } -static int end_cchunk(zckComp *comp, char **dst, size_t *dst_size, +static int end_cchunk(zckCtx *zck, zckComp *comp, char **dst, size_t *dst_size, int use_dict) { *dst = NULL; *dst_size = 0; @@ -43,11 +43,12 @@ static int end_cchunk(zckComp *comp, char **dst, size_t *dst_size, return True; } -static ssize_t compress(zckComp *comp, const char *src, const size_t src_size, - char **dst, size_t *dst_size, int use_dict) { +static ssize_t compress(zckCtx *zck, zckComp *comp, const char *src, + const size_t src_size, char **dst, size_t *dst_size, + int use_dict) { *dst = zmalloc(src_size); if(dst == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", src_size); + set_fatal_error(zck, "Unable to allocate %lu bytes", src_size); return -1; } @@ -58,12 +59,12 @@ static ssize_t compress(zckComp *comp, const char *src, const size_t src_size, } -static int decompress(zckComp *comp, const int use_dict) { +static int decompress(zckCtx *zck, zckComp *comp, const int use_dict) { char *src = comp->data; char src_size = comp->data_size; comp->data = NULL; comp->data_size = 0; - if(!comp_add_to_dc(comp, src, src_size)) { + if(!comp_add_to_dc(zck, comp, src, src_size)) { free(src); return False; } @@ -71,27 +72,29 @@ static int decompress(zckComp *comp, const int use_dict) { return True; } -static int end_dchunk(zckComp *comp, const int use_dict, const size_t fd_size) { +static int end_dchunk(zckCtx *zck, zckComp *comp, const int use_dict, + const size_t fd_size) { return True; } -static int close(zckComp *comp) { +static int close(zckCtx *zck, zckComp *comp) { return True; } /* Nocomp doesn't support any parameters, so return error if setting a parameter * was attempted */ -static int set_parameter(zckComp *comp, int option, const void *value) { - zck_log(ZCK_LOG_ERROR, "Invalid compression parameter for ZCK_COMP_NONE\n"); +static int set_parameter(zckCtx *zck, zckComp *comp, int option, + const void *value) { + set_error(zck, "Invalid compression parameter for ZCK_COMP_NONE"); return False; } /* No default parameters to set when there's no compression */ -static int set_default_parameters(zckComp *comp) { +static int set_default_parameters(zckCtx *zck, zckComp *comp) { return True; } -int nocomp_setup(zckComp *comp) { +int nocomp_setup(zckCtx *zck, zckComp *comp) { comp->init = init; comp->set_parameter = set_parameter; comp->compress = compress; @@ -100,5 +103,5 @@ int nocomp_setup(zckComp *comp) { comp->end_dchunk = end_dchunk; comp->close = close; comp->type = ZCK_COMP_NONE; - return set_default_parameters(comp); + return set_default_parameters(zck, comp); } diff --git a/src/lib/comp/nocomp/nocomp.h b/src/lib/comp/nocomp/nocomp.h index 31953cf..e15f22c 100644 --- a/src/lib/comp/nocomp/nocomp.h +++ b/src/lib/comp/nocomp/nocomp.h @@ -1,6 +1,6 @@ #ifndef ZCHUNK_COMPRESSION_NOCOMP_H #define ZCHUNK_COMPRESSION_NOCOMP_H -int nocomp_setup(zckComp *comp); +int nocomp_setup(zckCtx *zck, zckComp *comp); #endif diff --git a/src/lib/comp/zstd/zstd.c b/src/lib/comp/zstd/zstd.c index 0f59726..db50c4d 100644 --- a/src/lib/comp/zstd/zstd.c +++ b/src/lib/comp/zstd/zstd.c @@ -32,26 +32,24 @@ #include "zck_private.h" -#define VALIDATE(f) if(!f) { \ - zck_log(ZCK_LOG_ERROR, "zckComp not initialized\n"); \ - return False; \ - } +static int init(zckCtx *zck, zckComp *comp) { + VALIDATE_BOOL(zck); + _VALIDATE_BOOL(comp); -static int init(zckComp *comp) { comp->cctx = ZSTD_createCCtx(); comp->dctx = ZSTD_createDCtx(); if(comp->dict && comp->dict_size > 0) { comp->cdict_ctx = ZSTD_createCDict(comp->dict, comp->dict_size, comp->level); if(comp->cdict_ctx == NULL) { - zck_log(ZCK_LOG_ERROR, - "Unable to create zstd compression dict context\n"); + set_fatal_error(zck, + "Unable to create zstd compression dict context"); return False; } comp->ddict_ctx = ZSTD_createDDict(comp->dict, comp->dict_size); if(comp->ddict_ctx == NULL) { - zck_log(ZCK_LOG_ERROR, - "Unable to create zstd decompression dict context\n"); + set_fatal_error(zck, + "Unable to create zstd decompression dict context"); return False; } } @@ -61,12 +59,16 @@ static int init(zckComp *comp) { /* The zstd compression format doesn't allow streaming compression with a dict * unless you statically link to it. If we have a dict, we do pseudo-streaming * compression where we buffer the data until the chunk ends. */ -static ssize_t compress(zckComp *comp, const char *src, const size_t src_size, - char **dst, size_t *dst_size, int use_dict) { +static ssize_t compress(zckCtx *zck, zckComp *comp, const char *src, + const size_t src_size, char **dst, size_t *dst_size, + int use_dict) { + VALIDATE_TRI(zck); + _VALIDATE_TRI(comp); + comp->dc_data = realloc(comp->dc_data, comp->dc_data_size + src_size); if(comp->dc_data == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", - comp->dc_data_size + src_size); + set_fatal_error(zck, "Unable to allocate %lu bytes", + comp->dc_data_size + src_size); return -1; } memcpy(comp->dc_data + comp->dc_data_size, src, src_size); @@ -76,19 +78,21 @@ static ssize_t compress(zckComp *comp, const char *src, const size_t src_size, return 0; } -static int end_cchunk(zckComp *comp, char **dst, size_t *dst_size, +static int end_cchunk(zckCtx *zck, zckComp *comp, char **dst, size_t *dst_size, int use_dict) { - VALIDATE(comp); + VALIDATE_BOOL(zck); + _VALIDATE_BOOL(comp); + size_t max_size = ZSTD_compressBound(comp->dc_data_size); if(ZSTD_isError(max_size)) { - zck_log(ZCK_LOG_ERROR, "zstd compression error: %s\n", - ZSTD_getErrorName(max_size)); + set_fatal_error(zck, "zstd compression error: %s", + ZSTD_getErrorName(max_size)); return False; } *dst = zmalloc(max_size); if(dst == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", max_size); + set_fatal_error(zck, "Unable to allocate %lu bytes", max_size); return False; } @@ -105,47 +109,54 @@ static int end_cchunk(zckComp *comp, char **dst, size_t *dst_size, comp->dc_data_size = 0; comp->dc_data_loc = 0; if(ZSTD_isError(*dst_size)) { - zck_log(ZCK_LOG_ERROR, "zstd compression error: %s\n", - ZSTD_getErrorName(*dst_size)); + set_fatal_error(zck, "zstd compression error: %s", + ZSTD_getErrorName(*dst_size)); return False; } return True; } -static int decompress(zckComp *comp, const int use_dict) { - VALIDATE(comp); +static int decompress(zckCtx *zck, zckComp *comp, const int use_dict) { + VALIDATE_BOOL(zck); + _VALIDATE_BOOL(comp); return True; } -static int end_dchunk(zckComp *comp, const int use_dict, const size_t fd_size) { +static int end_dchunk(zckCtx *zck, zckComp *comp, const int use_dict, + const size_t fd_size) { + VALIDATE_BOOL(zck); + _VALIDATE_BOOL(comp); + char *src = comp->data; size_t src_size = comp->data_size; comp->data = NULL; comp->data_size = 0; char *dst = zmalloc(fd_size); - if(dst == NULL) + if(dst == NULL) { + set_fatal_error(zck, "Unable to allocate %lu bytes", fd_size); goto decomp_error_1; + } size_t retval; - zck_log(ZCK_LOG_DEBUG, "Decompressing %lu bytes to %lu bytes\n", src_size, + zck_log(ZCK_LOG_DEBUG, "Decompressing %lu bytes to %lu bytes", src_size, fd_size); if(use_dict && comp->ddict_ctx) { - zck_log(ZCK_LOG_DEBUG, "Running decompression using dict\n"); + zck_log(ZCK_LOG_DEBUG, "Running decompression using dict"); retval = ZSTD_decompress_usingDDict(comp->dctx, dst, fd_size, src, src_size, comp->ddict_ctx); } else { - zck_log(ZCK_LOG_DEBUG, "Running decompression\n"); + zck_log(ZCK_LOG_DEBUG, "Running decompression"); retval = ZSTD_decompressDCtx(comp->dctx, dst, fd_size, src, src_size); } if(ZSTD_isError(retval)) { - zck_log(ZCK_LOG_ERROR, "zstd decompression error: %s\n", - ZSTD_getErrorName(retval)); + set_fatal_error(zck, "zstd decompression error: %s", + ZSTD_getErrorName(retval)); goto decomp_error_2; } - if(!comp_add_to_dc(comp, dst, fd_size)) + if(!comp_add_to_dc(zck, comp, dst, fd_size)) goto decomp_error_2; free(dst); free(src); @@ -157,7 +168,7 @@ decomp_error_1: return False; } -static int close(zckComp *comp) { +static int close(zckCtx *zck, zckComp *comp) { if(comp->cdict_ctx) { ZSTD_freeCDict(comp->cdict_ctx); comp->cdict_ctx = NULL; @@ -177,24 +188,25 @@ static int close(zckComp *comp) { return True; } -static int set_parameter(zckComp *comp, int option, const void *value) { +static int set_parameter(zckCtx *zck, zckComp *comp, int option, + const void *value) { if(option == ZCK_ZSTD_COMP_LEVEL) { if(*(int*)value >= 0 && *(int*)value <= ZSTD_maxCLevel()) { comp->level = *(int*)value; return True; } } - zck_log(ZCK_LOG_ERROR, "Invalid compression parameter for ZCK_COMP_ZSTD\n"); + set_error(zck, "Invalid compression parameter for ZCK_COMP_ZSTD"); return False; } -static int set_default_parameters(zckComp *comp) { +static int set_default_parameters(zckCtx *zck, zckComp *comp) { /* Set default compression level to 16 */ int level=16; - return set_parameter(comp, ZCK_ZSTD_COMP_LEVEL, &level); + return set_parameter(zck, comp, ZCK_ZSTD_COMP_LEVEL, &level); } -int zstd_setup(zckComp *comp) { +int zstd_setup(zckCtx *zck, zckComp *comp) { comp->init = init; comp->set_parameter = set_parameter; comp->compress = compress; @@ -203,5 +215,5 @@ int zstd_setup(zckComp *comp) { comp->end_dchunk = end_dchunk; comp->close = close; comp->type = ZCK_COMP_ZSTD; - return set_default_parameters(comp); + return set_default_parameters(zck, comp); } diff --git a/src/lib/comp/zstd/zstd.h b/src/lib/comp/zstd/zstd.h index c3380ca..e948395 100644 --- a/src/lib/comp/zstd/zstd.h +++ b/src/lib/comp/zstd/zstd.h @@ -1,6 +1,6 @@ #ifndef ZCHUNK_COMPRESSION_ZSTD_H #define ZCHUNK_COMPRESSION_ZSTD_H -int zstd_setup(zckComp *comp); +int zstd_setup(zckCtx *zck, zckComp *comp); #endif diff --git a/src/lib/compint.c b/src/lib/compint.c index 8053509..519bdb8 100644 --- a/src/lib/compint.c +++ b/src/lib/compint.c @@ -42,8 +42,10 @@ void compint_from_size(char *compint, size_t val, size_t *length) { return; } -int compint_to_size(size_t *val, const char *compint, size_t *length, - size_t max_length) { +int compint_to_size(zckCtx *zck, size_t *val, const char *compint, + size_t *length, size_t max_length) { + VALIDATE_BOOL(zck); + *val = 0; size_t old_val = 0; const unsigned char *i = (unsigned char *)compint; @@ -67,9 +69,9 @@ int compint_to_size(size_t *val, const char *compint, size_t *length, /* Make sure we're not overflowing and fail if we do */ if(count > MAX_COMP_SIZE || count > max_length || *val < old_val) { if(count > max_length) - zck_log(ZCK_LOG_ERROR, "Read past end of header\n"); + set_fatal_error(zck, "Read past end of header"); else - zck_log(ZCK_LOG_ERROR, "Number too large\n"); + set_fatal_error(zck, "Number too large"); *length -= count; *val = 0; return False; @@ -79,9 +81,11 @@ int compint_to_size(size_t *val, const char *compint, size_t *length, return True; } -int compint_from_int(char *compint, int val, size_t *length) { +int compint_from_int(zckCtx *zck, char *compint, int val, size_t *length) { + VALIDATE_BOOL(zck); + if(val < 0) { - zck_log(ZCK_LOG_ERROR, "Unable to compress negative integers\n"); + set_error(zck, "Unable to compress negative integers"); return False; } @@ -89,14 +93,16 @@ int compint_from_int(char *compint, int val, size_t *length) { return True; } -int compint_to_int(int *val, const char *compint, size_t *length, +int compint_to_int(zckCtx *zck, int *val, const char *compint, size_t *length, size_t max_length) { + VALIDATE_BOOL(zck); + size_t new = (size_t)*val; - if(!compint_to_size(&new, compint, length, max_length)) + if(!compint_to_size(zck, &new, compint, length, max_length)) return False; *val = (int)new; if(*val < 0) { - zck_log(ZCK_LOG_ERROR, "Overflow error: compressed int is negative\n"); + set_fatal_error(zck, "Overflow error: compressed int is negative"); return False; } return True; diff --git a/src/lib/dl/dl.c b/src/lib/dl/dl.c index 533321f..5daf381 100644 --- a/src/lib/dl/dl.c +++ b/src/lib/dl/dl.c @@ -35,14 +35,9 @@ #include "zck_private.h" -#define VALIDATE(f) if(!f) { \ - zck_log(ZCK_LOG_ERROR, "zckDL not allocated\n"); \ - return False; \ - } - /* Free zckDL header regex used for downloading ranges */ static void clear_dl_regex(zckDL *dl) { - if(dl == NULL || dl == NULL) + if(dl == NULL) return; if(dl->hdr_regex) { @@ -66,13 +61,13 @@ static void clear_dl_regex(zckDL *dl) { static int zero_chunk(zckCtx *tgt, zckChunk *tgt_idx) { char buf[BUF_SIZE] = {0}; size_t to_read = tgt_idx->comp_length; - if(!seek_data(tgt->fd, tgt->data_offset + tgt_idx->start, SEEK_SET)) + if(!seek_data(tgt, tgt->data_offset + tgt_idx->start, SEEK_SET)) return False; while(to_read > 0) { int rb = BUF_SIZE; if(rb > to_read) rb = to_read; - if(!write_data(tgt->fd, buf, rb)) + if(!write_data(tgt, tgt->fd, buf, rb)) return False; to_read -= rb; } @@ -81,8 +76,8 @@ static int zero_chunk(zckCtx *tgt, zckChunk *tgt_idx) { /* Check whether last downloaded chunk is valid and zero it out if it isn't */ static int set_chunk_valid(zckDL *dl) { - VALIDATE(dl); - VALIDATE(dl); + _VALIDATE_BOOL(dl); + VALIDATE_BOOL(dl->zck); int retval = validate_chunk(dl->zck, dl->tgt_check, ZCK_LOG_WARNING, dl->tgt_number); @@ -100,20 +95,21 @@ static int set_chunk_valid(zckDL *dl) { /* Write length or to end of current chunk, whichever comes first */ static int dl_write(zckDL *dl, const char *at, size_t length) { - VALIDATE(dl); - VALIDATE(dl); + _VALIDATE_TRI(dl); + VALIDATE_TRI(dl->zck); + int wb = 0; if(dl->write_in_chunk > 0) { if(dl->write_in_chunk < length) wb = dl->write_in_chunk; else wb = length; - if(!write_data(dl->zck->fd, at, wb)) + if(!write_data(dl->zck, dl->zck->fd, at, wb)) return -1; dl->write_in_chunk -= wb; - if(!hash_update(&(dl->zck->check_chunk_hash), at, wb)) + if(!hash_update(dl->zck, &(dl->zck->check_chunk_hash), at, wb)) return -1; - zck_log(ZCK_LOG_DEBUG, "Writing %lu bytes\n", wb); + zck_log(ZCK_LOG_DEBUG, "Writing %lu bytes", wb); dl->dl_chunk_data += wb; } return wb; @@ -123,43 +119,46 @@ static int dl_write(zckDL *dl, const char *at, size_t length) { static int write_and_verify_chunk(zckCtx *src, zckCtx *tgt, zckChunk *src_idx, zckChunk *tgt_idx) { + VALIDATE_READ_BOOL(src); + VALIDATE_WRITE_BOOL(tgt); + static char buf[BUF_SIZE] = {0}; size_t to_read = src_idx->comp_length; - if(!seek_data(src->fd, src->data_offset + src_idx->start, SEEK_SET)) + if(!seek_data(src, src->data_offset + src_idx->start, SEEK_SET)) return False; - if(!seek_data(tgt->fd, tgt->data_offset + tgt_idx->start, SEEK_SET)) + if(!seek_data(tgt, tgt->data_offset + tgt_idx->start, SEEK_SET)) return False; zckHash check_hash = {0}; - if(!hash_init(&check_hash, &(src->chunk_hash_type))) + if(!hash_init(tgt, &check_hash, &(src->chunk_hash_type))) return False; while(to_read > 0) { int rb = BUF_SIZE; if(rb > to_read) rb = to_read; - if(!read_data(src->fd, buf, rb)) + if(!read_data(src, buf, rb)) return False; - if(!hash_update(&check_hash, buf, rb)) + if(!hash_update(tgt, &check_hash, buf, rb)) return False; - if(!write_data(tgt->fd, buf, rb)) + if(!write_data(tgt, tgt->fd, buf, rb)) return False; to_read -= rb; } - char *digest = hash_finalize(&check_hash); + char *digest = hash_finalize(tgt, &check_hash); /* If chunk is invalid, overwrite with zeros and add to download range */ if(memcmp(digest, src_idx->digest, src_idx->digest_size) != 0) { char *pdigest = zck_get_chunk_digest(src_idx); - zck_log(ZCK_LOG_WARNING, "Source hash: %s\n", pdigest); + zck_log(ZCK_LOG_WARNING, "Source hash: %s", pdigest); free(pdigest); pdigest = get_digest_string(digest, src_idx->digest_size); - zck_log(ZCK_LOG_WARNING, "Target hash: %s\n", pdigest); + zck_log(ZCK_LOG_WARNING, "Target hash: %s", pdigest); free(pdigest); if(!zero_chunk(tgt, tgt_idx)) return False; tgt_idx->valid = -1; } else { tgt_idx->valid = 1; - zck_log(ZCK_LOG_DEBUG, "Wrote %lu bytes at %lu\n", + zck_log(ZCK_LOG_DEBUG, "Wrote %lu bytes at %lu", tgt_idx->comp_length, tgt_idx->start); } free(digest); @@ -168,19 +167,20 @@ static int write_and_verify_chunk(zckCtx *src, zckCtx *tgt, /* Split current read into the appropriate chunks and write appropriately */ int dl_write_range(zckDL *dl, const char *at, size_t length) { - VALIDATE(dl); - VALIDATE(dl); + _VALIDATE_BOOL(dl); + VALIDATE_BOOL(dl->zck); + if(dl->range == NULL) { - zck_log(ZCK_LOG_ERROR, "zckDL range not initialized\n"); + set_error(dl->zck, "zckDL range not initialized"); return 0; } if(dl->range->index.first == NULL) { - zck_log(ZCK_LOG_ERROR, "zckDL index not initialized\n"); + set_error(dl->zck, "zckDL index not initialized"); return 0; } - if(dl->zck == NULL || dl->zck->index.first == NULL) { - zck_log(ZCK_LOG_ERROR, "zckCtx index not initialized\n"); + if(dl->zck->index.first == NULL) { + set_error(dl->zck, "zckCtx index not initialized"); return 0; } int wb = dl_write(dl, at, length); @@ -203,11 +203,11 @@ int dl_write_range(zckDL *dl, const char *at, size_t length) { chk->digest_size) == 0) { dl->tgt_check = tgt_chk; dl->tgt_number = count; - if(!hash_init(&(dl->zck->check_chunk_hash), - &(dl->zck->chunk_hash_type))) + if(!hash_init(dl->zck, &(dl->zck->check_chunk_hash), + &(dl->zck->chunk_hash_type))) return 0; dl->write_in_chunk = chk->comp_length; - if(!seek_data(dl->zck->fd, + if(!seek_data(dl->zck, dl->zck->data_offset + tgt_chk->start, SEEK_SET)) return 0; @@ -265,13 +265,15 @@ int PUBLIC zck_copy_chunks(zckCtx *src, zckCtx *tgt) { return True; } -size_t PUBLIC zck_dl_get_bytes_downloaded(zckDL *dl) { - VALIDATE(dl); +ssize_t PUBLIC zck_dl_get_bytes_downloaded(zckDL *dl) { + _VALIDATE_TRI(dl); + return dl->dl; } -size_t PUBLIC zck_dl_get_bytes_uploaded(zckDL *dl) { - VALIDATE(dl); +ssize_t PUBLIC zck_dl_get_bytes_uploaded(zckDL *dl) { + _VALIDATE_TRI(dl); + return dl->ul; } @@ -279,15 +281,14 @@ size_t PUBLIC zck_dl_get_bytes_uploaded(zckDL *dl) { zckDL PUBLIC *zck_dl_init(zckCtx *zck) { zckDL *dl = zmalloc(sizeof(zckDL)); if(!dl) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes for zckDL\n", - sizeof(zckDL)); + set_fatal_error(zck, "Unable to allocate %lu bytes for zckDL", + sizeof(zckDL)); return NULL; } dl->mp = zmalloc(sizeof(zckMP)); if(!dl->mp) { - zck_log(ZCK_LOG_ERROR, - "Unable to allocate %lu bytes for dl->mp\n", - sizeof(zckMP)); + set_fatal_error(zck, "Unable to allocate %lu bytes for dl->mp", + sizeof(zckMP)); return NULL; } dl->zck = zck; @@ -326,54 +327,54 @@ void PUBLIC zck_dl_free(zckDL **dl) { } zckCtx PUBLIC *zck_dl_get_zck(zckDL *dl) { - if(dl == NULL) - return NULL; + _VALIDATE_CHAR(dl); + return dl->zck; } int PUBLIC zck_dl_set_zck(zckDL *dl, zckCtx *zck) { - if(dl == NULL) - return False; + _VALIDATE_BOOL(dl); + dl->zck = zck; return True; } int PUBLIC zck_dl_set_range(zckDL *dl, zckRange *range) { - if(dl == NULL) - return False; + _VALIDATE_BOOL(dl); + dl->range = range; return True; } zckRange PUBLIC *zck_dl_get_range(zckDL *dl) { - if(dl == NULL) - return NULL; + _VALIDATE_CHAR(dl); + return dl->range; } int PUBLIC zck_dl_set_header_cb(zckDL *dl, zck_wcb func) { - if(dl == NULL) - return False; + _VALIDATE_BOOL(dl); + dl->header_cb = func; return True; } int PUBLIC zck_dl_set_header_data(zckDL *dl, void *data) { - if(dl == NULL) - return False; + _VALIDATE_BOOL(dl); + dl->header_data = data; return True; } int PUBLIC zck_dl_set_write_cb(zckDL *dl, zck_wcb func) { - if(dl == NULL) - return False; + _VALIDATE_BOOL(dl); + dl->write_cb = func; return True; } int PUBLIC zck_dl_set_write_data(zckDL *dl, void *data) { - if(dl == NULL) - return False; + _VALIDATE_BOOL(dl); + dl->write_data = data; return True; } @@ -383,8 +384,7 @@ int PUBLIC zck_dl_set_write_data(zckDL *dl, void *data) { *******************************************************************/ size_t PUBLIC zck_header_cb(char *b, size_t l, size_t c, void *dl_v) { - if(dl_v == NULL) - return 0; + _VALIDATE_BOOL(dl_v); zckDL *dl = (zckDL*)dl_v; if(multipart_get_boundary(dl, b, c*l) == 0) @@ -396,13 +396,13 @@ size_t PUBLIC zck_header_cb(char *b, size_t l, size_t c, void *dl_v) { } size_t PUBLIC zck_write_zck_header_cb(void *ptr, size_t l, size_t c, void *dl_v) { - if(dl_v == NULL) - return 0; + _VALIDATE_BOOL(dl_v); zckDL *dl = (zckDL*)dl_v; + size_t wb = 0; dl->dl += l*c; - size_t loc = tell_data(dl->zck->fd); - zck_log(ZCK_LOG_DEBUG, "Downloading %lu bytes to position %lu\n", l*c, loc); + size_t loc = tell_data(dl->zck); + zck_log(ZCK_LOG_DEBUG, "Downloading %lu bytes to position %lu", l*c, loc); wb = write(dl->zck->fd, ptr, l*c); if(dl->write_cb) return dl->write_cb(ptr, l, c, dl->write_data); @@ -410,9 +410,9 @@ size_t PUBLIC zck_write_zck_header_cb(void *ptr, size_t l, size_t c, void *dl_v) } size_t PUBLIC zck_write_chunk_cb(void *ptr, size_t l, size_t c, void *dl_v) { - if(dl_v == NULL) - return 0; + _VALIDATE_BOOL(dl_v); zckDL *dl = (zckDL*)dl_v; + size_t wb = 0; dl->dl += l*c; if(dl->boundary != NULL) { diff --git a/src/lib/dl/multipart.c b/src/lib/dl/multipart.c index 936b5c0..b616d7d 100644 --- a/src/lib/dl/multipart.c +++ b/src/lib/dl/multipart.c @@ -33,60 +33,63 @@ #include "zck_private.h" -#define VALIDATE(f) if(!f) { \ - zck_log(ZCK_LOG_ERROR, "zckDL not allocated\n"); \ - return False; \ - } +static char *add_boundary_to_regex(zckCtx *zck, const char *regex, + const char *boundary) { + VALIDATE_CHAR(zck); -static char *add_boundary_to_regex(const char *regex, const char *boundary) { if(regex == NULL || boundary == NULL) return NULL; char *regex_b = zmalloc(strlen(regex) + strlen(boundary) + 1); if(regex_b == NULL) { - zck_log(ZCK_LOG_ERROR, - "Unable to reallocate %lu bytes for regular expression\n", - strlen(regex) + strlen(boundary) - 2); + set_fatal_error(zck, + "Unable to reallocate %lu bytes for regular expression", + strlen(regex) + strlen(boundary) - 2); return NULL; } if(snprintf(regex_b, strlen(regex) + strlen(boundary), regex, boundary) != strlen(regex) + strlen(boundary) - 2) { free(regex_b); - zck_log(ZCK_LOG_ERROR, "Unable to build regular expression\n"); + set_error(zck, "Unable to build regular expression"); return NULL; } return regex_b; } -static int create_regex(regex_t *reg, const char *regex) { +static int create_regex(zckCtx *zck, regex_t *reg, const char *regex) { + VALIDATE_BOOL(zck); + if(reg == NULL || regex == NULL) { - zck_log(ZCK_LOG_ERROR, "Regular expression not initialized\n"); + set_error(zck, "Regular expression not initialized"); return False; } if(regcomp(reg, regex, REG_ICASE | REG_EXTENDED) != 0) { - zck_log(ZCK_LOG_ERROR, "Unable to compile regular expression\n"); + set_error(zck, "Unable to compile regular expression"); return False; } return True; } static int gen_regex(zckDL *dl) { + _VALIDATE_BOOL(dl); + VALIDATE_BOOL(dl->zck); + char *next = "\r\n--%s\r\ncontent-type:.*\r\n" \ "content-range: *bytes *([0-9]+) *- *([0-9]+) */.*\r\n\r"; char *end = "\r\n--%s--\r\n\r"; - char *regex_n = add_boundary_to_regex(next, dl->boundary); + char *regex_n = add_boundary_to_regex(dl->zck, next, dl->boundary); if(regex_n == NULL) return False; - char *regex_e = add_boundary_to_regex(end, dl->boundary); + char *regex_e = add_boundary_to_regex(dl->zck, end, dl->boundary); if(regex_n == NULL) return False; dl->dl_regex = zmalloc(sizeof(regex_t)); - if(!create_regex(dl->dl_regex, regex_n)) { + if(!create_regex(dl->zck, dl->dl_regex, regex_n)) { free(regex_n); return False; } free(regex_n); dl->end_regex = zmalloc(sizeof(regex_t)); - if(!create_regex(dl->end_regex, regex_e)) { + if(!create_regex(dl->zck, dl->end_regex, regex_e)) { free(regex_e); return False; } @@ -103,7 +106,9 @@ void reset_mp(zckMP *mp) { } size_t multipart_extract(zckDL *dl, char *b, size_t l) { - VALIDATE(dl); + _VALIDATE_BOOL(dl); + VALIDATE_BOOL(dl->zck); + if(dl == NULL || dl->mp == NULL) return 0; zckMP *mp = dl->mp; @@ -114,8 +119,8 @@ size_t multipart_extract(zckDL *dl, char *b, size_t l) { if(mp->buffer) { buf = realloc(mp->buffer, mp->buffer_len + l); if(buf == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to reallocate %lu bytes for zckDL\n", - mp->buffer_len + l); + set_fatal_error(dl->zck, "Unable to reallocate %lu bytes for zckDL", + mp->buffer_len + l); return 0; } memcpy(buf + mp->buffer_len, b, l); @@ -184,7 +189,7 @@ size_t multipart_extract(zckDL *dl, char *b, size_t l) { regmatch_t match[4] = {{0}}; if(regexec(dl->dl_regex, i, 3, match, 0) != 0) { if(regexec(dl->end_regex, i, 3, match, 0) != 0) - zck_log(ZCK_LOG_ERROR, "Unable to find multipart download range\n"); + set_error(dl->zck, "Unable to find multipart download range"); goto end; } @@ -199,7 +204,7 @@ size_t multipart_extract(zckDL *dl, char *b, size_t l) { rend = rend*10 + (size_t)(c[0] - 48); i += match[0].rm_eo + 1; - zck_log(ZCK_LOG_DEBUG, "Download range: %lu-%lu\n", rstart, rend); + zck_log(ZCK_LOG_DEBUG, "Download range: %lu-%lu", rstart, rend); mp->length = rend-rstart+1; mp->state = 1; } @@ -210,7 +215,9 @@ end: } size_t multipart_get_boundary(zckDL *dl, char *b, size_t size) { - VALIDATE(dl); + _VALIDATE_BOOL(dl); + VALIDATE_BOOL(dl->zck); + if(dl == NULL) return 0; @@ -218,7 +225,7 @@ size_t multipart_get_boundary(zckDL *dl, char *b, size_t size) { if(dl->hdr_regex == NULL) { char *regex = "boundary *= *([0-9a-fA-F]+)"; dl->hdr_regex = zmalloc(sizeof(regex_t)); - if(!create_regex(dl->hdr_regex, regex)) + if(!create_regex(dl->zck, dl->hdr_regex, regex)) return 0; } @@ -226,8 +233,8 @@ size_t multipart_get_boundary(zckDL *dl, char *b, size_t size) { * terminated string */ char *buf = zmalloc(size+1); if(buf == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes for header\n", - size+1); + set_fatal_error(dl->zck, "Unable to allocate %lu bytes for header", + size+1); return 0; } buf[size] = '\0'; @@ -239,7 +246,7 @@ size_t multipart_get_boundary(zckDL *dl, char *b, size_t size) { reset_mp(dl->mp); char *boundary = zmalloc(match[1].rm_eo - match[1].rm_so + 1); memcpy(boundary, buf + match[1].rm_so, match[1].rm_eo - match[1].rm_so); - zck_log(ZCK_LOG_DEBUG, "Multipart boundary: %s\n", boundary); + zck_log(ZCK_LOG_DEBUG, "Multipart boundary: %s", boundary); dl->boundary = boundary; } if(buf) diff --git a/src/lib/dl/range.c b/src/lib/dl/range.c index 04aa267..3bcb4c8 100644 --- a/src/lib/dl/range.c +++ b/src/lib/dl/range.c @@ -34,14 +34,16 @@ #include "zck_private.h" -static zckRangeItem *range_insert_new(zckRangeItem *prev, zckRangeItem *next, - uint64_t start, uint64_t end, - zckRange *info, zckChunk *idx, - int add_index) { +static zckRangeItem *range_insert_new(zckCtx *zck, zckRangeItem *prev, + zckRangeItem *next, uint64_t start, + uint64_t end, zckRange *info, + zckChunk *idx, int add_index) { + VALIDATE_CHAR(zck); + zckRangeItem *new = zmalloc(sizeof(zckRangeItem)); if(!new) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", - sizeof(zckRangeItem)); + set_fatal_error(zck, "Unable to allocate %lu bytes", + sizeof(zckRangeItem)); return NULL; } new->start = start; @@ -63,7 +65,7 @@ static zckRangeItem *range_insert_new(zckRangeItem *prev, zckRangeItem *next, return new; } -static void range_remove(zckRangeItem *range) { +static void range_remove(zckCtx *zck, zckRangeItem *range) { if(range->prev) range->prev->next = range->next; if(range->next) @@ -71,16 +73,16 @@ static void range_remove(zckRangeItem *range) { free(range); } -static void range_merge_combined(zckRange *info) { +static void range_merge_combined(zckCtx *zck, zckRange *info) { if(!info) { - zck_log(ZCK_LOG_ERROR, "zckRange not allocated\n"); + set_error(zck, "zckRange not allocated"); return; } for(zckRangeItem *ptr=info->first; ptr;) { if(ptr->next && ptr->end >= ptr->next->start-1) { if(ptr->end < ptr->next->end) ptr->end = ptr->next->end; - range_remove(ptr->next); + range_remove(zck, ptr->next); info->count -= 1; } else { ptr = ptr->next; @@ -90,7 +92,7 @@ static void range_merge_combined(zckRange *info) { static int range_add(zckRange *info, zckChunk *chk, zckCtx *zck) { if(info == NULL || chk == NULL) { - zck_log(ZCK_LOG_ERROR, "zckRange or zckChunk not allocated\n"); + set_error(zck, "zckRange or zckChunk not allocated"); return False; } size_t header_len = 0; @@ -109,32 +111,32 @@ static int range_add(zckRange *info, zckChunk *chk, zckCtx *zck) { ptr = ptr->next; continue; } else if(start < ptr->start) { - if(range_insert_new(ptr->prev, ptr, start, end, info, chk, + if(range_insert_new(zck, ptr->prev, ptr, start, end, info, chk, add_index) == NULL) return False; if(info->first == ptr) { info->first = ptr->prev; } info->count += 1; - range_merge_combined(info); + range_merge_combined(zck, info); return True; } else { // start == ptr->start if(end > ptr->end) ptr->end = end; info->count += 1; - range_merge_combined(info); + range_merge_combined(zck, info); return True; } } /* We've only reached here if we should be last item */ - zckRangeItem *new = range_insert_new(prev, NULL, start, end, info, chk, + zckRangeItem *new = range_insert_new(zck, prev, NULL, start, end, info, chk, add_index); if(new == NULL) return False; if(info->first == NULL) info->first = new; info->count += 1; - range_merge_combined(info); + range_merge_combined(zck, info); return True; } @@ -150,11 +152,11 @@ void PUBLIC zck_range_free(zckRange **info) { *info = NULL; } -char PUBLIC *zck_get_range_char(zckRange *range) { +char PUBLIC *zck_get_range_char(zckCtx *zck, zckRange *range) { int buf_size=BUF_SIZE; char *output=malloc(buf_size); if(!output) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", buf_size); + set_fatal_error(zck, "Unable to allocate %lu bytes", buf_size); return NULL; } @@ -166,8 +168,7 @@ char PUBLIC *zck_get_range_char(zckRange *range) { (long unsigned)ri->start, (long unsigned)ri->end); if(length < 0) { - zck_log(ZCK_LOG_ERROR, "Unable to get range: %s\n", - strerror(errno)); + set_fatal_error(zck, "Unable to get range: %s", strerror(errno)); free(output); return NULL; } @@ -175,8 +176,7 @@ char PUBLIC *zck_get_range_char(zckRange *range) { buf_size = (int)(buf_size * 1.5); output = realloc(output, buf_size); if(output == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", - buf_size); + set_fatal_error(zck, "Unable to allocate %lu bytes", buf_size); return NULL; } continue; @@ -188,8 +188,7 @@ char PUBLIC *zck_get_range_char(zckRange *range) { output[loc-1]='\0'; // Remove final comma output = realloc(output, loc); if(output == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to shrink range to %lu bytes\n", - loc); + set_fatal_error(zck, "Unable to shrink range to %lu bytes", loc); free(output); return NULL; } @@ -197,10 +196,11 @@ char PUBLIC *zck_get_range_char(zckRange *range) { } zckRange PUBLIC *zck_get_missing_range(zckCtx *zck, int max_ranges) { + VALIDATE_CHAR(zck); + zckRange *range = zmalloc(sizeof(zckRange)); if(range == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", - sizeof(zckRange)); + set_fatal_error(zck, "Unable to allocate %lu bytes", sizeof(zckRange)); return NULL; } for(zckChunk *chk = zck->index.first; chk; chk = chk->next) { @@ -220,14 +220,17 @@ zckRange PUBLIC *zck_get_missing_range(zckCtx *zck, int max_ranges) { char PUBLIC *zck_get_range(size_t start, size_t end) { zckRange range = {0}; zckRangeItem ri = {0}; + zckCtx *zck = zck_create(); range.first = &ri; ri.start = start; ri.end = end; - return zck_get_range_char(&range); + char *ret = zck_get_range_char(zck, &range); + zck_free(&zck); + return ret; } int PUBLIC zck_get_range_count(zckRange *range) { - if(range == NULL) - return -1; + _VALIDATE_TRI(range); + return range->count; } diff --git a/src/lib/hash/hash.c b/src/lib/hash/hash.c index 91dba5a..eefd6ef 100644 --- a/src/lib/hash/hash.c +++ b/src/lib/hash/hash.c @@ -57,32 +57,12 @@ static void SHA512_Final(unsigned char *md, SHA512_CTX *c) { #define sha1_byte void #endif -#define VALIDATE(f) if(!f) { \ - zck_log(ZCK_LOG_ERROR, "zckCtx not initialized\n"); \ - return False; \ - } - -#define VALIDATE_READ(f) VALIDATE(f); \ - if(f->mode != ZCK_MODE_READ) { \ - zck_log(ZCK_LOG_ERROR, \ - "zckCtx not opened for reading\n"); \ - return False; \ - } - -#define VALIDATE_WRITE(f) VALIDATE(f); \ - if(f->mode != ZCK_MODE_WRITE) { \ - zck_log(ZCK_LOG_ERROR, \ - "zckCtx not opened for writing\n"); \ - return False; \ - } /* This needs to be updated to the largest hash size every time a new hash type * is added */ int get_max_hash_size() { return SHA512_DIGEST_SIZE; } - - static char unknown[] = "Unknown(\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; const static char *HASH_NAME[] = { @@ -93,18 +73,18 @@ const static char *HASH_NAME[] = { }; static int validate_checksums(zckCtx *zck, zck_log_type bad_checksums) { - VALIDATE_READ(zck); + VALIDATE_READ_BOOL(zck); char buf[BUF_SIZE] = {0}; if(zck->data_offset == 0) { - zck_log(ZCK_LOG_ERROR, "Header hasn't been read yet\n"); + set_error(zck, "Header hasn't been read yet"); return 0; } - if(!hash_init(&(zck->check_full_hash), &(zck->hash_type))) + if(!hash_init(zck, &(zck->check_full_hash), &(zck->hash_type))) return 0; - if(!seek_data(zck->fd, zck->data_offset, SEEK_SET)) + if(!seek_data(zck, zck->data_offset, SEEK_SET)) return 0; /* Check each chunk checksum */ @@ -116,7 +96,7 @@ static int validate_checksums(zckCtx *zck, zck_log_type bad_checksums) { continue; } - if(!hash_init(&(zck->check_chunk_hash), &(zck->chunk_hash_type))) + if(!hash_init(zck, &(zck->check_chunk_hash), &(zck->chunk_hash_type))) return 0; size_t rlen = 0; @@ -124,11 +104,11 @@ static int validate_checksums(zckCtx *zck, zck_log_type bad_checksums) { size_t rsize = BUF_SIZE; if(BUF_SIZE > idx->comp_length - rlen) rsize = idx->comp_length - rlen; - if(read_data(zck->fd, buf, rsize) != rsize) - zck_log(ZCK_LOG_DEBUG, "No more data\n"); - if(!hash_update(&(zck->check_chunk_hash), buf, rsize)) + if(read_data(zck, buf, rsize) != rsize) + zck_log(ZCK_LOG_DEBUG, "No more data"); + if(!hash_update(zck, &(zck->check_chunk_hash), buf, rsize)) return 0; - if(!hash_update(&(zck->check_full_hash), buf, rsize)) + if(!hash_update(zck, &(zck->check_full_hash), buf, rsize)) return 0; rlen += rsize; } @@ -153,11 +133,11 @@ static int validate_checksums(zckCtx *zck, zck_log_type bad_checksums) { } /* Go back to beginning of data section */ - if(!seek_data(zck->fd, zck->data_offset, SEEK_SET)) + if(!seek_data(zck, zck->data_offset, SEEK_SET)) return 0; /* Reinitialize data checksum */ - if(!hash_init(&(zck->check_full_hash), &(zck->hash_type))) + if(!hash_init(zck, &(zck->check_full_hash), &(zck->hash_type))) return 0; return valid_file; @@ -171,39 +151,38 @@ char *get_digest_string(const char *digest, int size) { return str; } -int hash_setup(zckHashType *ht, int h) { - if(ht) { - if(h == ZCK_HASH_SHA1) { - memset(ht, 0, sizeof(zckHashType)); - ht->type = ZCK_HASH_SHA1; - ht->digest_size = SHA1_DIGEST_LENGTH; - zck_log(ZCK_LOG_DEBUG, "Setting up hash type %s\n", - zck_hash_name_from_type(ht->type)); - return True; - } else if(h == ZCK_HASH_SHA256) { - memset(ht, 0, sizeof(zckHashType)); - ht->type = ZCK_HASH_SHA256; - ht->digest_size = SHA256_DIGEST_SIZE; - zck_log(ZCK_LOG_DEBUG, "Setting up hash type %s\n", - zck_hash_name_from_type(ht->type)); - return True; - } else if(h >= ZCK_HASH_SHA512 && - h <= ZCK_HASH_SHA512_128) { - memset(ht, 0, sizeof(zckHashType)); - ht->type = h; - if(h == ZCK_HASH_SHA512) - ht->digest_size = SHA512_DIGEST_SIZE; - else if(h == ZCK_HASH_SHA512_128) - ht->digest_size = 16; - zck_log(ZCK_LOG_DEBUG, "Setting up hash type %s\n", - zck_hash_name_from_type(ht->type)); - return True; - } - zck_log(ZCK_LOG_ERROR, "Unsupported hash type: %s\n", - zck_hash_name_from_type(h)); +int hash_setup(zckCtx *zck, zckHashType *ht, int h) { + if(!ht) { + set_error(zck, "zckHashType is null"); return False; } - zck_log(ZCK_LOG_ERROR, "zckHashType is null\n"); + if(h == ZCK_HASH_SHA1) { + memset(ht, 0, sizeof(zckHashType)); + ht->type = ZCK_HASH_SHA1; + ht->digest_size = SHA1_DIGEST_LENGTH; + zck_log(ZCK_LOG_DEBUG, "Setting up hash type %s", + zck_hash_name_from_type(ht->type)); + return True; + } else if(h == ZCK_HASH_SHA256) { + memset(ht, 0, sizeof(zckHashType)); + ht->type = ZCK_HASH_SHA256; + ht->digest_size = SHA256_DIGEST_SIZE; + zck_log(ZCK_LOG_DEBUG, "Setting up hash type %s", + zck_hash_name_from_type(ht->type)); + return True; + } else if(h >= ZCK_HASH_SHA512 && + h <= ZCK_HASH_SHA512_128) { + memset(ht, 0, sizeof(zckHashType)); + ht->type = h; + if(h == ZCK_HASH_SHA512) + ht->digest_size = SHA512_DIGEST_SIZE; + else if(h == ZCK_HASH_SHA512_128) + ht->digest_size = 16; + zck_log(ZCK_LOG_DEBUG, "Setting up hash type %s", + zck_hash_name_from_type(ht->type)); + return True; + } + set_error(zck, "Unsupported hash type: %s", zck_hash_name_from_type(h)); return False; } @@ -224,53 +203,55 @@ void hash_reset(zckHashType *ht) { return; } -int hash_init(zckHash *hash, zckHashType *hash_type) { +int hash_init(zckCtx *zck, zckHash *hash, zckHashType *hash_type) { hash_close(hash); - if(hash && hash_type) { - if(hash_type->type == ZCK_HASH_SHA1) { - zck_log(ZCK_LOG_DDEBUG, "Initializing SHA-1 hash\n"); - hash->ctx = zmalloc(sizeof(SHA_CTX)); - hash->type = hash_type; - if(hash->ctx == NULL) - return False; - SHA1_Init((SHA_CTX *) hash->ctx); - return True; - } else if(hash_type->type == ZCK_HASH_SHA256) { - zck_log(ZCK_LOG_DDEBUG, "Initializing SHA-256 hash\n"); - hash->ctx = zmalloc(sizeof(SHA256_CTX)); - hash->type = hash_type; - if(hash->ctx == NULL) - return False; - SHA256_Init((SHA256_CTX *) hash->ctx); - return True; - } else if(hash_type->type >= ZCK_HASH_SHA512 && - hash_type->type <= ZCK_HASH_SHA512_128) { - zck_log(ZCK_LOG_DDEBUG, "Initializing SHA-512 hash\n"); - hash->ctx = zmalloc(sizeof(SHA512_CTX)); - hash->type = hash_type; - if(hash->ctx == NULL) - return False; - SHA512_Init((SHA512_CTX *) hash->ctx); - return True; - } - zck_log(ZCK_LOG_ERROR, "Unsupported hash type: %i\n", hash_type->type); + if(hash == NULL || hash_type == NULL) { + set_error(zck, "Either zckHash or zckHashType struct is null"); return False; } - zck_log(ZCK_LOG_ERROR, "Either zckHash or zckHashType struct is null\n"); + if(hash_type->type == ZCK_HASH_SHA1) { + zck_log(ZCK_LOG_DDEBUG, "Initializing SHA-1 hash"); + hash->ctx = zmalloc(sizeof(SHA_CTX)); + hash->type = hash_type; + if(hash->ctx == NULL) + return False; + SHA1_Init((SHA_CTX *) hash->ctx); + return True; + } else if(hash_type->type == ZCK_HASH_SHA256) { + zck_log(ZCK_LOG_DDEBUG, "Initializing SHA-256 hash"); + hash->ctx = zmalloc(sizeof(SHA256_CTX)); + hash->type = hash_type; + if(hash->ctx == NULL) + return False; + SHA256_Init((SHA256_CTX *) hash->ctx); + return True; + } else if(hash_type->type >= ZCK_HASH_SHA512 && + hash_type->type <= ZCK_HASH_SHA512_128) { + zck_log(ZCK_LOG_DDEBUG, "Initializing SHA-512 hash"); + hash->ctx = zmalloc(sizeof(SHA512_CTX)); + hash->type = hash_type; + if(hash->ctx == NULL) + return False; + SHA512_Init((SHA512_CTX *) hash->ctx); + return True; + } + set_error(zck, "Unsupported hash type: %s", + zck_hash_name_from_type(hash_type->type)); return False; } -int hash_update(zckHash *hash, const char *message, const size_t size) { +int hash_update(zckCtx *zck, zckHash *hash, const char *message, + const size_t size) { if(message == NULL && size == 0) return True; if(message == NULL) { - zck_log(ZCK_LOG_ERROR, - "Hash data is supposed to have %lu bytes, but is NULL\n", size); + set_error(zck, + "Hash data is supposed to have %lu bytes, but is NULL", size); return False; } if(size == 0) { - zck_log(ZCK_LOG_ERROR, - "Hash data is supposed to be 0-length, but is not NULL\n"); + set_error(zck, + "Hash data is supposed to be 0-length, but is not NULL"); return False; } if(hash && hash->ctx && hash->type) { @@ -278,72 +259,77 @@ int hash_update(zckHash *hash, const char *message, const size_t size) { SHA1_Update((SHA_CTX *)hash->ctx, (const sha1_byte *)message, size); return True; } else if(hash->type->type == ZCK_HASH_SHA256) { - SHA256_Update((SHA256_CTX *)hash->ctx, (const unsigned char *)message, size); + SHA256_Update((SHA256_CTX *)hash->ctx, + (const unsigned char *)message, size); return True; } else if(hash->type->type >= ZCK_HASH_SHA512 && hash->type->type <= ZCK_HASH_SHA512_128) { - SHA512_Update((SHA512_CTX *)hash->ctx, (const unsigned char *)message, size); + SHA512_Update((SHA512_CTX *)hash->ctx, + (const unsigned char *)message, size); return True; } - zck_log(ZCK_LOG_ERROR, "Unsupported hash type: %i\n", hash->type); + set_error(zck, "Unsupported hash type: %s", + zck_hash_name_from_type(hash->type->type)); + return False; } - zck_log(ZCK_LOG_ERROR, "Hash hasn't been initialized\n"); + set_error(zck, "Hash hasn't been initialized"); return False; } -char *hash_finalize(zckHash *hash) { - if(hash && hash->ctx && hash->type) { - if(hash->type->type == ZCK_HASH_SHA1) { - unsigned char *digest = zmalloc(SHA1_DIGEST_LENGTH); - SHA1_Final((sha1_byte*)digest, (SHA_CTX *)hash->ctx); - hash_close(hash); - return (char *)digest; - } else if(hash->type->type == ZCK_HASH_SHA256) { - unsigned char *digest = zmalloc(SHA256_DIGEST_SIZE); - SHA256_Final(digest, (SHA256_CTX *)hash->ctx); - hash_close(hash); - return (char *)digest; - } else if(hash->type->type >= ZCK_HASH_SHA512 && - hash->type->type <= ZCK_HASH_SHA512_128) { - unsigned char *digest = zmalloc(SHA512_DIGEST_SIZE); - SHA512_Final(digest, (SHA512_CTX *)hash->ctx); - hash_close(hash); - return (char *)digest; - } - zck_log(ZCK_LOG_ERROR, "Unsupported hash type: %i\n", hash->type); +char *hash_finalize(zckCtx *zck, zckHash *hash) { + if(!hash || !hash->ctx || !hash->type) { + set_error(zck, "Hash hasn't been initialized"); hash_close(hash); return NULL; } - zck_log(ZCK_LOG_ERROR, "Hash hasn't been initialized\n"); + if(hash->type->type == ZCK_HASH_SHA1) { + unsigned char *digest = zmalloc(SHA1_DIGEST_LENGTH); + SHA1_Final((sha1_byte*)digest, (SHA_CTX *)hash->ctx); + hash_close(hash); + return (char *)digest; + } else if(hash->type->type == ZCK_HASH_SHA256) { + unsigned char *digest = zmalloc(SHA256_DIGEST_SIZE); + SHA256_Final(digest, (SHA256_CTX *)hash->ctx); + hash_close(hash); + return (char *)digest; + } else if(hash->type->type >= ZCK_HASH_SHA512 && + hash->type->type <= ZCK_HASH_SHA512_128) { + unsigned char *digest = zmalloc(SHA512_DIGEST_SIZE); + SHA512_Final(digest, (SHA512_CTX *)hash->ctx); + hash_close(hash); + return (char *)digest; + } + set_error(zck, "Unsupported hash type: %s", + zck_hash_name_from_type(hash->type->type)); hash_close(hash); return NULL; } int set_full_hash_type(zckCtx *zck, int hash_type) { - VALIDATE(zck); - zck_log(ZCK_LOG_INFO, "Setting full hash to %s\n", + VALIDATE_BOOL(zck); + + zck_log(ZCK_LOG_INFO, "Setting full hash to %s", zck_hash_name_from_type(hash_type)); - if(!hash_setup(&(zck->hash_type), hash_type)) { - zck_log(ZCK_LOG_ERROR, "Unable to set full hash to %s\n", - zck_hash_name_from_type(hash_type)); + if(!hash_setup(zck, &(zck->hash_type), hash_type)) { + set_error(zck, "Unable to set full hash"); return False; } - if(!hash_init(&(zck->full_hash), &(zck->hash_type))) { - zck_log(ZCK_LOG_ERROR, "Unable initialize full hash\n"); + if(!hash_init(zck, &(zck->full_hash), &(zck->hash_type))) { + set_error(zck, "Unable initialize full hash"); return False; } return True; } int set_chunk_hash_type(zckCtx *zck, int hash_type) { - VALIDATE(zck); + VALIDATE_BOOL(zck); + memset(&(zck->chunk_hash_type), 0, sizeof(zckHashType)); - zck_log(ZCK_LOG_DEBUG, "Setting chunk hash to %s\n", + zck_log(ZCK_LOG_DEBUG, "Setting chunk hash to %s", zck_hash_name_from_type(hash_type)); - if(!hash_setup(&(zck->chunk_hash_type), hash_type)) { - zck_log(ZCK_LOG_ERROR, "Unable to set chunk hash to %s\n", - zck_hash_name_from_type(hash_type)); + if(!hash_setup(zck, &(zck->chunk_hash_type), hash_type)) { + set_error(zck, "Unable to set chunk hash"); return False; } zck->index.hash_type = zck->chunk_hash_type.type; @@ -354,100 +340,98 @@ int set_chunk_hash_type(zckCtx *zck, int hash_type) { /* Validate chunk, returning -1 if checksum fails, 1 if good, 0 if error */ int validate_chunk(zckCtx *zck, zckChunk *idx, zck_log_type bad_checksum, int chunk_number) { - VALIDATE(zck); + VALIDATE_BOOL(zck); if(idx == NULL) { - zck_log(ZCK_LOG_ERROR, "Index not initialized\n"); + set_error(zck, "Index not initialized"); return 0; } - char *digest = hash_finalize(&(zck->check_chunk_hash)); + char *digest = hash_finalize(zck, &(zck->check_chunk_hash)); if(digest == NULL) { - zck_log(ZCK_LOG_ERROR, - "Unable to calculate %s checksum for chunk\n"); + set_error(zck, "Unable to calculate chunk checksum"); return 0; } if(idx->comp_length == 0) memset(digest, 0, idx->digest_size); char *pdigest = zck_get_chunk_digest(idx); - zck_log(ZCK_LOG_DDEBUG, "Expected chunk checksum: %s\n", pdigest); + zck_log(ZCK_LOG_DDEBUG, "Expected chunk checksum: %s", pdigest); free(pdigest); pdigest = get_digest_string(digest, idx->digest_size); - zck_log(ZCK_LOG_DDEBUG, "Calculated chunk checksum: %s\n", pdigest); + zck_log(ZCK_LOG_DDEBUG, "Calculated chunk checksum: %s", pdigest); free(pdigest); if(memcmp(digest, idx->digest, idx->digest_size) != 0) { free(digest); if(chunk_number == -1) - zck_log(bad_checksum, "Chunk checksum: FAILED!\n"); + zck_log(bad_checksum, "Chunk checksum: FAILED!"); else - zck_log(bad_checksum, "Chunk %i's checksum: FAILED\n", + zck_log(bad_checksum, "Chunk %i's checksum: FAILED", chunk_number); return -1; } if(chunk_number == -1) - zck_log(ZCK_LOG_DEBUG, "Chunk checksum: valid\n"); + zck_log(ZCK_LOG_DEBUG, "Chunk checksum: valid"); else - zck_log(ZCK_LOG_DEBUG, "Chunk %i's checksum: valid\n", chunk_number); + zck_log(ZCK_LOG_DEBUG, "Chunk %i's checksum: valid", chunk_number); free(digest); return 1; } int validate_current_chunk(zckCtx *zck) { - VALIDATE(zck); + VALIDATE_BOOL(zck); return validate_chunk(zck, zck->comp.data_idx, ZCK_LOG_ERROR, -1); } int validate_file(zckCtx *zck, zck_log_type bad_checksums) { - VALIDATE(zck); - char *digest = hash_finalize(&(zck->check_full_hash)); + VALIDATE_BOOL(zck); + char *digest = hash_finalize(zck, &(zck->check_full_hash)); if(digest == NULL) { - zck_log(ZCK_LOG_ERROR, - "Unable to calculate %s checksum for full file\n"); + set_error(zck, "Unable to calculate full file checksum"); return 0; } - zck_log(ZCK_LOG_DEBUG, "Checking data checksum\n"); + zck_log(ZCK_LOG_DEBUG, "Checking data checksum"); char *cks = get_digest_string(zck->full_hash_digest, zck->hash_type.digest_size); - zck_log(ZCK_LOG_DEBUG, "Expected data checksum: %s\n", cks); + zck_log(ZCK_LOG_DEBUG, "Expected data checksum: %s", cks); free(cks); cks = get_digest_string(digest, zck->hash_type.digest_size); - zck_log(ZCK_LOG_DEBUG, "Calculated data checksum: %s\n", cks); + zck_log(ZCK_LOG_DEBUG, "Calculated data checksum: %s", cks); free(cks); if(memcmp(digest, zck->full_hash_digest, zck->hash_type.digest_size) != 0) { free(digest); - zck_log(bad_checksums, "Data checksum failed!\n"); + zck_log(bad_checksums, "Data checksum failed!"); return -1; } - zck_log(ZCK_LOG_DEBUG, "Data checksum valid\n"); + zck_log(ZCK_LOG_DEBUG, "Data checksum valid"); free(digest); return 1; } int validate_header(zckCtx *zck) { - VALIDATE(zck); - char *digest = hash_finalize(&(zck->check_full_hash)); + VALIDATE_BOOL(zck); + + char *digest = hash_finalize(zck, &(zck->check_full_hash)); if(digest == NULL) { - zck_log(ZCK_LOG_ERROR, - "Unable to calculate %s checksum for header\n"); + set_error(zck, "Unable to calculate header checksum"); return 0; } - zck_log(ZCK_LOG_DEBUG, "Checking header checksum\n"); + zck_log(ZCK_LOG_DEBUG, "Checking header checksum"); char *cks = get_digest_string(zck->header_digest, zck->hash_type.digest_size); - zck_log(ZCK_LOG_DEBUG, "Expected header checksum: %s\n", cks); + zck_log(ZCK_LOG_DEBUG, "Expected header checksum: %s", cks); free(cks); cks = get_digest_string(digest, zck->hash_type.digest_size); - zck_log(ZCK_LOG_DEBUG, "Calculated header checksum: %s\n", cks); + zck_log(ZCK_LOG_DEBUG, "Calculated header checksum: %s", cks); free(cks); if(memcmp(digest, zck->header_digest, zck->hash_type.digest_size) != 0) { free(digest); - zck_log(ZCK_LOG_ERROR, "Header checksum failed!\n"); + zck_log(ZCK_LOG_INFO, "Header checksum failed!"); return -1; } - zck_log(ZCK_LOG_DEBUG, "Header checksum valid\n"); + zck_log(ZCK_LOG_DEBUG, "Header checksum valid"); free(digest); - if(!hash_init(&(zck->check_full_hash), &(zck->hash_type))) + if(!hash_init(zck, &(zck->check_full_hash), &(zck->hash_type))) return 0; return 1; @@ -455,22 +439,24 @@ int validate_header(zckCtx *zck) { /* Returns 1 if data hash matches, -1 if it doesn't and 0 if error */ int PUBLIC zck_validate_data_checksum(zckCtx *zck) { - if(!seek_data(zck->fd, zck->data_offset, SEEK_SET)) + VALIDATE_READ_BOOL(zck); + + if(!seek_data(zck, zck->data_offset, SEEK_SET)) return 0; - if(!hash_init(&(zck->check_full_hash), &(zck->hash_type))) + if(!hash_init(zck, &(zck->check_full_hash), &(zck->hash_type))) return 0; char buf[BUF_SIZE] = {0}; zckChunk *idx = zck->index.first; - zck_log(ZCK_LOG_DEBUG, "Checking full hash\n"); + zck_log(ZCK_LOG_DEBUG, "Checking full hash"); while(idx) { size_t to_read = idx->comp_length; while(to_read > 0) { size_t rb = BUF_SIZE; if(rb > to_read) rb = to_read; - if(!read_data(zck->fd, buf, rb)) + if(!read_data(zck, buf, rb)) return 0; - if(!hash_update(&(zck->check_full_hash), buf, rb)) + if(!hash_update(zck, &(zck->check_full_hash), buf, rb)) return 0; to_read -= rb; } @@ -488,38 +474,38 @@ const char PUBLIC *zck_hash_name_from_type(int hash_type) { } int PUBLIC zck_get_full_hash_type(zckCtx *zck) { - if(zck == NULL) - return -1; + VALIDATE_TRI(zck); + return zck->hash_type.type; } ssize_t PUBLIC zck_get_full_digest_size(zckCtx *zck) { - if(zck == NULL) - return -1; + VALIDATE_TRI(zck); + return zck->hash_type.digest_size; } int PUBLIC zck_get_chunk_hash_type(zckCtx *zck) { - if(zck == NULL) - return -1; + VALIDATE_TRI(zck); + return zck->index.hash_type; } ssize_t PUBLIC zck_get_chunk_digest_size(zckCtx *zck) { - if(zck == NULL) - return -1; + VALIDATE_TRI(zck); + return zck->index.digest_size; } char PUBLIC *zck_get_header_digest(zckCtx *zck) { - if(zck == NULL) - return NULL; + VALIDATE_CHAR(zck); + return get_digest_string(zck->header_digest, zck->hash_type.digest_size); } char PUBLIC *zck_get_data_digest(zckCtx *zck) { - if(zck == NULL) - return NULL; + VALIDATE_CHAR(zck); + return get_digest_string(zck->full_hash_digest, zck->hash_type.digest_size); } @@ -531,10 +517,14 @@ char PUBLIC *zck_get_chunk_digest(zckChunk *item) { /* Returns 1 if all chunks are valid, -1 if even one isn't and 0 if error */ int PUBLIC zck_find_valid_chunks(zckCtx *zck) { + VALIDATE_READ_BOOL(zck); + return validate_checksums(zck, ZCK_LOG_DEBUG); } /* Returns 1 if all checksums matched, -1 if even one doesn't and 0 if error */ int PUBLIC zck_validate_checksums(zckCtx *zck) { + VALIDATE_READ_BOOL(zck); + return validate_checksums(zck, ZCK_LOG_WARNING); } diff --git a/src/lib/header.c b/src/lib/header.c index 78bafcf..46d8a7a 100644 --- a/src/lib/header.c +++ b/src/lib/header.c @@ -32,37 +32,16 @@ #include "zck_private.h" -#define MAX_HEADER_IN_MEM 10*1024*1024 - -#define VALIDATE(f) if(!f) { \ - zck_log(ZCK_LOG_ERROR, \ - "zckCtx not initialized\n"); \ - return False; \ - } - -#define VALIDATE_READ(f) VALIDATE(f); \ - if(f->mode != ZCK_MODE_READ) { \ - zck_log(ZCK_LOG_ERROR, \ - "zckCtx not opened for reading\n"); \ - return False; \ - } - -#define VALIDATE_WRITE(f) VALIDATE(f); \ - if(f->mode != ZCK_MODE_WRITE) { \ - zck_log(ZCK_LOG_ERROR, \ - "zckCtx not opened for writing\n"); \ - return False; \ - } - static int check_flags(zckCtx *zck, size_t flags) { zck->has_streams = flags & 1; if(zck->has_streams) { - zck_log(ZCK_LOG_ERROR, "This version of zchunk doesn't support streams\n"); + set_fatal_error(zck, + "This version of zchunk doesn't support streams"); return False; } flags = flags & (SIZE_MAX - 1); if(flags != 0) { - zck_log(ZCK_LOG_ERROR, "Unknown flags(s) set\n"); + set_fatal_error(zck, "Unknown flags(s) set"); return False; } return True; @@ -72,8 +51,8 @@ static int read_header_from_file(zckCtx *zck) { /* Allocate header and store any extra bytes at beginning of header */ zck->header = realloc(zck->header, zck->lead_size + zck->header_length); if(zck->header == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to reallocate %lu bytes\n", - zck->lead_size + zck->header_length); + set_fatal_error(zck, "Unable to reallocate %lu bytes", + zck->lead_size + zck->header_length); return False; } zck->lead_string = zck->header; @@ -81,27 +60,27 @@ static int read_header_from_file(zckCtx *zck) { size_t loaded = 0; if(zck->header_length < zck->header_size - zck->lead_size) { - zck_log(ZCK_LOG_ERROR, "Header size is too small for actual data\n"); + set_fatal_error(zck, "Header size is too small for actual data"); return False; } if(zck->lead_size < zck->header_size) loaded = zck->header_size - zck->lead_size; /* Read header from file */ - zck_log(ZCK_LOG_DEBUG, "Reading the rest of the header: %lu bytes\n", + zck_log(ZCK_LOG_DEBUG, "Reading the rest of the header: %lu bytes", zck->header_length); if(loaded < zck->header_length) { - if(!read_data(zck->fd, header + loaded, zck->header_length - loaded)) + if(!read_data(zck, header + loaded, zck->header_length - loaded)) return False; zck->header_size = zck->lead_size + zck->header_length; } - if(!hash_init(&(zck->check_full_hash), &(zck->hash_type))) + if(!hash_init(zck, &(zck->check_full_hash), &(zck->hash_type))) return False; - if(!hash_update(&(zck->check_full_hash), zck->header, - zck->hdr_digest_loc)) + if(!hash_update(zck, &(zck->check_full_hash), zck->header, + zck->hdr_digest_loc)) return False; - if(!hash_update(&(zck->check_full_hash), header, zck->header_length)) + if(!hash_update(zck, &(zck->check_full_hash), header, zck->header_length)) return False; if(validate_header(zck) < 1) return False; @@ -109,11 +88,10 @@ static int read_header_from_file(zckCtx *zck) { } static int read_preface(zckCtx *zck) { - VALIDATE_READ(zck); + VALIDATE_READ_BOOL(zck); if(zck->header_digest == NULL) { - zck_log(ZCK_LOG_ERROR, - "Reading preface before lead is read\n"); + set_error(zck, "Reading preface before lead is read"); return False; } @@ -122,15 +100,15 @@ static int read_preface(zckCtx *zck) { size_t max_length = zck->header_length; /* Read data digest */ - zck_log(ZCK_LOG_DEBUG, "Reading data digest\n"); + zck_log(ZCK_LOG_DEBUG, "Reading data digest"); if(length + zck->hash_type.digest_size > max_length) { - zck_log(ZCK_LOG_ERROR, "Read past end of header\n"); + set_fatal_error(zck, "Read past end of header"); return False; } zck->full_hash_digest = zmalloc(zck->hash_type.digest_size); if(!zck->full_hash_digest) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", - zck->hash_type.digest_size); + set_fatal_error(zck, "Unable to allocate %lu bytes", + zck->hash_type.digest_size); return False; } memcpy(zck->full_hash_digest, header+length, zck->hash_type.digest_size); @@ -138,17 +116,17 @@ static int read_preface(zckCtx *zck) { /* Read flags */ size_t flags = 0; - if(!compint_to_size(&flags, header+length, &length, max_length)) + if(!compint_to_size(zck, &flags, header+length, &length, max_length)) return False; if(!check_flags(zck, flags)) return False; /* Setup for reading compression type */ - zck_log(ZCK_LOG_DEBUG, "Reading compression type and index size\n"); + zck_log(ZCK_LOG_DEBUG, "Reading compression type and index size"); int tmp = 0; /* Read and initialize compression type */ - if(!compint_to_int(&tmp, header+length, &length, max_length)) + if(!compint_to_int(zck, &tmp, header+length, &length, max_length)) return False; if(!comp_ioption(zck, ZCK_COMP_TYPE, tmp)) return False; @@ -156,7 +134,7 @@ static int read_preface(zckCtx *zck) { return False; /* Read and initialize index size */ - if(!compint_to_int(&tmp, header+length, &length, max_length)) + if(!compint_to_int(zck, &tmp, header+length, &length, max_length)) return False; zck->index_size = tmp; @@ -166,19 +144,18 @@ static int read_preface(zckCtx *zck) { } static int read_index(zckCtx *zck) { - VALIDATE_READ(zck); + VALIDATE_READ_BOOL(zck); if(zck->preface_string == NULL) { - zck_log(ZCK_LOG_ERROR, - "Reading index before preface is read\n"); + set_error(zck, "Reading index before preface is read"); return False; } char *header = NULL; - zck_log(ZCK_LOG_DEBUG, "Reading index\n"); + zck_log(ZCK_LOG_DEBUG, "Reading index"); if(zck->lead_size + zck->preface_size + zck->index_size > zck->header_size) { - zck_log(ZCK_LOG_ERROR, "Read past end of header\n"); + set_fatal_error(zck, "Read past end of header"); return False; } header = zck->header + zck->lead_size + zck->preface_size; @@ -191,11 +168,10 @@ static int read_index(zckCtx *zck) { } static int read_sig(zckCtx *zck) { - VALIDATE_READ(zck); + VALIDATE_READ_BOOL(zck); if(zck->index_string == NULL) { - zck_log(ZCK_LOG_ERROR, - "Reading signatures before index is read\n"); + set_error(zck, "Reading signatures before index is read"); return False; } @@ -205,13 +181,13 @@ static int read_sig(zckCtx *zck) { zck->index_size); size_t length = 0; - if(!compint_to_int(&(zck->sigs.count), header, &length, max_length)) + if(!compint_to_int(zck, &(zck->sigs.count), header, &length, max_length)) return False; /* We don't actually support signatures yet, so bail if there is one */ - zck_log(ZCK_LOG_DEBUG, "Signature count: %i\n", zck->sigs.count); + zck_log(ZCK_LOG_DEBUG, "Signature count: %i", zck->sigs.count); if(zck->sigs.count > 0) { - zck_log(ZCK_LOG_ERROR, "Signatures aren't supported yet\n"); + set_fatal_error(zck, "Signatures aren't supported yet"); return False; } @@ -220,7 +196,7 @@ static int read_sig(zckCtx *zck) { if(zck->header_size > zck->lead_size + zck->preface_size + zck->index_size + length) - zck_log(ZCK_LOG_WARNING, "There are %lu unused bytes in the header\n"); + zck_log(ZCK_LOG_WARNING, "There are %lu unused bytes in the header"); zck->sig_size = length; zck->sig_string = header; @@ -228,11 +204,13 @@ static int read_sig(zckCtx *zck) { } static int preface_create(zckCtx *zck) { + VALIDATE_WRITE_BOOL(zck); + int header_malloc = zck->hash_type.digest_size + 4 + 2*MAX_COMP_SIZE; char *header = zmalloc(header_malloc); if(header == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", header_malloc); + set_error(zck, "Unable to allocate %lu bytes", header_malloc); return False; } size_t length = 0; @@ -248,7 +226,7 @@ static int preface_create(zckCtx *zck) { compint_from_size(header+length, flags, &length); /* Write out compression type and index size */ - if(!compint_from_int(header+length, zck->comp.type, &length)) { + if(!compint_from_int(zck, header+length, zck->comp.type, &length)) { free(header); return False; } @@ -257,28 +235,28 @@ static int preface_create(zckCtx *zck) { /* Shrink header to actual size */ header = realloc(header, length); if(header == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to reallocate %lu bytes\n", length); + set_fatal_error(zck, "Unable to reallocate %lu bytes", length); return False; } zck->preface_string = header; zck->preface_size = length; - zck_log(ZCK_LOG_DEBUG, "Generated preface: %lu bytes\n", zck->preface_size); + zck_log(ZCK_LOG_DEBUG, "Generated preface: %lu bytes", zck->preface_size); return True; } static int sig_create(zckCtx *zck) { char *header = zmalloc(MAX_COMP_SIZE); if(header == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", MAX_COMP_SIZE); + set_error(zck, "Unable to allocate %lu bytes", MAX_COMP_SIZE); return False; } size_t length = 0; - zck_log(ZCK_LOG_DEBUG, "Calculating %i signatures\n", zck->sigs.count); + zck_log(ZCK_LOG_DEBUG, "Calculating %i signatures", zck->sigs.count); /* Write out signature count and signatures */ - if(!compint_from_int(header+length, zck->sigs.count, &length)) { + if(!compint_from_int(zck, header+length, zck->sigs.count, &length)) { free(header); return False; } @@ -287,7 +265,7 @@ static int sig_create(zckCtx *zck) { } zck->sig_string = header; zck->sig_size = length; - zck_log(ZCK_LOG_DEBUG, "Generated signatures: %lu bytes\n", zck->sig_size); + zck_log(ZCK_LOG_DEBUG, "Generated signatures: %lu bytes", zck->sig_size); return True; } @@ -295,7 +273,7 @@ static int lead_create(zckCtx *zck) { int phs = 5 + 2*MAX_COMP_SIZE + zck->hash_type.digest_size; char *header = zmalloc(phs); if(header == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", phs); + set_error(zck, "Unable to allocate %lu bytes", phs); return False; } size_t length = 0; @@ -313,17 +291,19 @@ static int lead_create(zckCtx *zck) { header = realloc(header, length); if(header == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to reallocate %lu bytes\n", length); + set_fatal_error(zck, "Unable to reallocate %lu bytes", length); return False; } zck->lead_string = header; zck->lead_size = length; - zck_log(ZCK_LOG_DEBUG, "Generated lead: %lu bytes\n", zck->lead_size); + zck_log(ZCK_LOG_DEBUG, "Generated lead: %lu bytes", zck->lead_size); return True; } int header_create(zckCtx *zck) { + VALIDATE_WRITE_BOOL(zck); + /* Rebuild header without header hash */ if(zck->header_digest) { free(zck->header_digest); @@ -351,12 +331,12 @@ int header_create(zckCtx *zck) { zck->index_size + zck->sig_size; /* Merge everything into one large string */ - zck_log(ZCK_LOG_DEBUG, "Merging into header: %lu bytes\n", + zck_log(ZCK_LOG_DEBUG, "Merging into header: %lu bytes", zck->data_offset); zck->header = zmalloc(zck->data_offset); if(zck->header == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", - zck->data_offset); + set_fatal_error(zck, "Unable to allocate %lu bytes", + zck->data_offset); return False; } size_t offs = 0; @@ -380,24 +360,21 @@ int header_create(zckCtx *zck) { zckHash header_hash = {0}; /* Calculate hash of header */ - if(!hash_init(&header_hash, &(zck->hash_type))) + if(!hash_init(zck, &header_hash, &(zck->hash_type))) return False; - zck_log(ZCK_LOG_DEBUG, "Hashing lead\n"); + zck_log(ZCK_LOG_DEBUG, "Hashing lead"); /* Hash lead up to header digest */ - if(!hash_update(&header_hash, zck->lead_string, - zck->hdr_digest_loc)) + if(!hash_update(zck, &header_hash, zck->lead_string, + zck->hdr_digest_loc)) return False; - zck_log(ZCK_LOG_DEBUG, "Hashing the rest\n"); + zck_log(ZCK_LOG_DEBUG, "Hashing the rest"); /* Hash rest of header */ - if(!hash_update(&header_hash, zck->preface_string, zck->header_length)) + if(!hash_update(zck, &header_hash, zck->preface_string, zck->header_length)) return False; - zck->header_digest = hash_finalize(&header_hash); - if(zck->header_digest == NULL) { - zck_log(ZCK_LOG_ERROR, - "Unable to calculate %s checksum for index\n", - zck_hash_name_from_type(zck->hash_type.type)); + zck->header_digest = hash_finalize(zck, &header_hash); + if(zck->header_digest == NULL) return False; - } + /* Write digest to header */ memcpy(zck->lead_string+zck->hdr_digest_loc, zck->header_digest, zck->hash_type.digest_size); @@ -406,61 +383,59 @@ int header_create(zckCtx *zck) { } int write_header(zckCtx *zck) { - VALIDATE_WRITE(zck); + VALIDATE_WRITE_BOOL(zck); - zck_log(ZCK_LOG_DEBUG, "Writing header: %lu bytes\n", + zck_log(ZCK_LOG_DEBUG, "Writing header: %lu bytes", zck->lead_size); - if(!write_data(zck->fd, zck->header, zck->header_size)) + if(!write_data(zck, zck->fd, zck->header, zck->header_size)) return False; return True; } -static int read_lead(zckCtx *zck, zck_log_type log_level) { - VALIDATE_READ(zck); +static int read_lead(zckCtx *zck) { + VALIDATE_READ_BOOL(zck); int lead = 5 + 2*MAX_COMP_SIZE; char *header = zmalloc(lead); if(header == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", lead); + set_error(zck, "Unable to allocate %lu bytes", lead); return False; } size_t length = 0; - if(read_data(zck->fd, header, lead) < lead) + if(read_data(zck, header, lead) < lead) return False; if(memcmp(header, "\0ZCK1", 5) != 0) { free(header); - zck_log(log_level, - "Invalid lead, perhaps this is not a zck file?\n"); + set_error(zck, "Invalid lead, perhaps this is not a zck file?"); return False; } length += 5; /* Read hash type for header and full digest and initialize check hash */ int hash_type = 0; - if(!compint_to_int(&hash_type, header+length, &length, lead)) { + if(!compint_to_int(zck, &hash_type, header+length, &length, lead)) { free(header); return False; } if(zck->prep_hash_type > -1 && zck->prep_hash_type != hash_type) { free(header); - zck_log(log_level, - "Hash type (%i) doesn't match requested hash type " - "(%i)\n", hash_type, zck->prep_hash_type); + set_error(zck, "Hash type (%i) doesn't match requested hash type " + "(%i)", hash_type, zck->prep_hash_type); return False; } - if(!hash_setup(&(zck->hash_type), hash_type)) { + if(!hash_setup(zck, &(zck->hash_type), hash_type)) { free(header); return False; } - zck_log(ZCK_LOG_DEBUG, "Setting header and full digest hash type to %s\n", + zck_log(ZCK_LOG_DEBUG, "Setting header and full digest hash type to %s", zck_hash_name_from_type(hash_type)); /* Read header size */ size_t header_length = 0; - if(!compint_to_size(&header_length, header+length, &length, lead)) { + if(!compint_to_size(zck, &header_length, header+length, &length, lead)) { free(header); hash_reset(&(zck->hash_type)); return False; @@ -471,20 +446,20 @@ static int read_lead(zckCtx *zck, zck_log_type log_level) { zck->hdr_digest_loc = length; /* Read header digest */ - zck_log(ZCK_LOG_DEBUG, "Reading header digest\n"); + zck_log(ZCK_LOG_DEBUG, "Reading header digest"); header = realloc(header, length + zck->hash_type.digest_size); if(header == NULL) { zck->header_length = 0; zck->hdr_digest_loc = 0; hash_reset(&(zck->hash_type)); - zck_log(ZCK_LOG_ERROR, "Unable to re-allocate %lu bytes\n", - length + zck->hash_type.digest_size); + set_fatal_error(zck, "Unable to re-allocate %lu bytes", + length + zck->hash_type.digest_size); return False; } size_t to_read = 0; if(lead < length + zck->hash_type.digest_size) to_read = length + zck->hash_type.digest_size - lead; - if(read_data(zck->fd, header + lead, to_read) < to_read) { + if(read_data(zck, header + lead, to_read) < to_read) { free(header); zck->header_length = 0; zck->hdr_digest_loc = 0; @@ -499,11 +474,13 @@ static int read_lead(zckCtx *zck, zck_log_type log_level) { zck->header_length = 0; zck->hdr_digest_loc = 0; hash_reset(&(zck->hash_type)); - zck_log(log_level, - "Header digest doesn't match requested header digest\n" - "Expected: %s\nActual: %s\n", - get_digest_string(zck->prep_digest, zck->hash_type.digest_size), - get_digest_string(header + length, zck->hash_type.digest_size)); + set_error(zck, + "Header digest doesn't match requested header digest" + "Expected: %sActual: %s", + get_digest_string(zck->prep_digest, + zck->hash_type.digest_size), + get_digest_string(header + length, + zck->hash_type.digest_size)); return False; } zck->header_digest = zmalloc(zck->hash_type.digest_size); @@ -512,8 +489,8 @@ static int read_lead(zckCtx *zck, zck_log_type log_level) { zck->header_length = 0; zck->hdr_digest_loc = 0; hash_reset(&(zck->hash_type)); - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", - zck->hash_type.digest_size); + set_error(zck, "Unable to allocate %lu bytes", + zck->hash_type.digest_size); return False; } memcpy(zck->header_digest, header + length, zck->hash_type.digest_size); @@ -528,10 +505,10 @@ static int read_lead(zckCtx *zck, zck_log_type log_level) { hash_reset(&(zck->hash_type)); free(zck->header_digest); zck->header_digest = NULL; - zck_log(log_level, - "Header length (%lu) doesn't match requested header length " - "(%lu)\n", zck->header_length + length, - zck->prep_hdr_size); + set_error(zck, + "Header length (%lu) doesn't match requested header length " + "(%lu)", zck->header_length + length, + zck->prep_hdr_size); return False; } /* Store pre-header */ @@ -539,20 +516,21 @@ static int read_lead(zckCtx *zck, zck_log_type log_level) { zck->header_size = lead; zck->lead_string = header; zck->lead_size = length; - zck_log(ZCK_LOG_DEBUG, "Parsed lead: %lu bytes\n", length); + zck_log(ZCK_LOG_DEBUG, "Parsed lead: %lu bytes", length); return True; } int PUBLIC zck_read_lead(zckCtx *zck) { - if(zck == NULL) - return False; - return read_lead(zck, ZCK_LOG_ERROR); + VALIDATE_BOOL(zck); + + return read_lead(zck); } int PUBLIC zck_validate_lead(zckCtx *zck) { - if(zck == NULL) - return False; - int retval = read_lead(zck, ZCK_LOG_DEBUG); + VALIDATE_BOOL(zck); + + int retval = read_lead(zck); + zck_clear_error(zck); free(zck->header); free(zck->header_digest); zck->header = NULL; @@ -564,13 +542,13 @@ int PUBLIC zck_validate_lead(zckCtx *zck) { zck->header_digest = NULL; zck->hdr_digest_loc = 0; hash_reset(&(zck->hash_type)); - if(!seek_data(zck->fd, 0, SEEK_SET)) + if(!seek_data(zck, 0, SEEK_SET)) return False; return retval; } int PUBLIC zck_read_header(zckCtx *zck) { - VALIDATE_READ(zck); + VALIDATE_READ_BOOL(zck); if(!read_header_from_file(zck)) return False; @@ -584,18 +562,17 @@ int PUBLIC zck_read_header(zckCtx *zck) { } ssize_t PUBLIC zck_get_header_length(zckCtx *zck) { - if(zck == NULL) - return -1; + VALIDATE_TRI(zck); return zck->lead_size + zck->header_length; } ssize_t PUBLIC zck_get_lead_length(zckCtx *zck) { - if(zck == NULL) - return -1; + VALIDATE_TRI(zck); return zck->lead_size; } ssize_t PUBLIC zck_get_data_length(zckCtx *zck) { + VALIDATE_TRI(zck); zckChunk *idx = zck->index.first; while(idx->next != NULL) idx = idx->next; @@ -603,5 +580,6 @@ ssize_t PUBLIC zck_get_data_length(zckCtx *zck) { } ssize_t PUBLIC zck_get_length(zckCtx *zck) { + VALIDATE_TRI(zck); return zck_get_header_length(zck) + zck_get_data_length(zck); } diff --git a/src/lib/index/index_create.c b/src/lib/index/index_create.c index a845b0a..0a2bd3c 100644 --- a/src/lib/index/index_create.c +++ b/src/lib/index/index_create.c @@ -31,35 +31,30 @@ #include "zck_private.h" -#define VALIDATE(f) if(!f) { \ - zck_log(ZCK_LOG_ERROR, "zckCtx not initialized\n"); \ - return False; \ - } - static int create_chunk(zckCtx *zck) { - VALIDATE(zck); + VALIDATE_BOOL(zck); clear_work_index(zck); zck->work_index_item = zmalloc(sizeof(zckChunk)); if(zck->work_index_item == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", - sizeof(zckChunk)); + set_error(zck, "Unable to allocate %lu bytes", + sizeof(zckChunk)); return False; } - if(!hash_init(&(zck->work_index_hash), &(zck->chunk_hash_type))) + if(!hash_init(zck, &(zck->work_index_hash), &(zck->chunk_hash_type))) return False; return True; } static int finish_chunk(zckIndex *index, zckChunk *item, char *digest, int valid, zckCtx *zck) { - VALIDATE(index); - VALIDATE(item); + VALIDATE_BOOL(zck); + _VALIDATE_BOOL(index); + _VALIDATE_BOOL(item); item->digest = zmalloc(index->digest_size); if(item->digest == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", - index->digest_size); + set_error(zck, "Unable to allocate %lu bytes", index->digest_size); return False; } if(digest) { @@ -83,14 +78,14 @@ static int finish_chunk(zckIndex *index, zckChunk *item, char *digest, } int index_create(zckCtx *zck) { - VALIDATE(zck); + VALIDATE_BOOL(zck); char *index; size_t index_malloc = 0; size_t index_size = 0; - zck->full_hash_digest = hash_finalize(&(zck->full_hash)); + zck->full_hash_digest = hash_finalize(zck, &(zck->full_hash)); if(zck->full_hash_digest == NULL) return False; @@ -129,30 +124,31 @@ int index_create(zckCtx *zck) { /* Shrink index to actual size */ index = realloc(index, index_size); if(index == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to reallocate %lu bytes\n", index_size); + set_fatal_error(zck, "Unable to reallocate %lu bytes", index_size); return False; } zck->index_string = index; zck->index_size = index_size; - zck_log(ZCK_LOG_DEBUG, "Generated index: %lu bytes\n", zck->index_size); + zck_log(ZCK_LOG_DEBUG, "Generated index: %lu bytes", zck->index_size); return True; } int index_new_chunk(zckIndex *index, char *digest, int digest_size, size_t comp_size, size_t orig_size, int finished, zckCtx *zck) { + VALIDATE_BOOL(zck); + if(index == NULL) { - zck_log(ZCK_LOG_ERROR, "Invalid index\n"); + set_error(zck, "Invalid index"); return False; } if(digest_size == 0) { - zck_log(ZCK_LOG_ERROR, "Digest size 0 too small\n"); + set_error(zck, "Digest size 0 too small"); return False; } zckChunk *chk = zmalloc(sizeof(zckChunk)); if(chk == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", - sizeof(zckChunk)); + set_error(zck, "Unable to allocate %lu bytes", sizeof(zckChunk)); return False; } index->digest_size = digest_size; @@ -163,7 +159,7 @@ int index_new_chunk(zckIndex *index, char *digest, int digest_size, int index_add_to_chunk(zckCtx *zck, char *data, size_t comp_size, size_t orig_size) { - VALIDATE(zck); + VALIDATE_BOOL(zck); if(zck->work_index_item == NULL && !create_chunk(zck)) return False; @@ -172,9 +168,9 @@ int index_add_to_chunk(zckCtx *zck, char *data, size_t comp_size, if(comp_size == 0) return True; - if(!hash_update(&(zck->full_hash), data, comp_size)) + if(!hash_update(zck, &(zck->full_hash), data, comp_size)) return False; - if(!hash_update(&(zck->work_index_hash), data, comp_size)) + if(!hash_update(zck, &(zck->work_index_hash), data, comp_size)) return False; zck->work_index_item->comp_length += comp_size; @@ -182,7 +178,7 @@ int index_add_to_chunk(zckCtx *zck, char *data, size_t comp_size, } int index_finish_chunk(zckCtx *zck) { - VALIDATE(zck); + VALIDATE_BOOL(zck); if(zck->work_index_item == NULL && !create_chunk(zck)) return False; @@ -190,18 +186,18 @@ int index_finish_chunk(zckCtx *zck) { char *digest = NULL; if(zck->work_index_item->length > 0) { /* Finalize chunk checksum */ - digest = hash_finalize(&(zck->work_index_hash)); + digest = hash_finalize(zck, &(zck->work_index_hash)); if(digest == NULL) { - zck_log(ZCK_LOG_ERROR, - "Unable to calculate %s checksum for new chunk\n", - zck_hash_name_from_type(zck->index.hash_type)); + set_fatal_error(zck, + "Unable to calculate %s checksum for new chunk", + zck_hash_name_from_type(zck->index.hash_type)); return False; } } else { digest = zmalloc(zck->chunk_hash_type.digest_size); if(digest == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", - zck->chunk_hash_type.digest_size); + set_fatal_error(zck, "Unable to allocate %lu bytes", + zck->chunk_hash_type.digest_size); return False; } } diff --git a/src/lib/index/index_read.c b/src/lib/index/index_read.c index 96b103d..1cadd48 100644 --- a/src/lib/index/index_read.c +++ b/src/lib/index/index_read.c @@ -32,48 +32,51 @@ #include "zck_private.h" -#define VALIDATE(f) if(!f) { \ - zck_log(ZCK_LOG_ERROR, "zckCtx not initialized\n"); \ - return False; \ - } - int index_read(zckCtx *zck, char *data, size_t size, size_t max_length) { - VALIDATE(zck); + VALIDATE_BOOL(zck); size_t length = 0; /* Read and configure hash type */ int hash_type; - if(!compint_to_int(&hash_type, data + length, &length, max_length)) + if(!compint_to_int(zck, &hash_type, data + length, &length, max_length)) { + set_fatal_error(zck, "Unable to read hash type"); return False; - if(!set_chunk_hash_type(zck, hash_type)) + } + if(!set_chunk_hash_type(zck, hash_type)) { + set_fatal_error(zck, "Unable to set chunk hash type"); return False; + } /* Read number of index entries */ size_t index_count; - if(!compint_to_size(&index_count, data + length, &length, max_length)) + if(!compint_to_size(zck, &index_count, data + length, &length, + max_length)) { + set_fatal_error(zck, "Unable to read index count"); return False; + } zck->index.count = index_count; zckChunk *prev = zck->index.first; size_t idx_loc = 0; + int count = 0; while(length < size) { if(length + zck->index.digest_size > max_length) { - zck_log(ZCK_LOG_ERROR, "Read past end of header\n"); + set_fatal_error(zck, "Read past end of header"); return False; } zckChunk *new = zmalloc(sizeof(zckChunk)); if(!new) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", - sizeof(zckChunk)); + set_fatal_error(zck, "Unable to allocate %lu bytes", + sizeof(zckChunk)); return False; } /* Read index entry digest */ new->digest = zmalloc(zck->index.digest_size); if(!new->digest) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", - zck->index.digest_size); + set_fatal_error(zck, "Unable to allocate %lu bytes", + zck->index.digest_size); return False; } memcpy(new->digest, data+length, zck->index.digest_size); @@ -82,19 +85,28 @@ int index_read(zckCtx *zck, char *data, size_t size, size_t max_length) { /* Read and store entry length */ size_t chunk_length = 0; - if(!compint_to_size(&chunk_length, data+length, &length, max_length)) + if(!compint_to_size(zck, &chunk_length, data+length, &length, + max_length)) { + set_fatal_error(zck, "Unable to read chunk %i compressed size", + count); return False; + } new->start = idx_loc; new->comp_length = chunk_length; /* Read and store uncompressed entry length */ chunk_length = 0; - if(!compint_to_size(&chunk_length, data+length, &length, max_length)) + if(!compint_to_size(zck, &chunk_length, data+length, &length, + max_length)) { + set_fatal_error(zck, "Unable to read chunk %i uncompressed size", + count); return False; + } new->length = chunk_length; new->zck = zck; new->valid = 0; idx_loc += new->comp_length; + count++; zck->index.length = idx_loc; if(prev) @@ -109,53 +121,56 @@ int index_read(zckCtx *zck, char *data, size_t size, size_t max_length) { } ssize_t PUBLIC zck_get_chunk_count(zckCtx *zck) { - if(zck == NULL) - return -1; + VALIDATE_TRI(zck); + return zck->index.count; } zckChunk PUBLIC *zck_get_first_chunk(zckCtx *zck) { - if(zck == NULL) - return NULL; + VALIDATE_CHAR(zck); + return zck->index.first; } zckChunk PUBLIC *zck_get_next_chunk(zckChunk *idx) { - if(idx == NULL) - return NULL; + _VALIDATE_CHAR(idx); + return idx->next; } ssize_t PUBLIC zck_get_chunk_start(zckChunk *idx) { - if(idx == NULL) - return -1; - if(idx->zck) + _VALIDATE_TRI(idx); + + if(idx->zck) { + VALIDATE_TRI(idx->zck); return idx->start + zck_get_header_length(idx->zck); - else + } else { return idx->start; + } } ssize_t PUBLIC zck_get_chunk_size(zckChunk *idx) { - if(idx == NULL) - return -1; + _VALIDATE_TRI(idx); + return idx->length; } ssize_t PUBLIC zck_get_chunk_comp_size(zckChunk *idx) { - if(idx == NULL) - return -1; + _VALIDATE_TRI(idx); + return idx->comp_length; } int PUBLIC zck_get_chunk_valid(zckChunk *idx) { - if(idx == NULL) - return -1; + _VALIDATE_TRI(idx); + return idx->valid; } int PUBLIC zck_compare_chunk_digest(zckChunk *a, zckChunk *b) { - if(a == NULL || b == NULL) - return False; + _VALIDATE_BOOL(a); + _VALIDATE_BOOL(b); + if(a->digest_size != b->digest_size) return False; if(memcmp(a->digest, b->digest, a->digest_size) != 0) @@ -164,10 +179,8 @@ int PUBLIC zck_compare_chunk_digest(zckChunk *a, zckChunk *b) { } int PUBLIC zck_missing_chunks(zckCtx *zck) { - if(zck == NULL) { - zck_log(ZCK_LOG_ERROR, "zckCtx not initialized\n"); - return -1; - } + VALIDATE_READ_TRI(zck); + int missing = 0; for(zckChunk *idx = zck->index.first; idx; idx=idx->next) if(idx->valid == 0) @@ -176,10 +189,8 @@ int PUBLIC zck_missing_chunks(zckCtx *zck) { } int PUBLIC zck_failed_chunks(zckCtx *zck) { - if(zck == NULL) { - zck_log(ZCK_LOG_ERROR, "zckCtx not initialized\n"); - return -1; - } + VALIDATE_READ_TRI(zck); + int failed = 0; for(zckChunk *idx = zck->index.first; idx; idx=idx->next) if(idx->valid == -1) diff --git a/src/lib/io.c b/src/lib/io.c index 8a3ddca..f7c79f9 100644 --- a/src/lib/io.c +++ b/src/lib/io.c @@ -33,41 +33,47 @@ #include "zck_private.h" -ssize_t read_data(int fd, char *data, size_t length) { +ssize_t read_data(zckCtx *zck, char *data, size_t length) { + VALIDATE_READ_TRI(zck); + if(length == 0) return 0; if(data == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to read to NULL data pointer\n"); + set_error(zck, "Unable to read to NULL data pointer"); return -1; } - ssize_t read_bytes = read(fd, data, length); + ssize_t read_bytes = read(zck->fd, data, length); if(read_bytes == -1) { - zck_log(ZCK_LOG_ERROR, "Error reading data: %s\n", strerror(errno)); + set_error(zck, "Error reading data: %s", strerror(errno)); return -1; } return read_bytes; } -int write_data(int fd, const char *data, size_t length) { +int write_data(zckCtx *zck, int fd, const char *data, size_t length) { + VALIDATE_WRITE_TRI(zck); + if(length == 0) return True; if(data == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to write from NULL data pointer\n"); + set_error(zck, "Unable to write from NULL data pointer"); return False; } ssize_t write_bytes = write(fd, data, length); if(write_bytes == -1) { - zck_log(ZCK_LOG_ERROR, "Error write data: %s\n", strerror(errno)); + set_error(zck, "Error write data: %s", strerror(errno)); return False; } else if(write_bytes != length) { - zck_log(ZCK_LOG_ERROR, "Short write\n"); + set_fatal_error(zck, "Short write"); return False; } return True; } -int seek_data(int fd, off_t offset, int whence) { - if(lseek(fd, offset, whence) == -1) { +int seek_data(zckCtx *zck, off_t offset, int whence) { + VALIDATE_TRI(zck); + + if(lseek(zck->fd, offset, whence) == -1) { char *wh_str = NULL; if(whence == SEEK_CUR) { @@ -79,15 +85,15 @@ int seek_data(int fd, off_t offset, int whence) { } else { wh_str = "using unknown measurement"; } - zck_log(ZCK_LOG_ERROR, "Unable to seek to %lu %s: %s\n", offset, wh_str, - strerror(errno)); + set_error(zck, "Unable to seek to %lu %s: %s", offset, wh_str, + strerror(errno)); return False; } return True; } -ssize_t tell_data(int fd) { - ssize_t loc = lseek(fd, 0, SEEK_CUR); +ssize_t tell_data(zckCtx *zck) { + ssize_t loc = lseek(zck->fd, 0, SEEK_CUR); return loc; } @@ -101,7 +107,7 @@ int chunks_from_temp(zckCtx *zck) { return False; while((read_count = read(zck->temp_fd, data, BUF_SIZE)) > 0) { - if(read_count == -1 || !write_data(zck->fd, data, read_count)) { + if(read_count == -1 || !write_data(zck, zck->fd, data, read_count)) { free(data); return False; } diff --git a/src/lib/zck.c b/src/lib/zck.c index 3e9b1ed..686257f 100644 --- a/src/lib/zck.c +++ b/src/lib/zck.c @@ -35,24 +35,7 @@ #include "zck_private.h" -#define VALIDATE(f) if(!f) { \ - zck_log(ZCK_LOG_ERROR, "zckCtx not initialized\n"); \ - return False; \ - } - -#define VALIDATE_READ(f) VALIDATE(f); \ - if(f->mode != ZCK_MODE_READ) { \ - zck_log(ZCK_LOG_ERROR, \ - "zckCtx not opened for reading\n"); \ - return False; \ - } - -#define VALIDATE_WRITE(f) VALIDATE(f); \ - if(f->mode != ZCK_MODE_WRITE) { \ - zck_log(ZCK_LOG_ERROR, \ - "zckCtx not opened for writing\n"); \ - return False; \ - } + /* If lead format changes, this needs to be changed */ int PUBLIC zck_get_min_download_size() { @@ -105,11 +88,11 @@ static int hex_to_int (char c) { return result; } -static char *ascii_checksum_to_bin (char *checksum) { +static char *ascii_checksum_to_bin (zckCtx *zck, char *checksum) { int cl = strlen(checksum); char *raw_checksum = zmalloc(cl/2); if(raw_checksum == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", cl/2); + set_error(zck, "Unable to allocate %lu bytes\n", cl/2); return NULL; } char *rp = raw_checksum; @@ -133,7 +116,9 @@ static void update_buzhash_bits(zckCtx *zck) { zck->buzhash_bitmask = s; } -int get_tmp_fd() { +int get_tmp_fd(zckCtx *zck) { + VALIDATE_BOOL(zck); + int temp_fd; char *fname = NULL; char template[] = "zcktempXXXXXX"; @@ -144,8 +129,8 @@ int get_tmp_fd() { } fname = zmalloc(strlen(template) + strlen(tmpdir) + 2); if(fname == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", - strlen(template) + strlen(tmpdir) + 2); + set_error(zck, "Unable to allocate %lu bytes\n", + strlen(template) + strlen(tmpdir) + 2); return -1; } strncpy(fname, tmpdir, strlen(tmpdir)); @@ -155,12 +140,12 @@ int get_tmp_fd() { temp_fd = mkstemp(fname); if(temp_fd < 0) { free(fname); - zck_log(ZCK_LOG_ERROR, "Unable to create temporary file\n"); + set_error(zck, "Unable to create temporary file\n"); return -1; } if(unlink(fname) < 0) { free(fname); - zck_log(ZCK_LOG_ERROR, "Unable to delete temporary file\n"); + set_error(zck, "Unable to delete temporary file\n"); return -1; } free(fname); @@ -168,7 +153,7 @@ int get_tmp_fd() { } int import_dict(zckCtx *zck) { - VALIDATE(zck); + VALIDATE_BOOL(zck); size_t size = zck->index.first->length; @@ -179,11 +164,11 @@ int import_dict(zckCtx *zck) { zck_log(ZCK_LOG_DEBUG, "Reading compression dict\n"); char *data = zmalloc(size); if(data == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", size); + set_error(zck, "Unable to allocate %lu bytes\n", size); return False; } if(comp_read(zck, data, size, 0) != size) { - zck_log(ZCK_LOG_ERROR, "Error reading compressed dict\n"); + set_error(zck, "Error reading compressed dict\n"); return False; } zck_log(ZCK_LOG_DEBUG, "Resetting compression\n"); @@ -201,92 +186,93 @@ int import_dict(zckCtx *zck) { int PUBLIC zck_set_soption(zckCtx *zck, zck_soption option, const char *value, size_t length) { + VALIDATE_BOOL(zck); char *data = zmalloc(length); if(data == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", length); + set_error(zck, "Unable to allocate %lu bytes\n", length); return False; } memcpy(data, value, length); /* Validation options */ if(option == ZCK_VAL_HEADER_DIGEST) { - VALIDATE_READ(zck); + VALIDATE_READ_BOOL(zck); zckHashType chk_type = {0}; if(zck->prep_hash_type < 0) { free(data); - zck_log(ZCK_LOG_ERROR, - "For validation, you must set the header hash type " - "*before* the header digest itself\n"); + set_error(zck, "For validation, you must set the header hash type " + "*before* the header digest itself\n"); return False; } - if(!hash_setup(&chk_type, zck->prep_hash_type)) { + if(!hash_setup(zck, &chk_type, zck->prep_hash_type)) { free(data); return False; } if(chk_type.digest_size*2 != length) { free(data); - zck_log(ZCK_LOG_ERROR, "Hash digest size mismatch for header " - "validation\n" - "Expected: %lu\nProvided: %lu\n", chk_type.digest_size*2, - length); + set_fatal_error(zck, "Hash digest size mismatch for header " + "validation\n" + "Expected: %lu\nProvided: %lu\n", + chk_type.digest_size*2, length); return False; } - zck_log(ZCK_LOG_DEBUG, "Setting expected hash to (%s)%s\n", zck_hash_name_from_type(zck->prep_hash_type), data); - zck->prep_digest = ascii_checksum_to_bin(data); + zck_log(ZCK_LOG_DEBUG, "Setting expected hash to (%s)%s\n", + zck_hash_name_from_type(zck->prep_hash_type), data); + zck->prep_digest = ascii_checksum_to_bin(zck, data); free(data); /* Compression options */ } else if(option < 2000) { - VALIDATE_WRITE(zck); + VALIDATE_WRITE_BOOL(zck); return comp_soption(zck, option, data, length); /* Unknown options */ } else { free(data); - zck_log(ZCK_LOG_ERROR, "Unknown string option %i\n", option); + set_error(zck, "Unknown string option %i\n", option); return False; } return True; } int PUBLIC zck_set_ioption(zckCtx *zck, zck_ioption option, ssize_t value) { + VALIDATE_BOOL(zck); + /* Set hash type */ if(option == ZCK_HASH_FULL_TYPE) { - VALIDATE_WRITE(zck); + VALIDATE_WRITE_BOOL(zck); return set_full_hash_type(zck, value); } else if(option == ZCK_HASH_CHUNK_TYPE) { - VALIDATE_WRITE(zck); + VALIDATE_WRITE_BOOL(zck); return set_chunk_hash_type(zck, value); /* Validation options */ } else if(option == ZCK_VAL_HEADER_HASH_TYPE) { - VALIDATE_READ(zck); + VALIDATE_READ_BOOL(zck); if(value < 0) { - zck_log(ZCK_LOG_ERROR, - "Header hash type can't be less than zero: %li\n", - value); + set_error(zck, "Header hash type can't be less than zero: %li\n", + value); return False; } /* Make sure that header hash type is set before the header digest, * otherwise we run the risk of a buffer overflow */ if(zck->prep_digest != NULL) { - zck_log(ZCK_LOG_ERROR, - "For validation, you must set the header hash type " - "*before* the header digest itself\n"); + set_error(zck, "For validation, you must set the header hash type " + "*before* the header digest itself\n"); return False; } zck->prep_hash_type = value; } else if(option == ZCK_VAL_HEADER_LENGTH) { - VALIDATE_READ(zck); + VALIDATE_READ_BOOL(zck); if(value < 0) { - zck_log(ZCK_LOG_ERROR, - "Header size validation can't be less than zero: %li\n", - value); + set_error(zck, + "Header size validation can't be less than zero: %li\n", + value); return False; } zck->prep_hdr_size = value; } else if(option == ZCK_MANUAL_CHUNK) { - VALIDATE_WRITE(zck); + VALIDATE_WRITE_BOOL(zck); if(value != 0) { zck_log(ZCK_LOG_DEBUG, "Disabling automatic chunking\n"); zck->manual_chunk = 1; @@ -298,24 +284,24 @@ int PUBLIC zck_set_ioption(zckCtx *zck, zck_ioption option, ssize_t value) { /* Hash options */ } else if(option < 100) { /* Currently no hash options other than setting hash type, so bail */ - zck_log(ZCK_LOG_ERROR, "Unknown option %lu\n", value); + set_error(zck, "Unknown option %lu\n", value); return False; /* Compression options */ } else if(option < 2000) { - VALIDATE_WRITE(zck); + VALIDATE_WRITE_BOOL(zck); return comp_ioption(zck, option, value); /* Unknown options */ } else { - zck_log(ZCK_LOG_ERROR, "Unknown integer option %i\n", option); + set_error(zck, "Unknown integer option %i\n", option); return False; } return True; } int PUBLIC zck_close(zckCtx *zck) { - VALIDATE(zck); + VALIDATE_BOOL(zck); if(zck->mode == ZCK_MODE_WRITE) { if(zck_end_chunk(zck) < 0) @@ -343,7 +329,7 @@ int PUBLIC zck_close(zckCtx *zck) { } void PUBLIC zck_free(zckCtx **zck) { - if(*zck == NULL) + if(zck == NULL || *zck == NULL) return; zck_clear(*zck); free(*zck); @@ -353,9 +339,9 @@ void PUBLIC zck_free(zckCtx **zck) { zckCtx PUBLIC *zck_create() { zckCtx *zck = zmalloc(sizeof(zckCtx)); if(zck == NULL) { - zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n", + zck_log(ZCK_LOG_NONE, "Unable to allocate %lu bytes\n", sizeof(zckCtx)); - return False; + return NULL; } zck->prep_hash_type = -1; zck->prep_hdr_size = -1; @@ -365,68 +351,61 @@ zckCtx PUBLIC *zck_create() { return zck; } -zckCtx PUBLIC *zck_init_adv_read (int src_fd) { - zckCtx *zck = zck_create(); - if(zck == NULL) - return NULL; +int PUBLIC zck_init_adv_read (zckCtx *zck, int src_fd) { + VALIDATE_BOOL(zck); zck->mode = ZCK_MODE_READ; zck->fd = src_fd; - return zck; + return True; } -zckCtx PUBLIC *zck_init_read (int src_fd) { - zckCtx *zck = zck_init_adv_read(src_fd); - if(zck == NULL) - return NULL; +int PUBLIC zck_init_read (zckCtx *zck, int src_fd) { + VALIDATE_BOOL(zck); - if(!zck_read_lead(zck)) { - zck_free(&zck); - return NULL; - } - if(!zck_read_header(zck)) { - zck_free(&zck); - return NULL; - } + if(!zck_init_adv_read(zck, src_fd)) + return False; - return zck; + if(!zck_read_lead(zck)) + return False; + + if(!zck_read_header(zck)) + return False; + + return True; } -zckCtx PUBLIC *zck_init_write (int dst_fd) { - zckCtx *zck = zck_create(); - if(zck == NULL) - return NULL; +int PUBLIC zck_init_write (zckCtx *zck, int dst_fd) { + VALIDATE_BOOL(zck); zck->mode = ZCK_MODE_WRITE; - zck->temp_fd = get_tmp_fd(); + zck->temp_fd = get_tmp_fd(zck); if(zck->temp_fd < 0) - goto iw_error; + return False; /* Set defaults */ #ifdef ZCHUNK_ZSTD if(!zck_set_ioption(zck, ZCK_COMP_TYPE, ZCK_COMP_ZSTD)) - goto iw_error; + return False; #else if(!zck_set_ioption(zck, ZCK_COMP_TYPE, ZCK_COMP_NONE)) - goto iw_error; + return False; #endif if(!zck_set_ioption(zck, ZCK_HASH_FULL_TYPE, ZCK_HASH_SHA256)) - goto iw_error; + return False; if(!zck_set_ioption(zck, ZCK_HASH_CHUNK_TYPE, ZCK_HASH_SHA512_128)) - goto iw_error; + return False; zck->fd = dst_fd; - return zck; -iw_error: - free(zck); - return NULL; + return True; } int PUBLIC zck_get_fd(zckCtx *zck) { + VALIDATE_BOOL(zck); return zck->fd; } -void PUBLIC zck_set_fd(zckCtx *zck, int fd) { +int PUBLIC zck_set_fd(zckCtx *zck, int fd) { + VALIDATE_BOOL(zck); zck->fd = fd; - return; + return True; } diff --git a/src/lib/zck_private.h b/src/lib/zck_private.h index cf15bf2..fa44465 100644 --- a/src/lib/zck_private.h +++ b/src/lib/zck_private.h @@ -22,23 +22,82 @@ #define zck_log(...) zck_log_wf(__func__, __VA_ARGS__) -#define set_error(zck, ...) set_error_wf(zck, 0, __VA_ARGS__); \ - zck_log(__VA_ARGS__) -#define set_fatal_error(zck, ...) set_error_wf(zck, 1, __VA_ARGS__); \ - zck_log(__VA_ARGS__) -struct zckComp; - -typedef int (*finit)(struct zckComp *comp); -typedef int (*fparam)(struct zckComp *comp, int option, const void *value); -typedef int (*fccompend)(struct zckComp *comp, char **dst, size_t *dst_size, - int use_dict); -typedef ssize_t (*fcomp)(struct zckComp *comp, const char *src, +#define set_error(zck, ...) set_error_wf(zck, 0, __func__, __VA_ARGS__) +#define set_fatal_error(zck, ...) set_error_wf(zck, 1, __func__, __VA_ARGS__) + +#define _VALIDATE_BOOL(f) if(!f) { \ + zck_log(ZCK_LOG_NONE, \ + "zckCtx not initialized\n"); \ + return False; \ + } +#define _VALIDATE_TRI(f) if(!f) { \ + zck_log(ZCK_LOG_NONE, \ + "zckCtx not initialized\n"); \ + return -1; \ + } +#define _VALIDATE_CHAR(f) if(!f) { \ + zck_log(ZCK_LOG_NONE, \ + "zckCtx not initialized\n"); \ + return NULL; \ + } +#define VALIDATE_BOOL(f) _VALIDATE_BOOL(f) \ + if((f)->error_state > 0) return False; +#define VALIDATE_TRI(f) _VALIDATE_TRI(f) \ + if((f)->error_state > 0) return -1; +#define VALIDATE_CHAR(f) _VALIDATE_CHAR(f) \ + if((f)->error_state > 0) return NULL; + +#define VALIDATE_READ_BOOL(f) VALIDATE_BOOL(f); \ + if(f->mode != ZCK_MODE_READ) { \ + set_error(f, \ + "zckCtx not opened for reading\n"); \ + return False; \ + } +#define VALIDATE_READ_TRI(f) VALIDATE_TRI(f); \ + if(f->mode != ZCK_MODE_READ) { \ + set_error(f, \ + "zckCtx not opened for reading\n"); \ + return -1; \ + } +#define VALIDATE_READ_CHAR(f) VALIDATE_CHAR(f); \ + if(f->mode != ZCK_MODE_READ) { \ + set_error(f, \ + "zckCtx not opened for reading\n"); \ + return NULL; \ + } + +#define VALIDATE_WRITE_BOOL(f) VALIDATE_BOOL(f); \ + if(f->mode != ZCK_MODE_WRITE) { \ + set_error(f, \ + "zckCtx not opened for writing\n"); \ + return False; \ + } +#define VALIDATE_WRITE_TRI(f) VALIDATE_TRI(f); \ + if(f->mode != ZCK_MODE_WRITE) { \ + set_error(f, \ + "zckCtx not opened for writing\n"); \ + return -1; \ + } +#define VALIDATE_WRITE_CHAR(f) VALIDATE_CHAR(f); \ + if(f->mode != ZCK_MODE_WRITE) { \ + set_error(f, \ + "zckCtx not opened for writing\n"); \ + return NULL; \ + } +typedef struct zckComp zckComp; +typedef zckCtx zckCtx; + +typedef int (*finit)(zckCtx *zck, zckComp *comp); +typedef int (*fparam)(zckCtx *zck,zckComp *comp, int option, const void *value); +typedef int (*fccompend)(zckCtx *zck, zckComp *comp, char **dst, + size_t *dst_size, int use_dict); +typedef ssize_t (*fcomp)(zckCtx *zck, zckComp *comp, const char *src, const size_t src_size, char **dst, size_t *dst_size, int use_dict); -typedef int (*fdecomp)(struct zckComp *comp, const int use_dict); -typedef int (*fdcompend)(struct zckComp *comp, const int use_dict, +typedef int (*fdecomp)(zckCtx *zck, zckComp *comp, const int use_dict); +typedef int (*fdcompend)(zckCtx *zck, zckComp *comp, const int use_dict, const size_t fd_size); -typedef int (*fcclose)(struct zckComp *comp); +typedef int (*fcclose)(zckCtx *zck, zckComp *comp); typedef enum zck_log_type zck_log_type; @@ -230,13 +289,14 @@ int import_dict(zckCtx *zck) /* hash/hash.h */ -int hash_setup(zckHashType *ht, int h) +int hash_setup(zckCtx *zck, zckHashType *ht, int h) __attribute__ ((warn_unused_result)); -int hash_init(zckHash *hash, zckHashType *hash_type) +int hash_init(zckCtx *zck, zckHash *hash, zckHashType *hash_type) __attribute__ ((warn_unused_result)); -int hash_update(zckHash *hash, const char *message, const size_t size) +int hash_update(zckCtx *zck, zckHash *hash, const char *message, + const size_t size) __attribute__ ((warn_unused_result)); -char *hash_finalize(zckHash *hash) +char *hash_finalize(zckCtx *zck, zckHash *hash) __attribute__ ((warn_unused_result)); void hash_close(zckHash *hash); void hash_reset(zckHashType *ht); @@ -281,13 +341,13 @@ int write_index(zckCtx *zck) /* io.c */ -int seek_data(int fd, off_t offset, int whence) +int seek_data(zckCtx *zck, off_t offset, int whence) __attribute__ ((warn_unused_result)); -ssize_t tell_data(int fd) +ssize_t tell_data(zckCtx *zck) __attribute__ ((warn_unused_result)); -ssize_t read_data(int fd, char *data, size_t length) +ssize_t read_data(zckCtx *zck, char *data, size_t length) __attribute__ ((warn_unused_result)); -int write_data(int fd, const char *data, size_t length) +int write_data(zckCtx *zck, int fd, const char *data, size_t length) __attribute__ ((warn_unused_result)); int chunks_from_temp(zckCtx *zck) __attribute__ ((warn_unused_result)); @@ -305,7 +365,7 @@ int comp_close(zckCtx *zck) __attribute__ ((warn_unused_result)); int comp_reset(zckCtx *zck) __attribute__ ((warn_unused_result)); -int comp_add_to_dc(zckComp *comp, const char *src, size_t src_size) +int comp_add_to_dc(zckCtx *zck, zckComp *comp, const char *src, size_t src_size) __attribute__ ((warn_unused_result)); ssize_t comp_read(zckCtx *zck, char *dst, size_t dst_size, int use_dict) __attribute__ ((warn_unused_result)); @@ -331,20 +391,23 @@ int dl_write_range(zckDL *dl, const char *at, size_t length) __attribute__ ((warn_unused_result)); /* compint.c */ -int compint_from_int(char *compint, int val, size_t *length) +int compint_from_int(zckCtx *zck, char *compint, int val, size_t *length) __attribute__ ((warn_unused_result)); void compint_from_size(char *compint, size_t val, size_t *length); -int compint_to_int(int *val, const char *compint, size_t *length, +int compint_to_int(zckCtx *zck, int *val, const char *compint, size_t *length, size_t max_length) __attribute__ ((warn_unused_result)); -int compint_to_size(size_t *val, const char *compint, size_t *length, - size_t max_length) +int compint_to_size(zckCtx *zck, size_t *val, const char *compint, + size_t *length, size_t max_length) __attribute__ ((warn_unused_result)); /* log.c */ +void zck_log_v(const char *function, zck_log_type lt, const char *format, + va_list args); void zck_log_wf(const char *function, zck_log_type lt, const char *format, ...); /* error.c */ -void set_error_wf(zckCtx *zck, int fatal, const char *format, ...); +void set_error_wf(zckCtx *zck, int fatal, const char *function, + const char *format, ...); #endif diff --git a/src/unzck.c b/src/unzck.c index ff8f2db..11d8e64 100644 --- a/src/unzck.c +++ b/src/unzck.c @@ -132,11 +132,14 @@ int main (int argc, char *argv[]) { int good_exit = False; - zckCtx *zck = zck_init_read(src_fd); + zckCtx *zck = zck_create(); if(zck == NULL) goto error1; char *data = malloc(BUF_SIZE); + if(!zck_init_read(zck, src_fd)) + goto error2; + size_t total = 0; while(True) { ssize_t read = zck_read(zck, data, BUF_SIZE); @@ -157,6 +160,8 @@ int main (int argc, char *argv[]) { good_exit = True; error2: free(data); + if(!good_exit) + printf(zck_get_error(zck)); zck_free(&zck); error1: if(!good_exit) diff --git a/src/zck.c b/src/zck.c index 1bbe3ce..faeee4f 100644 --- a/src/zck.c +++ b/src/zck.c @@ -168,8 +168,12 @@ int main (int argc, char *argv[]) { } free(out_name); - zckCtx *zck = zck_init_write(dst_fd); + zckCtx *zck = zck_create(); if(zck == NULL) { + printf("Unable to allocate zchunk context\n"); + exit(1); + } + if(!zck_init_write(zck, dst_fd)) { printf("Unable to write to %s\n", out_name); exit(1); } @@ -179,13 +183,17 @@ int main (int argc, char *argv[]) { exit(1); }*/ if(dict_size > 0) { - if(!zck_set_soption(zck, ZCK_COMP_DICT, dict, dict_size)) + if(!zck_set_soption(zck, ZCK_COMP_DICT, dict, dict_size)) { + printf(zck_get_error(zck)); exit(1); + } } free(dict); if(arguments.manual_chunk) { - if(!zck_set_ioption(zck, ZCK_MANUAL_CHUNK, 1)) + if(!zck_set_ioption(zck, ZCK_MANUAL_CHUNK, 1)) { + printf(zck_get_error(zck)); exit(1); + } } char *data; @@ -265,13 +273,17 @@ int main (int argc, char *argv[]) { } /* Buzhash rolling window */ } else { - if(zck_write(zck, data, in_size) < 0) + if(zck_write(zck, data, in_size) < 0) { + printf(zck_get_error(zck)); exit(1); + } } free(data); } - if(!zck_close(zck)) + if(!zck_close(zck)) { + printf(zck_get_error(zck)); exit(1); + } if(arguments.log_level <= ZCK_LOG_INFO) { printf("Wrote %lu bytes in %lu chunks\n", (unsigned long)(zck_get_data_length(zck) + diff --git a/src/zck_delta_size.c b/src/zck_delta_size.c index 578de77..4f43871 100644 --- a/src/zck_delta_size.c +++ b/src/zck_delta_size.c @@ -111,8 +111,12 @@ int main (int argc, char *argv[]) { perror(""); exit(1); } - zckCtx *zck_src = zck_init_read(src_fd); + zckCtx *zck_src = zck_create(); if(zck_src == NULL) { + printf("Unable to create zchunk context\n"); + exit(1); + } + if(!zck_init_read(zck_src, src_fd)) { printf("Unable to read header from %s\n", arguments.args[0]); exit(1); } @@ -124,8 +128,12 @@ int main (int argc, char *argv[]) { perror(""); exit(1); } - zckCtx *zck_tgt = zck_init_read(tgt_fd); + zckCtx *zck_tgt = zck_create(); if(zck_tgt == NULL) { + printf("Unable to create zchunk context\n"); + exit(1); + } + if(!zck_init_read(zck_tgt, tgt_fd)) { printf("Unable to open %s\n", arguments.args[1]); exit(1); } diff --git a/src/zck_dl.c b/src/zck_dl.c index fd42bad..caee343 100644 --- a/src/zck_dl.c +++ b/src/zck_dl.c @@ -282,8 +282,12 @@ int main (int argc, char *argv[]) { perror(""); exit(10); } - zck_src = zck_init_read(src_fd); + zck_src = zck_create(); if(zck_src == NULL) { + printf("Unable to create zchunk context\n"); + exit(10); + } + if(!zck_init_read(zck_src, src_fd)) { printf("Unable to open %s\n", arguments.source); exit(10); } @@ -305,9 +309,15 @@ int main (int argc, char *argv[]) { free(outname_full); exit(10); } - zckCtx *zck_tgt = zck_init_adv_read(dst_fd); - if(zck_tgt == NULL) + zckCtx *zck_tgt = zck_create(); + if(zck_tgt == NULL) { + printf("Unable to create zchunk context\n"); exit(10); + } + if(!zck_init_adv_read(zck_tgt, dst_fd)) { + printf(zck_get_error(zck_tgt)); + exit(10); + } zckDL *dl = zck_dl_init(zck_tgt); if(dl == NULL) @@ -393,8 +403,9 @@ int main (int argc, char *argv[]) { while(range_attempt[ra_index] > 1 && range_attempt[ra_index+1] > zck_get_range_count(range)) ra_index++; - char *range_string = zck_get_range_char(range); + char *range_string = zck_get_range_char(zck_src, range); if(range_string == NULL) { + printf(zck_get_error(zck_src)); exit_val = 10; goto out; } diff --git a/src/zck_read_header.c b/src/zck_read_header.c index ff84301..d530b4c 100644 --- a/src/zck_read_header.c +++ b/src/zck_read_header.c @@ -114,8 +114,14 @@ int main (int argc, char *argv[]) { perror(""); exit(1); } - zckCtx *zck = zck_init_read(src_fd); + + zckCtx *zck = zck_create(); if(zck == NULL) { + printf("Unable to create zchunk context\n"); + exit(1); + } + if(!zck_init_read(zck, src_fd)) { + printf(zck_get_error(zck)); printf("Unable to read zchunk header\n"); exit(1); }