Merge pull request #2279 from senhuang42/show_warnings_with_multiple_input_files
Add a warning whenever (de)compressing multiple files
This commit is contained in:
+48
-11
@@ -619,17 +619,10 @@ FIO_openDstFile(FIO_prefs_t* const prefs,
|
|||||||
dstFileName);
|
dstFileName);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
DISPLAY("zstd: %s already exists; overwrite (y/N) ? ",
|
DISPLAY("zstd: %s already exists; ", dstFileName);
|
||||||
dstFileName);
|
if (UTIL_requireUserConfirmation("overwrite (y/n) ? ", "Not overwritten \n", "yY"))
|
||||||
{ int ch = getchar();
|
return NULL;
|
||||||
if ((ch!='Y') && (ch!='y')) {
|
}
|
||||||
DISPLAY(" not overwritten \n");
|
|
||||||
/* flush rest of input line */
|
|
||||||
while ((ch!=EOF) && (ch!='\n')) ch = getchar();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
while ((ch!=EOF) && (ch!='\n')) ch = getchar();
|
|
||||||
} }
|
|
||||||
/* need to unlink */
|
/* need to unlink */
|
||||||
FIO_removeFile(dstFileName);
|
FIO_removeFile(dstFileName);
|
||||||
} }
|
} }
|
||||||
@@ -796,6 +789,42 @@ static void FIO_adjustMemLimitForPatchFromMode(FIO_prefs_t* const prefs,
|
|||||||
FIO_setMemLimit(prefs, (unsigned)maxSize);
|
FIO_setMemLimit(prefs, (unsigned)maxSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIO_removeMultiFilesWarning() :
|
||||||
|
* Returns 1 if the console should abort, 0 if console should proceed.
|
||||||
|
* 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 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)
|
||||||
|
{
|
||||||
|
int 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);
|
||||||
|
}
|
||||||
|
DISPLAYLEVEL(2, "\nThe concatenated output CANNOT regenerate the original directory tree. ")
|
||||||
|
if (prefs->removeSrcFile) {
|
||||||
|
error = g_display_prefs.displayLevel > displayLevelCutoff && UTIL_requireUserConfirmation("This is a destructive operation. Proceed? (y/n): ", "Aborting...", "yY");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DISPLAY("\n");
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef ZSTD_NOCOMPRESS
|
#ifndef ZSTD_NOCOMPRESS
|
||||||
|
|
||||||
/* **********************************************************************
|
/* **********************************************************************
|
||||||
@@ -1700,6 +1729,10 @@ int FIO_compressMultipleFilenames(FIO_prefs_t* const prefs,
|
|||||||
/* init */
|
/* init */
|
||||||
assert(outFileName != NULL || suffix != NULL);
|
assert(outFileName != NULL || suffix != NULL);
|
||||||
if (outFileName != NULL) { /* output into a single destination (stdout typically) */
|
if (outFileName != NULL) { /* output into a single destination (stdout typically) */
|
||||||
|
if (FIO_removeMultiFilesWarning(prefs, 1 /* displayLevelCutoff */, outFileName)) {
|
||||||
|
FIO_freeCResources(ress);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
ress.dstFile = FIO_openDstFile(prefs, NULL, outFileName);
|
ress.dstFile = FIO_openDstFile(prefs, NULL, outFileName);
|
||||||
if (ress.dstFile == NULL) { /* could not open outFileName */
|
if (ress.dstFile == NULL) { /* could not open outFileName */
|
||||||
error = 1;
|
error = 1;
|
||||||
@@ -2594,6 +2627,10 @@ FIO_decompressMultipleFilenames(FIO_prefs_t* const prefs,
|
|||||||
dRess_t ress = FIO_createDResources(prefs, dictFileName);
|
dRess_t ress = FIO_createDResources(prefs, dictFileName);
|
||||||
|
|
||||||
if (outFileName) {
|
if (outFileName) {
|
||||||
|
if (FIO_removeMultiFilesWarning(prefs, 1 /* displayLevelCutoff */, outFileName)) {
|
||||||
|
FIO_freeDResources(ress);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (!prefs->testMode) {
|
if (!prefs->testMode) {
|
||||||
ress.dstFile = FIO_openDstFile(prefs, NULL, outFileName);
|
ress.dstFile = FIO_openDstFile(prefs, NULL, outFileName);
|
||||||
if (ress.dstFile == 0) EXM_THROW(19, "cannot open %s", outFileName);
|
if (ress.dstFile == 0) EXM_THROW(19, "cannot open %s", outFileName);
|
||||||
|
|||||||
@@ -87,6 +87,22 @@ UTIL_STATIC void* UTIL_realloc(void *ptr, size_t size)
|
|||||||
******************************************/
|
******************************************/
|
||||||
int g_utilDisplayLevel;
|
int g_utilDisplayLevel;
|
||||||
|
|
||||||
|
int UTIL_requireUserConfirmation(const char* prompt, const char* abortMsg,
|
||||||
|
const char* acceptableLetters) {
|
||||||
|
int ch, result;
|
||||||
|
UTIL_DISPLAY("%s", prompt);
|
||||||
|
ch = getchar();
|
||||||
|
result = 0;
|
||||||
|
if (strchr(acceptableLetters, ch) == NULL) {
|
||||||
|
UTIL_DISPLAY("%s", abortMsg);
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
/* flush the rest */
|
||||||
|
while ((ch!=EOF) && (ch!='\n'))
|
||||||
|
ch = getchar();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-*************************************
|
/*-*************************************
|
||||||
* Constants
|
* Constants
|
||||||
|
|||||||
@@ -93,6 +93,12 @@ extern "C" {
|
|||||||
******************************************/
|
******************************************/
|
||||||
extern int g_utilDisplayLevel;
|
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* prompt, const char* abortMsg, const char* acceptableLetters);
|
||||||
|
|
||||||
|
|
||||||
/*-****************************************
|
/*-****************************************
|
||||||
* File functions
|
* File functions
|
||||||
|
|||||||
+2
-1
@@ -213,7 +213,8 @@ the last one takes effect.
|
|||||||
and disabled when output is stdout.
|
and disabled when output is stdout.
|
||||||
This setting overrides default and can force sparse mode over stdout.
|
This setting overrides default and can force sparse mode over stdout.
|
||||||
* `--rm`:
|
* `--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`:
|
* `-k`, `--keep`:
|
||||||
keep source file(s) after successful compression or decompression.
|
keep source file(s) after successful compression or decompression.
|
||||||
This is the default behavior.
|
This is the default behavior.
|
||||||
|
|||||||
@@ -369,6 +369,22 @@ zstd -d tmp1.zst tmp2.zst -o tmp
|
|||||||
touch tmpexists
|
touch tmpexists
|
||||||
zstd tmp1 tmp2 -f -o tmpexists
|
zstd tmp1 tmp2 -f -o tmpexists
|
||||||
zstd tmp1 tmp2 -q -o tmpexists && die "should have refused to overwrite"
|
zstd tmp1 tmp2 -q -o tmpexists && die "should have refused to overwrite"
|
||||||
|
println gooder > tmp_rm1
|
||||||
|
println boi > tmp_rm2
|
||||||
|
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
|
# Bug: PR #972
|
||||||
if [ "$?" -eq 139 ]; then
|
if [ "$?" -eq 139 ]; then
|
||||||
die "should not have segfaulted"
|
die "should not have segfaulted"
|
||||||
|
|||||||
Reference in New Issue
Block a user