compress.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 649 行 · 第 1/2 页

C
649
字号
                        "%s: compressed with %d bits, can only handle %d bits\n",
                        ifname, maxbits, MAXBITS);
                        continue;
                    }
                }  /* end if nomagic */
                                             /* Generate output filename */
                if (*outpath){               /* adjust for outpath name */
                    strcpy(ofname,outpath);  /* and copy into ofname   */
                    strcat(ofname,name_index(ifname));
                }
                else
                    strcpy(ofname,ifname); /* DjG may screw up the placement */
                                           /* of the outfile */
                unmake_z_name(ofname);     /* strip off Z or .Z */
            }
            else {            /* COMPRESSION */
                if (*inpath){               /* adjust for inpath name */
                    strcpy(ifname,inpath);  /* and copy into ifname   */
                    strcat(ifname,name_index(*fileptr));
                }
                else
                    strcpy(ifname,*fileptr);
                if (is_z_name(ifname)) {
                    fprintf(stderr, "%s: already has %s suffix -- no change\n",
                        ifname,suffix);
                    continue;
                }
                /* Open input file */
                if ((freopen(ifname,READ_FILE_TYPE, stdin)) == NULL) {
                    perror(ifname);
                    continue;
                }
                else
                    setvbuf(stdin,xbuf,_IOFBF,XBUFSIZE);
                /* Generate output filename */
                if (*outpath){               /* adjust for outpath name */
                    strcpy(ofname,outpath);  /* and copy into ofname   */
                    strcat(ofname,name_index(ifname));
                }
                else  /* place it in directory of input file */
                    strcpy(ofname,ifname); /* DjG may screw up the placement */
                                           /* of the outfile */
                if (!(make_z_name(ofname)))
                    continue;
            } /* end else compression  we now have the files set up */

            /* Check for overwrite of existing file */
            if (!overwrite && !zcat_flg) {
                if (!stat(ofname, &statbuf)) {
                    char response, get_one();

                    response = 'n';
                    fprintf(stderr, "%s already exists;", ofname);
#ifndef NOSIGNAL
                    if (foreground()) {
#else
                    if (TRUE) {
#endif
                        fprintf(stderr, "\ndo you wish to overwrite %s (y or n)? ",
                        ofname);
                        fflush(stderr);
                        response = get_one();
                    }
                    if ((response != 'y') && (response != 'Y')) {
                        fprintf(stderr, "\tnot overwritten\n");
                        continue;
                    }
                } /* end if stat */
            } /* end if overwrite */
            /* Output file  is opened in compress/decompress routines */

            /* Actually do the compression/decompression  on files */
            if (!do_decomp){
                compress();
                check_error();
            }
            else{
                decompress();
                check_error();
            }
            if(!zcat_flg) {
                copystat(ifname, ofname); /* Copy stats */
                if((exit_stat ) || (!quiet))
                    putc('\n', stderr);
            }       /* end if zcat */
        }           /*end for  loop */
    }               /* end if filelist */
    else {          /* it is standard input to standard output*/
#if (FILTER == FALSE)     /* filter is defined as true or false */
    /* DjG added to make more sense.  The following tests for standard
       input being a character device. If so, there is no use in MsDos
       for the program, as that will compress from the keyboard to the
       console. Sure not what is needed. Instead, the usage function
       is called. In Xenix/Unix systems, there is a need for this type
       of pipe as the input may be from a char dev, remote station.
     */

        /* check if input is unredirected */
        if ( isatty(fileno(stdin)) ){
            Usage(1);
            exit(NORMAL);
        }
#endif
        /* filter */
        if (do_decomp){
            setvbuf(stdin,zbuf,_IOFBF,ZBUFSIZE);  /* make the buffers larger */
            setvbuf(stdout,xbuf,_IOFBF,XBUFSIZE);
        }
        else{
            setvbuf(stdin,xbuf,_IOFBF,XBUFSIZE);  /* make the buffers larger */
            setvbuf(stdout,zbuf,_IOFBF,ZBUFSIZE);
        }
        if (!do_decomp) {   /* compress stdin to stdout */
            compress();
            check_error();
            if(!quiet)
                putc('\n', stderr);
        } /* end compress stdio */
        else {   /* decompress stdin to stdout */
            /* Check the magic number */
            if (!nomagic) {
                if ((getchar()!=(magic_header[0] & 0xFF))
                 || (getchar()!=(magic_header[1] & 0xFF))) {
                    fprintf(stderr, "stdin: not in compressed format\n");
                    exit(ERROR);
                }
                maxbits = getchar();    /* set -b from file */
                block_compress = maxbits & BLOCK_MASK;
                maxbits &= BIT_MASK;
                if(maxbits > MAXBITS) {
                    fprintf(stderr,
                    "stdin: compressed with %d bits, can only handle %d bits\n",
                    maxbits, MAXBITS);
                    exit(ERROR);
                }
            }
            decompress();
            check_error();
        } /* end else decomp stdio */
    } /* end else standard input */
    exit(exit_stat);
}

