ewilts%Ins.MRC.AdhocNet.CA%Stasis.MRC.AdhocNet.CA%UNCAEDU.@CORNELLC.CCS.CORNELL.EDU.BITNET (Ed Wilts) (06/24/88)
$Part17: $ File_is="ARCUNP.C" $ Check_Sum_is=705508013 $ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY Xstatic char *RCSid = "$Header: arcunp.c,v 1.2 86/07/15 07:54:25 turner Exp $"; X X/* X * $Log:`009arcunp.c,v $ X * Hack-attack 1.3 86/12/20 01:23:45 wilhite@usceast.uucp X * `009Bludgeoned into submission for VAX 11/780 BSD4.2 X *`009(ugly code, but fewer core dumps) X * X * Revision 1.2 86/07/15 07:54:25 turner X * X * X * Revision 1.1 86/06/26 15:01:04 turner X * initial version X * X * X */ X X/* ARC - Archive utility - ARCUNP X X$define(tag,$$segment(@1,$$index(@1,=)+1))# X$define(version,Version $tag( XTED_VERSION DB =3.16), created on $tag( XTED_DATE DB =02/03/86) at $tag( XTED_TIME DB =23:01:16))# X$undefine(tag)# X $version X X(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED X X By: Thom Henderson X X Description: X This file contains the routines used to expand a file X when taking it out of an archive. X X Language: X Computer Innovations Optimizing C86 X*/ X#include <stdio.h> X#include "arc.h" X X/* stuff for repeat unpacking */ X X#define DLE 0x90 /* repeat byte flag */ X Xstatic INT state; /* repeat unpacking state */ X X/* repeat unpacking states */ X X#define NOHIST 0 /* no relevant history */ X#define INREP 1 /* sending a repeated value */ X Xstatic INT crcval; /* CRC check value */ Xstatic long size; /* bytes to read */ X XINT unpack(f,t,hdr) /* unpack an archive entry */ XFILE *f, *t; /* source, destination */ Xstruct heads *hdr; /* pointer to file header data */ X{ X INT c; /* one char of stream */ X INT putc_unp(); X INT putc_ncr(); X INT getc_unp(); X X /* setups common to all methods */ X X crcval = 0; /* reset CRC check value */ X size = hdr->size; /* set input byte counter */ X state = NOHIST; /* initial repeat unpacking state */ X setcode(); /* set up for decoding */ X X /* use whatever method is appropriate */ X X switch(hdrver) /* choose proper unpack method */ X { X case 1: /* standard packing */ X case 2: X while((c=getc_unp(f))!=EOF) X putc_unp(c,t); X break; X X case 3: /* non-repeat packing */ X while((c=getc_unp(f))!=EOF) X putc_ncr(c,t); X break; X X case 4: /* Huffman squeezing */ X init_usq(f); X while((c=getc_usq(f))!=EOF) X putc_ncr(c,t); X break; X X case 5: /* Lempel-Zev compression */ X init_ucr(0); X while((c=getc_ucr(f))!=EOF) X putc_unp(c,t); X break; X X case 6: /* Lempel-Zev plus non-repeat */ X init_ucr(0); X while((c=getc_ucr(f))!=EOF) X putc_ncr(c,t); X break; X X case 7: /* L-Z plus ncr with new hash */ X init_ucr(1); X while((c=getc_ucr(f))!=EOF) X putc_ncr(c,t); X break; X X case 8: /* dynamic Lempel-Zev */ X decomp(f,t); X break; X X case 9: X`009 sqdecomp(f,t); X`009 break; X X default: /* unknown method */ X if(warn) X { printf("I don't know how to unpack file %s\n",hdr->name); X printf("I think you need a newer version of ARC\n"); X nerrs++; X } X fseek(f,hdr->size,1); /* skip over bad file */ X return 1; /* note defective file */ X } X X /* cleanups common to all methods */ X X if((crcval&0xffff)!=(hdr->crc&0x0000ffff)) X { if(warn) X { printf("WARNING: File %s fails CRC check\n",hdr->name); X nerrs++; X } X return 1; /* note defective file */ X } X return 0; /* file is okay */ X} X X/* This routine is used to put bytes in the output file. It also X performs various housekeeping functions, such as maintaining the X CRC check value. X*/ X XINT putc_unp(c,t) /* output an unpacked byte */ Xchar c; /* byte to output */ XFILE *t; /* file to output to */ X{ X crcval = addcrc(crcval,c); /* update the CRC check value */ X putc_tst(c,t); X} X X/* This routine is used to decode non-repeat compression. Bytes are X passed one at a time in coded format, and are written out uncoded. X The data is stored normally, except that runs of more than two X characters are represented as: X X <char> <DLE> <count> X X With a special case that a count of zero indicates a DLE as data, X not as a repeat marker. X*/ X XINT putc_ncr(c,t) /* put NCR coded bytes */ Xunsigned char c; /* next byte of stream */ XFILE *t; /* file to receive data */ X{ X static INT lastc; /* last character seen */ X X switch(state) /* action depends on our state */ X { X case NOHIST: /* no previous history */ X if(c==DLE) /* if starting a series */ X state = INREP; /* then remember it next time */ X else putc_unp(lastc=c,t); /* else nothing unusual */ X return; X X case INREP: /* in a repeat */ X if(c) /* if count is nonzero */ X while(--c) /* then repeatedly ... */ X putc_unp(lastc,t); /* ... output the byte */ X else putc_unp(DLE,t); /* else output DLE as data */ X state = NOHIST; /* back to no history */ X return; X X default: X abort("Bad NCR unpacking state (%d)",state); X } X} X X/* This routine provides low-level byte input from an archive. This X routine MUST be used, as end-of-file is simulated at the end of X the archive entry. X*/ X XINT getc_unp(f) /* get a byte from an archive */ XFILE *f; /* archive file to read */ X{ X if(!size) /* if no data left */ X return EOF; /* then pretend end of file */ X X size--; /* deduct from input counter */ X return code(fgetc(f)); /* and return next decoded byte */ X} X $ GoSub Convert_File $ File_is="ARCUSQ.C" $ Check_Sum_is=85750201 $ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY Xstatic char *RCSid = "$Header: arcusq.c,v 1.2 86/07/15 07:54:30 turner Exp $"; X X/* X * $Log:`009arcusq.c,v $ X * Hack-attack 1.3 86/12/20 01:23:45 wilhite@usceast.uucp X * `009Bludgeoned into submission for VAX 11/780 BSD4.2 X *`009(ugly code, but fewer core dumps) X * X * Revision 1.2 86/07/15 07:54:30 turner X * X * X * Revision 1.1 86/06/26 15:01:07 turner X * initial version X * X * X */ X X/* ARC - Archive utility - ARCUSQ X X$define(tag,$$segment(@1,$$index(@1,=)+1))# X$define(version,Version $tag( XTED_VERSION DB =3.13), created on $tag( XTED_DATE DB =01/30/86) at $tag( XTED_TIME DB =20:11:42))# X$undefine(tag)# X $version X X(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED X X By: Thom Henderson X X Description: X This file contains the routines used to expand a file X which was packed using Huffman squeezing. X X Most of this code is taken from an USQ program by Richard X Greenlaw, which was adapted to CI-C86 by Robert J. Beilstein. X X Language: X Computer Innovations Optimizing C86 X*/ X#include <stdio.h> X#include "arc.h" X X/* stuff for Huffman unsqueezing */ X X#define ERROR (-1) X X#define SPEOF 256 /* special endfile token */ X#define NUMVALS 257 /* 256 data values plus SPEOF */ X XEXTERN struct nd /* decoding tree */ X{ INT child[2]; /* left, right */ X} node[NUMVALS]; /* use large buffer */ X Xstatic INT bpos; /* last bit position read */ Xstatic INT curin; /* last byte value read */ Xstatic INT numnodes; /* number of nodes in decode tree */ X Xstatic INT get_int(f) /* get an integer */ XFILE *f; /* file to get it from */ X{ X INT i; X X i = getc_unp(f); X return (short)(i | (getc_unp(f)<<8)); X} X XINT init_usq(f) /* initialize Huffman unsqueezing */ XFILE *f; /* file containing squeezed data */ X{ X INT i; /* node index */ X X bpos = 99; /* force initial read */ X X numnodes = get_int(f); X X if(numnodes<0 || numnodes>=NUMVALS) X abort("File has an invalid decode tree"); X X /* initialize for possible empty tree (SPEOF only) */ X X node[0].child[0] = -(SPEOF + 1); X node[0].child[1] = -(SPEOF + 1); X X for(i=0; i<numnodes; ++i) /* get decoding tree from file */ X { node[i].child[0] = get_int(f); X node[i].child[1] = get_int(f); X } X} X XINT getc_usq(f) /* get byte from squeezed file */ XFILE *f; /* file containing squeezed data */ X{ X INT i; /* tree index */ X X /* follow bit stream in tree to a leaf */ X X for(i=0; i>=0; ) /* work down(up?) from root */ X { if(++bpos>7) X { if((curin=getc_unp(f)) == ERROR) X return(ERROR); X bpos = 0; X X /* move a level deeper in tree */ X i = node[i].child[1&curin]; X } X else i = node[i].child[1 & (curin >>= 1)]; X } X X /* decode fake node index to original data value */ X X i = -(i + 1); X X /* decode special endfile token to normal EOF */ X X i = (i==SPEOF) ? EOF : i; X return i; X} X $ GoSub Convert_File $ Goto Part18