gzip, bzip2: add -n flag to suppress modification timestamp

This commit is contained in:
cinap_lenrek 2021-07-21 17:36:02 +00:00
parent 28057f67a0
commit 403149d7de
3 changed files with 37 additions and 14 deletions

View file

@ -3,7 +3,7 @@
gzip, gunzip, bzip2, bunzip2, compress, uncompress, zip, unzip \- compress and expand data gzip, gunzip, bzip2, bunzip2, compress, uncompress, zip, unzip \- compress and expand data
.SH SYNOPSIS .SH SYNOPSIS
.B gzip .B gzip
.RB [ -cvD [ 1-9 ]] .RB [ -cvnD [ 1-9 ]]
.RI [ file .RI [ file
.BR ... ] .BR ... ]
.PP .PP
@ -13,7 +13,7 @@ gzip, gunzip, bzip2, bunzip2, compress, uncompress, zip, unzip \- compress and e
.BR ... ] .BR ... ]
.PP .PP
.B bzip2 .B bzip2
.RB [ -cvD [ 1-9 ]] .RB [ -cvnD [ 1-9 ]]
.RI [ file .RI [ file
.BR ... ] .BR ... ]
.PP .PP
@ -180,6 +180,19 @@ Without
.BR -t , .BR -t ,
prints the names of files on standard error as they are compressed or decompressed. prints the names of files on standard error as they are compressed or decompressed.
.TP .TP
.B -n
The
.I gzip
and
.I bzip2
file formats include a modification timestamp which is by default set
to the modification time of the files being compressed or the current
time when the source file is read from standard input.
The
.B -n
flag overrides this behaviour and puts a timestamp of zero instead,
making the compressed output deterministic.
.TP
.B -D .B -D
Produce debugging output. Produce debugging output.
.SH SOURCE .SH SOURCE

View file

