Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement more gzip compatibility (#3037) #3059

Merged
merged 1 commit into from
Mar 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions programs/zstd.1
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,17 @@ If input directory contains "\.\.", the files in this directory will be ignored\
.
.IP "" 0
.
.SS "gzip Operation modifiers"
When invoked via a \fBgzip\fR symlink, \fBzstd\fR will support further options that intend to mimic the \fBgzip\fR behavior:
.
.TP
\fB\-n\fR, \fB\-\-no\-name\fR
do not store the original filename and timestamps when compressing a file\. This is the default behavior and hence a no\-op\.
.
.TP
\fB\-\-best\fR
alias to the option \fB\-9\fR\.
.
.SS "Restricted usage of Environment Variables"
Using environment variables to set parameters has security implications\. Therefore, this avenue is intentionally restricted\. Only \fBZSTD_CLEVEL\fR and \fBZSTD_NBTHREADS\fR are currently supported\. They set the compression level and number of threads to use during compression, respectively\.
.
Expand Down
12 changes: 12 additions & 0 deletions programs/zstd.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,18 @@ the last one takes effect.
* `--`:
All arguments after `--` are treated as files


### gzip Operation modifiers
When invoked via a `gzip` symlink, `zstd` will support further
options that intend to mimic the `gzip` behavior:

* `-n`, `--no-name`:
do not store the original filename and timestamps when compressing
a file. This is the default behavior and hence a no-op.
* `--best`:
alias to the option `-9`.


### Restricted usage of Environment Variables

Using environment variables to set parameters has security implications.
Expand Down
41 changes: 31 additions & 10 deletions programs/zstdcli.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,15 @@ static void checkLibVersion(void)
}


/*! exeNameMatch() :
@return : a non-zero value if exeName matches test, excluding the extension
*/
static int exeNameMatch(const char* exeName, const char* test)
{
return !strncmp(exeName, test, strlen(test)) &&
(exeName[strlen(test)] == '\0' || exeName[strlen(test)] == '.');
}

/*-************************************
* Command Line
**************************************/
Expand Down Expand Up @@ -153,6 +162,11 @@ static void usage(FILE* f, const char* programName)
DISPLAY_F(f, " block devices, etc.\n");
DISPLAY_F(f, "--rm : remove source file(s) after successful de/compression \n");
DISPLAY_F(f, " -k : preserve source file(s) (default) \n");
#ifdef ZSTD_GZCOMPRESS
if (exeNameMatch(programName, ZSTD_GZ)) { /* behave like gzip */
DISPLAY_F(f, " -n : do not store original filename when compressing \n");
}
#endif
DISPLAY_F(f, " -h/-H : display help/long help and exit \n");
}

Expand Down Expand Up @@ -208,6 +222,12 @@ static void usage_advanced(const char* programName)
DISPLAYOUT( "--ultra : enable levels beyond %i, up to %i (requires more memory) \n", ZSTDCLI_CLEVEL_MAX, ZSTD_maxCLevel());
DISPLAYOUT( "--long[=#]: enable long distance matching with given window log (default: %u) \n", g_defaultMaxWindowLog);
DISPLAYOUT( "--fast[=#]: switch to very fast compression levels (default: %u) \n", 1);
#ifdef ZSTD_GZCOMPRESS
if (exeNameMatch(programName, ZSTD_GZ)) { /* behave like gzip */
DISPLAYOUT( "--best : compatibility alias for -9 \n");
DISPLAYOUT( "--no-name : do not store original filename when compressing \n");
}
#endif
DISPLAYOUT( "--adapt : dynamically adapt compression level to I/O conditions \n");
DISPLAYOUT( "--[no-]row-match-finder : force enable/disable usage of fast row-based matchfinder for greedy, lazy, and lazy2 strategies \n");
DISPLAYOUT( "--patch-from=FILE : specify the file to be used as a reference point for zstd's diff engine. \n");
Expand Down Expand Up @@ -298,15 +318,6 @@ static const char* lastNameFromPath(const char* path)
return name;
}

/*! exeNameMatch() :
@return : a non-zero value if exeName matches test, excluding the extension
*/
static int exeNameMatch(const char* exeName, const char* test)
{
return !strncmp(exeName, test, strlen(test)) &&
(exeName[strlen(test)] == '\0' || exeName[strlen(test)] == '.');
}

