Skip to content

Commit 1411cb7

Browse files
author
Dave Mack
committed
compress - Compress 4.1, Patch01
This patch brings the version of compress 4.1 posted to comp.sources.misc up to patchlevel 1. It corrects one severe bug, a number of minor annoyances, and some diagnostic and documentation errors.
1 parent fb52189 commit 1411cb7

File tree

3 files changed

+112
-57
lines changed

3 files changed

+112
-57
lines changed

compress.1

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -51,32 +51,55 @@ each file is replaced by one with the extension
5151
while keeping the same ownership modes, access and modification times.
5252
If no files are specified, the standard input is compressed to the
5353
standard output.
54-
Compressed files can be restored to their original form using
55-
.I uncompress
56-
or
57-
.I zcat.
58-
.PP
59-
The
54+
.I Compress
55+
will only attempt to compress regular files.
56+
In particular, it will ignore symbolic links. If a file has multiple
57+
hard links,
58+
.I compress
59+
will refuse to compress it unless the
6060
.B \-f
61-
option will force compression of
62-
.I name.
61+
flag is given.
62+
.PP
6363
If
6464
.B \-f
6565
is not given and
6666
.I compress
6767
is run in the foreground,
6868
the user is prompted as to whether an existing file should be overwritten.
6969
.PP
70+
Compressed files can be restored to their original form using
71+
.I uncompress
72+
or
73+
.I zcat.
74+
.PP
75+
.I uncompress
76+
takes a list of files on its command line and replaces each
77+
file whose name ends with
78+
.B "\&.Z"
79+
and which begins with the correct magic number with an uncompressed
80+
file without the
81+
.B "\&.Z."
82+
The uncompressed file will have the mode, ownership and
83+
timestamps of the compressed file.
84+
.PP
7085
The
7186
.B \-c
7287
option makes
7388
.I compress/uncompress
7489
write to the standard output; no files are changed.
75-
The nondestructive behavior of
90+
.PP
7691
.I zcat
77-
is identical to that of
92+
is identical to
7893
.I uncompress
7994
.B \-c.
95+
.I zcat
96+
uncompresses either a list of files on the command line or its
97+
standard input and writes the uncompressed data on standard output.
98+
.I zcat
99+
will uncompress files that have the correct magic number whether
100+
they have a
101+
.B "\&.Z"
102+
suffix or not.
80103
.PP
81104
If the
82105
.B \-r
@@ -87,6 +110,12 @@ line are directories,
87110
.I compress
88111
will descend into the directory and compress all the files it finds there.
89112
.PP
113+
The
114+
.B \-V
115+
flag tells each of these programs to print its version and patchlevel,
116+
along with any preprocessor flags specified during compilation, on
117+
stderr before doing any compression or uncompression.
118+
.PP
90119
.I Compress
91120
uses the modified Lempel-Ziv algorithm popularized in
92121
"A Technique for High Performance Data Compression",
@@ -147,18 +176,13 @@ option,
147176
a message is printed yielding the percentage of
148177
reduction for each file compressed.
149178
.PP
150-
If the
151-
.B \-V
152-
option is specified, the current version and compile options are printed on
153-
stderr.
154-
.PP
155179
Exit status is normally 0;
156180
if the last file is larger after (attempted) compression, the status is 2;
157181
if an error occurs, exit status is 1.
158182
.SH "SEE ALSO"
159183
pack(1), compact(1)
160184
.SH "DIAGNOSTICS"
161-
Usage: compress [\-dfvcV] [\-b maxbits] [file ...]
185+
Usage: compress [\-dfvcVr] [\-b maxbits] [file ...]
162186
.in +8
163187
Invalid options were specified on the command line.
164188
.in -8
@@ -220,10 +244,10 @@ Percentage of the input saved by compression.
220244
(Relevant only for
221245
.BR \-v \.)
222246
.in -8
223-
-- not a regular file: unchanged
247+
-- not a regular file or directory: ignored
224248
.in +8
225-
When the input file is not a regular file,
226-
(e.g. a directory), it is
249+
When the input file is not a regular file or directory,
250+
(e.g. a symbolic link, socket, FIFO, device file), it is
227251
left unaltered.
228252
.in -8
229253
-- has
@@ -232,7 +256,9 @@ other links: unchanged
232256
.in +8
233257
The input file has links; it is left unchanged. See
234258
.IR ln "(1)"
235-
for more information.
259+
for more information. Use the
260+
.B \-f
261+
flag to force compression of multiply-linked files.
236262
.in -8
237263
-- file unchanged
238264
.in +8
@@ -245,3 +271,14 @@ Although compressed files are compatible between machines with large memory,
245271
should be used for file transfer to architectures with
246272
a small process data space (64KB or less, as exhibited by the DEC PDP
247273
series, the Intel 80286, etc.)
274+
.PP
275+
Invoking compress with a \-r
276+
flag will occasionally cause it to produce spurious error warnings of the form
277+
.PP
278+
.in 8
279+
"<filename>.Z already has .Z suffix - ignored"
280+
.in -8
281+
.PP
282+
These warnings can be ignored. See the comments in compress.c:compdir()
283+
for an explanation.
284+