void Usage(flag)
int flag;
{
static char *keep2 =  "keep";
static char *keep3 =  "kill (erase)";
static char *on = "on";
static char *off = "off";

#ifndef NDEBUG
    fprintf(stderr,"Usage: %s [-cCdDf?hkKvV][-b maxbits][-Iinpath][-Ooutpath][filenames...]\n",
        prog_name);
#else
    fprintf(stderr,"Usage: %s [-cCdf?hkKvV][-b maxbits][-Iinpath][-Ooutpath][filenames...]\n",
        prog_name);
#endif
    if (flag)
        return;
    fprintf(stderr,"Argument Processing..case is significant:\n");
    fprintf(stderr,"     MUST use '-' for switch character\nAll flags are optional.\n");
#ifndef NDEBUG
    fprintf(stderr,"     -D => debug; Keep file on error.\n");
    fprintf(stderr,"     -V => print Version; debug verbose\n");
#else
    fprintf(stderr,"     -V => print Version\n");
#endif
    fprintf(stderr,"     -d => do_decomp default = %s\n",(do_decomp)?on:off);
    fprintf(stderr,"     -v => verbose default = %s\n", (quiet)?off:on);
    fprintf(stderr,"     -f => force overwrite of output file default = %s\n",
        (force)?on:off);
    fprintf(stderr,"     -n => no header: useful to uncompress old files\n");
    fprintf(stderr,"     -c => cat all output to stdout default = %s\n",
        (zcat_flg)?on:off);
    fprintf(stderr,"     -C => generate output compatible with compress 2.0.\n");
    fprintf(stderr,"     -k => %s input file, default = %s\n",(keep)?keep3:keep2,
            (keep)?keep2:keep3);
    fprintf(stderr,"     -K => %s output file on error, default = %s\n",
            (keep_error)?keep3:keep2,(keep_error)?keep2:keep3);
    fprintf(stderr,"     -b maxbits  => default = %d bits, max = %d bits\n",maxbits,MAXBITS);
    fprintf(stderr,"     -I pathname => infile path  = %s\n",inpath);
    fprintf(stderr,"     -O pathname => outfile path = %s\n",outpath);
    fprintf(stderr,"     -? -h => help usage.\n");
}

char get_one()
/*
 * get a single character, with echo.
 */
{
        char tmp[2];
        int fd;

#ifdef SOZOBON
        return(0x7F & getche());
#endif
#ifdef MSC
        return(getche());
#endif
/*
 * All previous #ifdef'ed code should return() a value.
 * If no other option is available, the following is the original code.
 * It not only reads from stderr (not a defined operation)
 * but it does so via an explicit read() call on file descriptor 2!
 * So much for portability.                    -Dal
 */
#ifdef MINIX
        fd = open("/dev/tty", 0);       /* open the tty directly */
#else
        fd = 2;                         /* read from stderr */
#endif
        read(fd, tmp, 2);
        while (tmp[1] != '\n') {
                if (read(fd, tmp+1, 1) < 0) {   /* Ack! */
                        perror("stderr");
                        break;
                }
        }
        return(tmp[0]);
}

void writeerr()
{
    perror ( ofname );
    if (!zcat_flg && !keep_error){
        fclose(stdout);
        unlink ( ofname );
    }
    exit ( 1 );
}

#ifndef NOSIGNAL
/*
 * This routine returns 1 if we are running in the foreground and stderr
 * is a tty.
 */
int foreground()
{
    if(bgnd_flag) { /* background? */
        return(0);
    }
    else {            /* foreground */
        if(isatty(2)) {     /* and stderr is a tty */
            return(1);
        } else {
            return(0);
        }
    }
}
#endif

void prratio(stream, num, den)
FILE *stream;
long int num, den;
{
    register int q;         /* Doesn't need to be long */

    if(num > 214748L) {     /* 2147483647/10000 */
        q = (int) (num / (den / 10000L));
    }
    else {
        q = (int) (10000L * num / den);     /* Long calculations, though */
    }
    if (q < 0) {
        putc('-', stream);
        q = -q;
    }
    fprintf(stream, "%d.%02d%%", q / 100, q % 100);
}


int check_error()     /* returning OK continues with processing next file */
{
    switch(exit_stat) {
  case OK:
    return (OK);
  case NOMEM:
    if (do_decomp)
        fprintf(stderr,"%s: not enough memory to decompress '%s'.\n", prog_name, ifname);
    else
        fprintf(stderr,"%s: not enough memory to compress '%s'.\n", prog_name, ifname);
    return(OK);
  case SIGNAL_ERROR:
    fprintf(stderr,"%s: error setting signal interupt.\n",prog_name);
    exit(ERROR);
    break;
  case READERR:
    fprintf(stderr,"%s: read error on input '%s'.\n", prog_name, ifname);
    break;
  case WRITEERR:
    fprintf(stderr,"%s: write error on output '%s'.\n", prog_name, ofname);
    break;
   case TOKTOOBIG:
    fprintf(stderr,"%s: token too long in '%s'.\n", prog_name, ifname);
    break;
  case INFILEBAD:
    fprintf(stderr, "%s: '%s' in unknown compressed format.\n", prog_name, ifname);
    break;
 case CODEBAD:
    fprintf(stderr,"%s: file token bad in '%s'.\n", prog_name,ifname);
    break;
 case TABLEBAD:
    fprintf(stderr,"%s: internal error -- tables corrupted.\n", prog_name);
    break;
  case NOTOPENED:
    fprintf(stderr,"%s: could not open output file %s\n",prog_name,ofname);
    exit(ERROR);
    break;
  case NOSAVING:
    if (force)
        exit_stat = OK;
    return (OK);
  default:
    fprintf(stderr,"%s: internal error -- illegal return value = %d.\n", prog_name,exit_stat);
  }
  if (!zcat_flg && !keep_error){
        fclose(stdout);         /* won't get here without an error */
        unlink ( ofname );
    }
  exit(exit_stat);
  return(ERROR);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?