home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / archiver / compres2 / compress.c < prev    next >
C/C++ Source or Header  |  1993-07-07  |  26KB  |  621 lines

  1. /*@H************************ < COMPRESS utility> ****************************
  2. *                                                                           *
  3. *   compress : compress.c                                                   *
  4. *              Main and Operating System Independent support functions      *
  5. *                                                                           *
  6. *   port by  : Donald J. Gloistein                                          *
  7. *                                                                           *
  8. *   Source, Documentation, Object Code:                                     *
  9. *   released to Public Domain. This code is ported from compress v4.0       *
  10. *   release joe.                                                            *
  11. *---------------------------  Module Description  --------------------------*
  12. *   The compress program is compatible with the compression/decompression   *
  13. *   used on the Unix systems compress programs.  This is version 4 and      *
  14. *   supports up to 16 bits compression. The porting retained the Unix       *
  15. *   meanings of all options, added a couple for MsDos and modified the      *
  16. *   file name conventions to make more sense.                               *
  17. *                                                                           *
  18. *--------------------------- Implementation Notes --------------------------*
  19. *                                                                           *
  20. *   compiled with : compress.h compress.fns                                 *
  21. *   linked with   : compapi.obj  compusi.obj                                *
  22. *   problems:                                                               *
  23. *              See notes in compress.h for defines needed.                  *
  24. *              It should work now with Xenix                                *
  25. *                                                                           *
  26. *              Check the signal() handler functions in your compiler        *
  27. *              documentation. This code assumes ANSI SYS V compatible       *
  28. *              header and return values. Change as appropriate for your     *
  29. *              compiler and operating system.                               *
  30. *                                                                           *
  31. *              This source compiles properly with Microsoft C compiler      *
  32. *              version 5.1.                                                 *
  33. *                                                                           *
  34. *   CAUTION:   because the program is in modules, make sure you recompile   *
  35. *              all modules if you change the header or a define in the      *
  36. *              compress.c file                                              *
  37. *                                                                           *
  38. * Algorithm from "A Technique for High Performance Data Compression",       *
  39. * Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.          *
  40. *                                                                           *
  41. * Assumptions:                                                              *
  42. *  When filenames are given, replaces with the compressed version           *
  43. *  (.Z suffix) only if the file decreases in size.                          *
  44. * Algorithm:                                                                *
  45. *  Modified Lempel-Ziv method (LZW).  Basically finds common                *
  46. * substrings and replaces them with a variable size code.  This is          *
  47. * deterministic, and can be done on the fly.  Thus, the decompression       *
  48. * procedure needs no input table, but tracks the way the table was built.   *
  49. *                                                                           *
  50. *                                                                           *
  51. *---------------------------      Author(s)        -------------------------*
  52. *     Initials ---- Name ---------------------------------                  *
  53. *      DjG          Donald J. Gloistein                                     *
  54. *                   Plus many others, see rev.hst file for full list        *
  55. *      LvR          Lyle V. Rains, many thanks for improved implementation  *
  56. *************************************************************************@H*/
  57.  
  58. /*@R************************< Revision History >*****************************
  59. *                                                                           *
  60. *   version -- date -- init ---Notes----------------------                  *
  61. *    4.01    08-29-88  DjG    first cut  for 16 bit MsDos version           *
  62. *            09-04-88  DjG    fixed unlink on zcat if interupted.           *
  63. *                             added msdos filename logic and functions      *
  64. *    4.10    10-27-88  DjG  revised API with coding changes by LvR.         *
  65. *    4.10a   10-30-88  DjG  cleaned up code and fixed bug in freeing ptr.   *
  66. *    4.10b   11-01-88  DjG  cleaned up the logic for inpath/outpath         *
  67. *                           Changed the logic to finding the file name      *
  68. *                           Fixed the allocation bug in the api             *
  69. *                           Added some more portability macros              *
  70. *    4.10c   11-04-88  DjG  Changed maxcode from global to static in api.   *
  71. *                           Supplied some library functions for those who   *
  72. *                           don't have them, changed dos usi to use the     *
  73. *                           strrpbrk(). Checked casts in api again. Compiles*
  74. *                           without warnings at pick level 3.               *
  75. *    4.10d   11-25-88  DjG  revised some memory allocation, put more in the *
  76. *                           header file. Corrected some typos.              *
  77. *                           Changed prog_name() to force lower case         *
  78. *                           Corrected bug, no longer unlinks existing file  *
  79. *                           if not enough memory to compress or decompress  *
  80. *            12-06-88  DjG  VERY minor changes for casts and header defines *
  81. *            12-08-88  DjG  Adjusted path separator check in main function  *
  82. *                           Amiga uses split seg because of compiler        *
  83. *            12-09-88  DjG  Debugging done, all defaults now Unix compress  *
  84. *                           defaults, including unlinking input file and    *
  85. *                           acting as a filter. Must use -h option to get   *
  86. *                           help screen.                                    *
  87. *    4.10e   12-11-88  DjG  Fixed more casts, prototypes and header file.   *
  88. *    4.10f   12-12-88  DjG  Fixed unlinking open files on error. This fails *
  89. *                           on shared or os/2 platforms.                    *
  90. *            12-15-88  DjG  Fixed SIGTYPE for function passed to signal     *
  91. *                           Fixed problems with Xenix 2.2.1                 *
  92. *    4.2     12-19-88  DjG  Replaced adaptive reset as an option.           *
  93. *    4.3     12-26-88  DjG  Fixed long file name bug, fixed bug with        *
  94. *                           compressdir. -B option added, same as -b option *
  95. *            05-06-89  Dal  Ported to Sozobon/Alcyon C for Atari ST.  Also, *
  96. *                           created get_one() for console prompting.        *
  97. *            05-08-89  Dal  Ported to Minix-ST                              *
  98. *************************************************************************@R*/
  99.  
  100. #include <stdio.h>
  101.  
  102. #define MAIN        /* header has defining instances of globals */
  103. #include "compress.h" /* contains the rest of the include file declarations */
  104.  
  105. #define ARGVAL() (*++(*argv) || (--argc && *++argv))
  106. char suffix[] = SUFFIX ;          /* only used in this file */
  107.  
  108. void main( argc, argv )
  109. register int argc; char **argv;
  110. {
  111.     char **filelist, **fileptr,*temp;
  112.     struct stat statbuf;
  113.  
  114. #ifndef NOSIGNAL
  115.     if ( (bgnd_flag = signal ( SIGINT, SIG_IGN )) != SIG_IGN ) {
  116.         /* ANSI/SYS V compatible */
  117.         /* the following test checks for error on setting signals */
  118.         /* check your documentation on the value to test          */
  119.         /* if your signal.h doesn't support the return, it is     */
  120.         /* essentially a no-op test                               */
  121.         if (bgnd_flag == SIG_ERR){   
  122.             exit_stat = SIGNAL_ERROR;
  123.             check_error();
  124.         }
  125.         if( (signal(SIGINT,onintr) == SIG_ERR)
  126.         || (signal(SIGSEGV,oops) == SIG_ERR)) {/* check your compiler docs. */
  127.             exit_stat = SIGNAL_ERROR;
  128.             check_error();
  129.         }
  130.     }
  131. #endif
  132.  
  133.     /* set up array for files to be converted */
  134. #ifdef ALLOC
  135.     filelist = fileptr = (char **)(alloc(argc * sizeof(char *)));
  136. #else
  137. #ifdef __GNUC__
  138.     filelist = fileptr = (char **)(malloc((size_t)(argc * sizeof(char *))));
  139. #else
  140.     filelist = fileptr = (char **)(malloc(argc * sizeof(char *)));
  141. #endif
  142. #endif
  143.     *filelist = NULL;
  144.  
  145.     /* gets name, compares and sets defaults */
  146.     prog_name = get_program_name(argv[0]);
  147.  
  148.     /* now parse command line and get file list */
  149.     for (argc--, argv++; argc > 0; argc--, argv++) {
  150.         if (**argv == '-') {        /* A flag argument */
  151.             while (*++(*argv)) {    /* Process all flags in this arg */
  152.                 switch (**argv) {
  153. #if !defined(NDEBUG)
  154.                     case 'D':
  155.                         debug = TRUE;
  156.                         keep_error = TRUE;
  157.                         break;
  158.                     case 'V':
  159.                         verbose = TRUE;
  160.                         version();
  161.                         break;
  162. #else
  163.                     case 'V':
  164.                         version();
  165.                         break;
  166. #endif /*!NDEBUG */
  167.                     case 'v':
  168.                         quiet = !quiet;
  169.                         break;
  170.                     case 'd':
  171.                         do_decomp = TRUE;
  172.                         break;
  173.                     case 'f':
  174.                         force = overwrite = TRUE;
  175.                         break;
  176.                     case 'n':
  177.                         nomagic = TRUE;
  178.                         break;
  179.                     case 'C':
  180.                         block_compress = FALSE;
  181.                         break;
  182.                     case 'b': case 'B':
  183.                         if (!ARGVAL()) {
  184.                             fprintf(stderr, "Missing maxbits\n");
  185.                             Usage(1);
  186.                             exit(ERROR);
  187.                         }
  188.                         maxbits = atoi(*argv);
  189.                         goto nextarg;
  190.                     case 'I':
  191.                         if (!ARGVAL()) {
  192.                             fprintf(stderr, "Missing in_path name\n");
  193.                             Usage(1);
  194.                             exit(ERROR);
  195.                         }
  196.                         strcpy(inpath,*argv);
  197.                         temp = &inpath[strlen(inpath)-1];
  198. #ifdef MSDOS
  199.                         if (*temp != '\\' && *temp != '/')
  200. #else
  201.                         if (*temp != separator[0])
  202. #endif
  203.                             strcat(inpath,separator);
  204.                         goto nextarg;
  205.                     case 'O':
  206.                         if (!ARGVAL()){
  207.                             fprintf(stderr, "Missing out_path name\n");
  208.                             Usage(1);
  209.                             exit(ERROR);
  210.                         }
  211.                         strcpy(outpath,*argv);
  212.                         temp = &outpath[strlen(outpath)-1];
  213. #ifdef MSDOS
  214.                         if (*temp != '\\' && *temp != '/')
  215. #else
  216.                         if (*temp != separator[0])
  217. #endif
  218.                             strcat(outpath,separator);
  219.                         goto nextarg;
  220.                     case 'c':
  221.                         keep = zcat_flg = TRUE;
  222.                         break;
  223.                     case 'K':
  224.                         keep_error = TRUE;
  225.                         break;
  226.                     case 'k':
  227.                         keep = !keep;
  228.                         break;
  229.                     case '?':case 'h':case 'H':
  230.                         Usage(0);
  231.                         exit(NORMAL);
  232.                         break;
  233.                     case 'q':
  234.                         quiet = TRUE;
  235.                         break;
  236.                     default:
  237.                         fprintf(stderr, "%s : Unknown flag: '%c'\n",prog_name, **argv);
  238.                         Usage(1);
  239.                         exit(ERROR);
  240.                 } /* end switch */
  241.             } /* end while processing this argument */
  242.         }  /* end if option parameter */
  243.         else {                                  /* must be input file name */
  244.             *fileptr++ = *argv;                 /* Build input file list */
  245.             *fileptr = NULL;
  246.         } /* end else */
  247. nextarg:     continue;                          /* process nextarg */
  248.     } /* end command line processing */
  249.  
  250.     /* adjust for possible errors or conflicts */
  251.     if(maxbits < MINBITS || maxbits > MAXBITS){
  252.         fprintf(stderr,"\n%s: illegal bit value, range = %d to %d\n",prog_name,MINBITS,MAXBITS);
  253.         exit(NORMAL);
  254.     }
  255.     if (zcat_flg && *outpath)         /* can't have an out path and zcat */
  256.         *outpath = '\0';
  257.  
  258.     /* to make the error messages make sense */
  259.     strcpy(ifname,"stdin");
  260.     strcpy(ofname,"stdout");
  261.  
  262.     if (*filelist) {         /* Check if there are files specified */
  263.                              /* *fileptr must continue to specify  */
  264.                              /* command line in/out file name      */
  265.         is_list = TRUE;
  266.         for (fileptr = filelist; *fileptr; fileptr++) {
  267.             exit_stat = 0;
  268.             endchar[0] = '\0';
  269.             if (do_decomp) {                /* DECOMPRESSION          */
  270.                 if (*inpath){               /* adjust for inpath name */
  271.                     strcpy(ifname,inpath);  /* and copy into ifname   */
  272.                     strcat(ifname,name_index(*fileptr));
  273.                 }
  274.                 else
  275.                     strcpy(ifname,*fileptr);
  276.                 if(!is_z_name(ifname))         /* Check for .Z suffix    */
  277.                     if(!(make_z_name(ifname))) /* No .Z: tack one on     */
  278.                         continue;
  279.                                                /* Open input file        */
  280.                 if ((freopen(ifname, READ_FILE_TYPE, stdin)) == NULL) {
  281.                     perror(ifname);
  282.                     continue;
  283.                 }
  284.                 else
  285.                     setvbuf(stdin,zbuf,_IOFBF,ZBUFSIZE);
  286.                 if (!nomagic) {             /* Check the magic number */
  287.                     if ((getchar() != (magic_header[0] & 0xFF))
  288.                       || (getchar() != (magic_header[1] & 0xFF))) {
  289.                         fprintf(stderr, "%s: not in compressed format\n",
  290.                             *ifname);
  291.                         continue;
  292.                     }
  293.                     maxbits = getchar();    /* set -b from file */
  294.                     block_compress = maxbits & BLOCK_MASK;
  295.                     maxbits &= BIT_MASK;
  296.                     if(maxbits > MAXBITS) {
  297.                         fprintf(stderr,
  298.                         "%s: compressed with %d bits, can only handle %d bits\n",
  299.                         ifname, maxbits, MAXBITS);
  300.                         continue;
  301.                     }
  302.                 }  /* end if nomagic */
  303.                                              /* Generate output filename */
  304.                 if (*outpath){               /* adjust for outpath name */
  305.                     strcpy(ofname,outpath);  /* and copy into ofname   */
  306.                     strcat(ofname,name_index(ifname));
  307.                 }
  308.                 else
  309.                     strcpy(ofname,ifname); /* DjG may screw up the placement */
  310.                                            /* of the outfile */
  311.                 unmake_z_name(ofname);     /* strip off Z or .Z */
  312.             }
  313.             else {            /* COMPRESSION */
  314.                 if (*inpath){               /* adjust for inpath name */
  315.                     strcpy(ifname,inpath);  /* and copy into ifname   */
  316.                     strcat(ifname,name_index(*fileptr));
  317.                 }
  318.                 else
  319.                     strcpy(ifname,*fileptr);
  320.                 if (is_z_name(ifname)) {
  321.                     fprintf(stderr, "%s: already has %s suffix -- no change\n",
  322.                         ifname,suffix);
  323.                     continue;
  324.                 }
  325.                 /* Open input file */
  326.                 if ((freopen(ifname,READ_FILE_TYPE, stdin)) == NULL) {
  327.                     perror(ifname);
  328.                     continue;
  329.                 }
  330.                 else
  331.                     setvbuf(stdin,xbuf,_IOFBF,XBUFSIZE);
  332.                 /* Generate output filename */
  333.                 if (*outpath){               /* adjust for outpath name */
  334.                     strcpy(ofname,outpath);  /* and copy into ofname   */
  335.                     strcat(ofname,name_index(ifname));
  336.                 }
  337.                 else  /* place it in directory of input file */
  338.                     strcpy(ofname,ifname); /* DjG may screw up the placement */
  339.                                            /* of the outfile */
  340.                 if (!(make_z_name(ofname)))
  341.                     continue;
  342.             } /* end else compression  we now have the files set up */
  343.  
  344.             /* Check for overwrite of existing file */
  345.             if (!overwrite && !zcat_flg) {
  346.                 if (!stat(ofname, &statbuf)) {
  347.                     char response, get_one();
  348.  
  349.                     response = 'n';
  350.                     fprintf(stderr, "%s already exists;", ofname);
  351. #ifndef NOSIGNAL
  352.                     if (foreground()) {
  353. #else
  354.                     if (TRUE) {
  355. #endif
  356.                         fprintf(stderr, "\ndo you wish to overwrite %s (y or n)? ",
  357.                         ofname);
  358.                         fflush(stderr);
  359.             response = get_one();
  360.                     }
  361.                     if ((response != 'y') && (response != 'Y')) {
  362.                         fprintf(stderr, "\tnot overwritten\n");
  363.                         continue;
  364.                     }
  365.                 } /* end if stat */
  366.             } /* end if overwrite */
  367.             /* Output file  is opened in compress/decompress routines */
  368.  
  369.             /* Actually do the compression/decompression  on files */
  370.             if (!do_decomp){
  371.                 compress();
  372.                 check_error();
  373.             }
  374.             else{
  375.                 decompress();
  376.                 check_error();
  377.             }
  378.             if(!zcat_flg) {
  379.                 copystat(ifname, ofname); /* Copy stats */
  380.                 if((exit_stat ) || (!quiet))
  381.                     putc('\n', stderr);
  382.             }       /* end if zcat */
  383.         }           /*end for  loop */
  384.     }               /* end if filelist */
  385.     else {          /* it is standard input to standard output*/
  386. #if (FILTER == FALSE)     /* filter is defined as true or false */
  387.     /* DjG added to make more sense.  The following tests for standard
  388.        input being a character device. If so, there is no use in MsDos
  389.        for the program, as that will compress from the keyboard to the
  390.        console. Sure not what is needed. Instead, the usage function
  391.        is called. In Xenix/Unix systems, there is a need for this type
  392.        of pipe as the input may be from a char dev, remote station.
  393.      */
  394.  
  395.         /* check if input is unredirected */
  396.         if ( isatty(fileno(stdin)) ){
  397.             Usage(1);
  398.             exit(NORMAL);
  399.         }
  400. #endif
  401.         /* filter */
  402.         if (do_decomp){
  403.             setvbuf(stdin,zbuf,_IOFBF,ZBUFSIZE);  /* make the buffers larger */
  404.             setvbuf(stdout,xbuf,_IOFBF,XBUFSIZE);
  405.         }
  406.         else{
  407.             setvbuf(stdin,xbuf,_IOFBF,XBUFSIZE);  /* make the buffers larger */
  408.             setvbuf(stdout,zbuf,_IOFBF,ZBUFSIZE);
  409.         }
  410.         if (!do_decomp) {   /* compress stdin to stdout */
  411.             compress();
  412.             check_error();
  413.             if(!quiet)
  414.                 putc('\n', stderr);
  415.         } /* end compress stdio */
  416.         else {   /* decompress stdin to stdout */
  417.             /* Check the magic number */
  418.             if (!nomagic) {
  419.                 if ((getchar()!=(magic_header[0] & 0xFF))
  420.                  || (getchar()!=(magic_header[1] & 0xFF))) {
  421.                     fprintf(stderr, "stdin: not in compressed format\n");
  422.                     exit(ERROR);
  423.                 }
  424.                 maxbits = getchar();    /* set -b from file */
  425.                 block_compress = maxbits & BLOCK_MASK;
  426.                 maxbits &= BIT_MASK;
  427.                 if(maxbits > MAXBITS) {
  428.                     fprintf(stderr,
  429.                     "stdin: compressed with %d bits, can only handle %d bits\n",
  430.                     maxbits, MAXBITS);
  431.                     exit(ERROR);
  432.                 }
  433.             }
  434.             decompress();
  435.             check_error();
  436.         } /* end else decomp stdio */
  437.     } /* end else standard input */
  438.     exit(exit_stat);
  439. }
  440.  
  441. void Usage(flag)
  442. int flag;
  443. {
  444. static char *keep2 =  "keep";
  445. static char *keep3 =  "kill (erase)";
  446. static char *on = "on";
  447. static char *off = "off";
  448.  
  449. #ifndef NDEBUG
  450.     fprintf(stderr,"Usage: %s [-cCdDf?hkKvV][-b maxbits][-Iinpath][-Ooutpath][filenames...]\n",
  451.         prog_name);
  452. #else
  453.     fprintf(stderr,"Usage: %s [-cCdf?hkKvV][-b maxbits][-Iinpath][-Ooutpath][filenames...]\n",
  454.         prog_name);
  455. #endif
  456.     if (flag)
  457.         return;
  458.     fprintf(stderr,"Argument Processing..case is significant:\n");
  459.     fprintf(stderr,"     MUST use '-' for switch character\nAll flags are optional.\n");
  460. #ifndef NDEBUG
  461.     fprintf(stderr,"     -D => debug; Keep file on error.\n");
  462.     fprintf(stderr,"     -V => print Version; debug verbose\n");
  463. #else
  464.     fprintf(stderr,"     -V => print Version\n");
  465. #endif
  466.     fprintf(stderr,"     -d => do_decomp default = %s\n",(do_decomp)?on:off);
  467.     fprintf(stderr,"     -v => verbose default = %s\n", (quiet)?off:on);
  468.     fprintf(stderr,"     -f => force overwrite of output file default = %s\n",
  469.         (force)?on:off);
  470.     fprintf(stderr,"     -n => no header: useful to uncompress old files\n");
  471.     fprintf(stderr,"     -c => cat all output to stdout default = %s\n",
  472.         (zcat_flg)?on:off);
  473.     fprintf(stderr,"     -C => generate output compatible with compress 2.0.\n");
  474.     fprintf(stderr,"     -k => %s input file, default = %s\n",(keep)?keep3:keep2,
  475.             (keep)?keep2:keep3);
  476.     fprintf(stderr,"     -K => %s output file on error, default = %s\n",
  477.             (keep_error)?keep3:keep2,(keep_error)?keep2:keep3);
  478.     fprintf(stderr,"     -b maxbits  => default = %d bits, max = %d bits\n",maxbits,MAXBITS);
  479.     fprintf(stderr,"     -I pathname => infile path  = %s\n",inpath);
  480.     fprintf(stderr,"     -O pathname => outfile path = %s\n",outpath);
  481.     fprintf(stderr,"     -? -h => help usage.\n");
  482. }
  483.  
  484. char get_one()
  485. /*
  486.  * get a single character, with echo.
  487.  */
  488. {
  489.         char tmp[2];
  490.     int fd;
  491.  
  492. #ifdef SOZOBON
  493.     return(0x7F & getche());
  494. #endif
  495. #ifdef MSC
  496.     return(getche());
  497. #endif
  498. /*
  499.  * All previous #ifdef'ed code should return() a value.
  500.  * If no other option is available, the following is the original code.
  501.  * It not only reads from stderr (not a defined operation)
  502.  * but it does so via an explicit read() call on file descriptor 2!
  503.  * So much for portability.                    -Dal
  504.  */
  505. #if MINIX
  506.     fd = open("/dev/tty", 0);    /* open the tty directly */
  507. #else
  508.     fd = 2;                /* read from stderr */
  509. #endif
  510.         read(fd, tmp, 2);
  511.         while (tmp[1] != '\n') {
  512.                 if (read(fd, tmp+1, 1) < 0) {   /* Ack! */
  513.                         perror("stderr");
  514.                         break;
  515.                 }
  516.         }
  517.     return(tmp[0]);
  518. }
  519.  
  520. void writeerr()
  521. {
  522.     perror ( ofname );
  523.     if (!zcat_flg && !keep_error){
  524.         fclose(stdout);
  525.         unlink ( ofname );
  526.     }
  527.     exit ( 1 );
  528. }
  529.  
  530. #ifndef NOSIGNAL
  531. /*
  532.  * This routine returns 1 if we are running in the foreground and stderr
  533.  * is a tty.
  534.  */
  535. int foreground()
  536. {
  537.     if(bgnd_flag) { /* background? */
  538.         return(0);
  539.     }
  540.     else {            /* foreground */
  541.         if(isatty(2)) {     /* and stderr is a tty */
  542.             return(1);
  543.         } else {
  544.             return(0);
  545.         }
  546.     }
  547. }
  548. #endif
  549.  
  550. void prratio(stream, num, den)
  551. FILE *stream;
  552. long int num, den;
  553. {
  554.     register int q;         /* Doesn't need to be long */
  555.  
  556.     if(num > 214748L) {     /* 2147483647/10000 */
  557.         q = (int) (num / (den / 10000L));
  558.     }
  559.     else {
  560.         q = (int) (10000L * num / den);     /* Long calculations, though */
  561.     }
  562.     if (q < 0) {
  563.         putc('-', stream);
  564.         q = -q;
  565.     }
  566.     fprintf(stream, "%d.%02d%%", q / 100, q % 100);
  567. }
  568.  
  569.  
  570. int check_error()     /* returning OK continues with processing next file */
  571. {
  572.     switch(exit_stat) {
  573.   case OK:
  574.     return (OK);
  575.   case NOMEM:
  576.     if (do_decomp)
  577.         fprintf(stderr,"%s: not enough memory to decompress '%s'.\n", prog_name, ifname);
  578.     else
  579.         fprintf(stderr,"%s: not enough memory to compress '%s'.\n", prog_name, ifname);
  580.     return(OK);
  581.   case SIGNAL_ERROR:
  582.     fprintf(stderr,"%s: error setting signal interupt.\n",prog_name);
  583.     exit(ERROR);
  584.     break;
  585.   case READERR:
  586.     fprintf(stderr,"%s: read error on input '%s'.\n", prog_name, ifname);
  587.     break;
  588.   case WRITEERR:
  589.     fprintf(stderr,"%s: write error on output '%s'.\n", prog_name, ofname);
  590.     break;
  591.    case TOKTOOBIG:
  592.     fprintf(stderr,"%s: token too long in '%s'.\n", prog_name, ifname);
  593.     break;
  594.   case INFILEBAD:
  595.     fprintf(stderr, "%s: '%s' in unknown compressed format.\n", prog_name, ifname);
  596.     break;
  597.  case CODEBAD:
  598.     fprintf(stderr,"%s: file token bad in '%s'.\n", prog_name,ifname);
  599.     break;
  600.  case TABLEBAD:
  601.     fprintf(stderr,"%s: internal error -- tables corrupted.\n", prog_name);
  602.     break;
  603.   case NOTOPENED:
  604.     fprintf(stderr,"%s: could not open output file %s\n",prog_name,ofname);
  605.     exit(ERROR);
  606.     break;
  607.   case NOSAVING:
  608.     if (force)
  609.         exit_stat = OK;
  610.     return (OK);
  611.   default:
  612.     fprintf(stderr,"%s: internal error -- illegal return value = %d.\n", prog_name,exit_stat);
  613.   }
  614.   if (!zcat_flg && !keep_error){
  615.         fclose(stdout);         /* won't get here without an error */
  616.         unlink ( ofname );
  617.     }
  618.   exit(exit_stat);
  619.   return(ERROR);
  620. }
  621.