From 1acf2435400730869c6d22856251008dd98126d9 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Mon, 24 Aug 2020 19:10:03 -0400 Subject: [PATCH 01/10] Add a warning whenever (de)compressing multiple files into one source, or into stdout --- programs/fileio.c | 23 +++++++++++++++++++++++ tests/playTests.sh | 24 +++++++++++++++--------- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index d5b8a7d14..bdf42543b 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1677,6 +1677,29 @@ int FIO_compressMultipleFilenames(FIO_prefs_t* const prefs, /* init */ assert(outFileName != NULL || suffix != NULL); if (outFileName != NULL) { /* output into a single destination (stdout typically) */ + if (nbFiles > 1) { + if (!strcmp (outFileName, stdoutmark)) { + DISPLAY("zstd: WARNING: all input files will be processed and concatenated into stdout. "); + } else { + DISPLAY("zstd: WARNING: all input files will be processed and concatenated into a single output file: %s ", outFileName); + } + if (prefs->removeSrcFile && !prefs->overwrite) { + DISPLAY("\nYou must specify -f as well in order to execute this command with --rm. Aborting..."); + return 1; + } + + DISPLAY("Proceed? (y/n): "); + { + int ch = getchar(); + if ((ch != 'y') && (ch != 'Y')) { + DISPLAY("zstd: aborting...\n"); + return 1; + } + /* flush the rest */ + while ((ch!=EOF) && (ch!='\n')) + ch = getchar(); + } + } ress.dstFile = FIO_openDstFile(prefs, NULL, outFileName); if (ress.dstFile == NULL) { /* could not open outFileName */ error = 1; diff --git a/tests/playTests.sh b/tests/playTests.sh index b7bfa76cd..b84cffd01 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -349,19 +349,25 @@ rm tmp* println "\n===> compress multiple files" println hello > tmp1 println world > tmp2 -zstd tmp1 tmp2 -o "$INTOVOID" -f -zstd tmp1 tmp2 -c | zstd -t -zstd tmp1 tmp2 -o tmp.zst +echo 'y' | zstd tmp1 tmp2 -o "$INTOVOID" -f # echo 'y' confirms the warning prompt +echo 'y' | zstd tmp1 tmp2 -c | zstd -t +echo 'y' | zstd tmp1 tmp2 -o tmp.zst test ! -f tmp1.zst test ! -f tmp2.zst zstd tmp1 tmp2 zstd -t tmp1.zst tmp2.zst zstd -dc tmp1.zst tmp2.zst -zstd tmp1.zst tmp2.zst -o "$INTOVOID" -f -zstd -d tmp1.zst tmp2.zst -o tmp +echo 'y' | zstd tmp1.zst tmp2.zst -o "$INTOVOID" -f +echo 'y' | zstd -d tmp1.zst tmp2.zst -o tmp touch tmpexists -zstd tmp1 tmp2 -f -o tmpexists -zstd tmp1 tmp2 -o tmpexists && die "should have refused to overwrite" +echo 'y' | zstd tmp1 tmp2 -f -o tmpexists +echo 'y' | zstd tmp1 tmp2 -o tmpexists && die "should have refused to overwrite" +zstd tmp1 tmp2 -o "$INTOVOID" --rm && die "should have refused to execute with --rm" +println gooder > tmp_rm1 +println boi > tmp_rm2 +echo 'y' | zstd tmp_rm1 tmp_rm2 -o tmp_rm3.zst -f --rm +rm tmp_rm3.zst + # Bug: PR #972 if [ "$?" -eq 139 ]; then die "should not have segfaulted" @@ -382,7 +388,7 @@ test -f tmp1 test -f tmp2 test -f tmp3 println "compress tmp* into stdout > tmpall : " -zstd -c tmp1 tmp2 tmp3 > tmpall +echo 'y' | zstd -c tmp1 tmp2 tmp3 > tmpall test -f tmpall # should check size of tmpall (should be tmp1.zst + tmp2.zst + tmp3.zst) println "decompress tmpall* into stdout > tmpdec : " cp tmpall tmpall2 @@ -920,7 +926,7 @@ datagen | zstd -c | zstd -t println "\n===> golden files tests " zstd -t -r "$TESTDIR/golden-decompression" -zstd -c -r "$TESTDIR/golden-compression" | zstd -t +echo 'y' | zstd -c -r "$TESTDIR/golden-compression" | zstd -t zstd -D "$TESTDIR/golden-dictionaries/http-dict-missing-symbols" "$TESTDIR/golden-compression/http" -c | zstd -D "$TESTDIR/golden-dictionaries/http-dict-missing-symbols" -t From dde97de6c43f0f6ca43c7ba382471f698ccb2873 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Mon, 24 Aug 2020 20:19:55 -0400 Subject: [PATCH 02/10] Only ask to proceed if using --rm, otherwise just display warning. -f bypasses it all. More robust tests --- programs/fileio.c | 28 +++++++++++++--------------- tests/playTests.sh | 34 ++++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index bdf42543b..c4737372a 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1677,28 +1677,26 @@ int FIO_compressMultipleFilenames(FIO_prefs_t* const prefs, /* init */ assert(outFileName != NULL || suffix != NULL); if (outFileName != NULL) { /* output into a single destination (stdout typically) */ - if (nbFiles > 1) { + if (nbFiles > 1 && !prefs->overwrite) { if (!strcmp (outFileName, stdoutmark)) { DISPLAY("zstd: WARNING: all input files will be processed and concatenated into stdout. "); } else { DISPLAY("zstd: WARNING: all input files will be processed and concatenated into a single output file: %s ", outFileName); } - if (prefs->removeSrcFile && !prefs->overwrite) { - DISPLAY("\nYou must specify -f as well in order to execute this command with --rm. Aborting..."); - return 1; - } - - DISPLAY("Proceed? (y/n): "); - { - int ch = getchar(); - if ((ch != 'y') && (ch != 'Y')) { - DISPLAY("zstd: aborting...\n"); - return 1; + if (prefs->removeSrcFile) { + DISPLAY("Proceed? (y/n): "); + { + int ch = getchar(); + if ((ch != 'y') && (ch != 'Y')) { + DISPLAY("zstd: aborting...\n"); + return 1; + } + /* flush the rest */ + while ((ch!=EOF) && (ch!='\n')) + ch = getchar(); } - /* flush the rest */ - while ((ch!=EOF) && (ch!='\n')) - ch = getchar(); } + DISPLAY("\n"); } ress.dstFile = FIO_openDstFile(prefs, NULL, outFileName); if (ress.dstFile == NULL) { /* could not open outFileName */ diff --git a/tests/playTests.sh b/tests/playTests.sh index b84cffd01..02fd7cdc1 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -349,24 +349,34 @@ rm tmp* println "\n===> compress multiple files" println hello > tmp1 println world > tmp2 -echo 'y' | zstd tmp1 tmp2 -o "$INTOVOID" -f # echo 'y' confirms the warning prompt -echo 'y' | zstd tmp1 tmp2 -c | zstd -t -echo 'y' | zstd tmp1 tmp2 -o tmp.zst +zstd tmp1 tmp2 -o "$INTOVOID" -f +zstd tmp1 tmp2 -c | zstd -t +zstd tmp1 tmp2 -o tmp.zst test ! -f tmp1.zst test ! -f tmp2.zst zstd tmp1 tmp2 zstd -t tmp1.zst tmp2.zst zstd -dc tmp1.zst tmp2.zst -echo 'y' | zstd tmp1.zst tmp2.zst -o "$INTOVOID" -f -echo 'y' | zstd -d tmp1.zst tmp2.zst -o tmp +zstd tmp1.zst tmp2.zst -o "$INTOVOID" -f +zstd -d tmp1.zst tmp2.zst -o tmp touch tmpexists -echo 'y' | zstd tmp1 tmp2 -f -o tmpexists -echo 'y' | zstd tmp1 tmp2 -o tmpexists && die "should have refused to overwrite" -zstd tmp1 tmp2 -o "$INTOVOID" --rm && die "should have refused to execute with --rm" +zstd tmp1 tmp2 -f -o tmpexists +zstd tmp1 tmp2 -o tmpexists && die "should have refused to overwrite" println gooder > tmp_rm1 println boi > tmp_rm2 -echo 'y' | zstd tmp_rm1 tmp_rm2 -o tmp_rm3.zst -f --rm -rm tmp_rm3.zst +println worldly > tmp_rm3 +echo 'y' | zstd tmp_rm1 tmp_rm2 -o tmp_rm3.zst --rm # tests the warning prompt for --rm with multiple inputs into once source +test ! -f tmp_rm1 +test ! -f tmp_rm2 +cp tmp_rm3.zst tmp_rm4.zst +echo 'Y' | zstd -d tmp_rm3.zst tmp_rm4.zst -o tmp_rm_out --rm +test ! -f tmp_rm3.zst +test ! -f tmp_rm4.zst +echo 'yes' | zstd tmp_rm_out tmp_rm3 -c --rm +test ! -f tmp_rm_out +test ! -f tmp_rm3 +println gooder > tmpexists1 +zstd tmpexists1 tmpexists -c --rm -f # Bug: PR #972 if [ "$?" -eq 139 ]; then @@ -388,7 +398,7 @@ test -f tmp1 test -f tmp2 test -f tmp3 println "compress tmp* into stdout > tmpall : " -echo 'y' | zstd -c tmp1 tmp2 tmp3 > tmpall +zstd -c tmp1 tmp2 tmp3 > tmpall test -f tmpall # should check size of tmpall (should be tmp1.zst + tmp2.zst + tmp3.zst) println "decompress tmpall* into stdout > tmpdec : " cp tmpall tmpall2 @@ -926,7 +936,7 @@ datagen | zstd -c | zstd -t println "\n===> golden files tests " zstd -t -r "$TESTDIR/golden-decompression" -echo 'y' | zstd -c -r "$TESTDIR/golden-compression" | zstd -t +zstd -c -r "$TESTDIR/golden-compression" | zstd -t zstd -D "$TESTDIR/golden-dictionaries/http-dict-missing-symbols" "$TESTDIR/golden-compression/http" -c | zstd -D "$TESTDIR/golden-dictionaries/http-dict-missing-symbols" -t From aab11ce3db79b08c00da0c7be813f188bdd5eb67 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Tue, 25 Aug 2020 11:25:49 -0400 Subject: [PATCH 03/10] Unified warning prompts into new function UTIL_requireUserConfirmationToProceed() --- programs/fileio.c | 29 ++++++----------------------- programs/util.c | 16 ++++++++++++++++ programs/util.h | 6 ++++++ 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index c4737372a..9eb35fa8f 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -605,16 +605,10 @@ FIO_openDstFile(FIO_prefs_t* const prefs, dstFileName); return NULL; } - DISPLAY("zstd: %s already exists; overwrite (y/N) ? ", - dstFileName); - { int ch = getchar(); - if ((ch!='Y') && (ch!='y')) { - DISPLAY(" not overwritten \n"); - return NULL; - } - /* flush rest of input line */ - while ((ch!=EOF) && (ch!='\n')) ch = getchar(); - } } + DISPLAY("zstd: %s already exists; ", dstFileName); + if (UTIL_requireUserConfirmationToProceed("overwrite (y/n) ? ", "Not overwritten \n", "yY")) + return NULL; + } /* need to unlink */ FIO_removeFile(dstFileName); } } @@ -1683,19 +1677,8 @@ int FIO_compressMultipleFilenames(FIO_prefs_t* const prefs, } else { DISPLAY("zstd: WARNING: all input files will be processed and concatenated into a single output file: %s ", outFileName); } - if (prefs->removeSrcFile) { - DISPLAY("Proceed? (y/n): "); - { - int ch = getchar(); - if ((ch != 'y') && (ch != 'Y')) { - DISPLAY("zstd: aborting...\n"); - return 1; - } - /* flush the rest */ - while ((ch!=EOF) && (ch!='\n')) - ch = getchar(); - } - } + if (prefs->removeSrcFile) + error = UTIL_requireUserConfirmationToProceed("Proceed? (y/n): ", "Aborting...", "yY"); DISPLAY("\n"); } ress.dstFile = FIO_openDstFile(prefs, NULL, outFileName); diff --git a/programs/util.c b/programs/util.c index fc88ab35c..6b220f39a 100644 --- a/programs/util.c +++ b/programs/util.c @@ -87,6 +87,22 @@ UTIL_STATIC void* UTIL_realloc(void *ptr, size_t size) ******************************************/ int g_utilDisplayLevel; +int UTIL_requireUserConfirmationToProceed(const char* prompt, const char* abortMsg, + const char* acceptableLetters) { + int ch; + UTIL_DISPLAY("%s", prompt); + ch = getchar(); + if (strchr(acceptableLetters, ch) == NULL) { + UTIL_DISPLAY("%s", abortMsg); + return 1; + } + /* flush the rest */ + while ((ch!=EOF) && (ch!='\n')) + ch = getchar(); + + return 0; +} + /*-************************************* * Constants diff --git a/programs/util.h b/programs/util.h index f8eee86ad..aa48fd47a 100644 --- a/programs/util.h +++ b/programs/util.h @@ -93,6 +93,12 @@ extern "C" { ******************************************/ extern int g_utilDisplayLevel; +/** + * Displays a message prompt and returns success (0) if first character from stdin + * matches any from acceptableLetters. Otherwise, returns failure (1) and displays abortMsg. + */ +int UTIL_requireUserConfirmationToProceed(const char* const prompt, const char* const abortMsg, const char* const acceptableLetters); + /*-**************************************** * File functions From 7a7cd8861ae990660fea1d4703259edfa6ec1baf Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Tue, 25 Aug 2020 13:50:44 -0400 Subject: [PATCH 04/10] Add initial functionality to support -q --- programs/fileio.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 9eb35fa8f..f2978fe8b 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1672,14 +1672,23 @@ int FIO_compressMultipleFilenames(FIO_prefs_t* const prefs, assert(outFileName != NULL || suffix != NULL); if (outFileName != NULL) { /* output into a single destination (stdout typically) */ if (nbFiles > 1 && !prefs->overwrite) { - if (!strcmp (outFileName, stdoutmark)) { - DISPLAY("zstd: WARNING: all input files will be processed and concatenated into stdout. "); + /* g_display_prefs.displayLevel <= 1 corresponds to -q flag */ + DISPLAY("%d\n", g_display_prefs.displayLevel); + if (g_display_prefs.displayLevel <= 1) { + if (prefs->removeSrcFile) { + DISPLAY("zstd: Aborting... not deleting files and processing into dst: %s", outFileName); + return 1; + } } else { - DISPLAY("zstd: WARNING: all input files will be processed and concatenated into a single output file: %s ", outFileName); + if (!strcmp (outFileName, stdoutmark)) { + DISPLAY("zstd: WARNING: all input files will be processed and concatenated into stdout. "); + } else { + DISPLAY("zstd: WARNING: all input files will be processed and concatenated into a single output file: %s ", outFileName); + } + if (prefs->removeSrcFile) + error = g_display_prefs.displayLevel > 1 && UTIL_requireUserConfirmationToProceed("Proceed? (y/n): ", "Aborting...", "yY"); + DISPLAY("\n"); } - if (prefs->removeSrcFile) - error = UTIL_requireUserConfirmationToProceed("Proceed? (y/n): ", "Aborting...", "yY"); - DISPLAY("\n"); } ress.dstFile = FIO_openDstFile(prefs, NULL, outFileName); if (ress.dstFile == NULL) { /* could not open outFileName */ From 7991c55181af49c5981ab7956d0189edd38e4274 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Wed, 26 Aug 2020 16:50:20 -0400 Subject: [PATCH 05/10] Move logic into new function FIO_removeMultiFilesWarning, add support for decompression --- programs/fileio.c | 54 +++++++++++++++++++++++++++++------------------ programs/util.c | 10 ++++----- programs/util.h | 2 +- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 25b7d4d11..c982bda94 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -620,7 +620,7 @@ FIO_openDstFile(FIO_prefs_t* const prefs, return NULL; } DISPLAY("zstd: %s already exists; ", dstFileName); - if (UTIL_requireUserConfirmationToProceed("overwrite (y/n) ? ", "Not overwritten \n", "yY")) + if (UTIL_requireUserConfirmation("overwrite (y/n) ? ", "Not overwritten \n", "yY")) return NULL; } /* need to unlink */ @@ -789,6 +789,35 @@ static void FIO_adjustMemLimitForPatchFromMode(FIO_prefs_t* const prefs, FIO_setMemLimit(prefs, (unsigned)maxSize); } +/* FIO_removeMultiFilesWarning() : + * Returns 1 if the console should abort, 0 if console should proceed. + * Based on displayLevelCutoff (typically == 1) and the global setting g_display_prefs.displayLevel, this + * function may print a warning message, a user prompt, both, or none. + */ +static int FIO_removeMultiFilesWarning(const FIO_prefs_t* const prefs, int displayLevelCutoff, const char* outFileName) +{ + int error; + error = 0; + if (prefs->nbFiles > 1 && !prefs->overwrite) { + if (g_display_prefs.displayLevel <= displayLevelCutoff) { + if (prefs->removeSrcFile) { + DISPLAYLEVEL(1, "zstd: Aborting... not deleting files and processing into dst: %s", outFileName); + error = 1; + } + } else { + if (!strcmp(outFileName, stdoutmark)) { + DISPLAYLEVEL(2, "zstd: WARNING: all input files will be processed and concatenated into stdout. "); + } else { + DISPLAYLEVEL(2, "zstd: WARNING: all input files will be processed and concatenated into a single output file: %s ", outFileName); + } + if (prefs->removeSrcFile) + error = g_display_prefs.displayLevel > displayLevelCutoff && UTIL_requireUserConfirmation("Proceed? (y/n): ", "Aborting...", "yY"); + DISPLAY("\n"); + } + } + return error; +} + #ifndef ZSTD_NOCOMPRESS /* ********************************************************************** @@ -1693,25 +1722,8 @@ int FIO_compressMultipleFilenames(FIO_prefs_t* const prefs, /* init */ assert(outFileName != NULL || suffix != NULL); if (outFileName != NULL) { /* output into a single destination (stdout typically) */ - if (nbFiles > 1 && !prefs->overwrite) { - /* g_display_prefs.displayLevel <= 1 corresponds to -q flag */ - DISPLAY("%d\n", g_display_prefs.displayLevel); - if (g_display_prefs.displayLevel <= 1) { - if (prefs->removeSrcFile) { - DISPLAY("zstd: Aborting... not deleting files and processing into dst: %s", outFileName); - return 1; - } - } else { - if (!strcmp (outFileName, stdoutmark)) { - DISPLAY("zstd: WARNING: all input files will be processed and concatenated into stdout. "); - } else { - DISPLAY("zstd: WARNING: all input files will be processed and concatenated into a single output file: %s ", outFileName); - } - if (prefs->removeSrcFile) - error = g_display_prefs.displayLevel > 1 && UTIL_requireUserConfirmationToProceed("Proceed? (y/n): ", "Aborting...", "yY"); - DISPLAY("\n"); - } - } + if (FIO_removeMultiFilesWarning(prefs, 1 /* displayLevelCutoff */, outFileName)) + return 1; ress.dstFile = FIO_openDstFile(prefs, NULL, outFileName); if (ress.dstFile == NULL) { /* could not open outFileName */ error = 1; @@ -2606,6 +2618,8 @@ FIO_decompressMultipleFilenames(FIO_prefs_t* const prefs, dRess_t ress = FIO_createDResources(prefs, dictFileName); if (outFileName) { + if (FIO_removeMultiFilesWarning(prefs, 1 /* displayLevelCutoff */, outFileName)) + return 1; if (!prefs->testMode) { ress.dstFile = FIO_openDstFile(prefs, NULL, outFileName); if (ress.dstFile == 0) EXM_THROW(19, "cannot open %s", outFileName); diff --git a/programs/util.c b/programs/util.c index 6b220f39a..d828dc428 100644 --- a/programs/util.c +++ b/programs/util.c @@ -87,20 +87,20 @@ UTIL_STATIC void* UTIL_realloc(void *ptr, size_t size) ******************************************/ int g_utilDisplayLevel; -int UTIL_requireUserConfirmationToProceed(const char* prompt, const char* abortMsg, +int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, const char* acceptableLetters) { - int ch; + int ch, result; UTIL_DISPLAY("%s", prompt); ch = getchar(); + result = 0; if (strchr(acceptableLetters, ch) == NULL) { UTIL_DISPLAY("%s", abortMsg); - return 1; + result = 1; } /* flush the rest */ while ((ch!=EOF) && (ch!='\n')) ch = getchar(); - - return 0; + return result; } diff --git a/programs/util.h b/programs/util.h index aa48fd47a..32649bf25 100644 --- a/programs/util.h +++ b/programs/util.h @@ -97,7 +97,7 @@ extern int g_utilDisplayLevel; * Displays a message prompt and returns success (0) if first character from stdin * matches any from acceptableLetters. Otherwise, returns failure (1) and displays abortMsg. */ -int UTIL_requireUserConfirmationToProceed(const char* const prompt, const char* const abortMsg, const char* const acceptableLetters); +int UTIL_requireUserConfirmation(const char* const prompt, const char* const abortMsg, const char* const acceptableLetters); /*-**************************************** From ef11aadc0cf810a34b7a6035e041b902c30e9f80 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Wed, 26 Aug 2020 17:20:37 -0400 Subject: [PATCH 06/10] Fix UTIL_requireUserConfirmation() declaration --- programs/util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/util.h b/programs/util.h index 32649bf25..eeb6a15e2 100644 --- a/programs/util.h +++ b/programs/util.h @@ -97,7 +97,7 @@ extern int g_utilDisplayLevel; * Displays a message prompt and returns success (0) if first character from stdin * matches any from acceptableLetters. Otherwise, returns failure (1) and displays abortMsg. */ -int UTIL_requireUserConfirmation(const char* const prompt, const char* const abortMsg, const char* const acceptableLetters); +int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg, const char* acceptableLetters); /*-**************************************** From 7e867ad61f4938f63f3f4f04332a01d4cf17ba49 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Wed, 26 Aug 2020 18:52:32 -0400 Subject: [PATCH 07/10] Fix potential memory leak --- programs/fileio.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index c982bda94..3eaa0455a 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -1722,8 +1722,10 @@ int FIO_compressMultipleFilenames(FIO_prefs_t* const prefs, /* init */ assert(outFileName != NULL || suffix != NULL); if (outFileName != NULL) { /* output into a single destination (stdout typically) */ - if (FIO_removeMultiFilesWarning(prefs, 1 /* displayLevelCutoff */, outFileName)) + if (FIO_removeMultiFilesWarning(prefs, 1 /* displayLevelCutoff */, outFileName)) { + FIO_freeCResources(ress); return 1; + } ress.dstFile = FIO_openDstFile(prefs, NULL, outFileName); if (ress.dstFile == NULL) { /* could not open outFileName */ error = 1; @@ -2618,8 +2620,10 @@ FIO_decompressMultipleFilenames(FIO_prefs_t* const prefs, dRess_t ress = FIO_createDResources(prefs, dictFileName); if (outFileName) { - if (FIO_removeMultiFilesWarning(prefs, 1 /* displayLevelCutoff */, outFileName)) + if (FIO_removeMultiFilesWarning(prefs, 1 /* displayLevelCutoff */, outFileName)) { + FIO_freeDResources(ress); return 1; + } if (!prefs->testMode) { ress.dstFile = FIO_openDstFile(prefs, NULL, outFileName); if (ress.dstFile == 0) EXM_THROW(19, "cannot open %s", outFileName); From 01828b27e28988e77edaf1178253bbf7cb21b08e Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Thu, 27 Aug 2020 17:57:20 -0400 Subject: [PATCH 08/10] Improve documentation, update man --- programs/fileio.c | 17 ++++++++++++----- programs/zstd.1.md | 3 ++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 3eaa0455a..03b282b88 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -791,13 +791,18 @@ static void FIO_adjustMemLimitForPatchFromMode(FIO_prefs_t* const prefs, /* FIO_removeMultiFilesWarning() : * Returns 1 if the console should abort, 0 if console should proceed. - * Based on displayLevelCutoff (typically == 1) and the global setting g_display_prefs.displayLevel, this - * function may print a warning message, a user prompt, both, or none. + * This function handles logic when processing multiple files with -o, displaying the appropriate warnings/prompts. + * + * If -f is specified, or there is just 1 file, zstd will always proceed as usual. + * If --rm is specified, there will be a prompt asking for user confirmation. + * If -f is specified with --rm, zstd will proceed as usual + * If -q is specified with --rm, zstd will abort pre-emptively + * If neither flag is specified, zstd will prompt the user for confirmation to proceed. + * If --rm is not specified, then zstd may print a warning to the user. */ static int FIO_removeMultiFilesWarning(const FIO_prefs_t* const prefs, int displayLevelCutoff, const char* outFileName) { - int error; - error = 0; + int error = 0; if (prefs->nbFiles > 1 && !prefs->overwrite) { if (g_display_prefs.displayLevel <= displayLevelCutoff) { if (prefs->removeSrcFile) { @@ -810,8 +815,10 @@ static int FIO_removeMultiFilesWarning(const FIO_prefs_t* const prefs, int displ } else { DISPLAYLEVEL(2, "zstd: WARNING: all input files will be processed and concatenated into a single output file: %s ", outFileName); } - if (prefs->removeSrcFile) + if (prefs->removeSrcFile) { + DISPLAYLEVEL(2, "\nThe concatenated output CANNOT regenerate the original directory tree. This is a destructive operation. ") error = g_display_prefs.displayLevel > displayLevelCutoff && UTIL_requireUserConfirmation("Proceed? (y/n): ", "Aborting...", "yY"); + } DISPLAY("\n"); } } diff --git a/programs/zstd.1.md b/programs/zstd.1.md index 5b90b2df0..e7fa9cd4e 100644 --- a/programs/zstd.1.md +++ b/programs/zstd.1.md @@ -213,7 +213,8 @@ the last one takes effect. and disabled when output is stdout. This setting overrides default and can force sparse mode over stdout. * `--rm`: - remove source file(s) after successful compression or decompression + remove source file(s) after successful compression or decompression. If used in combination with + -o, will trigger a confirmation prompt (which can be silenced with -f), as this is a destructive operation. * `-k`, `--keep`: keep source file(s) after successful compression or decompression. This is the default behavior. From 99039988a58f579e646536ea2728260cade14027 Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Tue, 1 Sep 2020 13:18:30 -0400 Subject: [PATCH 09/10] Fixed newline issue and adjusted wording in comment --- programs/fileio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 03b282b88..117b3f330 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -798,7 +798,7 @@ static void FIO_adjustMemLimitForPatchFromMode(FIO_prefs_t* const prefs, * If -f is specified with --rm, zstd will proceed as usual * If -q is specified with --rm, zstd will abort pre-emptively * If neither flag is specified, zstd will prompt the user for confirmation to proceed. - * If --rm is not specified, then zstd may print a warning to the user. + * If --rm is not specified, then zstd will print a warning to the user (which can be silenced with -q). */ static int FIO_removeMultiFilesWarning(const FIO_prefs_t* const prefs, int displayLevelCutoff, const char* outFileName) { @@ -819,8 +819,8 @@ static int FIO_removeMultiFilesWarning(const FIO_prefs_t* const prefs, int displ DISPLAYLEVEL(2, "\nThe concatenated output CANNOT regenerate the original directory tree. This is a destructive operation. ") error = g_display_prefs.displayLevel > displayLevelCutoff && UTIL_requireUserConfirmation("Proceed? (y/n): ", "Aborting...", "yY"); } - DISPLAY("\n"); } + DISPLAY("\n"); } return error; } From dbe53052509176d51ffaeef859f6fe0d20f165ad Mon Sep 17 00:00:00 2001 From: senhuang42 Date: Wed, 2 Sep 2020 08:44:42 -0400 Subject: [PATCH 10/10] Adjusted extra explanation warning to always pop up if applicable --- programs/fileio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 117b3f330..241afd7cf 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -815,9 +815,9 @@ static int FIO_removeMultiFilesWarning(const FIO_prefs_t* const prefs, int displ } else { DISPLAYLEVEL(2, "zstd: WARNING: all input files will be processed and concatenated into a single output file: %s ", outFileName); } + DISPLAYLEVEL(2, "\nThe concatenated output CANNOT regenerate the original directory tree. ") if (prefs->removeSrcFile) { - DISPLAYLEVEL(2, "\nThe concatenated output CANNOT regenerate the original directory tree. This is a destructive operation. ") - error = g_display_prefs.displayLevel > displayLevelCutoff && UTIL_requireUserConfirmation("Proceed? (y/n): ", "Aborting...", "yY"); + error = g_display_prefs.displayLevel > displayLevelCutoff && UTIL_requireUserConfirmation("This is a destructive operation. Proceed? (y/n): ", "Aborting...", "yY"); } } DISPLAY("\n");