static void errorOut(const char* msg)
{
DISPLAY("%s \n", msg); exit(1);
Expand Down Expand Up @@ -866,7 +877,10 @@ int main(int argCount, const char* argv[])
if (exeNameMatch(programName, ZSTD_UNZSTD)) operation=zom_decompress;
if (exeNameMatch(programName, ZSTD_CAT)) { operation=zom_decompress; FIO_overwriteMode(prefs); forceStdout=1; followLinks=1; outFileName=stdoutmark; g_displayLevel=1; } /* supports multiple formats */
if (exeNameMatch(programName, ZSTD_ZCAT)) { operation=zom_decompress; FIO_overwriteMode(prefs); forceStdout=1; followLinks=1; outFileName=stdoutmark; g_displayLevel=1; } /* behave like zcat, also supports multiple formats */
if (exeNameMatch(programName, ZSTD_GZ)) { suffix = GZ_EXTENSION; FIO_setCompressionType(prefs, FIO_gzipCompression); FIO_setRemoveSrcFile(prefs, 1); } /* behave like gzip */
if (exeNameMatch(programName, ZSTD_GZ)) { /* behave like gzip */
suffix = GZ_EXTENSION; FIO_setCompressionType(prefs, FIO_gzipCompression); FIO_setRemoveSrcFile(prefs, 1);
dictCLevel = cLevel = 6; /* gzip default is -6 */
}
if (exeNameMatch(programName, ZSTD_GUNZIP)) { operation=zom_decompress; FIO_setRemoveSrcFile(prefs, 1); } /* behave like gunzip, also supports multiple formats */
if (exeNameMatch(programName, ZSTD_GZCAT)) { operation=zom_decompress; FIO_overwriteMode(prefs); forceStdout=1; followLinks=1; outFileName=stdoutmark; g_displayLevel=1; } /* behave like gzcat, also supports multiple formats */
if (exeNameMatch(programName, ZSTD_LZMA)) { suffix = LZMA_EXTENSION; FIO_setCompressionType(prefs, FIO_lzmaCompression); FIO_setRemoveSrcFile(prefs, 1); } /* behave like lzma */
Expand Down Expand Up @@ -936,6 +950,10 @@ int main(int argCount, const char* argv[])
if (!strcmp(argument, "--format=zstd")) { suffix = ZSTD_EXTENSION; FIO_setCompressionType(prefs, FIO_zstdCompression); continue; }
#ifdef ZSTD_GZCOMPRESS
if (!strcmp(argument, "--format=gzip")) { suffix = GZ_EXTENSION; FIO_setCompressionType(prefs, FIO_gzipCompression); continue; }
if (exeNameMatch(programName, ZSTD_GZ)) { /* behave like gzip */
if (!strcmp(argument, "--best")) { dictCLevel = cLevel = 9; continue; }
if (!strcmp(argument, "--no-name")) { /* ignore for now */; continue; }
}
#endif
#ifdef ZSTD_LZMACOMPRESS
if (!strcmp(argument, "--format=lzma")) { suffix = LZMA_EXTENSION; FIO_setCompressionType(prefs, FIO_lzmaCompression); continue; }
Expand Down Expand Up @@ -1098,6 +1116,9 @@ int main(int argCount, const char* argv[])
/* Force stdout, even if stdout==console */
case 'c': forceStdout=1; outFileName=stdoutmark; argument++; break;

/* do not store filename - gzip compatibility - nothing to do */
case 'n': argument++; break;

/* Use file content as dictionary */
case 'D': argument++; NEXT_FIELD(dictFileName); break;

Expand Down
15 changes: 15 additions & 0 deletions tests/cli-tests/compression/gzip-compat.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh

set -e

# Uncomment the set -v line for debugging
# set -v

# Test gzip specific compression option
$ZSTD_SYMLINK_DIR/gzip --fast file ; $ZSTD_SYMLINK_DIR/gzip -d file.gz
$ZSTD_SYMLINK_DIR/gzip --best file ; $ZSTD_SYMLINK_DIR/gzip -d file.gz

# Test -n / --no-name: do not embed original filename in archive
$ZSTD_SYMLINK_DIR/gzip -n file ; grep -qv file file.gz ; $ZSTD_SYMLINK_DIR/gzip -d file.gz
$ZSTD_SYMLINK_DIR/gzip --no-name file ; grep -qv file file.gz ; $ZSTD_SYMLINK_DIR/gzip -d file.gz
$ZSTD_SYMLINK_DIR/gzip -c --no-name file | grep -qv file