From 279be2015b4af98200b4d6b3e32c1b0155f51cd2 Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Thu, 6 Apr 2017 12:56:40 -0700 Subject: [PATCH 1/3] Let zstd overwrite read-only files --- programs/fileio.c | 47 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/programs/fileio.c b/programs/fileio.c index 78fb9a26..b384c3c2 100644 --- a/programs/fileio.c +++ b/programs/fileio.c @@ -31,6 +31,11 @@ #include /* clock */ #include /* errno */ +#if defined (_MSC_VER) +# include +# include +#endif + #include "mem.h" #include "fileio.h" #define ZSTD_STATIC_LINKING_ONLY /* ZSTD_magicNumber, ZSTD_frameHeaderSize_max */ @@ -188,6 +193,18 @@ void FIO_setOverlapLog(unsigned overlapLog){ /*-************************************* * Functions ***************************************/ +/** FIO_remove() : + * @result : Unlink `fileName`, even if it's read-only */ +static int FIO_remove(const char* path) +{ +#if defined(_WIN32) || defined(WIN32) + /* windows doesn't allow remove read-only files, so try to make it + * writable first */ + chmod(path, _S_IWRITE); +#endif + return remove(path); +} + /** FIO_openSrcFile() : * condition : `dstFileName` must be non-NULL. * @result : FILE* to `dstFileName`, or NULL if it fails */ @@ -230,23 +247,29 @@ static FILE* FIO_openDstFile(const char* dstFileName) if (g_sparseFileSupport == 1) { g_sparseFileSupport = ZSTD_SPARSE_DEFAULT; } - if (!g_overwrite && strcmp (dstFileName, nulmark)) { /* Check if destination file already exists */ + if (strcmp (dstFileName, nulmark)) { /* Check if destination file already exists */ f = fopen( dstFileName, "rb" ); if (f != 0) { /* dest file exists, prompt for overwrite authorization */ fclose(f); - if (g_displayLevel <= 1) { - /* No interaction possible */ - DISPLAY("zstd: %s already exists; not overwritten \n", dstFileName); - return NULL; - } - DISPLAY("zstd: %s already exists; do you wish to overwrite (y/N) ? ", dstFileName); - { int ch = getchar(); - if ((ch!='Y') && (ch!='y')) { - DISPLAY(" not overwritten \n"); + if (!g_overwrite) { + if (g_displayLevel <= 1) { + /* No interaction possible */ + DISPLAY("zstd: %s already exists; not overwritten \n", dstFileName); return NULL; } - while ((ch!=EOF) && (ch!='\n')) ch = getchar(); /* flush rest of input line */ - } } } + DISPLAY("zstd: %s already exists; do you wish to overwrite (y/N) ? ", dstFileName); + { int ch = getchar(); + if ((ch!='Y') && (ch!='y')) { + DISPLAY(" not overwritten \n"); + return NULL; + } + while ((ch!=EOF) && (ch!='\n')) ch = getchar(); /* flush rest of input line */ + } + } + + /* need to unlink */ + FIO_remove(dstFileName); + } } f = fopen( dstFileName, "wb" ); if (f==NULL) DISPLAYLEVEL(1, "zstd: %s: %s\n", dstFileName, strerror(errno)); } From 9da11c6aaecff37e2b167f1e5d1e5c1463689f9a Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Thu, 6 Apr 2017 12:58:49 -0700 Subject: [PATCH 2/3] Add test for overwriting read-only --- tests/playTests.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/playTests.sh b/tests/playTests.sh index 5abbb14e..5409d9aa 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -109,6 +109,13 @@ $ZSTD -q tmp && die "overwrite check failed!" $ECHO "test : force overwrite" $ZSTD -q -f tmp $ZSTD -q --force tmp +$ECHO "test : overwrite readonly file" +$ECHO foo > tmpro.zst +$ECHO foo > tmpro +chmod 400 tmpro.zst +$ZSTD -q --force tmpro || die "failed to overwrite read-only file" +chmod 600 tmpro.zst +rm tmpro tmpro.zst $ECHO "test : file removal" $ZSTD -f --rm tmp ls tmp && die "tmp should no longer be present" From 1652172b2d11e87ef26ad04a0406428cd13be3c1 Mon Sep 17 00:00:00 2001 From: Sean Purcell Date: Thu, 6 Apr 2017 17:06:30 -0700 Subject: [PATCH 3/3] Add refuse to overwrite test and fix format --- tests/playTests.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/playTests.sh b/tests/playTests.sh index 5409d9aa..266bbd91 100755 --- a/tests/playTests.sh +++ b/tests/playTests.sh @@ -110,12 +110,13 @@ $ECHO "test : force overwrite" $ZSTD -q -f tmp $ZSTD -q --force tmp $ECHO "test : overwrite readonly file" +rm -f tmpro tmpro.zst $ECHO foo > tmpro.zst $ECHO foo > tmpro chmod 400 tmpro.zst -$ZSTD -q --force tmpro || die "failed to overwrite read-only file" -chmod 600 tmpro.zst -rm tmpro tmpro.zst +$ZSTD -q tmpro && die "should have refused to overwrite read-only file" +$ZSTD -q -f tmpro +rm -f tmpro tmpro.zst $ECHO "test : file removal" $ZSTD -f --rm tmp ls tmp && die "tmp should no longer be present"