[net.bugs.4bsd] fix for compact and uncompact

chongo@nsc.UUCP (Landon C. Noll) (01/04/85)

<ultracompact this line>

 Subject: compact/uncompact exit wrong, are always verbose, are not consistent
 Index:	/usr/src/ucb/compact/{compact,uncompact}.c,/usr/man/man1/compact.1 4.2

 Description:
	Compact and uncompact exit with an exit code of 1 when everything
	worked just fine.  Compact and uncompact always announce their
	actions (% file reduction or new file name) to standard error.

	Compact does not always form a .C file.  There is no way when
	compacting a file would not save bytes to have compact form the .C
	file.  This causes problems for make/shell scripts which which to setup
	deompacting rules and expect to find the compact file.  There is
	no way to force compact to compact a file.
	
	Compact and uncompact do not need to have a 12 byte filename
	limit as the man page suggests.
 Repeat-By:
	Compact a file and notice the non-zero exit code.  Uncompact the
	file and notice the same thing.  Notice the balby reports.

	Notice that the compacted file is not formed:

	echo -n 'a' > very.small.file
	compact very.small.file
	echo 'abcdefghjiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVW' > bigger.file
	compact bugger.file
 Fix:
	Below you will find the diffs of compact.c, uncompact.c and man page
	compact.1.  The following is a summary of the changes:

		* -q flag added to shutup the programs
		* -f flag in compact forces it to form a compacted file
		* programs exit with 0 if all is o.k.
		* compact exits with EINVAL on short files unless -f is used
		* proper exit codes are used
		* documenttation of changes in the man page

	An attempt to change few lines of code was made.  Programming style
	comflicts were resolved in favor of the old program to make the
	diff as small as reasonable.

	--------------------------diff between compact.c (old new) below-----
	*** oldcompact.c	Mon Oct 29 04:01:41 1984
	--- compact.c	Thu Jan  3 23:53:18 1985
	***************
	*** 1,5
	  #ifndef lint
	! static char sccsid[] = "@(#)compact.c	4.4 (Berkeley) 8/11/83";
	  #endif lint
	  
	  /*
	
	--- 1,5 -----
	  #ifndef lint
	! static char sccsid[] = "@(#)compact.c	4.4.1 (Modified) 4-jan-85";
	  #endif lint
	  
	  /*
	***************
	*** 10,15
	   *  Does not prepend decoding tree
	   *
	   *  Written by Colin L. Mc Master (UCB) February 28, 1979
	   */
	  
	  
	
	--- 10,17 -----
	   *  Does not prepend decoding tree
	   *
	   *  Written by Colin L. Mc Master (UCB) February 28, 1979
	+  *  Modified by Landon Noll (nsc) October 22, 1984: Added -f & -q options,
	+  *	exits with 0 on normal ending.
	   */
	  
	  #define TRUE 1
	***************
	*** 12,17
	   *  Written by Colin L. Mc Master (UCB) February 28, 1979
	   */
	  
	  
	  #include "compact.h"
	  
	
	--- 14,21 -----
	   *	exits with 0 on normal ending.
	   */
	  
	+ #define TRUE 1
	+ #define FALSE 0
	  
	  #include "compact.h"
	  #include <errno.h>
	***************
	*** 14,19
	  
	  
	  #include "compact.h"
	  
	  union cio d;
	  int bits;
	
	--- 18,24 -----
	  #define FALSE 0
	  
	  #include "compact.h"
	+ #include <errno.h>
	  
	  union cio d;
	  int bits;
	***************
	*** 17,22
	  
	  union cio d;
	  int bits;
	  
	  
	  main (argc, argv)
	
	--- 22,29 -----
	  
	  union cio d;
	  int bits;
	+ extern int errno;	/* last system error */
	+ int saved_errno=0;	/* last saved errno */
	  
	  main (argc, argv)
	  short argc;
	***************
	*** 18,24
	  union cio d;
	  int bits;
	  
	- 
	  main (argc, argv)
	  short argc;
	  char *argv [ ];
	
	--- 25,30 -----
	  extern int errno;	/* last system error */
	  int saved_errno=0;	/* last saved errno */
	  
	  main (argc, argv)
	  short argc;
	  char *argv [ ];
	***************
	*** 29,34
		short l;
		longint ic, n;
		char *cp, fname [LNAME];
	  
		dir [513] . next = NULL;
		for (head = dir + (j = 513); j--; ) {
	
	--- 35,42 -----
		short l;
		longint ic, n;
		char *cp, fname [LNAME];
	+ 	char forced;			/* TRUE => compact no matter what */
	+ 	char quiet;			/* TRUE => don't report results */
	  
		/* process flags */
		forced = FALSE;
	***************
	*** 30,35
		longint ic, n;
		char *cp, fname [LNAME];
	  
		dir [513] . next = NULL;
		for (head = dir + (j = 513); j--; ) {
			dirp = head--;
	
	--- 38,67 -----
		char forced;			/* TRUE => compact no matter what */
		char quiet;			/* TRUE => don't report results */
	  
	+ 	/* process flags */
	+ 	forced = FALSE;
	+ 	quiet = FALSE;
	+ 	while ( argc > 1 && argv[1][0] == '-' ) {
	+ 		if ( argv[1][2] == 0 ) {
	+ 			if ( argv[1][1] == 'f' ) {
	+ 				forced = TRUE;
	+ 			} else if ( argv[1][1] == 'q' ) {
	+ 				quiet = TRUE;
	+ 			} else {
	+ 				fprintf( stderr, "usage: compact [-f] [-q] [file ...]\n");
	+ 				exit(EINVAL);
	+ 			}
	+ 		} else if ( strcmp( argv[1], "-fq" ) == 0 || strcmp( argv[1], "-qf" ) == 0 ) {
	+ 			forced = TRUE;
	+ 			quiet = TRUE;
	+ 		} else {
	+ 			fprintf( stderr, "usage: compact [-f] [-q] [file ...]\n");
	+ 			exit(EINVAL);
	+ 		}
	+ 		--argc;
	+ 		++argv;
	+ 	}
	+ 
		dir [513] . next = NULL;
		for (head = dir + (j = 513); j--; ) {
			dirp = head--;
	***************
	*** 55,60
				for (l = 0; l < (LNAME - 3) && (*cp = argv [i][l]); l++)
					if (*cp++ == '/') m = l;
				if (l >= (LNAME - 3) || (l - m) > MAXNAMLEN - 1) {
					fprintf (stderr, "%s: File name too long\n", argv [i]);
					if (i == argc - 1) break;
					continue;
	
	--- 87,93 -----
				for (l = 0; l < (LNAME - 3) && (*cp = argv [i][l]); l++)
					if (*cp++ == '/') m = l;
				if (l >= (LNAME - 3) || (l - m) > MAXNAMLEN - 1) {
	+ 				saved_errno = ENAMETOOLONG;
					fprintf (stderr, "%s: File name too long\n", argv [i]);
					if (i >= argc - 1) break;
					continue;
	***************
	*** 56,62
					if (*cp++ == '/') m = l;
				if (l >= (LNAME - 3) || (l - m) > MAXNAMLEN - 1) {
					fprintf (stderr, "%s: File name too long\n", argv [i]);
	! 				if (i == argc - 1) break;
					continue;
				}
				if ((uncfp = fopen (argv [i], "r")) == NULL) {
	
	--- 89,95 -----
				if (l >= (LNAME - 3) || (l - m) > MAXNAMLEN - 1) {
					saved_errno = ENAMETOOLONG;
					fprintf (stderr, "%s: File name too long\n", argv [i]);
	! 				if (i >= argc - 1) break;
					continue;
				}
				if ((uncfp = fopen (argv [i], "r")) == NULL) {
	***************
	*** 60,65
					continue;
				}
				if ((uncfp = fopen (argv [i], "r")) == NULL) {
					perror (argv [i]);
					if (i == argc - 1) break;
					continue;
	
	--- 93,99 -----
					continue;
				}
				if ((uncfp = fopen (argv [i], "r")) == NULL) {
	+ 				saved_errno = (errno) ? errno : EINVAL;
					perror (argv [i]);
					if (i >= argc - 1) break;
					continue;
	***************
	*** 61,67
				}
				if ((uncfp = fopen (argv [i], "r")) == NULL) {
					perror (argv [i]);
	! 				if (i == argc - 1) break;
					continue;
				}
			}
	
	--- 95,101 -----
				if ((uncfp = fopen (argv [i], "r")) == NULL) {
					saved_errno = (errno) ? errno : EINVAL;
					perror (argv [i]);
	! 				if (i >= argc - 1) break;
					continue;
				}
			}
	***************
	*** 68,73
	  
			fstat (fileno (uncfp), &status);
			if ((status.st_mode & 040000) == 040000) {
				fprintf (stderr, "%s: Can't compact a directory\n", argv [i]);
				if (i < argc) goto closein;
				break;
	
	--- 102,108 -----
	  
			fstat (fileno (uncfp), &status);
			if ((status.st_mode & 040000) == 040000) {
	+ 			saved_errno = EISDIR;
				fprintf (stderr, "%s: Can't compact a directory\n", argv [i]);
				if (i < argc) goto closein;
				break;
	***************
	*** 78,83
				if ((c . integ = getc (uncfp)) != EOF) {
					d . chars . hib = c . integ & 0377;
					if ((d . integ &= 0177777) == COMPACTED) {
						fprintf (stderr, "%s: Already compacted.\n", argv [i]);
						if (i < argc) goto closein;
						break;
	
	--- 113,119 -----
				if ((c . integ = getc (uncfp)) != EOF) {
					d . chars . hib = c . integ & 0377;
					if ((d . integ &= 0177777) == COMPACTED) {
	+ 					saved_errno = EINVAL;
						fprintf (stderr, "%s: Already compacted.\n", argv [i]);
						if (i < argc) goto closein;
						break;
	***************
	*** 83,88
						break;
					}
					if (d . integ == PACKED) {
						fprintf (stderr, "%s: Already packed using program pack.  Use unpack.\n", argv [i]);
						if (i < argc) goto closein;
						break;
	
	--- 119,125 -----
						break;
					}
					if (d . integ == PACKED) {
	+ 					saved_errno = EINVAL;
						fprintf (stderr, "%s: Already packed using program pack.  Use unpack.\n", argv [i]);
						if (i < argc) goto closein;
						break;
	***************
	*** 89,95
					}
					if (i < argc) {
						*cp++ = '.'; *cp++ = 'C'; *cp = '\0';
	! 					if ((cfp = fopen (fname, "w")) == NULL) {
							perror (fname);
							goto closein;
						}
	
	--- 126,133 -----
					}
					if (i < argc) {
						*cp++ = '.'; *cp++ = 'C'; *cp = '\0';
	! 					if ((cfp = fopen(fname,"w")) == NULL) {
	! 						saved_errno = errno;
							perror (fname);
							goto closein;
						}
	***************
	*** 93,99
							perror (fname);
							goto closein;
						}
	! 					chmod (fname, status.st_mode);
					}
					c . integ = COMPACTED;
					putc (c . chars . lob, cfp);
	
	--- 131,141 -----
							perror (fname);
							goto closein;
						}
	! 					if (chmod(fname, status.st_mode) < 0) {
	! 						saved_errno = errno;
	! 						perror (fname);
	! 						goto closein;
	! 					}
					}
					c . integ = COMPACTED;
					putc (c . chars . lob, cfp);
	***************
	*** 98,104
					c . integ = COMPACTED;
					putc (c . chars . lob, cfp);
					putc (c . chars . hib, cfp);
	! 				if (ferror (cfp))
						if (i < argc) {
							perror (fname);
							unlink (fname);
	
	--- 140,147 -----
					c . integ = COMPACTED;
					putc (c . chars . lob, cfp);
					putc (c . chars . hib, cfp);
	! 				if (ferror (cfp)) {
	! 					saved_errno = (errno) ? errno : EINVAL;
						if (i < argc) {
							perror (fname);
							unlink (fname);
	***************
	*** 105,110
							goto closeboth;
						}
						else goto fail;
					bits = 8;
					oc = 2;
					c . integ = d . integ & 0377;
	
	--- 148,154 -----
							goto closeboth;
						}
						else goto fail;
	+ 				}
					bits = 8;
					oc = 2;
					c . integ = d . integ & 0377;
	***************
	*** 120,126
					dict [0] . fath . flags = RLEAF;
					bottom -> fath . flags = (LLEAF | RLEAF);
					dict [0] . count [0] = 2;
	! 	
					dict [0] . sp [1] . ch = c . integ;
					bottom -> sp [0] . ch = NC;
					bottom -> sp [1] . ch = EF;
	
	--- 164,170 -----
					dict [0] . fath . flags = RLEAF;
					bottom -> fath . flags = (LLEAF | RLEAF);
					dict [0] . count [0] = 2;
	! 
					dict [0] . sp [1] . ch = c . integ;
					bottom -> sp [0] . ch = NC;
					bottom -> sp [1] . ch = EF;
	***************
	*** 145,151
								}
							}
						}
	! 					if (ferror (cfp))
							if (i < argc) {
								perror (fname);
								unlink (fname);
	
	--- 189,196 -----
								}
							}
						}
	! 					if (ferror (cfp)) {
	! 						saved_errno = (errno) ? errno : EINVAL;
							if (i < argc) {
								perror (fname);
								unlink (fname);
	***************
	*** 152,157
								goto closeboth;
							}
							else goto fail;
						uptree (c . integ);
		
					}
	
	--- 197,203 -----
								goto closeboth;
							}
							else goto fail;
	+ 					}
						uptree (c . integ);
		
					}
	***************
	*** 156,162
		
					}
	  
	! 				if (ferror (uncfp))
						if (i < argc) {
							perror (argv [i]);
							unlink (fname);
	
	--- 202,209 -----
		
					}
	  
	! 				if (ferror (uncfp)) {
	! 					saved_errno = (errno) ? errno : EINVAL;
						if (i < argc) {
							perror (argv [i]);
							unlink (fname);
	***************
	*** 163,168
							goto closeboth;
						}
						else goto fail;
		
					encode (EF);
		
	
	--- 210,216 -----
							goto closeboth;
						}
						else goto fail;
	+ 				}
		
					encode (EF);
		
	***************
	*** 177,183
						bits = 0;
					}
				}
	! 			else oc = ic;
			}
	  
			if (ferror (uncfp) || ferror (cfp))
	
	--- 225,271 -----
						bits = 0;
					}
				}
	! 			else {			/* single char file */
	! 				clearerr(uncfp);
	! 				if (i < argc) {
	! 					*cp++ = '.'; *cp++ = 'C'; *cp = '\0';
	! 					if ((cfp = fopen(fname,"w")) == NULL) {
	! 						saved_errno = errno;
	! 						perror (fname);
	! 						goto closein;
	! 					}
	! 					if (chmod(fname, status.st_mode) < 0) {
	! 						saved_errno = errno;
	! 						perror (fname);
	! 						goto closein;
	! 					}
	! 				}
	! 				c . integ = COMPACTED;
	! 				putc (c . chars . lob, cfp);
	! 				putc (c . chars . hib, cfp);
	! 				putc(d.chars.lob,cfp);
	! 				oc = ic+1;
	! 			}
	! 
	! 		/* empty input file, force process if needed */
	! 		} else if ( forced == TRUE ) {
	! 			clearerr(uncfp);
	! 			if (i < argc) {
	! 				*cp++ = '.'; *cp++ = 'C'; *cp = '\0';
	! 				if ((cfp = fopen(fname,"w")) == NULL) {
	! 					saved_errno = errno;
	! 					perror (fname);
	! 					goto closein;
	! 				}
	! 				if (chmod(fname, status.st_mode) < 0) {
	! 					saved_errno = errno;
	! 					perror (fname);
	! 					goto closein;
	! 				}
	! 			}
	! 			c . integ = COMPACTED;
	! 			putc (c . chars . lob, cfp);
	! 			putc (c . chars . hib, cfp);
			}
	  
			if (ferror (uncfp) || ferror (cfp)) {
	***************
	*** 180,186
				else oc = ic;
			}
	  
	! 		if (ferror (uncfp) || ferror (cfp))
				if (i < argc) {
					if (ferror (cfp))
						perror (fname);
	
	--- 268,275 -----
				putc (c . chars . hib, cfp);
			}
	  
	! 		if (ferror (uncfp) || ferror (cfp)) {
	! 			saved_errno = (errno) ? errno : EINVAL;
				if (i < argc) {
					if (ferror (cfp))
						perror (fname);
	***************
	*** 193,203
					goto closein;
				}
				else goto fail;
	! 		else {
	! 			if (oc >= ic) {
	! 				if (i < argc) fprintf (stderr, "%s: ", argv [i]);
	! 				if (i < argc) fprintf (stderr, "Not compacted.  ");
	! 				fprintf (stderr, "Does not save bytes.\n");
					if (i < argc) {
						if (oc > 1) {
							unlink (fname);
	
	--- 282,343 -----
					goto closein;
				}
				else goto fail;
	! 		} else {
	! 			/* be sure they want a report */
	! 			if ( quiet == FALSE ) {
	! 				/* was not forced to poorly compress report */
	! 				if (forced == FALSE && oc >= ic) {
	! 					/* exit non-zero if non-forced bad compress size */
	! 					saved_errno = (saved_errno==0) ? EINVAL : saved_errno;
	! 					if (i < argc) fprintf (stderr, "%s: ", argv [i]);
	! 					if (i < argc) fprintf (stderr, "Not compacted.  ");
	! 					fprintf (stderr, "Does not save bytes.\n");
	! 					if (i < argc) {
	! 						if (oc > 1) {
	! 							unlink (fname);
	! 							goto closeboth;
	! 						}
	! 						goto closein;
	! 					}
	! 					else break;
	! 				/* forced poor compression report */
	! 				} else if ( oc > ic ) {
	! 					while ((oc - ic) > 21474) {
	! 						ic /= 10;
	! 						oc /= 10;
	! 					}
	! 					n = 100000 * (oc - ic) / oc + 5;
	! 					m = (n % 1000) / 10;
	! 					bits = m % 10 + '0';
	! 					c . integ = m / 10 + '0';
	! 					if (i < argc) fprintf (stderr, "%s:  ", argv [i]);
	! 					fprintf (stderr, "Compression : %5ld.%c%c%%\n", (-n) / 1000, c . chars . lob, bits);
	! 				/* no change in size report */
	! 				} else if ( oc == ic ) {
	! 					if (i < argc) fprintf (stderr, "%s:  ", argv [i]);
	! 					if ( oc == 0 ) {
	! 						fprintf (stderr, "Compression : was empty, now 2 bytes\n");
	! 					} else {
	! 						fprintf (stderr, "Compression : 0.00%\n");
	! 					}
	! 				/* normal compression report */
	! 				} else {
	! 					while ((ic - oc) > 21474) {
	! 						ic /= 10;
	! 						oc /= 10;
	! 					}
	! 					n = 100000 * (ic - oc) / ic + 5;
	! 					m = (n % 1000) / 10;
	! 					bits = m % 10 + '0';
	! 					c . integ = m / 10 + '0';
	! 					if (i < argc) fprintf (stderr, "%s:  ", argv [i]);
	! 					fprintf (stderr, "Compression : %4ld.%c%c%%\n", n / 1000, c . chars . lob, bits);
	! 				}
	! 			}
	! 			/* note a non-forced non-compact */
	! 			if (forced == FALSE && oc >= ic) {
	! 				/* exit non-zero if non-forced bad compress size */
	! 				saved_errno = (saved_errno==0) ? EINVAL : saved_errno;
					if (i < argc) {
						if (oc > 1) {
							unlink (fname);
	***************
	*** 207,222
					}
					else break;
				}
	- 			while ((ic - oc) > 21474) {
	- 				ic /= 10;
	- 				oc /= 10;
	- 			}
	- 			n = 100000 * (ic - oc) / ic + 5;
	- 			m = (n % 1000) / 10;
	- 			bits = m % 10 + '0';
	- 			c . integ = m / 10 + '0';
	- 			if (i < argc) fprintf (stderr, "%s:  ", argv [i]);
	- 			fprintf (stderr, "Compression : %4ld.%c%c%%\n", n / 1000, c . chars . lob, bits);
			}
	  
				    if (i >= argc) break;
	
	--- 347,352 -----
					}
					else break;
				}
			}
	  
				    if (i >= argc) break;
	***************
	*** 223,229
				    unlink (argv [i]);
			closeboth : fclose (cfp);
			closein   : fclose (uncfp);
	! 			    if (i == argc - 1) break;
				    for (j = 256; j--; ) in [j] . flags = 0;
				    continue;
			fail 	  : fprintf (stderr, "Unsuccessful compact of standard input to standard output.\n");
	
	--- 353,359 -----
				    unlink (argv [i]);
			closeboth : fclose (cfp);
			closein   : fclose (uncfp);
	! 			    if (i >= argc-1) break;
				    for (j = 256; j--; ) in [j] . flags = 0;
				    continue;
			fail 	  : fprintf (stderr, "Unsuccessful compact of standard input to standard output.\n");
	***************
	*** 229,234
			fail 	  : fprintf (stderr, "Unsuccessful compact of standard input to standard output.\n");
				    break;
		}
	  }
	  
	  encode (ch)
	
	--- 359,365 -----
			fail 	  : fprintf (stderr, "Unsuccessful compact of standard input to standard output.\n");
				    break;
		}
	+ 	exit(saved_errno);
	  }
	  
	  encode (ch)
	----------------------------end of compact.c diff-------------------

	-------------------diff of uncompact.c (old new) below-----------------
	*** olduncompact.c	Mon Oct 29 04:02:35 1984
	--- uncompact.c	Thu Jan  3 23:53:40 1985
	***************
	*** 1,5
	  #ifndef lint
	! static char sccsid[] = "@(#)uncompact.c	4.4 (Berkeley) 8/11/83";
	  #endif lint
	  
	  /*
	
	--- 1,5 -----
	  #ifndef lint
	! static char sccsid[] = "@(#)compact.c	4.4.1 (Modified) 4-jan-85";
	  #endif lint
	  
	  /*
	***************
	*** 10,15
	   *  Input file does not contain decoding tree
	   *
	   *  Written by Colin L. Mc Master (UCB) February 14, 1979
	   */
	  
	  #include "compact.h"
	
	--- 10,17 -----
	   *  Input file does not contain decoding tree
	   *
	   *  Written by Colin L. Mc Master (UCB) February 14, 1979
	+  *  Modified by Landon Noll (nsc) October 22, 1984: exits with 0 when o.k.,
	+  *				added -q flag for being quiet
	   */
	  
	  #include "compact.h"
	***************
	*** 13,18
	   */
	  
	  #include "compact.h"
	  
	  
	  main (argc, argv)
	
	--- 15,21 -----
	   */
	  
	  #include "compact.h"
	+ #include <errno.h>
	  
	  #define TRUE 1
	  #define FALSE 0
	***************
	*** 14,19
	  
	  #include "compact.h"
	  
	  
	  main (argc, argv)
	  short argc;
	
	--- 17,24 -----
	  #include "compact.h"
	  #include <errno.h>
	  
	+ #define TRUE 1
	+ #define FALSE 0
	  
	  extern int errno;		/* last system error */
	  int saved_errno=0;		/* last saved errno */
	***************
	*** 15,20
	  #include "compact.h"
	  
	  
	  main (argc, argv)
	  short argc;
	  char *argv [ ];
	
	--- 20,28 -----
	  #define TRUE 1
	  #define FALSE 0
	  
	+ extern int errno;		/* last system error */
	+ int saved_errno=0;		/* last saved errno */
	+ 
	  main (argc, argv)
	  short argc;
	  char *argv [ ];
	***************
	*** 27,32
		char b;
		longint ic, n;
		char fname [LNAME], *cp;
	  
		dir [513] . next = NULL;
		for (head = dir + (j = 513); j--; ) {
	
	--- 35,41 -----
		char b;
		longint ic, n;
		char fname [LNAME], *cp;
	+ 	char quiet;
	  
		/* check for the quiet flag */
		if ( argc > 1 && strcmp( argv[1], "-q" ) == 0 ) {
	***************
	*** 28,33
		longint ic, n;
		char fname [LNAME], *cp;
	  
		dir [513] . next = NULL;
		for (head = dir + (j = 513); j--; ) {
			dirp = head--;
	
	--- 37,51 -----
		char fname [LNAME], *cp;
		char quiet;
	  
	+ 	/* check for the quiet flag */
	+ 	if ( argc > 1 && strcmp( argv[1], "-q" ) == 0 ) {
	+ 		quiet = TRUE;
	+ 		--argc;
	+ 		++argv;
	+ 	} else {
	+ 		quiet = FALSE;
	+ 	}
	+ 
		dir [513] . next = NULL;
		for (head = dir + (j = 513); j--; ) {
			dirp = head--;
	***************
	*** 54,59
					if (*cp++ == '/') m = j;
				if (cp [-1] == 'C' && cp [-2] == '.') cp [-2] = 0;
				else {
					fprintf (stderr, "%s: File name must end with \".C\"\n", argv [i]);
					if (i == argc - 1) break;
					continue;
	
	--- 72,78 -----
					if (*cp++ == '/') m = j;
				if (cp [-1] == 'C' && cp [-2] == '.') cp [-2] = 0;
				else {
	+ 				saved_errno = EINVAL;
					fprintf (stderr, "%s: File name must end with \".C\"\n", argv [i]);
					if (i == argc - 1) break;
					continue;
	***************
	*** 59,64
					continue;
				}
				if (j >= (LNAME - 3) || (j - m) > MAXNAMLEN) {
					fprintf (stderr, "File name too long -- %s\n", argv [i]);
					if (i == argc - 1) break;
					continue;
	
	--- 78,84 -----
					continue;
				}
				if (j >= (LNAME - 3) || (j - m) > MAXNAMLEN) {
	+ 				saved_errno = ENAMETOOLONG;
					fprintf (stderr, "File name too long -- %s\n", argv [i]);
					if (i == argc - 1) break;
					continue;
	***************
	*** 64,69
					continue;
				}
				if ((cfp = fopen (argv [i], "r")) == NULL) {
					perror (argv [i]);
					if (i == argc - 1) break;
					continue;
	
	--- 84,90 -----
					continue;
				}
				if ((cfp = fopen (argv [i], "r")) == NULL) {
	+ 				saved_errno = (errno) ? errno : EINVAL;
					perror (argv [i]);
					if (i == argc - 1) break;
					continue;
	***************
	*** 68,74
					if (i == argc - 1) break;
					continue;
				}
	! 			if ((uncfp = fopen (fname, "w")) == NULL) {
					perror (fname);
					fclose (cfp);
					if (i == argc - 1) break;
	
	--- 89,98 -----
					if (i == argc - 1) break;
					continue;
				}
	! 			if ((uncfp = fopen (fname, "w")) == NULL ||
	! 			    fstat(fileno(cfp),&status) < 0 ||
	! 			    chmod(fname,status.st_mode & 07777) < 0) {
	! 				saved_errno = (errno) ? errno : EINVAL;
					perror (fname);
					fclose (cfp);
					if (i == argc - 1) break;
	***************
	*** 74,81
					if (i == argc - 1) break;
					continue;
				}
	- 			fstat (fileno (cfp), &status);
	- 			chmod (fname, status.st_mode & 07777);
			}
	  
			if ((c . integ = getc (cfp)) != EOF) {
	
	--- 98,103 -----
					if (i == argc - 1) break;
					continue;
				}
			}
	  
			if ((c . integ = getc (cfp)) != EOF) {
	***************
	*** 143,148
						     fprintf (stderr, "%s: ", argv [i]);
						     unlink (fname);
					     }
					     if (c . integ == PACKED) fprintf (stderr, "File is packed. Use unpack.\n");
					     else fprintf (stderr, "Not a compacted file.\n");
					     if (i >= argc) break;
	
	--- 165,171 -----
						     fprintf (stderr, "%s: ", argv [i]);
						     unlink (fname);
					     }
	+ 				     saved_errno = EINVAL;
					     if (c . integ == PACKED) fprintf (stderr, "File is packed. Use unpack.\n");
					     else fprintf (stderr, "Not a compacted file.\n");
					     if (i >= argc) break;
	***************
	*** 149,155
					     goto closeboth;
			}
	  
	! 		if (ferror (uncfp) || ferror (cfp))
				if (i < argc) {
					if (ferror (uncfp))
						perror (fname);
	
	--- 172,179 -----
					     goto closeboth;
			}
	  
	! 		if (ferror (uncfp) || ferror (cfp)) {
	! 			saved_errno = (errno) ? errno : EINVAL;
				if (i < argc) {
					if (ferror (uncfp))
						perror (fname);
	***************
	*** 159,164
					unlink (fname);
					goto closeboth;
				}
				    if (i >= argc) break;
				    fprintf (stderr, "%s uncompacted to %s\n", argv [i], fname);
				    unlink (argv [i]);
	
	--- 183,189 -----
					unlink (fname);
					goto closeboth;
				}
	+ 		}
				    if (i >= argc) break;
				    if ( quiet == FALSE ) {
					    fprintf (stderr, "%s uncompacted to %s\n", argv [i], fname);
	***************
	*** 160,166
					goto closeboth;
				}
				    if (i >= argc) break;
	! 			    fprintf (stderr, "%s uncompacted to %s\n", argv [i], fname);
				    unlink (argv [i]);
			closeboth : fclose (cfp);
			closein   : fclose (uncfp);
	
	--- 185,193 -----
				}
			}
				    if (i >= argc) break;
	! 			    if ( quiet == FALSE ) {
	! 				    fprintf (stderr, "%s uncompacted to %s\n", argv [i], fname);
	! 			    }
				    unlink (argv [i]);
			closeboth : fclose (cfp);
			closein   : fclose (uncfp);
	***************
	*** 170,173
			fail 	  : fprintf (stderr, "Unsuccessful uncompact of standard input to standard output.\n");
				    break;
		}
	  }
	
	--- 197,201 -----
			fail 	  : fprintf (stderr, "Unsuccessful uncompact of standard input to standard output.\n");
				    break;
		}
	+ 	exit(saved_errno);
	  }
	----------------------------------end of uncompact.c diff-------------

	-----------diff for the man page compact.1 (old new) below------------
	1c1
	< .TH COMPACT 1 "18 January 1983"
	---
	> .TH COMPACT 1 "22 October 1984"
	4c4
	< compact, uncompact, ccat \- compress and uncompress files, and cat them
	---
	> compact, uncompact, ccat \- compress/uncompress/cat files
	7c7
	< [ name ... ]
	---
	> [ -f ] [ -q ] [ name ... ]
	9c9
	< .B uncompact
	---
	> .B uncompact [ -q ]
	44a45,78
	> If
	> .I compact
	> is given the flag
	> .I -f
	> it will be forced to compress the file even if the resulting
	> compression results in a larger file.  This option is useful when
	> dealing with
	> .I make(1)
	> or a shell script which wants to treat compression in a uniform way.
	> By default, when the compression would result in a file larger than
	> size of the data being compressed,
	> .I compact
	> operates in one of two ways.  First, if
	> .I compact
	> being used as a filter, the data is passed through compressed.  When
	> it is working on files, they are left unmodified and the resulting
	> *.C is attempted to be removed.  In both cases an error message is produced.
	> .PP
	> The
	> .I -q
	> flag when used with
	> .I compact
	> will prevent the degree of compression report.
	> .I Compact
	> will still report when the size of data is too small for compression,
	> unless the
	> .I -f
	> flag is also given.
	> When the
	> .I -q
	> flag is used with
	> .I uncompact
	> the new file name reports are suppressed.
	> .PP
	61,62c95,96
	< The last segment of the filename must contain fewer than thirteen characters
	< to allow space for the appended '.C'.
	---
	> The last segment of the filename must contain fewer than 2 characters
	> less than the maximum filename length to allow space for the appended '.C'.
	71a106,113
	> .SH BUGS
	> Compression routines are by default noisy, the
	> .I -q
	> and
	> .I -f
	> flags were added as an option rather than the default to
	> preserve the historical method of operation.  Not all
	> systems will have these options.
	-------------------------end of compact.1 diff------------------------
-- 
    "Don't blame me, I voted for Mondale!"
				John Alton 85'