@ -3,7 +3,7 @@
#include <bio.h> #include <bio.h>
#include "bzlib.h" #include "bzlib.h"
static int bzipf(char*, int); static int bzipf(char*, int, int);
static int bzip(char*, long, int, Biobuf*); static int bzip(char*, long, int, Biobuf*);
static Biobuf bout; static Biobuf bout;
@ -15,7 +15,7 @@ static int verbose;
static void static void
usage(void) usage(void)
{ {
fprint(2, "usage: bzip2 [-vcD] [-1-9] [file ...]\n"); fprint(2, "usage: bzip2 [-vcnD] [-1-9] [file ...]\n");
exits("usage"); exits("usage");
} }
@ -23,9 +23,11 @@ void
main(int argc, char **argv) main(int argc, char **argv)
{ {
int i, ok, stdout; int i, ok, stdout;
long mtime;
level = 6; level = 6;
stdout = 0; stdout = 0;
mtime = time(nil);
ARGBEGIN{ ARGBEGIN{
case 'D': case 'D':
debug++; debug++;
@ -36,6 +38,9 @@ main(int argc, char **argv)
case 'c': case 'c':
stdout++; stdout++;
break; break;
case 'n':
mtime = 0;
break;
case '1': case '2': case '3': case '4': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '5': case '6': case '7': case '8': case '9':
level = ARGC() - '0'; level = ARGC() - '0';
@ -47,18 +52,18 @@ main(int argc, char **argv)
if(argc == 0){ if(argc == 0){
Binit(&bout, 1, OWRITE); Binit(&bout, 1, OWRITE);
ok = bzip(nil, time(0), 0, &bout); ok = bzip(nil, mtime, 0, &bout);
Bterm(&bout); Bterm(&bout);
}else{ }else{
ok = 1; ok = 1;
for(i = 0; i < argc; i++) for(i = 0; i < argc; i++)
ok &= bzipf(argv[i], stdout); ok &= bzipf(argv[i], !mtime, stdout);
} }
exits(ok ? nil: "errors"); exits(ok ? nil: "errors");
} }
static int static int
bzipf(char *file, int stdout) bzipf(char *file, int nomtime, int stdout)
{ {
Dir *dir; Dir *dir;
char ofile[128], *f, *s; char ofile[128], *f, *s;
@ -110,7 +115,7 @@ bzipf(char *file, int stdout)
fprint(2, "compressing %s to %s\n", file, ofile); fprint(2, "compressing %s to %s\n", file, ofile);
Binit(&bout, ofd, OWRITE); Binit(&bout, ofd, OWRITE);
ok = bzip(file, dir->mtime, ifd, &bout); ok = bzip(file, nomtime ? 0 : dir->mtime, ifd, &bout);
if(!ok || Bflush(&bout) < 0){ if(!ok || Bflush(&bout) < 0){
fprint(2, "bzip2: error writing %s: %r\n", ofile); fprint(2, "bzip2: error writing %s: %r\n", ofile);
if(!stdout) if(!stdout)

View file

@ -4,7 +4,7 @@
#include <flate.h> #include <flate.h>
#include "gzip.h" #include "gzip.h"
static int gzipf(char*, int); static int gzipf(char*, int, int);
static int gzip(char*, long, int, Biobuf*); static int gzip(char*, long, int, Biobuf*);
static int crcread(void *fd, void *buf, int n); static int crcread(void *fd, void *buf, int n);
static int gzwrite(void *bout, void *buf, int n); static int gzwrite(void *bout, void *buf, int n);
@ -21,7 +21,7 @@ static int verbose;
void void
usage(void) usage(void)
{ {
fprint(2, "usage: gzip [-vcD] [-1-9] [file ...]\n"); fprint(2, "usage: gzip [-vcnD] [-1-9] [file ...]\n");
exits("usage"); exits("usage");
} }
@ -29,9 +29,11 @@ void
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
int i, ok, stdout; int i, ok, stdout;
long mtime;
level = 6; level = 6;
stdout = 0; stdout = 0;
mtime = time(nil);
ARGBEGIN{ ARGBEGIN{
case 'D': case 'D':
debug++; debug++;
@ -42,6 +44,9 @@ main(int argc, char *argv[])
case 'c': case 'c':
stdout = 1; stdout = 1;
break; break;
case 'n':
mtime = 0;
break;
case '1': case '2': case '3': case '4': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '5': case '6': case '7': case '8': case '9':
level = ARGC() - '0'; level = ARGC() - '0';
@ -58,18 +63,18 @@ main(int argc, char *argv[])
if(argc == 0){ if(argc == 0){
Binit(&bout, 1, OWRITE); Binit(&bout, 1, OWRITE);
ok = gzip(nil, time(0), 0, &bout); ok = gzip(nil, mtime, 0, &bout);
Bterm(&bout); Bterm(&bout);
}else{ }else{
ok = 1; ok = 1;
for(i = 0; i < argc; i++) for(i = 0; i < argc; i++)
ok &= gzipf(argv[i], stdout); ok &= gzipf(argv[i], !mtime, stdout);
} }
exits(ok ? nil: "errors"); exits(ok ? nil: "errors");
} }
static int static int
gzipf(char *file, int stdout) gzipf(char *file, int nomtime, int stdout)
{ {
Dir *dir; Dir *dir;
char ofile[256], *f, *s; char ofile[256], *f, *s;
@ -120,7 +125,7 @@ gzipf(char *file, int stdout)
fprint(2, "compressing %s to %s\n", file, ofile); fprint(2, "compressing %s to %s\n", file, ofile);
Binit(&bout, ofd, OWRITE); Binit(&bout, ofd, OWRITE);
ok = gzip(file, dir->mtime, ifd, &bout); ok = gzip(file, nomtime ? 0 : dir->mtime, ifd, &bout);
if(!ok || Bflush(&bout) < 0){ if(!ok || Bflush(&bout) < 0){
fprint(2, "gzip: error writing %s: %r\n", ofile); fprint(2, "gzip: error writing %s: %r\n", ofile);
if(!stdout) if(!stdout)