home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / UTILS / SQUEEZE / USQ.C < prev    next >
Text File  |  2000-06-30  |  7KB  |  269 lines

  1. /* Program to unsqueeze files formed by sq.com
  2.  *
  3.  * Useage:
  4.  *
  5.  *    usq [-count] [-fcount] [file1] [file2] ... [filen]
  6.  *
  7.  * where file1 through filen represent one or more files to be compressed,
  8.  * and the following options may be specified:
  9.  *
  10.  *    -count        Previewing feature: redirects output
  11.  *             files to standard output with parity stripped
  12.  *            and unprintables except CR, LF, TAB and  FF
  13.  *            converted to periods. Limits each file
  14.  *            to first count lines.
  15.  *            Defaults to console, but see below how
  16.  *            to capture all in one file for further
  17.  *            processing, such as by PIP.
  18.  *            Count defaults to a very high value.
  19.  *            No CRC check is performed when previewing.
  20.  *            Use drive: to cancel this.
  21.  *
  22.  *    -fcount        Same as -count except formfeed
  23.  *            appended to preview of each file.
  24.  *            Example: -f10.
  25.  *
  26.  * If no such items are given on the command line you will be
  27.  * prompted for commands (one at a time). An empty command
  28.  * terminates the program.
  29.  *
  30.  * The unsqueezed file name is recorded in the squeezed file.
  31.  * 
  32.  */
  33. /* CHANGE HISTORY:
  34.  * 1.3    Close inbuff to avoid exceeding maximum number of
  35.  *    open files. Includes rearranging error exits.
  36.  * 1.4    Add -count option to allow quick inspection of files.
  37.  * 1.5  Break up long lines of introductory text
  38.  * 1.5  -count no longer appends formfeed to preview of each file.
  39.  *    -fcount (-f10, -F10) does append formfeed.
  40.  * 1.6  Modified to work correctly under MP/M II (DIO.C change) and
  41.  *      signon message shortened.
  42.  * 2.0    Modified to work with CI-C86 compiler (CP/M-86 and MS-DOS)
  43.  * 2.1  Modified for use in MLINK
  44.  * 2.2  Modified for use with optimizing CI-C86 compiler (MS-DOS)
  45.  * 3.0  Generalized for use under UNIX
  46.  */
  47.  
  48. /* eject eject */
  49.  
  50. #define SQMAIN
  51.  
  52. #include <stdio.h>
  53. #include "sqcom.h"
  54. #include "usq.h"
  55. #define VERSION "3.1   12/19/84"
  56.  
  57. /* This must follow all include files */
  58. unsigned int dispcnt;    /* How much of each file to preview */
  59. char    ffflag;        /* should formfeed separate preview from different files */
  60.  
  61. main(argc, argv)
  62. int argc;
  63. char *argv[];
  64. {
  65.     int i,c;
  66.     char inparg[16];    /* parameter from input */
  67.  
  68.     dispcnt = 0;    /* Not in preview mode */
  69.  
  70.     printf("File unsqueezer version %s (original author: R. Greenlaw)\n\n", VERSION);
  71.  
  72.     /* Process the parameters in order */
  73.     for(i = 1; i < argc; ++i)
  74.         obey(argv[i]);
  75.  
  76.     if(argc < 2) {
  77.         printf("Enter file names, one line at a time, or type <RETURN> to quit.");
  78.         do {
  79.             printf("\n*");
  80.             for(i = 0; i < 16; ++i) {
  81.                 if((c = getchar()) == EOF)
  82.                     c = '\n';    /* force empty (exit) command */
  83.                 if((inparg[i] = c) == '\n') {
  84.                     inparg[i] = '\0';
  85.                     break;
  86.                 }
  87.             }
  88.             if(inparg[0] != '\0')
  89.                 obey(inparg);
  90.         } while(inparg[0] != '\0');
  91.     }
  92. }
  93.  
  94. /* eject eject */
  95.  
  96. obey(p)
  97. char *p;
  98. {
  99.     char *q, cc;
  100.  
  101.     if(*p == '-') {
  102.         if(ffflag = ((*(p+1) == 'F') || (*(p+1) == 'f')))
  103.             ++p;
  104.         /* Set number of lines of each file to view */
  105.         dispcnt = 65535;    /* default */
  106.         if(*(p+1))
  107.             if((dispcnt = atoi(p + 1)) == 0)
  108.                 printf("\nBAD COUNT %s", p + 1);
  109.         return;
  110.     }    
  111.  
  112.     /* Check for ambiguous (wild-card) name */
  113.     for(q = p; *q != '\0'; ++q)
  114.         if(*q == '*' || *q == '?') {
  115.             printf("\nCan't accept ambiguous name %s", p);
  116.             return;
  117.         }
  118.  
  119.     unsqueeze(p);
  120. }
  121.  
  122. /* eject eject */
  123.  
  124. unsqueeze(infile)
  125. char *infile;
  126. {
  127.     FILE *inbuff, *outbuff;    /* file buffers */
  128.     int i, c;
  129.     char cc;
  130.  
  131.     char *p;
  132.     unsigned int filecrc;    /* checksum */
  133.     int numnodes;        /* size of decoding tree */
  134.     char outfile[128];    /* output file name */
  135.     unsigned int linect;    /* count of number of lines previewed */
  136.     char obuf[128];        /* output buffer */
  137.     int oblen;        /* length of output buffer */
  138.     static char errmsg[] = "ERROR - write failure in %s\n";
  139.  
  140.     if(!(inbuff=fopen(infile, "rb"))) {
  141.         printf("Can't open %s\n", infile);
  142.         return;
  143.     }
  144.     /* Initialization */
  145.     linect = 0;
  146.     crc = 0;
  147.     init_cr();
  148.     init_huff();
  149.  
  150.     /* Process header */
  151.     if(getx16(inbuff) != RECOGNIZE) {
  152.         printf("%s is not a squeezed file\n", infile);
  153.         goto closein;
  154.     }
  155.  
  156.     filecrc = getw16(inbuff);
  157.  
  158.     /* Get original file name */
  159.     p = outfile;            /* send it to array */
  160.     do {
  161.         *p = getc(inbuff);
  162.     } while(*p++ != '\0');
  163.  
  164.     printf("%s -> %s: ", infile, outfile);
  165.  
  166.  
  167.     numnodes = getw16(inbuff);
  168.  
  169.     if(numnodes < 0 || numnodes >= NUMVALS) {
  170.         printf("%s has invalid decode tree size\n", infile);
  171.         goto closein;
  172.     }
  173.  
  174.     /* Initialize for possible empty tree (SPEOF only) */
  175.     dnode[0].children[0] = -(SPEOF + 1);
  176.     dnode[0].children[1] = -(SPEOF + 1);
  177.  
  178.     /* Get decoding tree from file */
  179.     for(i = 0; i < numnodes; ++i) {
  180.         dnode[i].children[0] = getw16(inbuff);
  181.         dnode[i].children[1] = getw16(inbuff);
  182.     }
  183.  
  184.     if(dispcnt) {
  185.         /* Use standard output for previewing */
  186.         putchar('\n');
  187.         while(((c = getcr(inbuff)) != EOF) && (linect < dispcnt)) {
  188.             cc = 0x7f & c;    /* strip parity */
  189.             if((cc < ' ') || (cc > '~'))
  190.                 /* Unprintable */
  191.                 switch(cc) {
  192.                 case '\r':    /* return */
  193.                     /* newline will generate CR-LF */
  194.                     goto next;
  195.                 case '\n':    /* newline */
  196.                     ++linect;
  197.                 case '\f':    /* formfeed */
  198.                 case '\t':    /* tab */
  199.                     break;
  200.                 default:
  201.                     cc = '.';
  202.                 }
  203.             putchar(cc);
  204.         next: ;
  205.         }
  206.         if(ffflag)
  207.             putchar('\f');    /* formfeed */
  208.     } else {
  209.         /* Create output file */
  210.         if(!(outbuff=fopen(outfile, "wb"))) {
  211.             printf("Can't create %s\n", outfile);
  212.             goto closeall;
  213.         }
  214.         printf("unsqueezing,");
  215.         /* Get translated output bytes and write file */
  216.         oblen = 0;
  217.         while((c = getcr(inbuff)) != EOF) {
  218.             crc += c;
  219.             obuf[oblen++] = c;
  220.             if (oblen >= sizeof(obuf)) {
  221.                 if(!fwrite(obuf, sizeof(obuf), 1, outbuff)) {
  222.                     printf(errmsg, outfile);
  223.                     goto closeall;
  224.                 }
  225.                 oblen = 0;
  226.             }
  227.         }
  228.         if (oblen && !fwrite(obuf, oblen, 1, outbuff)) {
  229.             printf(errmsg, outfile);
  230.             goto closeall;
  231.         }
  232.  
  233.         if((filecrc && 0xFFFF) != (crc && 0xFFFF))
  234.             printf("ERROR - checksum error in %s\n", outfile);
  235.         else    printf(" done.\n");
  236.  
  237.     closeall:
  238.         fclose(outbuff);
  239.     }
  240.  
  241. closein:
  242.     fclose(inbuff);
  243. }
  244.  
  245. getw16(iob)            /* get 16-bit word from file */
  246. FILE *iob;
  247. {
  248. int temp;
  249.  
  250. temp = getc(iob);        /* get low order byte */
  251. temp |= getc(iob) << 8;
  252. if (temp & 0x8000) temp |= (~0) << 15;    /* propogate sign for big ints */
  253. return temp;
  254.  
  255. }
  256.  
  257.  
  258. getx16(iob)            /* get 16-bit (unsigned) word from file */
  259. FILE *iob;
  260. {
  261. int temp;
  262.  
  263. temp = getc(iob);        /* get low order byte */
  264. return temp | (getc(iob) << 8);
  265.  
  266. }
  267.  
  268.  
  269.