compress.c

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
*/
44
#define min(a,b) ((a>b) ? b : a)
55

6+
/* MAXPATHLEN - maximum length of a pathname we allow */
7+
#define MAXPATHLEN 1024
8+
69
/*
710
* machine variants which require cc -Dmachine: pdp11, z8000, pcxt
811
*/
@@ -373,7 +376,7 @@ count_int checkpoint = CHECK_GAP;
373376
#define CLEAR 256 /* table clear output code */
374377

375378
int force = 0;
376-
char ofname [100];
379+
char ofname[MAXPATHLEN];
377380
#ifdef DEBUG
378381
int verbose = 0;
379382
#endif /* DEBUG */
@@ -386,6 +389,7 @@ void (*bgnd_flag)();
386389

387390

388391
int do_decomp = 0;
392+
struct stat statbuf, insbuf;
389393

390394
/*****************************************************************
391395
* TAG( main )
@@ -596,8 +600,7 @@ register int argc; char **argv;
596600
comprexx(fileptr)
597601
char **fileptr;
598602
{
599-
struct stat statbuf,insbuf;
600-
char tempname[1024], *cp;
603+
char tempname[MAXPATHLEN], *cp;
601604

602605
strcpy(tempname,*fileptr);
603606
errno = 0;
@@ -647,6 +650,9 @@ char **fileptr;
647650
case S_IFDIR: /* directory */
648651
if (recursive)
649652
compdir(tempname);
653+
else if ( ! quiet )
654+
fprintf(stderr,"%s is a directory -- ignored\n",
655+
tempname);
650656
break;
651657

