Patch Priority: COSMIC
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.
Please apply it using "patch [-d compress41-source-dir] < patch-file".
Dave Mack
-----
diff -rc compress.posted/compress.1 compress41/compress.1
*** compress.posted/compress.1 Fri Jun 28 19:07:12 1991
--- compress41/compress.1 Fri Jun 28 19:08:45 1991
***************
*** 51,65 ****
while keeping the same ownership modes, access and modification times.
If no files are specified, the standard input is compressed to the
standard output.
! Compressed files can be restored to their original form using
! .I uncompress
! or
! .I zcat.
! .PP
! The
.B \-f
! option will force compression of
! .I name.
If
.B \-f
is not given and
--- 51,65 ----
while keeping the same ownership modes, access and modification times.
If no files are specified, the standard input is compressed to the
standard output.
! .I Compress
! will only attempt to compress regular files.
! In particular, it will ignore symbolic links. If a file has multiple
! hard links,
! .I compress
! will refuse to compress it unless the
.B \-f
! flag is given.
! .PP
If
.B \-f
is not given and
***************
*** 67,82 ****
is run in the foreground,
the user is prompted as to whether an existing file should be overwritten.
.PP
The
.B \-c
option makes
.I compress/uncompress
write to the standard output; no files are changed.
! The nondestructive behavior of
.I zcat
! is identical to that of
.I uncompress
.B \-c.
.PP
If the
.B \-r
--- 67,105 ----
is run in the foreground,
the user is prompted as to whether an existing file should be overwritten.
.PP
+ Compressed files can be restored to their original form using
+ .I uncompress
+ or
+ .I zcat.
+ .PP
+ .I uncompress
+ takes a list of files on its command line and replaces each
+ file whose name ends with
+ .B "\&.Z"
+ and which begins with the correct magic number with an uncompressed
+ file without the
+ .B "\&.Z."
+ The uncompressed file will have the mode, ownership and
+ timestamps of the compressed file.
+ .PP
The
.B \-c
option makes
.I compress/uncompress
write to the standard output; no files are changed.
! .PP
.I zcat
! is identical to
.I uncompress
.B \-c.
+ .I zcat
+ uncompresses either a list of files on the command line or its
+ standard input and writes the uncompressed data on standard output.
+ .I zcat
+ will uncompress files that have the correct magic number whether
+ they have a
+ .B "\&.Z"
+ suffix or not.
.PP
If the
.B \-r
***************
*** 87,92 ****
--- 110,121 ----
.I compress
will descend into the directory and compress all the files it finds there.
.PP
+ The
+ .B \-V
+ flag tells each of these programs to print its version and patchlevel,
+ along with any preprocessor flags specified during compilation, on
+ stderr before doing any compression or uncompression.
+ .PP
.I Compress
uses the modified Lempel-Ziv algorithm popularized in
"A Technique for High Performance Data Compression",
***************
*** 147,157 ****
a message is printed yielding the percentage of
reduction for each file compressed.
.PP
- If the
- .B \-V
- option is specified, the current version and compile options are printed on
- stderr.
- .PP
Exit status is normally 0;
if the last file is larger after (attempted) compression, the status is 2;
if an error occurs, exit status is 1.
--- 176,181 ----
***************
*** 158,164 ****
.SH "SEE ALSO"
pack(1), compact(1)
.SH "DIAGNOSTICS"
! Usage: compress [\-dfvcV] [\-b maxbits] [file ...]
.in +8
Invalid options were specified on the command line.
.in -8
--- 182,188 ----
.SH "SEE ALSO"
pack(1), compact(1)
.SH "DIAGNOSTICS"
! Usage: compress [\-dfvcVr] [\-b maxbits] [file ...]
.in +8
Invalid options were specified on the command line.
.in -8
***************
*** 220,229 ****
(Relevant only for
.BR \-v \.)
.in -8
! -- not a regular file: unchanged
.in +8
! When the input file is not a regular file,
! (e.g. a directory), it is
left unaltered.
.in -8
-- has
--- 244,253 ----
(Relevant only for
.BR \-v \.)
.in -8
! -- not a regular file or directory: ignored
.in +8
! When the input file is not a regular file or directory,
! (e.g. a symbolic link, socket, FIFO, device file), it is
left unaltered.
.in -8
-- has
***************
*** 232,238 ****
.in +8
The input file has links; it is left unchanged. See
.IR ln "(1)"
! for more information.
.in -8
-- file unchanged
.in +8
--- 256,264 ----
.in +8
The input file has links; it is left unchanged. See
.IR ln "(1)"
! for more information. Use the
! .B \-f
! flag to force compression of multiply-linked files.
.in -8
-- file unchanged
.in +8
***************
*** 245,247 ****
--- 271,284 ----
should be used for file transfer to architectures with
a small process data space (64KB or less, as exhibited by the DEC PDP
series, the Intel 80286, etc.)
+ .PP
+ Invoking compress with a \-r
+ flag will occasionally cause it to produce spurious error warnings of the form
+ .PP
+ .in 8
+ "<filename>.Z already has .Z suffix - ignored"
+ .in -8
+ .PP
+ These warnings can be ignored. See the comments in compress.c:compdir()
+ for an explanation.
+
diff -rc compress.posted/compress.c compress41/compress.c
*** compress.posted/compress.c Fri Jun 28 19:07:09 1991
--- compress41/compress.c Fri Jun 28 19:08:41 1991
***************
*** 3,8 ****
--- 3,11 ----
*/
#define min(a,b) ((a>b) ? b : a)
+ /* MAXPATHLEN - maximum length of a pathname we allow */
+ #define MAXPATHLEN 1024
+
/*
* machine variants which require cc -Dmachine: pdp11, z8000, pcxt
*/
***************
*** 373,379 ****
#define CLEAR 256 /* table clear output code */
int force = 0;
! char ofname [100];
#ifdef DEBUG
int verbose = 0;
#endif /* DEBUG */
--- 376,382 ----
#define CLEAR 256 /* table clear output code */
int force = 0;
! char ofname[MAXPATHLEN];
#ifdef DEBUG
int verbose = 0;
#endif /* DEBUG */
***************
*** 386,391 ****
--- 389,395 ----
int do_decomp = 0;
+ struct stat statbuf, insbuf;
/*****************************************************************
* TAG( main )
***************
*** 596,603 ****
comprexx(fileptr)
char **fileptr;
{
! struct stat statbuf,insbuf;
! char tempname[1024], *cp;
strcpy(tempname,*fileptr);
errno = 0;
--- 600,606 ----
comprexx(fileptr)
char **fileptr;
{
! char tempname[MAXPATHLEN], *cp;
strcpy(tempname,*fileptr);
errno = 0;
***************
*** 647,652 ****
--- 650,658 ----
case S_IFDIR: /* directory */
if (recursive)
compdir(tempname);
+ else if ( ! quiet )
+ fprintf(stderr,"%s is a directory -- ignored\n",
+ tempname);
break;
case S_IFREG: /* regular file */
***************
*** 697,706 ****
else {
/* COMPRESSION */
if (strcmp(tempname + strlen(tempname) - 2, ".Z") == 0) {
! fprintf(stderr, "%s: already has .Z suffix -- no change\n",
! tempname);
! return;
}
/* Open input file */
if ((freopen(tempname, "r", stdin)) == NULL) {
perror(tempname); return;
--- 703,717 ----
else {
/* COMPRESSION */
if (strcmp(tempname + strlen(tempname) - 2, ".Z") == 0) {
! fprintf(stderr, "%s: already has .Z suffix -- no change\n",
! tempname);
! return;
}
+ if (insbuf.st_nlink > 1 && (! force) ) {
+ fprintf(stderr, "%s has %d other links: unchanged\n",
+ tempname,insbuf.st_nlink - 1);
+ return;
+ }
/* Open input file */
if ((freopen(tempname, "r", stdin)) == NULL) {
perror(tempname); return;
***************
*** 787,794 ****
if((exit_stat == 1) || (!quiet))
putc('\n', stderr);
}
default:
! break;
} /* end switch */
return;
} /* end comprexx */
--- 798,808 ----
if((exit_stat == 1) || (!quiet))
putc('\n', stderr);
}
+ break;
default:
! fprintf(stderr,"%s is not a directory or a regular file - ignored\n",
! tempname);
! break;
} /* end switch */
return;
} /* end comprexx */
***************
*** 802,808 ****
#else
register struct dirent *dp;
#endif
! char nbuf[1024];
char *nptr = nbuf;
dirp = opendir(dir);
if (dirp == NULL) {
--- 816,822 ----
#else
register struct dirent *dp;
#endif
! char nbuf[MAXPATHLEN];
char *nptr = nbuf;
dirp = opendir(dir);
if (dirp == NULL) {
***************
*** 809,823 ****
printf("%s unreadable\n", dir); /* not stderr! */
return ;
}
while (dp = readdir(dirp)) {
if (dp->d_ino == 0)
continue;
! if (strcmp(dp->d_name,".") == 0 || strcmp(dp->d_name,"..") == 0)
continue;
! strcpy(nbuf,dir);
! strcat(nbuf,"/");
! strcat(nbuf,dp->d_name);
! comprexx(&nptr);
}
closedir(dirp);
return;
--- 823,856 ----
printf("%s unreadable\n", dir); /* not stderr! */
return ;
}
+ /*
+ ** WARNING: the following algorithm will occasionally cause
+ ** compress to produce error warnings of the form "<filename>.Z
+ ** already has .Z suffix - ignored". This occurs when the
+ ** .Z output file is inserted into the directory below
+ ** readdir's current pointer.
+ ** These warnings are harmless but annoying. The alternative
+ ** to allowing this would be to store the entire directory
+ ** list in memory, then compress the entries in the stored
+ ** list. Given the depth-first recursive algorithm used here,
+ ** this could use up a tremendous amount of memory. I don't
+ ** think it's worth it. -- Dave Mack
+ */
while (dp = readdir(dirp)) {
if (dp->d_ino == 0)
continue;
! if (strcmp(dp->d_name,".") == 0 ||
! strcmp(dp->d_name,"..") == 0)
continue;
! if ( (strlen(dir)+strlen(dp->d_name)+1) < (MAXPATHLEN - 1)){
! strcpy(nbuf,dir);
! strcat(nbuf,"/");
! strcat(nbuf,dp->d_name);
! comprexx(&nptr);
! }
! else {
! fprintf(stderr,"Pathname too long: %s/%s\n",dir,dp->d_name);
! }
}
closedir(dirp);
return;
***************
*** 1407,1448 ****
copystat(ifname, ofname)
char *ifname, *ofname;
{
- struct stat statbuf;
int mode;
time_t timep[2];
fclose(stdout);
! if (stat(ifname, &statbuf)) { /* Get stat on input file */
! perror(ifname);
! return;
! }
! if ((statbuf.st_mode & S_IFMT/*0170000*/) != S_IFREG/*0100000*/) {
! if(quiet)
! fprintf(stderr, "%s: ", ifname);
! fprintf(stderr, " -- not a regular file: unchanged");
! exit_stat = 1;
! } else if (statbuf.st_nlink > 1 && (! force) ) {
! if(quiet)
! fprintf(stderr, "%s: ", ifname);
! fprintf(stderr, " -- has %d other links: unchanged",
! statbuf.st_nlink - 1);
! exit_stat = 1;
! } else if (exit_stat == 2 && (!force)) { /* No compression: remove file.Z */
if(!quiet)
! fprintf(stderr, " -- file unchanged");
} else { /* ***** Successful Compression ***** */
exit_stat = 0;
! mode = statbuf.st_mode & 07777;
if (chmod(ofname, mode)) /* Copy modes */
perror(ofname);
! chown(ofname, statbuf.st_uid, statbuf.st_gid); /* Copy ownership */
! timep[0] = statbuf.st_atime;
! timep[1] = statbuf.st_mtime;
utime(ofname, timep); /* Update last accessed and modified times */
if (unlink(ifname)) /* Remove input file */
perror(ifname);
if(!quiet)
! fprintf(stderr, " -- replaced with %s", ofname);
return; /* Successful return */
}
--- 1440,1466 ----
copystat(ifname, ofname)
char *ifname, *ofname;
{
int mode;
time_t timep[2];
fclose(stdout);
! if (exit_stat == 2 && (!force)) { /* No compression: remove file.Z */
if(!quiet)
! fprintf(stderr, "No compression -- %s unchanged",
! ifname);
} else { /* ***** Successful Compression ***** */
exit_stat = 0;
! mode = insbuf.st_mode & 07777;
if (chmod(ofname, mode)) /* Copy modes */
perror(ofname);
! chown(ofname, insbuf.st_uid, insbuf.st_gid); /* Copy ownership */
! timep[0] = insbuf.st_atime;
! timep[1] = insbuf.st_mtime;
utime(ofname, timep); /* Update last accessed and modified times */
if (unlink(ifname)) /* Remove input file */
perror(ifname);
if(!quiet)
! fprintf(stderr, " -- replaced with %s",ofname);
return; /* Successful return */
}
diff -rc compress.posted/patchlevel.h compress41/patchlevel.h
*** compress.posted/patchlevel.h Fri Jun 28 19:07:16 1991
--- compress41/patchlevel.h Fri Jun 28 19:12:42 1991
***************
*** 1 ****
! #define PATCHLEVEL 0
--- 1 ----
! #define PATCHLEVEL 1
exit 0 # Just in case...
--
Kent Landfield INTERNET: ke...@sparky.IMD.Sterling.COM
Sterling Software, IMD UUCP: uunet!sparky!kent
Phone: (402) 291-8300 FAX: (402) 291-4362
Please send comp.sources.misc-related mail to ke...@uunet.uu.net.