From: Jonathan Dieter Date: Sat, 1 Dec 2018 22:19:44 +0000 (+0000) Subject: Add argument to unzck to extract dictionary X-Git-Tag: archive/raspbian/1.1.9+ds1-1+rpi1~1^2~68 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=8108cb3b6171dcb8cab2c567d5964f3544ac0d39;p=zchunk.git Add argument to unzck to extract dictionary Signed-off-by: Jonathan Dieter --- diff --git a/src/unzck.c b/src/unzck.c index 6816a92..46f6d9a 100644 --- a/src/unzck.c +++ b/src/unzck.c @@ -49,6 +49,7 @@ static struct argp_option options[] = { {"verbose", 'v', 0, 0, "Increase verbosity (can be specified more than once for debugging)"}, {"stdout", 'c', 0, 0, "Direct output to stdout"}, + {"dict", 1000, 0, 0, "Only extract the dictionary"}, {"version", 'V', 0, 0, "Show program version"}, { 0 } }; @@ -56,6 +57,7 @@ static struct argp_option options[] = { struct arguments { char *args[1]; zck_log_type log_level; + bool dict; bool stdout; bool exit; }; @@ -79,7 +81,9 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) { version(); arguments->exit = true; break; - + case 1000: + arguments->dict = true; + break; case ARGP_KEY_ARG: if (state->arg_num >= 1) { argp_usage (state); @@ -123,9 +127,15 @@ int main (int argc, char *argv[]) { exit(1); } char *base_name = basename(arguments.args[0]); - char *out_name = malloc(strlen(base_name) - 3); + char *out_name = NULL; + if(arguments.dict) + out_name = calloc(strlen(base_name) + 2, 1); // len .zck -> .zdict = +2 + else + out_name = calloc(strlen(base_name) - 3, 1); assert(out_name); - snprintf(out_name, strlen(base_name) - 3, "%s", base_name); + snprintf(out_name, strlen(base_name) - 3, "%s", base_name); //Strip off .zck + if(arguments.dict) + snprintf(out_name + strlen(base_name) - 4, 7, ".zdict"); int dst_fd = STDOUT_FILENO; if(!arguments.stdout) { @@ -140,12 +150,50 @@ int main (int argc, char *argv[]) { bool good_exit = false; + char *data = NULL; zckCtx *zck = zck_create(); - char *data = malloc(BUF_SIZE); - assert(data); - if(!zck_init_read(zck, src_fd)) + if(!zck_init_read(zck, src_fd)) { + dprintf(STDERR_FILENO, "%s", zck_get_error(zck)); goto error2; + } + /* Only write dictionary */ + if(arguments.dict) { + zckChunk *dict = zck_get_first_chunk(zck); + ssize_t dict_size = zck_get_chunk_size(dict); + if(dict_size < 0) { + dprintf(STDERR_FILENO, "%s", zck_get_error(zck)); + goto error2; + } + data = calloc(dict_size, 1); + assert(data); + ssize_t read_size = zck_get_chunk_data(dict, data, dict_size); + if(read_size != dict_size) { + if(read_size < 0) + dprintf(STDERR_FILENO, "%s", zck_get_error(zck)); + else + dprintf(STDERR_FILENO, + "Dict size doesn't match expected size: %li != %li\n", + read_size, dict_size); + goto error2; + } + if(write(dst_fd, data, dict_size) != dict_size) { + dprintf(STDERR_FILENO, "Error writing to %s\n", out_name); + goto error2; + } + if(dict_size > 0) { + int ret = zck_get_chunk_valid(dict); + if(ret < 1) { + if(ret == -1) + dprintf(STDERR_FILENO, "Data checksum failed verification\n"); + else + dprintf(STDERR_FILENO, "%s", zck_get_error(zck)); + goto error2; + } + } + good_exit = true; + goto error2; + } int ret = zck_validate_data_checksum(zck); if(ret < 1) { if(ret == -1) @@ -153,11 +201,15 @@ int main (int argc, char *argv[]) { goto error2; } + data = calloc(BUF_SIZE, 1); + assert(data); size_t total = 0; while(true) { ssize_t read = zck_read(zck, data, BUF_SIZE); - if(read < 0) + if(read < 0) { + dprintf(STDERR_FILENO, "%s", zck_get_error(zck)); goto error2; + } if(read == 0) break; if(write(dst_fd, data, read) != read) { @@ -166,15 +218,15 @@ int main (int argc, char *argv[]) { } total += read; } - if(!zck_close(zck)) + if(!zck_close(zck)) { + dprintf(STDERR_FILENO, "%s", zck_get_error(zck)); goto error2; + } if(arguments.log_level <= ZCK_LOG_INFO) dprintf(STDERR_FILENO, "Decompressed %lu bytes\n", (unsigned long)total); good_exit = true; error2: free(data); - if(!good_exit) - dprintf(STDERR_FILENO, "%s", zck_get_error(zck)); zck_free(&zck); if(!good_exit) unlink(out_name); diff --git a/test/meson.build b/test/meson.build index 8f6e267..94080b3 100644 --- a/test/meson.build +++ b/test/meson.build @@ -189,6 +189,17 @@ test( join_paths(file_path, 'LICENSE.manual.dict.fodt.zck') ] ) +test( + 'decompress dict from auto-chunked file', + shacheck, + args: [ + unzck, + 'LICENSE.dict.fodt.zdict', + 'b20064d89c3beb8605d99c994ff45304f308abd840c0981475dd2faca6ec854b', + '--dict', + join_paths(file_path, 'LICENSE.dict.fodt.zck') + ] +) check_sha = '430c1963f71efe663272d39f7a7941d4a4e78d43c20caba8876a12f6a18eaeb1'