652658
case S_IFREG: /* regular file */
@@ -697,9 +703,14 @@ char **fileptr;
697703
else {
698704
/* COMPRESSION */
699705
if (strcmp(tempname + strlen(tempname) - 2, ".Z") == 0) {
700-
fprintf(stderr, "%s: already has .Z suffix -- no change\n",
701-
tempname);
702-
return;
706+
fprintf(stderr, "%s: already has .Z suffix -- no change\n",
707+
tempname);
708+
return;
709+
}
710+
if (insbuf.st_nlink > 1 && (! force) ) {
711+
fprintf(stderr, "%s has %d other links: unchanged\n",
712+
tempname,insbuf.st_nlink - 1);
713+
return;
703714
}
704715
/* Open input file */
705716
if ((freopen(tempname, "r", stdin)) == NULL) {
@@ -787,8 +798,11 @@ char **fileptr;
787798
if((exit_stat == 1) || (!quiet))
788799
putc('\n', stderr);
789800
}
801+
break;
790802
default:
791-
break;
803+
fprintf(stderr,"%s is not a directory or a regular file - ignored\n",
804+
tempname);
805+
break;
792806
} /* end switch */
793807
return;
794808
} /* end comprexx */
@@ -802,22 +816,41 @@ char *dir;
802816
#else
803817
register struct dirent *dp;
804818
#endif
805-
char nbuf[1024];
819+
char nbuf[MAXPATHLEN];
806820
char *nptr = nbuf;
807821
dirp = opendir(dir);
808822
if (dirp == NULL) {
809823
printf("%s unreadable\n", dir); /* not stderr! */
810824
return ;
811825
}
826+
/*
827+
** WARNING: the following algorithm will occasionally cause
828+
** compress to produce error warnings of the form "<filename>.Z
829+
** already has .Z suffix - ignored". This occurs when the
830+
** .Z output file is inserted into the directory below
831+
** readdir's current pointer.
832+
** These warnings are harmless but annoying. The alternative
833+
** to allowing this would be to store the entire directory
834+
** list in memory, then compress the entries in the stored
835+
** list. Given the depth-first recursive algorithm used here,
836+
** this could use up a tremendous amount of memory. I don't
837+
** think it's worth it. -- Dave Mack
838+
*/
812839
while (dp = readdir(dirp)) {
813840
if (dp->d_ino == 0)
814841
continue;
815-
if (strcmp(dp->d_name,".") == 0 || strcmp(dp->d_name,"..") == 0)
842+
if (strcmp(dp->d_name,".") == 0 ||
843+
strcmp(dp->d_name,"..") == 0)
816844
continue;
817-
strcpy(nbuf,dir);
818-
strcat(nbuf,"/");
819-
strcat(nbuf,dp->d_name);
820-
comprexx(&nptr);
845+
if ( (strlen(dir)+strlen(dp->d_name)+1) < (MAXPATHLEN - 1)){
846+
strcpy(nbuf,dir);
847+
strcat(nbuf,"/");
848+
strcat(nbuf,dp->d_name);
849+
comprexx(&nptr);
850+
}
851+
else {
852+
fprintf(stderr,"Pathname too long: %s/%s\n",dir,dp->d_name);
853+
}
821854
}
822855
closedir(dirp);
823856
return;
@@ -1407,42 +1440,27 @@ writeerr()
14071440
copystat(ifname, ofname)
14081441
char *ifname, *ofname;
14091442
{
1410-
struct stat statbuf;
14111443
int mode;
14121444
time_t timep[2];
14131445

14141446
fclose(stdout);
1415-
if (stat(ifname, &statbuf)) { /* Get stat on input file */
1416-
perror(ifname);
1417-
return;
1418-
}
1419-
if ((statbuf.st_mode & S_IFMT/*0170000*/) != S_IFREG/*0100000*/) {
1420-
if(quiet)
1421-
fprintf(stderr, "%s: ", ifname);
1422-
fprintf(stderr, " -- not a regular file: unchanged");
1423-
exit_stat = 1;
1424-
} else if (statbuf.st_nlink > 1 && (! force) ) {
1425-
if(quiet)
1426-
fprintf(stderr, "%s: ", ifname);
1427-
fprintf(stderr, " -- has %d other links: unchanged",
1428-
statbuf.st_nlink - 1);
1429-
exit_stat = 1;
1430-
} else if (exit_stat == 2 && (!force)) { /* No compression: remove file.Z */
1447+
if (exit_stat == 2 && (!force)) { /* No compression: remove file.Z */
14311448
if(!quiet)
1432-
fprintf(stderr, " -- file unchanged");
1449+
fprintf(stderr, "No compression -- %s unchanged",
1450+
ifname);
14331451
} else { /* ***** Successful Compression ***** */
14341452
exit_stat = 0;
1435-
mode = statbuf.st_mode & 07777;
1453+
mode = insbuf.st_mode & 07777;
14361454
if (chmod(ofname, mode)) /* Copy modes */
14371455
perror(ofname);
1438-
chown(ofname, statbuf.st_uid, statbuf.st_gid); /* Copy ownership */
1439-
timep[0] = statbuf.st_atime;
1440-
timep[1] = statbuf.st_mtime;
1456+
chown(ofname, insbuf.st_uid, insbuf.st_gid); /* Copy ownership */
1457+
timep[0] = insbuf.st_atime;
1458+
timep[1] = insbuf.st_mtime;
14411459
utime(ofname, timep); /* Update last accessed and modified times */
14421460
if (unlink(ifname)) /* Remove input file */
14431461
perror(ifname);
14441462
if(!quiet)
1445-
fprintf(stderr, " -- replaced with %s", ofname);
1463+
fprintf(stderr, " -- replaced with %s",ofname);
14461464
return; /* Successful return */
14471465
}
14481466

patchlevel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
#define PATCHLEVEL 0
1+
#define PATCHLEVEL 1

0 commit comments

Comments
 (0)