home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
misc
/
volume28
/
cfx
/
part01
next >
Wrap
Text File
|
1992-02-02
|
42KB
|
1,635 lines
Newsgroups: comp.sources.misc
From: carson@sputnik.uucp (Carson Wilson)
Subject: v28i012: cfx - Cp/m File eXpress, v1.1.0, Part01/02
Message-ID: <csm-v28i012=cfx.210051@sparky.IMD.Sterling.COM>
X-Md4-Signature: fbd4d82cb546e57bd5451d1f7690c52a
Date: Mon, 3 Feb 1992 03:01:33 GMT
Approved: kent@sparky.imd.sterling.com
Submitted-by: carson@sputnik.uucp (Carson Wilson)
Posting-number: Volume 28, Issue 12
Archive-name: cfx/part01
Environment: UNIX, MS-DOS, PC
CFX is a universal utility written in the C programming
language, whose main purpose in life is to make access to files
stored under the CP/M operating system accessible to users of
other operating systems. CFX may be freely used and distributed
for nonprofit purposes.
CFX will extract to screen or disk normal, squeezed (typical
CP/M filename extension, .?Q?), crunched (.?Z?), CrLZH (.?Y?),
and library (.LBR) files. It will also display library file
directory information and embedded compressed file datestamps
and comments. CFX is an interactive, integrated utility, and as
such can prompt the user before displaying files, page the
screen, etc.
This design choice permits CFX to preserve embedded names in
compressed files and allows use with secure remote systems. One
drawback of this choice is that CFX cannot easily be used as
part of a Unix pipeline (e.g., to send CP/M text files through
your favorite pager). This may be addressed in future versions.
--
CFX should compile under most operating systems. It has been
tested under the following systems:
ISC Unix SVR3.2, version 2.2.1
MSDOS Turbo C, version 2.01
To compile under Unix, edit the Makefile, optionally inspect
cfx.h, and type
"make" to build cfx
"make install" to place the executable in the proper
location
"make clean" to remove compiler output files
To compile under MSDOS, copy MAKEFILE.TC to MAKEFILE first.
--
Documentation is in cfx.1, cfx.man, and cfx.doc.
For a short usage message, type "cfx" at your command prompt.
--
Bug fixes, bug reports, and requests welcome to:
Carson Wilson
1359 W. Greenleaf, #1D
Chicago, IL 60626
UUCP: carson@sputnik.uucp
..!uunet!ddsw1!carson
BBS: Antelope Freeway, 1-708-455-0120
--
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 1 (of 2)."
# Contents: MANIFEST Makefile README lbr.c lzh.c makefile.tc
# patchlev.h unc.c unixfunc.c usq.c
# Wrapped by carson@sputnik on Sat Jan 25 10:39:40 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'MANIFEST' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(125 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
MANIFEST
Makefile
README
cfx.1
cfx.c
cfx.doc
cfx.h
cfx.hst
cfx.man
lbr.c
lzh.c
makefile.tc
patchlev.h
unc.c
unixfunc.c
usq.c
END_OF_FILE
if test 125 -ne `wc -c <'MANIFEST'`; then
echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(740 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#
X# Unix Makefile for CP/M File eXpress
X# Copyright 20 Jan 1992 by
X# Carson Wilson
X# 1359 W. Greenleaf, #1D
X# Chicago, IL 60626
X#
X# UUCP: carson@sputnik.uucp
X# ..!uunet!ddsw1!carson
X#
X# BBS: Antelope Freeway, 1-708-455-0120
X#
X# Name and path of C compiler:
CC = cc
X
X#CFLAGS = -g
CFLAGS =
X
BINDIR = /usr/local/bin
X
X.c.o :
X $(CC) $(CFLAGS) -DUNIX -c $<
X
cfx : cfx.o lbr.o unc.o usq.o lzh.o unixfunc.o
X $(CC) $(CFLAGS) -o cfx cfx.o lbr.o unc.o usq.o lzh.o unixfunc.o
X
lint :
X lint -DUNIX -u "cfx.c lbr.c unc.c usq.c lzh.c unixfunc.c"
X
install :
X mv cfx $(BINDIR)
X
clean :
X rm cfx.o lbr.o unc.o usq.o lzh.o unixfunc.o
X
cfx.o : cfx.c cfx.h
lbr.o : lbr.c cfx.h
unc.o : unc.c cfx.h
usq.o : usq.c cfx.h
lzh.o : lzh.c cfx.h
unixfunc.o : unixfunc.c
END_OF_FILE
if test 740 -ne `wc -c <'Makefile'`; then
echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(1855 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
README file for CFX - CP/M File eXpress
X
Copyright 20 Jan 1992 by Carson Wilson
X--
CFX is a universal utility written in the C programming
language, whose main purpose in life is to make access to files
stored under the CP/M operating system accessible to users of
other operating systems. CFX may be freely used and distributed
for nonprofit purposes.
X
CFX will extract to screen or disk normal, squeezed (typical
CP/M filename extension, .?Q?), crunched (.?Z?), CrLZH (.?Y?),
and library (.LBR) files. It will also display library file
directory information and embedded compressed file datestamps
and comments. CFX is an interactive, integrated utility, and as
such can prompt the user before displaying files, page the
screen, etc.
X
This design choice permits CFX to preserve embedded names in
compressed files and allows use with secure remote systems. One
drawback of this choice is that CFX cannot easily be used as
part of a Unix pipeline (e.g., to send CP/M text files through
your favorite pager). This may be addressed in future versions.
X--
CFX should compile under most operating systems. It has been
tested under the following systems:
X
ISC Unix SVR3.2, version 2.2.1
MSDOS Turbo C, version 2.01
X
To compile under Unix, edit the Makefile, optionally inspect
cfx.h, and type
X
X "make" to build cfx
X
X "make install" to place the executable in the proper
X location
X
X "make clean" to remove compiler output files
X
To compile under MSDOS, copy MAKEFILE.TC to MAKEFILE first.
X--
Documentation is in cfx.1, cfx.man, and cfx.doc.
X
XFor a short usage message, type "cfx" at your command prompt.
X--
Bug fixes, bug reports, and requests welcome to:
X
Carson Wilson
X1359 W. Greenleaf, #1D
Chicago, IL 60626
X
UUCP: carson@sputnik.uucp
X ..!uunet!ddsw1!carson
X
BBS: Antelope Freeway, 1-708-455-0120
X
END_OF_FILE
if test 1855 -ne `wc -c <'README'`; then
echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'lbr.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lbr.c'\"
else
echo shar: Extracting \"'lbr.c'\" \(3403 characters\)
sed "s/^X//" >'lbr.c' <<'END_OF_FILE'
X/*
LBR.C - CP/M library file module of CP/M File eXpress
Copyright 20 Jan 1992 by
Carson Wilson
X1359 W. Greenleaf, #1D
Chicago, IL 60626
X
UUCP: carson@sputnik.uucp
X ..!uunet!ddsw1!carson
X
BBS: Antelope Freeway, 1-708-455-0120
X
Notes:
X Novosielski format library utility module
X Notes: Doesn't do any datestamp processing.
X Assumes short int is 2 bytes long.
X*/
X
X#include "cfx.h"
X
X/* -------------------------------------------------------- */
X
void blankout(textstring, arraysize)
char *textstring;
int arraysize;
X{
X int slength;
X slength = strlen(textstring);
X
X while (slength < arraysize)
X {
X *(textstring + slength) = ' ';
X slength++;
X }
X *(textstring + arraysize - 1) = '\0';
X}
X/* -------------------------------------------------------- */
X
int getentry(gefile, lbrentry)
XFILE *gefile;
struct direntry *lbrentry;
X{
X int rresult;
X rresult = fread(lbrentry, sizeof(*lbrentry), 1, gefile);
X return (rresult && (lbrentry->status == 0));
X}
X/* -------------------------------------------------------- */
X
int wildfnmatch(wildname, name, wildext, ext)
char *wildname, *name, *wildext, *ext;
X{
X int position;
X
X /* test names */
X for (position = 1;
X ((*wildname != '*') && (position < 9));
X position++, wildname++, name++)
X if ((*wildname != '?') && (*wildname != *name))
X return 0; /* nonmatch */
X
X /* test extents */
X for (position = 1;
X ((*wildext != '*') && (position < 4));
X position++, wildext++, ext++)
X if ((*wildext != '?') && (*wildext != *ext))
X return 0; /* nonmatch */
X
X return (1);
X}
X/* -------------------------------------------------------- */
X
void lbr(lufd)
XFILE *lufd;
X{
X char procname[13];
X int lbrents, tlbrents;
X long lbrmarker, lbrmarker1;
X FILE *randfd;
X char matchwork[40]; /* for destructive strtok() */
X
X char matchname[9], matchext[4];
X char *matchptr;
X char tempname[9], tempext[4];
X struct direntry DCEntry, workentry;
X
X lbrmarker = ftell(lufd);
X if ((fread(&DCEntry, sizeof(DCEntry), 1, lufd)) < 1)
X { cerror("zero length library file; abort!");
X return;
X }
X lbrmarker1 = ftell(lufd);
X lbrents = DCEntry.length * 4; /* 4 entries per sector */
X
X randfd = fopen(infname, "rb"); /* open a spare */
X if (strlen(membername)) /* member specified */
X { strcpy(matchwork, membername);
X matchptr = matchwork;
X strcpy(matchname, strtok(matchptr, ". "));
X matchptr = NULLCHARPTR; /* initialize */
X strcpy(matchext, strtok(matchptr, ". "));
X blankout(&matchname[0], 9);
X blankout(&matchext[0], 4);
X stupcase(matchname);
X stupcase(matchext);
X }
X
X if (!brief)
X infoflag = 1; /* just show info first */
X rescan:
X tlbrents = lbrents;
X while (--tlbrents)
X if (getentry(lufd, &workentry))
X { memcpy(tempname, workentry.name, 8);
X memcpy(tempext, workentry.ext, 3);
X tempname[8] = tempext[3] = '\0';
X strcpy(procname, tempname);
X strcat(procname, ".");
X strcat(procname, tempext);
X if (!strlen(membername) ||
X wildfnmatch(matchname, tempname, matchext, tempext))
X { /* seek to member location */
X xferndate(workentry.credate, workentry.moddate);
X fseek (randfd, (workentry.index * 128L) + lbrmarker, SEEK_SET);
X mlength = workentry.length * 128;
X /* use recursion to process member */
X process(randfd, procname, mlength);
X }
X }
X if (infoflag && !info) /* info shown; now do members */
X { infoflag = 0;
X fseek (lufd, lbrmarker1, SEEK_SET);
X outcrlf(1);
X goto rescan;
X }
X fclose(randfd);
X}
X/* End of LBR.C */
END_OF_FILE
if test 3403 -ne `wc -c <'lbr.c'`; then
echo shar: \"'lbr.c'\" unpacked with wrong size!
fi
# end of 'lbr.c'
fi
if test -f 'lzh.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'lzh.c'\"
else
echo shar: Extracting \"'lzh.c'\" \(10331 characters\)
sed "s/^X//" >'lzh.c' <<'END_OF_FILE'
X/*
LZH.C - .LZH file module of CP/M File eXpress
Copyright 20 Jan 1992 by
Carson Wilson
X1359 W. Greenleaf, #1D
Chicago, IL 60626
X
UUCP: carson@sputnik.uucp
X ..!uunet!ddsw1!carson
X
BBS: Antelope Freeway, 1-708-455-0120
X
Notes:
X This module is based on the UNLZH.C code distributed with
X LZH21SRC.LBR by R. Warren, included by his permission.
X*/
X
X#include "cfx.h"
X
X/* -------- COMPILER/IMPLEMENTATION DEPENDENT ---------- */
X
X#define ID1 0x76
X#define ID2 0xFD
X
typedef unsigned char uchar;
X
uchar lgetbuf;
unsigned vbits, vmask, vshift;
char flag_checksum;
X
X/*----------------------- LZSS Parameters ----------------------------- */
X
X/* Size of string buffer */
X#define N 2048
X
X/* Size of look-ahead buffer */
X#define F 60
X
X#define THRESHOLD 2
X
X/* End of tree's node */
X#define NIL N
X
uchar text_buf[N];
X
X/*------------------ Huffman coding parameters ----------------------------*/
X
X/* Number of Special Characters */
X#define NUMSPEC 1
X
X/* EOF code (special character) */
X#define EOF_CODE 256
X
X/* character code (= 0..N_CHAR-1) */
X#define N_CHAR (256 + NUMSPEC + F - THRESHOLD )
X
X/* Size of table */
X#define T (N_CHAR * 2 - 1)
X
X/* root position */
X#define R (T - 1)
X
X/* update when cumulative frequency */
X/* reaches to this value */
X#define MAX_FREQ 0x8000
X
unsigned freq[T + 1]; /* cumulative freq table */
X
X/*
X * pointing parent nodes.
X * area [T..(T + N_CHAR - 1)] are pointers for leaves
X */
int prnt[T + N_CHAR];
X
X/* pointing children nodes (son[], son[] + 1)*/
int son[T];
X
X/* decoder table */
uchar d_code[256] = {
X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
X 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
X 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
X 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
X 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
X 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
X 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
X 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
X 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
X 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
X 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
X 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
X 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
X 0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
X 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
X 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
X 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
X 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
X 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
X 0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
X 0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
X 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
X 0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
X 0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
X 0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
X 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
X 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
X};
X
uchar d_len[256] = {
X 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
X 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
X 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
X 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
X 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
X 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
X 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
X 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
X 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
X 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
X 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
X 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
X 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
X 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
X 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
X 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
X 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
X 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
X 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
X 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
X 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
X 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
X 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
X 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
X};
X/* ======================= CODE BEGINS ========================= */
X
void lputc(c, stream)
int c;
XFILE *stream;
X{
X output(c, stream);
X cksum += (unsigned) c;
X}
X/* ---------------------------------------------------------------- */
X
unsigned GetBit(infile)
XFILE *infile;
X{
X unsigned c;
X if (lgetbuf == 0x80)
X c = (unsigned) (cgetc(infile) << 1) | 0x1;
X else
X c = ((unsigned) lgetbuf) << 1;
X lgetbuf = (uchar) c;
X
X if (feof(infile))
X { cerror("unexpected EOF on input file.");
X contin = 0;
X }
X return ((c & 0x100) ? 1 : 0);
X}
X/* ---------------------------------------------------------------- */
X
unsigned GetByte(infile)
XFILE *infile;
X{
X char i;
X unsigned temp;
X
X for (i = 8, temp = 0 ; i ; i--)
X temp = (temp <<1) | GetBit(infile);
X return(temp);
X}
X/* ---------------------------------------------------------------- */
X
void StartHuff() /* initialize freq tree */
X{
X int i, j;
X
X for (i = 0; i < N_CHAR; i++) {
X freq[i] = 1;
X son[i] = i + T;
X prnt[i + T] = i;
X }
X i = 0; j = N_CHAR;
X while (j <= R) {
X freq[j] = freq[i] + freq[i + 1];
X son[j] = i;
X prnt[i] = prnt[i + 1] = j;
X i += 2; j++;
X }
X freq[T] = 0xffff;
X prnt[R] = 0;
X}
X/* ---------------------------------------------------------------- */
X
void reconst() /* reconstruct freq tree */
X{
X int i, j, k;
X unsigned f, l;
X
X /* halven cumulative freq for leaf nodes */
X j = 0;
X for (i = 0; i < T; i++)
X { if (son[i] >= T)
X { freq[j] = (freq[i] + 1) / 2;
X son[j] = son[i];
X j++;
X }
X }
X
X /* make a tree : first, connect child nodes */
X for (i = 0, j = N_CHAR; j < T; i += 2, j++)
X { k = i + 1;
X f = freq[j] = freq[i] + freq[k];
X for (k = j - 1; f < freq[k]; k--);
X k++;
X
X for (l=j; l != k ; l--)
X { freq[l] = freq[l-1];
X son[l] = son[l-1];
X }
X freq[k] = f;
X son[k] = i;
X }
X
X /* connect parent nodes */
X for (i = 0; i < T; i++)
X { if ((k = son[i]) >= T)
X prnt[k] = i;
X else
X prnt[k] = prnt[k + 1] = i;
X }
X}
X/* ---------------------------------------------------------------- */
X
void update(c) /* update freq tree */
int c;
X{
X int i, j, k, l;
X
X if (freq[R] == MAX_FREQ) {
X reconst();
X }
X c = prnt[c + T];
X do {
X k = ++freq[c];
X
X /* swap nodes to keep the tree freq-ordered */
X if (k > freq[l = c + 1])
X { while (k > freq[++l]);
X l--;
X freq[c] = freq[l];
X freq[l] = k;
X
X i = son[c];
X prnt[i] = l;
X if (i < T)
X prnt[i + 1] = l;
X
X j = son[l];
X son[l] = i;
X
X prnt[j] = c;
X if (j < T)
X prnt[j + 1] = c;
X son[c] = j;
X
X c = l;
X }
X } while ((c = prnt[c]) != 0); /* do it until reaching the root */
X}
X/* ---------------------------------------------------------------- */
X
unsigned DecodeChar(infile)
XFILE *infile;
X{
X unsigned c;
X
X c = son[R];
X
X /*
X * start searching tree from the root to leaves.
X * choose node #(son[]) if input bit == 0
X * else choose #(son[]+1) (input bit == 1)
X */
X while (c < T)
X { c += GetBit(infile);
X c = son[c];
X }
X c -= T;
X update(c);
X return c;
X}
X/* ---------------------------------------------------------------- */
X
unsigned DecodePosition(infile)
XFILE *infile;
X{
X unsigned i, j, c;
X
X /* decode upper 6 bits from given table */
X i = GetByte(infile);
X c = (unsigned) d_code[i] << vshift;
X j = d_len[i];
X
X /* input lower 6 bits directly */
X j -= vbits;
X while (j--)
X i = (i << 1) + GetBit(infile);
X return c | (i & vmask);
X}
X/* ---------------------------------------------------------------- */
X
void Decode(infile) /* Decoding/Uncompressing */
XFILE *infile;
X{
X int i, j, k, r, c;
X
X lgetbuf = 0x80; /* prime input engine */
X StartHuff();
X for (i = 0; i < N - F; i++)
X text_buf[i] = ' ';
X r = N - F;
X while ((c = DecodeChar(infile)) != EOF_CODE && (contin))
X { if (c < 256)
X { lputc(c, outfd);
X text_buf[r++] = c;
X r &= (N - 1);
X }
X else
X { i = (r - DecodePosition(infile) - 1) & (N - 1);
X j = c - 255-NUMSPEC + THRESHOLD;
X for (k = 0; k < j; k++)
X { c = text_buf[(i + k) & (N - 1)];
X lputc(c, outfd);
X text_buf[r++] = c;
X r &= (N - 1);
X }
X }
X }
X}
X/* ---------------------------------------------------------------- */
X/*
X Un-LZH a single file.
X*/
void unlzh(lzhfd, lzhfn, lzhfs)
XFILE *lzhfd;
char *lzhfn;
long lzhfs;
X{
X char *p;
X char outfn[80]; /* space to build output file name */
X
X uchar version;
X int i;
X unsigned hold_check;
X
X /* Extract and build output file name */
X
X cgetc(lzhfd); /* skip signature */
X cgetc(lzhfd);
X
X for ( p = outfn; (*p = (cgetc(lzhfd) & 0x7F)) != '\0' ; p++)
X {
X if (*p == '[') /* comment separator */
X {
X *p = ' ';
X *++p = '[';
X }
X else if (*p == 1) /* DateStamper separator */
X *p = '\0';
X }
X
X outcrlf(1);
X printf(" --> %s", outfn);
X
X *(cisubstr(outfn, ".") + 4) = '\0'; /* truncate non-name portion */
X if (diskout)
X {
X#ifdef UNIX
X unixfn(outfn);
X printf(" (%s)", outfn);
X#endif
X /* Open output file */
X if ( 0 == (outfd = fopen( outfn, "wb")) )
X { cerror("can't create %s!", outfn);
X return;
X }
X }
X else
X outcrlf(2);
X
X cgetc(lzhfd); /* Encoder version */
X
X if ((version = cgetc(lzhfd)) == 0x20) /* Significant version */
X { vbits = 3;
X vmask = 0x1F;
X vshift= 5;
X }
X else if (version < 0x20)
X { vbits = 2;
X vmask = 0x3F;
X vshift= 6;
X }
X else
X { outcrlf(1);
X cerror("needs newer LZH revision");
X return;
X }
X
X flag_checksum = (uchar) cgetc(lzhfd); /* Check Type */
X cgetc(lzhfd); /* Filler */
X outreccount = 0;
X
X Decode(lzhfd); /* Extract file to screen/disk */
X if (contin == 0)
X return; /* quit now if input error */
X
X /* Test checksum */
X if (flag_checksum == 0 ) /* Only handle CHECKSUM type == 0 */
X for (i = 0, hold_check = cksum; i++ < 2 ; hold_check >>= 8)
X if ((unsigned) cgetc(lzhfd) != (hold_check & 0xFF))
X cerror("checksum error");
X}
X/* End of LZH.C */
END_OF_FILE
if test 10331 -ne `wc -c <'lzh.c'`; then
echo shar: \"'lzh.c'\" unpacked with wrong size!
fi
# end of 'lzh.c'
fi
if test -f 'makefile.tc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'makefile.tc'\"
else
echo shar: Extracting \"'makefile.tc'\" \(1099 characters\)
sed "s/^X//" >'makefile.tc' <<'END_OF_FILE'
X#
X# Turbo C Makefile for CP/M File eXpress
X# Copyright 15 Dec 1991 by
X# Carson Wilson
X# 1359 W. Greenleaf, #1D
X# Chicago, IL 60626
X#
X# UUCP: carson@sputnik.uucp
X# carson@ddsw1.MCS.COM
X#
X# BBS: Antelope Freeway, 1-708-455-0120
X#
X# Name and path of C compiler:
CC = tcc
X
X# Turbo C's home directory (also where WILDARGS.OBJ is)
THOME = \DOS\TC
X
MDL = s
X
CFLAGS = -d- -y- -G -k- -N- -C- -A- -O -Z
INCLUDES = $(THOME)\INCLUDE
X
TLINK = tlink
TLFLAGS = /c /x
LIBS = $(THOME)\LIB
X
X# Where to put compiled CFX.EXE
BINDIR = \DOS
X
X.c.obj :
X $(CC) $(CFLAGS) -I$(INCLUDES) -c -m$(MDL) $<
X
cfx.exe : cfx.obj lbr.obj unc.obj usq.obj lzh.obj getopt.obj \
X $(THOME)\wildargs.obj
X $(TLINK) $(TLFLAGS) $(LIBS)\c0$(MDL) \
X cfx lbr unc usq lzh getopt $(THOME)\wildargs.obj, \
X cfx, cfx, $(LIBS)\c$(MDL)
X
install :
X copy cfx.exe $(BINDIR)
X del cfx.exe
X
clean :
X del cfx.exe
X del cfx.obj
X del lbr.obj
X del unc.obj
X del usq.obj
X del lzh.obj
X del getopt.obj
X
cfx.obj : cfx.c cfx.h
lbr.obj : lbr.c cfx.h
unc.obj : unc.c cfx.h
usq.obj : usq.c cfx.h
lzh.obj : lzh.c cfx.h
getopt.obj : getopt.c # proprietary Borland code
END_OF_FILE
if test 1099 -ne `wc -c <'makefile.tc'`; then
echo shar: \"'makefile.tc'\" unpacked with wrong size!
fi
# end of 'makefile.tc'
fi
if test -f 'patchlev.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'patchlev.h'\"
else
echo shar: Extracting \"'patchlev.h'\" \(73 characters\)
sed "s/^X//" >'patchlev.h' <<'END_OF_FILE'
X/* Indicate which patches have been applied to CFX
X*/
X#define PATCHLEV 0
END_OF_FILE
if test 73 -ne `wc -c <'patchlev.h'`; then
echo shar: \"'patchlev.h'\" unpacked with wrong size!
fi
# end of 'patchlev.h'
fi
if test -f 'unc.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unc.c'\"
else
echo shar: Extracting \"'unc.c'\" \(11415 characters\)
sed "s/^X//" >'unc.c' <<'END_OF_FILE'
X/*
UNC.C - Uncrunch module of CP/M File eXpress
Copyright 20 Jan 1992 by
Carson Wilson
X1359 W. Greenleaf, #1D
Chicago, IL 60626
X
UUCP: carson@sputnik.uucp
X ..!uunet!ddsw1!carson
X
BBS: Antelope Freeway, 1-708-455-0120
X
Notes:
X Adapted from UNCRunch/C by Frank Prindle.
X*/
X
X#include "cfx.h"
X
X#define DUMBLINKER
X#define TABLE_SIZE 4096 /* size of main LZW table for 12 bit codes */
X#define XLATBL_SIZE 5003 /* size of physical translation table */
X
X/* Special values for predecessor in table */
X#define NOPRED 0x6fff /* no predecessor in table */
X#define EMPTY 0x8000 /* empty table entry (xlatbl only) */
X#define REFERENCED 0x2000 /* table entry referenced if this bit set */
X#define IMPRED 0x7fff /* impossible predecessor */
X
X#define EOFCOD 0x100 /* special code for end-of-file */
X#define RSTCOD 0x101 /* special code for adaptive reset */
X#define NULCOD 0x102 /* special filler code */
X#define SPRCOD 0x103 /* spare special code */
X
X#ifdef DUMBLINKER
X
X/* Main LZW table and its structure */
struct entry
X{ short predecessor; /* index to previous entry, if any */
X unsigned char suffix; /* character suffixed to previous entries */
X} *table;
X
X/* auxilliary physical translation table */
X/* translates hash to main table index */
short *xlatbl;
X
X/*byte string stack used by decode */
unsigned char *stack;
X
X#else
X
struct entry
X{ short predecessor; /*index to previous entry, if any */
X unsigned char suffix; /*character suffixed to previous entries */
X} table[TABLE_SIZE];
X
X/* Auxilliary physical translation table */
X/* translates hash to main table index */
short xlatbl[XLATBL_SIZE];
X
X/* Byte string stack used by decode */
unsigned char stack[TABLE_SIZE];
X
X#endif
X
X/* Other Global Variables */
X
unsigned char codlen; /* Variable code length in bits (9-12) */
short trgmsk; /* Mask for codes of current length */
unsigned char fulflg; /* Full flag - set once main table is full */
short entry; /* Next available main table entry */
long getbuf; /* Buffer used by getcode */
short getbit; /* Residual bit counter used by getcode */
unsigned char entflg; /* Inhibit main loop from entering this code */
int finchar; /* First character of last substring output */
int lastpr; /* Last predecessor (in main loop) */
X
void initb2();
int okflag; /* Flags abort from nested routines */
X
unsigned char *stacklmt; /* crw */
X
X/* ---------------------------------------------------------------- */
X/*
X Uncrunch a single file.
X*/
void uncrunch(uncrfd, uncrfn, uncrfs)
XFILE *uncrfd;
char *uncrfn;
long uncrfs;
X{
X char *p;
X char outfn[80]; /* space to build output file name */
X int pred; /* current predecessor (in main loop)*/
X unsigned char reflevel; /* ref rev level from input file */
X unsigned char siglevel; /* sig rev level from input file */
X unsigned char errdetect; /* error detection flag from input file*/
X unsigned file_cksum; /* checksum read from input file */
X
X /* Extract and build output file name */
X
X cgetc(uncrfd); /* skip signature */
X cgetc(uncrfd);
X for ( p = outfn; (*p = (cgetc(uncrfd) & 0x7F)) != '\0' ; p++)
X {
X if (*p == '[') /* comment separator */
X {
X *p = ' ';
X *++p = '[';
X }
X else if (*p == 1) /* DateStamper separator */
X *p = '\0';
X }
X
X outcrlf(1);
X printf(" --> %s", outfn);
X
X *(cisubstr(outfn, ".") + 4) = '\0'; /* truncate non-name portion */
X
X if (diskout)
X {
X#ifdef UNIX
X unixfn(outfn);
X printf(" (%s)", outfn);
X#endif
X /* Open output file */
X if ( 0 == (outfd = fopen( outfn, "wb")) )
X { cerror("can't create %s!", outfn);
X return;
X }
X }
X else
X outcrlf(2);
X
X /* read the four info bytes */
X reflevel = cgetc(uncrfd); /* currently not used */
X siglevel = cgetc(uncrfd);
X errdetect = cgetc(uncrfd);
X cgetc(uncrfd); /* skip spare */
X
X /* Make sure we can uncrunch this format file */
X /* note: this program does not support CRUNCH 1.x format */
X if (siglevel < 0x20 || siglevel > 0x2f)
X { cerror("need newer UNCR version.");
X return;
X }
X
X#ifdef DUMBLINKER
X /* Allocate storage now for the big tables (keeps load short) */
X table = (struct entry *) malloc(TABLE_SIZE * sizeof(struct entry ));
X xlatbl = (short *) malloc(XLATBL_SIZE * sizeof(short));
X stack = (unsigned char *) malloc(TABLE_SIZE * sizeof(char));
X if (table == NULL || xlatbl == NULL || stack == NULL)
X { outcrlf(1);
X cerror("not enough memory to uncrunch.");
X goto uncrexit;
X }
X#endif
X /* Initialize variables for uncrunching a file */
X intram();
X stacklmt = stack + TABLE_SIZE;
X
X /* Set up atomic code definitions */
X initb2();
X
X /* =============== MAIN DECODING LOOP ============= */
X outreccount = 0;
X pred = NOPRED;
X okflag = 1;
X while ((okflag) && /* flags file corrupt */
X (contin)) /* file skip command flag */
X {
X lastpr = pred; /* Remember last predecessor */
X
X /* Read and process one code */
X if ((pred = getcode(uncrfd)) == EOFCOD) /* End-of-file code */
X break; /* All LZW codes read*/
X else if (pred == RSTCOD) /* reset code */
X { entry = 0;
X fulflg = 0;
X codlen = 9;
X trgmsk = 0x1ff;
X pred = NOPRED;
X entflg = 1;
X initb2();
X }
X else /* A normal code (nulls already deleted) */
X { /* Check for table full */
X if (fulflg != 2)
X /* Strategy if table not full */
X if (decode(pred) == 0)
X enterx(lastpr, finchar);
X else
X entflg = 0;
X else
X { /* Strategy if table is full */
X decode(pred);
X entfil(lastpr, finchar); /* attempt reassign */
X }
X }
X }
X /* Verify checksum if required */
X if ((errdetect == 0) && (contin))
X { file_cksum = cgetc(uncrfd);
X file_cksum |= cgetc(uncrfd) << 8;
X cksum &= 0xFFFF;
X if (file_cksum != cksum)
X cerror("checksum error: expected: %04xh actual: %04xh", file_cksum, cksum);
X }
X uncrexit:
X#ifdef DUMBLINKER
X free(table);
X free(xlatbl);
X free(stack);
X#endif
X}
X/* ---------------------------------------------------------------- */
X/*
X Initialize variables for each file to be uncrunched.
X*/
void intram()
X{
X trgmsk = 0x1ff; /* Nine bits */
X codlen = 9; /* " */
X fulflg = 0; /* Table empty */
X entry = 0; /* " */
X getbit = 0; /* Buffer emtpy */
X entflg = 1; /* First code always atomic */
X repeat_flag = 0; /* Repeat not active */
X getbuf = 0L; /* crw */
X}
X/* ---------------------------------------------------------------- */
X/*
X Initialize the LZW and physical translation tables.
X*/
void initb2()
X{
X register int i;
X
X /* First mark all entries of xlatbl as empty */
X for (i = 0; i < XLATBL_SIZE; i++)
X xlatbl[i] = EMPTY;
X
X /* Enter atomic and reserved codes into LZW table */
X for (i = 0; i < 0x100; i++)
X enterx(NOPRED, i); /* First 256 atomic codes */
X for (i = 0; i < 4; i++)
X enterx(IMPRED, 0); /* Reserved codes */
X}
X/* ---------------------------------------------------------------- */
X/*
X Enter the next code into the LZW table.
X*/
void enterx(pred, suff)
int pred; /* Table index of predecessor */
int suff; /* Suffix byte represented by this entry */
X{
X register struct entry *ep;
X ep = &table[entry]; /* entry is a global */
X
X /* Update xlatbl to point to this entry */
X figure(pred, suff);
X
X /* Make the new entry */
X ep->predecessor = (short)pred;
X ep->suffix = (unsigned char)suff;
X entry++;
X
X /* If only one entry of the current code length remains, update to */
X /* next code length because main loop is reading one code ahead */
X if (entry >= trgmsk)
X if (codlen < 12)
X {
X /* Table not full, just make length one more bit */
X codlen++;
X trgmsk = (trgmsk << 1) | 1;
X }
X else
X /* Table almost full (fulflg==0) or full (fulflg==1) */
X /* just increment fulflg - when it gets to 2 we */
X /* will never be called again */
X fulflg++;
X}
X/* ---------------------------------------------------------------- */
X/*
X Find an empty entry in xlatbl which hashes from this
X predecessor/suffix combo, and store the index of the
X next available LZW table entry in it.
X*/
void figure(pred, suff)
int pred;
int suff;
X{
X short *hash();
X /* auto int disp; */
X int disp;
X register short *p;
X p = hash(pred, suff, &disp);
X
X /* Follow secondary hash chain as necessary to find an empty slot */
X while (((*p) & 0xffff) != EMPTY)
X {
X p += disp;
X if (p < xlatbl || p > xlatbl + XLATBL_SIZE)
X p += XLATBL_SIZE;
X }
X
X /* Stuff next available index into this slot */
X *p = entry;
X}
X/* ---------------------------------------------------------------- */
X/*
X Hash pred/suff into xlatbl pointer.
X Duplicates the hash algorithm used by CRUNCH 2.3.
X*/
short *hash(pred, suff, disploc)
int pred;
int suff;
int *disploc;
X{
X register int hashval;
X
X hashval = ((((pred >> 4) & 0xff) ^ suff) | ((pred & 0xf) << 8)) + 1;
X *disploc = hashval - XLATBL_SIZE;
X return (xlatbl + hashval);
X}
X/* ---------------------------------------------------------------- */
X/*
X Return a code of length "codlen" bits from the input file
X bit-stream.
X*/
getcode(gcodefd)
XFILE *gcodefd;
X{
X register int hole;
X int code;
X
X /* Always get at least a byte */
X getbuf = (getbuf << codlen) | (((long) cgetc(gcodefd)) << (hole = codlen - getbit));
X getbit = 8 - hole;
X
X /* If is not enough to supply codlen bits, get another byte */
X if (getbit < 0)
X {
X getbuf |= ((long) cgetc(gcodefd)) << (hole - 8);
X getbit += 8;
X }
X
X if (feof(gcodefd))
X { cerror("unexpected EOF on input file.");
X return EOFCOD;
X }
X
X /* Skip spare or null codes */
X if ((code = ((getbuf >> 8) & trgmsk)) == NULCOD || code == SPRCOD)
X return getcode(gcodefd); /* Skip this code, get next */
X return code;
X}
X/* ---------------------------------------------------------------- */
X/*
X Decode this code.
X*/
decode(code)
short code;
X{
X register unsigned char *stackp; /* Byte string stack pointer */
X register struct entry *ep;
X
X ep = &table[code];
X
X if (code >= entry)
X {
X /* The ugly exception, "WsWsW" */
X entflg = 1;
X enterx(lastpr, finchar);
X }
X
X /* Mark corresponding table entry as referenced */
X ep->predecessor |= REFERENCED;
X
X /* Walk back the LZW table starting with this code */
X stackp = stack;
X
X /* Prevent overrun with corrupt files <crw> */
X while (ep > &table[255]) /* i.e. code not atomic */
X {
X *stackp++ = ep->suffix;
X ep = &table[(ep->predecessor)&0xfff];
X if (stackp > stacklmt)
X {
X cerror("CRUNCHed file corrupt: aborting.");
X okflag = 0;
X return(entflg);
X }
X }
X
X /* Then emit all bytes corresponding to this code in forward order */
X send(finchar = (ep->suffix) & 0xff); /*first byte*/
X
X while (stackp > stack) /*the rest*/
X send(*--stackp);
X
X return(entflg);
X}
X/* ----------------------------------------------------------------- */
X/*
X Attempt to reassign an existing code which has been defined,
X but never referenced.
X*/
void entfil(pred, suff)
int pred; /* Table index of predecessor */
int suff; /* Suffix byte represented by this entry */
X{
X auto int disp;
X register struct entry *ep;
X short *hash();
X short *p;
X p = hash(pred, suff, &disp);
X
X /* Search the candidate codes (all those which hash from this new */
X /* predecessor and suffix) for an unreferenced one */
X while (*p != (short)EMPTY)
X {
X /* Candidate code */
X ep = &table[*p];
X if (((ep->predecessor) & REFERENCED) == 0)
X {
X /* Entry reassignable, so do it! */
X ep->predecessor = pred;
X ep->suffix = suff;
X /* discontinue search */
X break;
X }
X /* Candidate unsuitable - follow secondary hash chain */
X /* and keep searching */
X p += disp;
X if (p < xlatbl || p > xlatbl + XLATBL_SIZE)
X p += XLATBL_SIZE;
X }
X}
X/* End of UNC.C */
END_OF_FILE
if test 11415 -ne `wc -c <'unc.c'`; then
echo shar: \"'unc.c'\" unpacked with wrong size!
fi
# end of 'unc.c'
fi
if test -f 'unixfunc.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'unixfunc.c'\"
else
echo shar: Extracting \"'unixfunc.c'\" \(1435 characters\)
sed "s/^X//" >'unixfunc.c' <<'END_OF_FILE'
X/*
UNIXFUNC.C - Unix functions module of CP/M File eXpress
Copyright 15 Dec 1991 by
Carson Wilson
X1359 W. Greenleaf, #1D
Chicago, IL 60626
X
UUCP: carson@sputnik.uucp
X carson@ddsw1.MCS.COM
X
BBS: Antelope Freeway, 1-708-455-0120
X*/
X
X#include "cfx.h"
X#include <termio.h>
X
struct termio save, term; /* terminal status buffer */
X
X/* ---------------------------------------------------------------- */
X/*
X Select "raw" tty mode.
X*/
int ttyraw()
X{
X if ( ioctl (0, TCGETA, &term) == -1) {
X fprintf (stderr, "standard input not a tty\n");
X exit (1);
X }
X
X /* save old tty state */
X save = term;
X
X /* turn off canonical processing */
X term.c_lflag &= ~ICANON;
X
X /* zero out echo bit of c_lflag */
X term.c_lflag &= ~ECHO;
X
X /* set MIN and TIME to zero */
X term.c_cc[VMIN] = 0;
X term.c_cc[VTIME] = 0;
X
X /* set new terminal state */
X ioctl (0, TCSETA, &term);
X}
X/* ---------------------------------------------------------------- */
X/*
X Restore tty state.
X*/
int ttyrestore()
X{
X /* reset old tty state */
X ioctl (0, TCSETA, &save);
X
X}
X/* ---------------------------------------------------------------- */
X/*
X Translate CP/M filename to Unix
X*/
void unixfn(inputfn)
char *inputfn;
X{
X char tempfn[30];
X char *fnptr = tempfn;
X char *inputptr = inputfn;
X
X *fnptr = '\0';
X for ( ; *inputptr ; inputptr++)
X if ((*inputptr & 0x7F) != ' ')
X *fnptr++ = (tolower(*inputptr) & 0x7F);
X *fnptr = '\0';
X strcpy(inputfn, tempfn);
X}
X/* End of UNIXFUNC.C */
END_OF_FILE
if test 1435 -ne `wc -c <'unixfunc.c'`; then
echo shar: \"'unixfunc.c'\" unpacked with wrong size!
fi
# end of 'unixfunc.c'
fi
if test -f 'usq.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'usq.c'\"
else
echo shar: Extracting \"'usq.c'\" \(3526 characters\)
sed "s/^X//" >'usq.c' <<'END_OF_FILE'
X/*
USQ.C - Unsqueeze module of CP/M File eXpress
Copyright 20 Jan 1992 by
Carson Wilson
X1359 W. Greenleaf, #1D
Chicago, IL 60626
X
UUCP: carson@sputnik.uucp
X ..!uunet!ddsw1!carson
X
BBS: Antelope Freeway, 1-708-455-0120
X*/
X
X#include "cfx.h"
X
X/* Stuff for Huffman unsqueezing */
X
X#define SPEOF 256 /* special endfile token */
X#define NUMVALS 257 /* 256 data values plus SPEOF */
X
X#ifdef DUMBLINKER
X
struct nd /* decoding tree */
X{
X int child[2]; /* left, right */
X} *node;
X
X#else
X
struct nd /* decoding tree */
X{
X int child[2]; /* left, right */
X} node[NUMVALS]; /* use large buffer */
X
X#endif
X
static int bpos; /* last bit position read */
static int curin; /* last byte value read */
static int numnodes; /* number of nodes in decode tree */
X
char *usqnptr; /* global squeezed file name */
X
X/* ------------------------------------------------------------------ */
X
static int get_int(f) /* get an integer */
XFILE *f; /* file to get it from */
X{
X int i;
X
X i = cgetc(f);
X return (short) (i | (cgetc(f) << 8));
X}
X/* ------------------------------------------------------------------ */
X
int 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 { cerror("invalid decode tree.");
X return (0);
X }
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 return (1);
X}
X/* ------------------------------------------------------------------ */
X
int 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 = cgetc(f)) == EOF)
X return(EOF);
X bpos = 0;
X
X /* move a level deeper in tree */
X i = node[i].child[1&curin];
X }
X else
X 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/* ==================================================================== */
X
void unsqueeze(usqfd, usqfn, usqflen)
XFILE *usqfd;
char *usqfn;
long usqflen;
X{
X unsigned usqfcrc;
X int tchar;
X char *p;
X char outfn[80]; /* space to build output file name */
X
X get_int(usqfd); /* skip ID bytes */
X usqfcrc = get_int(usqfd);
X usqnptr = usqfn;
X
X /* Extract and build output file name*/
X
X for ( p = outfn; (*p = cgetc(usqfd)) != '\0' ; p++);
X#ifdef UNIX
X unixfn(outfn);
X#endif
X outcrlf(1);
X printf(" --> %s", outfn);
X
X *(cisubstr(outfn, ".") + 4) = '\0'; /*truncate non-name portion*/
X
X if (diskout)
X { /* Open output file */
X if ( 0 == (outfd = fopen( outfn, "wb")) )
X { cerror("can't create %s", outfn);
X return;
X }
X }
X else
X outcrlf(2);
X#ifdef DUMBLINKER
X /* Allocate storage now for the table (keeps load short) */
X node = (struct nd *) malloc(NUMVALS * sizeof(struct nd));
X#endif
X if (init_usq(usqfd) == 0)
X return;
X
X outreccount = 0;
X
X while ((tchar = getc_usq(usqfd)) != EOF && (contin))
X send(tchar);
X cksum &= 0xFFFF;
X if (usqfcrc != cksum)
X cerror("checksum error: expected: %04xh actual: %04xh", usqfcrc, cksum);
X free(node);
X}
X/* End of USQ.C */
END_OF_FILE
if test 3526 -ne `wc -c <'usq.c'`; then
echo shar: \"'usq.c'\" unpacked with wrong size!
fi
# end of 'usq.c'
fi
echo shar: End of archive 1 \(of 2\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked both archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
exit 0 # Just in case...