From db5013d6690edc4848d54acb10231e338e9aaa8d Mon Sep 17 00:00:00 2001 From: aone Date: Mon, 22 Apr 2024 14:36:23 +0200 Subject: [PATCH 1/3] Added -o path parameter Added `-o path` parameter to specify a custom destination for the output file. Applies `-k` and only applies if `-c` is not used. --- snzip.c | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/snzip.c b/snzip.c index 6954498..52de5da 100644 --- a/snzip.c +++ b/snzip.c @@ -227,6 +227,7 @@ int main(int argc, char **argv) int block_size = 0; size_t rsize = 0; size_t wsize = 0; + const char *output_path = NULL; const char *format_name = NULL; stream_format_t *fmt = &DEFAULT_FORMAT; @@ -249,7 +250,7 @@ int main(int argc, char **argv) opt_keep = TRUE; } - while ((opt = getopt(argc, argv, "cdkt:hs:b:B:R:W:T")) != -1) { + while ((opt = getopt(argc, argv, "cdko:t:hs:b:B:R:W:T")) != -1) { char *endptr; switch (opt) { @@ -263,6 +264,10 @@ int main(int argc, char **argv) case 'k': opt_keep = TRUE; break; + case 'o': + output_path = optarg; + opt_keep = TRUE; + break; case 't': format_name = optarg; break; @@ -386,29 +391,43 @@ int main(int argc, char **argv) outfp = stdout; } else { size_t suffixlen = strlen(fmt->suffix); + size_t reffilelen = infilelen; + char *reffile = malloc(PATH_MAX); + sprintf(reffile, "%s", infile); + if (output_path) { + /* if output path is specified, prepare reffile */ + const char *lastpath = strrchr(reffile, '/'); + if (lastpath != NULL) { + sprintf(reffile, "%s/%s", output_path, lastpath + 1); + } + else { + sprintf(reffile, "%s", output_path); + } + reffilelen = strlen(reffile); + } if (opt_uncompress) { /* check suffix */ - const char *suffix = strrchr(infile, '.'); + const char *suffix = strrchr(reffile, '.'); int remove_suffix = (suffix != NULL && strcmp(suffix + 1, fmt->suffix) == 0); - size_t new_size = infilelen + (remove_suffix ? (- suffixlen) : 4); + size_t new_size = reffilelen + (remove_suffix ? (- suffixlen) : 4); if (new_size >= sizeof(outfile)) { - print_error("%s has too long file name.\n", infile); + print_error("%s has too long file name.\n", reffile); exit(1); } if (remove_suffix) { - memcpy(outfile, infile, infilelen - suffixlen - 1); - outfile[infilelen - suffixlen - 1] = '\0'; + memcpy(outfile, reffile, reffilelen - suffixlen - 1); + outfile[reffilelen - suffixlen - 1] = '\0'; } else { fprintf(stderr, "%s: Can't guess original name for %s -- using %s.out\n", - progname, infile, infile); - snprintf(outfile, sizeof(outfile), "%s.out", infile); + progname, reffile, reffile); + snprintf(outfile, sizeof(outfile), "%s.out", reffile); } } else { - if (infilelen + suffixlen + 2 >= sizeof(outfile)) { - print_error("%s has too long file name.\n", infile); + if (reffilelen + suffixlen + 2 >= sizeof(outfile)) { + print_error("%s has too long file name.\n", reffile); exit(1); } - sprintf(outfile, "%s.%s", infile, fmt->suffix); + sprintf(outfile, "%s.%s", reffile, fmt->suffix); } outfp = fopen(outfile, "wb" OPTIMIZE_SEQUENTIAL); if (outfp == NULL) { @@ -540,6 +559,7 @@ static void show_usage(const char *progname, int exit_code) " -c output to standard output, keep original files unchanged\n" " -d decompress\n" " -k keep (don't delete) input files\n" + " -o path output to the specified path, keep original files unchanged\n" " -t name file format name. see below. The default format is %s.\n" " -h give this help\n" "\n" From 8b30a53c1d6a93fcc91a628f7d9c25986cc2843c Mon Sep 17 00:00:00 2001 From: aone Date: Mon, 22 Apr 2024 16:15:38 +0200 Subject: [PATCH 2/3] Fixed setting `reffile` prematurely for -o parameter --- snzip.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/snzip.c b/snzip.c index 52de5da..e5c2335 100644 --- a/snzip.c +++ b/snzip.c @@ -393,10 +393,9 @@ int main(int argc, char **argv) size_t suffixlen = strlen(fmt->suffix); size_t reffilelen = infilelen; char *reffile = malloc(PATH_MAX); - sprintf(reffile, "%s", infile); if (output_path) { - /* if output path is specified, prepare reffile */ - const char *lastpath = strrchr(reffile, '/'); + /* if output_path is specified define reffile accordingly */ + const char *lastpath = strrchr(infile, '/'); if (lastpath != NULL) { sprintf(reffile, "%s/%s", output_path, lastpath + 1); } @@ -405,6 +404,9 @@ int main(int argc, char **argv) } reffilelen = strlen(reffile); } + else { + sprintf(reffile, "%s", infile); + } if (opt_uncompress) { /* check suffix */ const char *suffix = strrchr(reffile, '.'); From d964e69d4162ccb6ef46680854d04cf259622c71 Mon Sep 17 00:00:00 2001 From: aone Date: Mon, 22 Apr 2024 20:07:39 +0200 Subject: [PATCH 3/3] Custom name support in -o parameter If the parameter point to a directory, use the current naming method. If points to a new file, use as a custom name. --- snzip.c | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/snzip.c b/snzip.c index e5c2335..4568081 100644 --- a/snzip.c +++ b/snzip.c @@ -392,22 +392,46 @@ int main(int argc, char **argv) } else { size_t suffixlen = strlen(fmt->suffix); size_t reffilelen = infilelen; - char *reffile = malloc(PATH_MAX); + char reffile[PATH_MAX]; + int usingCustomName = 0; if (output_path) { /* if output_path is specified define reffile accordingly */ - const char *lastpath = strrchr(infile, '/'); - if (lastpath != NULL) { - sprintf(reffile, "%s/%s", output_path, lastpath + 1); + size_t output_pathlen = strlen(output_path); + if (output_pathlen >= sizeof(reffile)) { + print_error("%s has too long file name.\n", output_path); + exit(1); + } + struct stat statbuf; + if ((stat(output_path, &statbuf) == 0) && (S_ISDIR(statbuf.st_mode))) { + const char *lastpath = strrchr(infile, '/'); + if (lastpath != NULL) { + if (output_pathlen + strlen(lastpath) + 2 >= sizeof(reffile)) { + print_error("%s/%s has too long file name.\n", output_path, lastpath + 1); + exit(1); + } + sprintf(reffile, "%s/%s", output_path, lastpath + 1); + } + else { + if (output_pathlen + infilelen + 1 >= sizeof(reffile)) { + print_error("%s/%s has too long file name.\n", output_path, infile); + exit(1); + } + sprintf(reffile, "%s/%s", output_path, infile); + } } else { - sprintf(reffile, "%s", output_path); + usingCustomName = 1; + sprintf(reffile, "%s", output_path); } reffilelen = strlen(reffile); } else { sprintf(reffile, "%s", infile); } - if (opt_uncompress) { + if (usingCustomName) { + sprintf(outfile, "%s", reffile); + } + else if (opt_uncompress) { /* check suffix */ const char *suffix = strrchr(reffile, '.'); int remove_suffix = (suffix != NULL && strcmp(suffix + 1, fmt->suffix) == 0);