home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume28 / cfx / part01 next >
Text File  |  1992-02-02  |  42KB  |  1,635 lines

  1. Newsgroups: comp.sources.misc
  2. From: carson@sputnik.uucp (Carson Wilson)
  3. Subject:  v28i012:  cfx - Cp/m File eXpress, v1.1.0, Part01/02
  4. Message-ID: <csm-v28i012=cfx.210051@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: fbd4d82cb546e57bd5451d1f7690c52a
  6. Date: Mon, 3 Feb 1992 03:01:33 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: carson@sputnik.uucp (Carson Wilson)
  10. Posting-number: Volume 28, Issue 12
  11. Archive-name: cfx/part01
  12. Environment: UNIX, MS-DOS, PC
  13.  
  14. CFX is a universal utility written in the C programming 
  15. language, whose main purpose in life is to make access to files 
  16. stored under the CP/M operating system accessible to users of 
  17. other operating systems.  CFX may be freely used and distributed 
  18. for nonprofit purposes.
  19.  
  20. CFX will extract to screen or disk normal, squeezed (typical 
  21. CP/M filename extension, .?Q?), crunched (.?Z?), CrLZH (.?Y?), 
  22. and library (.LBR) files.  It will also display library file 
  23. directory information and embedded compressed file datestamps 
  24. and comments.  CFX is an interactive, integrated utility, and as 
  25. such can prompt the user before displaying files, page the 
  26. screen, etc.
  27.  
  28. This design choice permits CFX to preserve embedded names in 
  29. compressed files and allows use with secure remote systems.  One 
  30. drawback of this choice is that CFX cannot easily be used as 
  31. part of a Unix pipeline (e.g., to send CP/M text files through 
  32. your favorite pager).  This may be addressed in future versions.
  33.  --
  34. CFX should compile under most operating systems.  It has been 
  35. tested under the following systems:
  36.  
  37. ISC Unix SVR3.2, version 2.2.1
  38. MSDOS Turbo C, version 2.01
  39.  
  40. To compile under Unix, edit the Makefile, optionally inspect 
  41. cfx.h, and type
  42.  
  43.     "make"          to build cfx
  44.  
  45.     "make install"  to place the executable in the proper 
  46.                         location
  47.  
  48.     "make clean"    to remove compiler output files
  49.  
  50. To compile under MSDOS, copy MAKEFILE.TC to MAKEFILE first.
  51.  --
  52. Documentation is in cfx.1, cfx.man, and cfx.doc.
  53.  
  54. For a short usage message, type "cfx" at your command prompt.
  55.  --
  56. Bug fixes, bug reports, and requests welcome to:
  57.  
  58. Carson Wilson
  59. 1359 W. Greenleaf, #1D
  60. Chicago, IL 60626
  61.  
  62. UUCP:    carson@sputnik.uucp
  63.     ..!uunet!ddsw1!carson
  64.  
  65. BBS:    Antelope Freeway, 1-708-455-0120
  66. --
  67. #! /bin/sh
  68. # This is a shell archive.  Remove anything before this line, then unpack
  69. # it by saving it into a file and typing "sh file".  To overwrite existing
  70. # files, type "sh file -c".  You can also feed this as standard input via
  71. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  72. # will see the following message at the end:
  73. #        "End of archive 1 (of 2)."
  74. # Contents:  MANIFEST Makefile README lbr.c lzh.c makefile.tc
  75. #   patchlev.h unc.c unixfunc.c usq.c
  76. # Wrapped by carson@sputnik on Sat Jan 25 10:39:40 1992
  77. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  78. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  79.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  80. else
  81. echo shar: Extracting \"'MANIFEST'\" \(125 characters\)
  82. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  83. MANIFEST
  84. Makefile
  85. README
  86. cfx.1
  87. cfx.c
  88. cfx.doc
  89. cfx.h
  90. cfx.hst
  91. cfx.man
  92. lbr.c
  93. lzh.c
  94. makefile.tc
  95. patchlev.h
  96. unc.c
  97. unixfunc.c
  98. usq.c
  99. END_OF_FILE
  100. if test 125 -ne `wc -c <'MANIFEST'`; then
  101.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  102. fi
  103. # end of 'MANIFEST'
  104. fi
  105. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  106.   echo shar: Will not clobber existing file \"'Makefile'\"
  107. else
  108. echo shar: Extracting \"'Makefile'\" \(740 characters\)
  109. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  110. X#
  111. X# Unix Makefile for CP/M File eXpress
  112. X# Copyright 20 Jan 1992 by 
  113. X# Carson Wilson
  114. X# 1359 W. Greenleaf, #1D
  115. X# Chicago, IL 60626
  116. X#
  117. X# UUCP:    carson@sputnik.uucp
  118. X#    ..!uunet!ddsw1!carson
  119. X#
  120. X# BBS:    Antelope Freeway, 1-708-455-0120
  121. X#
  122. X# Name and path of C compiler:
  123. CC = cc
  124. X
  125. X#CFLAGS = -g
  126. CFLAGS =
  127. X
  128. BINDIR = /usr/local/bin
  129. X
  130. X.c.o    :
  131. X    $(CC) $(CFLAGS) -DUNIX -c $<
  132. X
  133. cfx    : cfx.o lbr.o unc.o usq.o lzh.o unixfunc.o
  134. X    $(CC) $(CFLAGS) -o cfx cfx.o lbr.o unc.o usq.o lzh.o unixfunc.o
  135. X
  136. lint    :
  137. X    lint -DUNIX -u "cfx.c lbr.c unc.c usq.c lzh.c unixfunc.c"
  138. X
  139. install :
  140. X    mv cfx $(BINDIR)
  141. X
  142. clean    :
  143. X    rm cfx.o lbr.o unc.o usq.o lzh.o unixfunc.o
  144. X
  145. cfx.o    : cfx.c cfx.h
  146. lbr.o    : lbr.c cfx.h
  147. unc.o    : unc.c cfx.h
  148. usq.o    : usq.c cfx.h
  149. lzh.o    : lzh.c cfx.h
  150. unixfunc.o : unixfunc.c
  151. END_OF_FILE
  152. if test 740 -ne `wc -c <'Makefile'`; then
  153.     echo shar: \"'Makefile'\" unpacked with wrong size!
  154. fi
  155. # end of 'Makefile'
  156. fi
  157. if test -f 'README' -a "${1}" != "-c" ; then 
  158.   echo shar: Will not clobber existing file \"'README'\"
  159. else
  160. echo shar: Extracting \"'README'\" \(1855 characters\)
  161. sed "s/^X//" >'README' <<'END_OF_FILE'
  162. README file for CFX - CP/M File eXpress
  163. X
  164. Copyright 20 Jan 1992 by Carson Wilson
  165. X--
  166. CFX is a universal utility written in the C programming 
  167. language, whose main purpose in life is to make access to files 
  168. stored under the CP/M operating system accessible to users of 
  169. other operating systems.  CFX may be freely used and distributed 
  170. for nonprofit purposes.
  171. X
  172. CFX will extract to screen or disk normal, squeezed (typical 
  173. CP/M filename extension, .?Q?), crunched (.?Z?), CrLZH (.?Y?), 
  174. and library (.LBR) files.  It will also display library file 
  175. directory information and embedded compressed file datestamps 
  176. and comments.  CFX is an interactive, integrated utility, and as 
  177. such can prompt the user before displaying files, page the 
  178. screen, etc.
  179. X
  180. This design choice permits CFX to preserve embedded names in 
  181. compressed files and allows use with secure remote systems.  One 
  182. drawback of this choice is that CFX cannot easily be used as 
  183. part of a Unix pipeline (e.g., to send CP/M text files through 
  184. your favorite pager).  This may be addressed in future versions.
  185. X--
  186. CFX should compile under most operating systems.  It has been 
  187. tested under the following systems:
  188. X
  189. ISC Unix SVR3.2, version 2.2.1
  190. MSDOS Turbo C, version 2.01
  191. X
  192. To compile under Unix, edit the Makefile, optionally inspect 
  193. cfx.h, and type
  194. X
  195. X    "make"          to build cfx
  196. X
  197. X    "make install"  to place the executable in the proper 
  198. X                        location
  199. X
  200. X    "make clean"    to remove compiler output files
  201. X
  202. To compile under MSDOS, copy MAKEFILE.TC to MAKEFILE first.
  203. X--
  204. Documentation is in cfx.1, cfx.man, and cfx.doc.
  205. X
  206. XFor a short usage message, type "cfx" at your command prompt.
  207. X--
  208. Bug fixes, bug reports, and requests welcome to:
  209. X
  210. Carson Wilson
  211. X1359 W. Greenleaf, #1D
  212. Chicago, IL 60626
  213. X
  214. UUCP:    carson@sputnik.uucp
  215. X    ..!uunet!ddsw1!carson
  216. X
  217. BBS:    Antelope Freeway, 1-708-455-0120
  218. X
  219. END_OF_FILE
  220. if test 1855 -ne `wc -c <'README'`; then
  221.     echo shar: \"'README'\" unpacked with wrong size!
  222. fi
  223. # end of 'README'
  224. fi
  225. if test -f 'lbr.c' -a "${1}" != "-c" ; then 
  226.   echo shar: Will not clobber existing file \"'lbr.c'\"
  227. else
  228. echo shar: Extracting \"'lbr.c'\" \(3403 characters\)
  229. sed "s/^X//" >'lbr.c' <<'END_OF_FILE'
  230. X/*
  231. LBR.C - CP/M library file module of CP/M File eXpress
  232. Copyright 20 Jan 1992 by 
  233. Carson Wilson
  234. X1359 W. Greenleaf, #1D
  235. Chicago, IL 60626
  236. X
  237. UUCP:    carson@sputnik.uucp
  238. X    ..!uunet!ddsw1!carson
  239. X
  240. BBS:    Antelope Freeway, 1-708-455-0120
  241. X
  242. Notes:
  243. X    Novosielski format library utility module
  244. X    Notes: Doesn't do any datestamp processing.
  245. X        Assumes short int is 2 bytes long.
  246. X*/
  247. X
  248. X#include "cfx.h"
  249. X
  250. X/* -------------------------------------------------------- */
  251. X
  252. void blankout(textstring, arraysize)
  253. char *textstring;
  254. int arraysize;
  255. X{
  256. X    int slength;
  257. X    slength = strlen(textstring);
  258. X
  259. X    while (slength < arraysize)
  260. X    {
  261. X        *(textstring + slength) = ' ';
  262. X        slength++;
  263. X    }
  264. X    *(textstring + arraysize - 1) = '\0';
  265. X}
  266. X/* -------------------------------------------------------- */
  267. X
  268. int getentry(gefile, lbrentry)
  269. XFILE *gefile;
  270. struct direntry *lbrentry;
  271. X{
  272. X    int rresult;
  273. X    rresult = fread(lbrentry, sizeof(*lbrentry), 1, gefile);
  274. X    return (rresult && (lbrentry->status == 0));
  275. X}
  276. X/* -------------------------------------------------------- */
  277. X
  278. int wildfnmatch(wildname, name, wildext, ext)
  279. char *wildname, *name, *wildext, *ext;
  280. X{
  281. X    int position;
  282. X
  283. X    /* test names */
  284. X    for (position = 1;
  285. X         ((*wildname != '*') && (position < 9));
  286. X         position++, wildname++, name++)
  287. X        if ((*wildname != '?') && (*wildname != *name))
  288. X            return 0;    /* nonmatch */
  289. X
  290. X    /* test extents */
  291. X    for (position = 1;
  292. X         ((*wildext != '*') && (position < 4));
  293. X         position++, wildext++, ext++)
  294. X        if ((*wildext != '?') && (*wildext != *ext))
  295. X            return 0;    /* nonmatch */
  296. X
  297. X    return (1);
  298. X}
  299. X/* -------------------------------------------------------- */
  300. X
  301. void lbr(lufd)
  302. XFILE *lufd;
  303. X{
  304. X    char procname[13];
  305. X    int lbrents, tlbrents;
  306. X    long lbrmarker, lbrmarker1;
  307. X    FILE *randfd;
  308. X    char matchwork[40];    /* for destructive strtok() */
  309. X
  310. X    char matchname[9], matchext[4];
  311. X    char *matchptr;
  312. X    char tempname[9], tempext[4];
  313. X    struct direntry DCEntry, workentry;
  314. X
  315. X    lbrmarker = ftell(lufd);
  316. X    if ((fread(&DCEntry, sizeof(DCEntry), 1, lufd)) < 1)
  317. X    {    cerror("zero length library file; abort!");
  318. X        return;
  319. X    }
  320. X    lbrmarker1 = ftell(lufd);
  321. X    lbrents = DCEntry.length * 4;    /* 4 entries per sector */
  322. X
  323. X    randfd = fopen(infname, "rb");        /* open a spare */
  324. X    if (strlen(membername))        /* member specified */
  325. X    {    strcpy(matchwork, membername);
  326. X        matchptr = matchwork;
  327. X        strcpy(matchname, strtok(matchptr, ". "));
  328. X        matchptr = NULLCHARPTR;        /* initialize */
  329. X        strcpy(matchext, strtok(matchptr, ". "));
  330. X        blankout(&matchname[0], 9);
  331. X        blankout(&matchext[0], 4);
  332. X        stupcase(matchname);
  333. X        stupcase(matchext);
  334. X    }
  335. X
  336. X    if (!brief)
  337. X        infoflag = 1;        /* just show info first */
  338. X    rescan:
  339. X    tlbrents = lbrents;
  340. X    while (--tlbrents)
  341. X        if (getentry(lufd, &workentry))
  342. X        {    memcpy(tempname, workentry.name, 8);
  343. X            memcpy(tempext, workentry.ext, 3);
  344. X            tempname[8] = tempext[3] = '\0';
  345. X            strcpy(procname, tempname);
  346. X            strcat(procname, ".");
  347. X            strcat(procname, tempext);
  348. X            if (!strlen(membername) ||
  349. X                wildfnmatch(matchname, tempname, matchext, tempext))
  350. X            {    /* seek to member location */
  351. X                xferndate(workentry.credate, workentry.moddate);
  352. X                fseek (randfd, (workentry.index * 128L) + lbrmarker, SEEK_SET);
  353. X                mlength = workentry.length * 128;
  354. X                /* use recursion to process member */
  355. X                process(randfd, procname, mlength);
  356. X            }
  357. X        }
  358. X    if (infoflag && !info)    /* info shown; now do members */
  359. X    {    infoflag = 0;
  360. X        fseek (lufd, lbrmarker1, SEEK_SET);
  361. X        outcrlf(1);
  362. X        goto rescan;
  363. X    }
  364. X    fclose(randfd);
  365. X}
  366. X/* End of LBR.C */
  367. END_OF_FILE
  368. if test 3403 -ne `wc -c <'lbr.c'`; then
  369.     echo shar: \"'lbr.c'\" unpacked with wrong size!
  370. fi
  371. # end of 'lbr.c'
  372. fi
  373. if test -f 'lzh.c' -a "${1}" != "-c" ; then 
  374.   echo shar: Will not clobber existing file \"'lzh.c'\"
  375. else
  376. echo shar: Extracting \"'lzh.c'\" \(10331 characters\)
  377. sed "s/^X//" >'lzh.c' <<'END_OF_FILE'
  378. X/*
  379. LZH.C - .LZH file module of CP/M File eXpress
  380. Copyright 20 Jan 1992 by 
  381. Carson Wilson
  382. X1359 W. Greenleaf, #1D
  383. Chicago, IL 60626
  384. X
  385. UUCP:    carson@sputnik.uucp
  386. X    ..!uunet!ddsw1!carson
  387. X
  388. BBS:    Antelope Freeway, 1-708-455-0120
  389. X
  390. Notes:
  391. X    This module is based on the UNLZH.C code distributed with 
  392. X    LZH21SRC.LBR by R. Warren, included by his permission.
  393. X*/
  394. X
  395. X#include "cfx.h"
  396. X
  397. X/* -------- COMPILER/IMPLEMENTATION DEPENDENT ---------- */
  398. X
  399. X#define ID1 0x76
  400. X#define ID2 0xFD
  401. X
  402. typedef unsigned char uchar;
  403. X
  404. uchar lgetbuf;
  405. unsigned vbits, vmask, vshift;
  406. char flag_checksum;
  407. X
  408. X/*----------------------- LZSS Parameters ----------------------------- */
  409. X
  410. X/* Size of string buffer */
  411. X#define N        2048
  412. X
  413. X/* Size of look-ahead buffer */
  414. X#define F        60
  415. X
  416. X#define THRESHOLD    2
  417. X
  418. X/* End of tree's node  */
  419. X#define NIL        N
  420. X
  421. uchar        text_buf[N];
  422. X
  423. X/*------------------ Huffman coding parameters ----------------------------*/
  424. X
  425. X/* Number of Special Characters */
  426. X#define NUMSPEC        1
  427. X
  428. X/* EOF code (special character) */
  429. X#define EOF_CODE    256
  430. X
  431. X/* character code (= 0..N_CHAR-1) */
  432. X#define N_CHAR      (256 + NUMSPEC + F - THRESHOLD )
  433. X
  434. X/* Size of table */
  435. X#define T         (N_CHAR * 2 - 1)
  436. X
  437. X/* root position */
  438. X#define R         (T - 1)
  439. X
  440. X/* update when cumulative frequency */
  441. X/* reaches to this value */
  442. X#define MAX_FREQ    0x8000
  443. X
  444. unsigned freq[T + 1];    /* cumulative freq table */
  445. X
  446. X/*
  447. X * pointing parent nodes.
  448. X * area [T..(T + N_CHAR - 1)] are pointers for leaves
  449. X */
  450. int prnt[T + N_CHAR];
  451. X
  452. X/* pointing children nodes (son[], son[] + 1)*/
  453. int son[T];
  454. X
  455. X/* decoder table */
  456. uchar d_code[256] = {
  457. X    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  458. X    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  459. X    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  460. X    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  461. X    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  462. X    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
  463. X    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  464. X    0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
  465. X    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  466. X    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  467. X    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  468. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  469. X    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  470. X    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  471. X    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  472. X    0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
  473. X    0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
  474. X    0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
  475. X    0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
  476. X    0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
  477. X    0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
  478. X    0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
  479. X    0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
  480. X    0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
  481. X    0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
  482. X    0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
  483. X    0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
  484. X    0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
  485. X    0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
  486. X    0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
  487. X    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  488. X    0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
  489. X};
  490. X
  491. uchar d_len[256] = {
  492. X    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  493. X    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  494. X    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  495. X    0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
  496. X    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  497. X    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  498. X    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  499. X    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  500. X    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  501. X    0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
  502. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  503. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  504. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  505. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  506. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  507. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  508. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  509. X    0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
  510. X    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  511. X    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  512. X    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  513. X    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  514. X    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  515. X    0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
  516. X    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  517. X    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  518. X    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  519. X    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  520. X    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  521. X    0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
  522. X    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  523. X    0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
  524. X};
  525. X/* ======================= CODE BEGINS ========================= */
  526. X
  527. void lputc(c, stream)
  528. int c;
  529. XFILE *stream;
  530. X{
  531. X    output(c, stream);
  532. X    cksum += (unsigned) c;
  533. X}
  534. X/* ---------------------------------------------------------------- */
  535. X
  536. unsigned GetBit(infile)
  537. XFILE *infile;
  538. X{
  539. X    unsigned c;
  540. X    if (lgetbuf == 0x80)
  541. X        c = (unsigned) (cgetc(infile) << 1) | 0x1;
  542. X    else
  543. X        c = ((unsigned) lgetbuf) << 1;
  544. X    lgetbuf = (uchar) c;
  545. X
  546. X    if (feof(infile))
  547. X    {    cerror("unexpected EOF on input file.");
  548. X        contin = 0;
  549. X    }
  550. X    return  ((c & 0x100) ? 1 : 0);
  551. X}
  552. X/* ---------------------------------------------------------------- */
  553. X
  554. unsigned GetByte(infile)
  555. XFILE *infile;
  556. X{
  557. X    char i;
  558. X    unsigned temp;
  559. X
  560. X    for (i = 8, temp = 0 ; i ; i--)
  561. X        temp = (temp <<1) | GetBit(infile);
  562. X    return(temp);
  563. X}
  564. X/* ---------------------------------------------------------------- */
  565. X
  566. void StartHuff()    /* initialize freq tree */
  567. X{
  568. X    int i, j;
  569. X
  570. X    for (i = 0; i < N_CHAR; i++) {
  571. X        freq[i] = 1;
  572. X        son[i] = i + T;
  573. X        prnt[i + T] = i;
  574. X    }
  575. X    i = 0; j = N_CHAR;
  576. X    while (j <= R) {
  577. X        freq[j] = freq[i] + freq[i + 1];
  578. X        son[j] = i;
  579. X        prnt[i] = prnt[i + 1] = j;
  580. X        i += 2; j++;
  581. X    }
  582. X    freq[T] = 0xffff;
  583. X    prnt[R] = 0;
  584. X}
  585. X/* ---------------------------------------------------------------- */
  586. X
  587. void reconst()        /* reconstruct freq tree */
  588. X{
  589. X    int i, j, k;
  590. X    unsigned f, l;
  591. X
  592. X    /* halven cumulative freq for leaf nodes */
  593. X    j = 0;
  594. X    for (i = 0; i < T; i++)
  595. X    {    if (son[i] >= T)
  596. X        {    freq[j] = (freq[i] + 1) / 2;
  597. X            son[j] = son[i];
  598. X            j++;
  599. X        }
  600. X    }
  601. X
  602. X    /* make a tree : first, connect child nodes */
  603. X    for (i = 0, j = N_CHAR; j < T; i += 2, j++)
  604. X    {    k = i + 1;
  605. X        f = freq[j] = freq[i] + freq[k];
  606. X        for (k = j - 1; f < freq[k]; k--);
  607. X        k++;
  608. X
  609. X        for (l=j; l != k ; l--)
  610. X        {    freq[l] = freq[l-1];
  611. X            son[l] = son[l-1];
  612. X        }
  613. X        freq[k] = f;
  614. X        son[k] = i;
  615. X    }
  616. X
  617. X    /* connect parent nodes */
  618. X    for (i = 0; i < T; i++)
  619. X    {    if ((k = son[i]) >= T)
  620. X            prnt[k] = i;
  621. X        else
  622. X            prnt[k] = prnt[k + 1] = i;
  623. X    }
  624. X}
  625. X/* ---------------------------------------------------------------- */
  626. X
  627. void update(c)        /* update freq tree */
  628. int c;
  629. X{
  630. X    int i, j, k, l;
  631. X
  632. X    if (freq[R] == MAX_FREQ) {
  633. X        reconst();
  634. X    }
  635. X    c = prnt[c + T];
  636. X    do {
  637. X        k = ++freq[c];
  638. X
  639. X        /* swap nodes to keep the tree freq-ordered */
  640. X        if (k > freq[l = c + 1])
  641. X        {    while (k > freq[++l]);
  642. X            l--;
  643. X            freq[c] = freq[l];
  644. X            freq[l] = k;
  645. X
  646. X            i = son[c];
  647. X            prnt[i] = l;
  648. X            if (i < T)
  649. X                prnt[i + 1] = l;
  650. X
  651. X            j = son[l];
  652. X            son[l] = i;
  653. X
  654. X            prnt[j] = c;
  655. X            if (j < T)
  656. X                prnt[j + 1] = c;
  657. X            son[c] = j;
  658. X
  659. X            c = l;
  660. X        }
  661. X    } while ((c = prnt[c]) != 0);    /* do it until reaching the root */
  662. X}
  663. X/* ---------------------------------------------------------------- */
  664. X
  665. unsigned DecodeChar(infile)
  666. XFILE *infile;
  667. X{
  668. X    unsigned c;
  669. X
  670. X    c = son[R];
  671. X
  672. X    /*
  673. X     * start searching tree from the root to leaves.
  674. X     * choose node #(son[]) if input bit == 0
  675. X     * else choose #(son[]+1) (input bit == 1)
  676. X     */
  677. X    while (c < T)
  678. X    {    c += GetBit(infile);
  679. X        c = son[c];
  680. X    }
  681. X    c -= T;
  682. X    update(c);
  683. X    return c;
  684. X}
  685. X/* ---------------------------------------------------------------- */
  686. X
  687. unsigned DecodePosition(infile)
  688. XFILE *infile;
  689. X{
  690. X    unsigned i, j, c;
  691. X
  692. X    /* decode upper 6 bits from given table */
  693. X    i = GetByte(infile);
  694. X    c = (unsigned) d_code[i] << vshift;
  695. X    j = d_len[i];
  696. X
  697. X    /* input lower 6 bits directly */
  698. X    j -= vbits;
  699. X    while (j--)
  700. X        i = (i << 1) + GetBit(infile);
  701. X    return c | (i & vmask);
  702. X}
  703. X/* ---------------------------------------------------------------- */
  704. X
  705. void Decode(infile)    /* Decoding/Uncompressing */
  706. XFILE *infile;
  707. X{
  708. X    int  i, j, k, r, c;
  709. X
  710. X    lgetbuf = 0x80;        /* prime input engine */
  711. X    StartHuff();
  712. X    for (i = 0; i < N - F; i++)
  713. X        text_buf[i] = ' ';
  714. X    r = N - F;
  715. X    while ((c = DecodeChar(infile)) != EOF_CODE && (contin))
  716. X    {    if (c < 256)
  717. X        {    lputc(c, outfd);
  718. X            text_buf[r++] = c;
  719. X            r &= (N - 1);
  720. X        }
  721. X        else
  722. X        {    i = (r - DecodePosition(infile) - 1) & (N - 1);
  723. X            j = c - 255-NUMSPEC + THRESHOLD;
  724. X            for (k = 0; k < j; k++)
  725. X            {    c = text_buf[(i + k) & (N - 1)];
  726. X                lputc(c, outfd);
  727. X                text_buf[r++] = c;
  728. X                r &= (N - 1);
  729. X            }
  730. X        }
  731. X    }
  732. X}
  733. X/* ---------------------------------------------------------------- */
  734. X/*
  735. X    Un-LZH a single file.
  736. X*/
  737. void unlzh(lzhfd, lzhfn, lzhfs)
  738. XFILE *lzhfd;
  739. char *lzhfn;
  740. long lzhfs;
  741. X{
  742. X    char *p;
  743. X    char outfn[80];        /* space to build output file name   */
  744. X
  745. X    uchar version;
  746. X    int  i;
  747. X    unsigned hold_check;
  748. X
  749. X    /* Extract and build output file name */
  750. X
  751. X    cgetc(lzhfd);    /* skip signature */
  752. X    cgetc(lzhfd);
  753. X
  754. X    for ( p = outfn; (*p = (cgetc(lzhfd) & 0x7F)) != '\0' ; p++)
  755. X    {
  756. X        if (*p == '[')        /* comment separator */
  757. X        {
  758. X            *p = ' ';
  759. X            *++p = '[';
  760. X        }
  761. X        else if (*p == 1)    /* DateStamper separator */
  762. X            *p = '\0';
  763. X    }
  764. X
  765. X    outcrlf(1);
  766. X    printf("  --> %s", outfn);
  767. X
  768. X    *(cisubstr(outfn, ".") + 4) = '\0'; /* truncate non-name portion */
  769. X    if (diskout)
  770. X    {
  771. X#ifdef UNIX
  772. X        unixfn(outfn);
  773. X        printf(" (%s)", outfn);
  774. X#endif
  775. X        /* Open output file */
  776. X        if ( 0 == (outfd = fopen( outfn, "wb")) )
  777. X        {    cerror("can't create %s!", outfn);
  778. X            return;
  779. X        }
  780. X        }
  781. X    else
  782. X        outcrlf(2);
  783. X
  784. X    cgetc(lzhfd);                 /* Encoder version */
  785. X
  786. X    if ((version = cgetc(lzhfd)) == 0x20)    /* Significant version */
  787. X    {    vbits = 3;
  788. X        vmask = 0x1F;
  789. X        vshift= 5;
  790. X    }
  791. X    else if (version < 0x20)
  792. X    {    vbits = 2;
  793. X        vmask = 0x3F;
  794. X        vshift= 6;
  795. X    }
  796. X    else
  797. X    {    outcrlf(1);
  798. X        cerror("needs newer LZH revision");
  799. X        return;
  800. X    }
  801. X
  802. X    flag_checksum = (uchar) cgetc(lzhfd);    /* Check Type */
  803. X    cgetc(lzhfd);                /* Filler */
  804. X    outreccount = 0;
  805. X
  806. X    Decode(lzhfd);            /* Extract file to screen/disk */
  807. X    if (contin == 0)
  808. X        return;            /* quit now if input error */
  809. X
  810. X    /* Test checksum */
  811. X    if (flag_checksum == 0 ) /* Only handle CHECKSUM type == 0 */
  812. X        for (i = 0, hold_check = cksum; i++ < 2 ; hold_check >>= 8)
  813. X            if ((unsigned) cgetc(lzhfd) != (hold_check & 0xFF))
  814. X                cerror("checksum error");
  815. X}
  816. X/* End of LZH.C */
  817. END_OF_FILE
  818. if test 10331 -ne `wc -c <'lzh.c'`; then
  819.     echo shar: \"'lzh.c'\" unpacked with wrong size!
  820. fi
  821. # end of 'lzh.c'
  822. fi
  823. if test -f 'makefile.tc' -a "${1}" != "-c" ; then 
  824.   echo shar: Will not clobber existing file \"'makefile.tc'\"
  825. else
  826. echo shar: Extracting \"'makefile.tc'\" \(1099 characters\)
  827. sed "s/^X//" >'makefile.tc' <<'END_OF_FILE'
  828. X#
  829. X# Turbo C Makefile for CP/M File eXpress
  830. X# Copyright 15 Dec 1991 by 
  831. X# Carson Wilson
  832. X# 1359 W. Greenleaf, #1D
  833. X# Chicago, IL 60626
  834. X#
  835. X# UUCP:    carson@sputnik.uucp
  836. X#     carson@ddsw1.MCS.COM
  837. X#
  838. X# BBS:    Antelope Freeway, 1-708-455-0120
  839. X#
  840. X# Name and path of C compiler:
  841. CC = tcc
  842. X
  843. X# Turbo C's home directory (also where WILDARGS.OBJ is)
  844. THOME = \DOS\TC
  845. X
  846. MDL = s
  847. X
  848. CFLAGS = -d- -y- -G -k- -N- -C- -A- -O -Z
  849. INCLUDES = $(THOME)\INCLUDE
  850. X
  851. TLINK = tlink
  852. TLFLAGS = /c /x
  853. LIBS = $(THOME)\LIB
  854. X
  855. X# Where to put compiled CFX.EXE
  856. BINDIR = \DOS
  857. X
  858. X.c.obj    :
  859. X    $(CC) $(CFLAGS) -I$(INCLUDES) -c -m$(MDL) $<
  860. X
  861. cfx.exe    : cfx.obj lbr.obj unc.obj usq.obj lzh.obj getopt.obj \
  862. X    $(THOME)\wildargs.obj
  863. X    $(TLINK) $(TLFLAGS) $(LIBS)\c0$(MDL) \
  864. X    cfx lbr unc usq lzh getopt $(THOME)\wildargs.obj, \
  865. X    cfx, cfx, $(LIBS)\c$(MDL)
  866. X
  867. install :
  868. X    copy cfx.exe $(BINDIR)
  869. X    del cfx.exe
  870. X
  871. clean    :
  872. X    del cfx.exe
  873. X    del cfx.obj
  874. X    del lbr.obj 
  875. X    del unc.obj 
  876. X    del usq.obj 
  877. X    del lzh.obj
  878. X    del getopt.obj
  879. X
  880. cfx.obj    : cfx.c cfx.h
  881. lbr.obj    : lbr.c cfx.h
  882. unc.obj    : unc.c cfx.h
  883. usq.obj    : usq.c cfx.h
  884. lzh.obj    : lzh.c cfx.h
  885. getopt.obj : getopt.c        # proprietary Borland code
  886. END_OF_FILE
  887. if test 1099 -ne `wc -c <'makefile.tc'`; then
  888.     echo shar: \"'makefile.tc'\" unpacked with wrong size!
  889. fi
  890. # end of 'makefile.tc'
  891. fi
  892. if test -f 'patchlev.h' -a "${1}" != "-c" ; then 
  893.   echo shar: Will not clobber existing file \"'patchlev.h'\"
  894. else
  895. echo shar: Extracting \"'patchlev.h'\" \(73 characters\)
  896. sed "s/^X//" >'patchlev.h' <<'END_OF_FILE'
  897. X/* Indicate which patches have been applied to CFX
  898. X*/
  899. X#define    PATCHLEV    0
  900. END_OF_FILE
  901. if test 73 -ne `wc -c <'patchlev.h'`; then
  902.     echo shar: \"'patchlev.h'\" unpacked with wrong size!
  903. fi
  904. # end of 'patchlev.h'
  905. fi
  906. if test -f 'unc.c' -a "${1}" != "-c" ; then 
  907.   echo shar: Will not clobber existing file \"'unc.c'\"
  908. else
  909. echo shar: Extracting \"'unc.c'\" \(11415 characters\)
  910. sed "s/^X//" >'unc.c' <<'END_OF_FILE'
  911. X/*
  912. UNC.C - Uncrunch module of CP/M File eXpress
  913. Copyright 20 Jan 1992 by 
  914. Carson Wilson
  915. X1359 W. Greenleaf, #1D
  916. Chicago, IL 60626
  917. X
  918. UUCP:    carson@sputnik.uucp
  919. X    ..!uunet!ddsw1!carson
  920. X
  921. BBS:    Antelope Freeway, 1-708-455-0120
  922. X
  923. Notes:
  924. X    Adapted from UNCRunch/C by Frank Prindle.
  925. X*/
  926. X
  927. X#include "cfx.h"
  928. X
  929. X#define DUMBLINKER
  930. X#define    TABLE_SIZE  4096    /* size of main LZW table for 12 bit codes */
  931. X#define    XLATBL_SIZE 5003    /* size of physical translation table  */
  932. X
  933. X/* Special values for predecessor in table */
  934. X#define    NOPRED 0x6fff        /* no predecessor in table */
  935. X#define    EMPTY  0x8000        /* empty table entry (xlatbl only) */
  936. X#define    REFERENCED 0x2000    /* table entry referenced if this bit set */
  937. X#define    IMPRED 0x7fff        /* impossible predecessor */
  938. X
  939. X#define    EOFCOD 0x100        /* special code for end-of-file */
  940. X#define    RSTCOD 0x101        /* special code for adaptive reset */
  941. X#define    NULCOD 0x102        /* special filler code */
  942. X#define    SPRCOD 0x103        /* spare special code */
  943. X
  944. X#ifdef        DUMBLINKER
  945. X
  946. X/* Main LZW table and its structure */
  947. struct entry
  948. X{    short predecessor;        /* index to previous entry, if any */
  949. X    unsigned char suffix;        /* character suffixed to previous entries */
  950. X} *table;
  951. X
  952. X/* auxilliary physical translation table */
  953. X/* translates hash to main table index */
  954. short *xlatbl;
  955. X
  956. X/*byte string stack used by decode */
  957. unsigned char *stack;
  958. X
  959. X#else
  960. X
  961. struct entry
  962. X{    short predecessor;        /*index to previous entry, if any */
  963. X        unsigned char suffix;        /*character suffixed to previous entries */
  964. X} table[TABLE_SIZE];
  965. X
  966. X/* Auxilliary physical translation table */
  967. X/*  translates hash to main table index */
  968. short xlatbl[XLATBL_SIZE];
  969. X
  970. X/* Byte string stack used by decode */
  971. unsigned char stack[TABLE_SIZE];
  972. X
  973. X#endif
  974. X
  975. X/* Other Global Variables */
  976. X
  977. unsigned char codlen;        /* Variable code length in bits (9-12)    */
  978. short trgmsk;            /* Mask for codes of current length    */
  979. unsigned char fulflg;        /* Full flag - set once main table is full */
  980. short entry;            /* Next available main table entry    */
  981. long getbuf;            /* Buffer used by getcode        */
  982. short getbit;            /* Residual bit counter used by getcode    */
  983. unsigned char entflg;        /* Inhibit main loop from entering this code */
  984. int finchar;            /* First character of last substring output */
  985. int lastpr;            /* Last predecessor (in main loop)    */
  986. X
  987. void initb2();
  988. int okflag;            /* Flags abort from nested routines */
  989. X
  990. unsigned char *stacklmt;        /* crw */
  991. X
  992. X/* ---------------------------------------------------------------- */
  993. X/*
  994. X    Uncrunch a single file.
  995. X*/
  996. void uncrunch(uncrfd, uncrfn, uncrfs)
  997. XFILE *uncrfd;
  998. char *uncrfn;
  999. long uncrfs;
  1000. X{
  1001. X    char *p;
  1002. X    char outfn[80];            /* space to build output file name   */
  1003. X    int pred;            /* current predecessor (in main loop)*/
  1004. X    unsigned char reflevel;     /* ref rev level from input file     */
  1005. X    unsigned char siglevel;     /* sig rev level from input file     */
  1006. X    unsigned char errdetect;    /* error detection flag from input file*/
  1007. X    unsigned file_cksum;        /* checksum read from input file     */
  1008. X
  1009. X    /* Extract and build output file name */
  1010. X
  1011. X    cgetc(uncrfd);    /* skip signature */
  1012. X    cgetc(uncrfd);
  1013. X    for ( p = outfn; (*p = (cgetc(uncrfd) & 0x7F)) != '\0' ; p++)
  1014. X    {
  1015. X        if (*p == '[')        /* comment separator */
  1016. X        {
  1017. X            *p = ' ';
  1018. X            *++p = '[';
  1019. X        }
  1020. X        else if (*p == 1)    /* DateStamper separator */
  1021. X            *p = '\0';
  1022. X    }
  1023. X
  1024. X    outcrlf(1);
  1025. X    printf("  --> %s", outfn);
  1026. X
  1027. X    *(cisubstr(outfn, ".") + 4) = '\0'; /* truncate non-name portion */
  1028. X
  1029. X    if (diskout)
  1030. X    {
  1031. X#ifdef UNIX
  1032. X        unixfn(outfn);
  1033. X        printf(" (%s)", outfn);
  1034. X#endif
  1035. X        /* Open output file */
  1036. X        if ( 0 == (outfd = fopen( outfn, "wb")) )
  1037. X        {    cerror("can't create %s!", outfn);
  1038. X            return;
  1039. X        }
  1040. X        }
  1041. X    else
  1042. X        outcrlf(2);
  1043. X
  1044. X    /* read the four info bytes */
  1045. X    reflevel  = cgetc(uncrfd);        /* currently not used */
  1046. X    siglevel  = cgetc(uncrfd);
  1047. X    errdetect = cgetc(uncrfd);
  1048. X    cgetc(uncrfd);    /* skip spare */
  1049. X
  1050. X    /* Make sure we can uncrunch this format file */
  1051. X    /* note: this program does not support CRUNCH 1.x format */
  1052. X    if (siglevel < 0x20 || siglevel > 0x2f)
  1053. X    {    cerror("need newer UNCR version.");
  1054. X        return;
  1055. X    }
  1056. X
  1057. X#ifdef        DUMBLINKER
  1058. X    /* Allocate storage now for the big tables (keeps load short) */
  1059. X    table    = (struct entry *) malloc(TABLE_SIZE * sizeof(struct entry ));
  1060. X    xlatbl    = (short *) malloc(XLATBL_SIZE * sizeof(short));
  1061. X    stack    = (unsigned char *) malloc(TABLE_SIZE * sizeof(char));
  1062. X    if (table == NULL || xlatbl == NULL || stack == NULL)
  1063. X    {       outcrlf(1);
  1064. X        cerror("not enough memory to uncrunch.");
  1065. X                goto uncrexit;
  1066. X        }
  1067. X#endif
  1068. X    /* Initialize variables for uncrunching a file */
  1069. X    intram();
  1070. X    stacklmt = stack + TABLE_SIZE;
  1071. X
  1072. X    /* Set up atomic code definitions */
  1073. X    initb2();
  1074. X
  1075. X    /* =============== MAIN DECODING LOOP ============= */
  1076. X    outreccount = 0;
  1077. X    pred = NOPRED;
  1078. X    okflag = 1;
  1079. X    while ((okflag)    &&            /* flags file corrupt */
  1080. X        (contin))            /* file skip command flag */
  1081. X    {
  1082. X        lastpr = pred;                 /* Remember last predecessor */
  1083. X
  1084. X        /* Read and process one code */
  1085. X        if ((pred = getcode(uncrfd)) == EOFCOD)    /* End-of-file code */
  1086. X            break;                /* All LZW codes read*/
  1087. X        else if (pred == RSTCOD) /* reset code */
  1088. X        {    entry = 0;
  1089. X            fulflg = 0;
  1090. X            codlen = 9;
  1091. X            trgmsk = 0x1ff;
  1092. X            pred = NOPRED;
  1093. X            entflg = 1;
  1094. X            initb2();
  1095. X        }
  1096. X        else    /* A normal code (nulls already deleted) */
  1097. X        {       /* Check for table full */
  1098. X            if (fulflg != 2)
  1099. X                /* Strategy if table not full */
  1100. X                if (decode(pred) == 0)
  1101. X                    enterx(lastpr, finchar);
  1102. X                else
  1103. X                    entflg = 0;
  1104. X            else
  1105. X            {    /* Strategy if table is full */
  1106. X                decode(pred);
  1107. X                entfil(lastpr, finchar); /* attempt reassign */
  1108. X            }
  1109. X        }
  1110. X    }
  1111. X    /* Verify checksum if required */
  1112. X    if ((errdetect == 0) && (contin))
  1113. X    {    file_cksum = cgetc(uncrfd);
  1114. X        file_cksum |= cgetc(uncrfd) << 8;
  1115. X        cksum &= 0xFFFF;
  1116. X        if (file_cksum != cksum)
  1117. X            cerror("checksum error: expected: %04xh actual: %04xh", file_cksum, cksum);
  1118. X    }
  1119. X    uncrexit:
  1120. X#ifdef DUMBLINKER
  1121. X    free(table);
  1122. X    free(xlatbl);
  1123. X    free(stack);
  1124. X#endif
  1125. X}
  1126. X/* ---------------------------------------------------------------- */
  1127. X/*
  1128. X    Initialize variables for each file to be uncrunched.
  1129. X*/
  1130. void intram()
  1131. X{
  1132. X    trgmsk = 0x1ff;        /* Nine bits    */
  1133. X    codlen = 9;        /*  "        */
  1134. X    fulflg = 0;        /* Table empty    */
  1135. X    entry = 0;        /*  "        */
  1136. X    getbit = 0;        /* Buffer emtpy    */
  1137. X    entflg = 1;        /* First code always atomic    */
  1138. X    repeat_flag = 0;    /* Repeat not active */
  1139. X    getbuf = 0L;        /* crw */
  1140. X}
  1141. X/* ---------------------------------------------------------------- */
  1142. X/*
  1143. X    Initialize the LZW and physical translation tables.
  1144. X*/
  1145. void initb2()
  1146. X{
  1147. X    register int i;
  1148. X
  1149. X    /* First mark all entries of xlatbl as empty */
  1150. X    for (i = 0; i < XLATBL_SIZE; i++)
  1151. X        xlatbl[i] = EMPTY;
  1152. X
  1153. X    /* Enter atomic and reserved codes into LZW table */
  1154. X    for (i = 0; i < 0x100; i++)
  1155. X        enterx(NOPRED, i);    /* First 256 atomic codes */
  1156. X    for (i = 0; i < 4; i++)
  1157. X        enterx(IMPRED, 0);    /* Reserved codes */
  1158. X}
  1159. X/* ---------------------------------------------------------------- */
  1160. X/*
  1161. X    Enter the next code into the LZW table.
  1162. X*/
  1163. void enterx(pred, suff)
  1164. int pred;        /* Table index of predecessor    */
  1165. int suff;        /* Suffix byte represented by this entry */
  1166. X{
  1167. X    register struct entry *ep;
  1168. X    ep = &table[entry];    /* entry is a global */
  1169. X
  1170. X    /* Update xlatbl to point to this entry */
  1171. X    figure(pred, suff);
  1172. X
  1173. X    /* Make the new entry */
  1174. X    ep->predecessor = (short)pred;
  1175. X    ep->suffix = (unsigned char)suff;
  1176. X    entry++;
  1177. X
  1178. X    /* If only one entry of the current code length remains, update to */
  1179. X    /*  next code length because main loop is reading one code ahead */
  1180. X    if (entry >= trgmsk)
  1181. X        if (codlen < 12)
  1182. X        {
  1183. X            /* Table not full, just make length one more bit */
  1184. X            codlen++;
  1185. X            trgmsk = (trgmsk << 1) | 1;
  1186. X        }
  1187. X        else
  1188. X            /* Table almost full (fulflg==0) or full (fulflg==1) */
  1189. X            /*  just increment fulflg - when it gets to 2 we     */
  1190. X            /*  will never be called again */
  1191. X            fulflg++;
  1192. X}
  1193. X/* ---------------------------------------------------------------- */
  1194. X/*
  1195. X    Find an empty entry in xlatbl which hashes from this
  1196. X      predecessor/suffix combo, and store the index of the
  1197. X      next available LZW table entry in it.
  1198. X*/
  1199. void figure(pred, suff)
  1200. int pred;
  1201. int suff;
  1202. X{
  1203. X    short *hash();
  1204. X    /* auto int disp; */
  1205. X    int disp;
  1206. X    register short *p;
  1207. X    p = hash(pred, suff, &disp);
  1208. X
  1209. X    /* Follow secondary hash chain as necessary to find an empty slot */
  1210. X    while (((*p) & 0xffff) != EMPTY)
  1211. X    {
  1212. X        p += disp;
  1213. X        if (p < xlatbl || p > xlatbl + XLATBL_SIZE)
  1214. X            p += XLATBL_SIZE;
  1215. X    }
  1216. X
  1217. X    /* Stuff next available index into this slot */
  1218. X    *p = entry;
  1219. X}
  1220. X/* ---------------------------------------------------------------- */
  1221. X/*
  1222. X    Hash pred/suff into xlatbl pointer.
  1223. X    Duplicates the hash algorithm used by CRUNCH 2.3.
  1224. X*/
  1225. short *hash(pred, suff, disploc)
  1226. int pred;
  1227. int suff;
  1228. int *disploc;
  1229. X{
  1230. X    register int hashval;
  1231. X
  1232. X    hashval = ((((pred >> 4) & 0xff) ^ suff) | ((pred & 0xf) << 8)) + 1;
  1233. X    *disploc = hashval - XLATBL_SIZE;
  1234. X    return (xlatbl + hashval);
  1235. X}
  1236. X/* ---------------------------------------------------------------- */
  1237. X/*
  1238. X    Return a code of length "codlen" bits from the input file
  1239. X      bit-stream.
  1240. X*/
  1241. getcode(gcodefd)
  1242. XFILE *gcodefd;
  1243. X{
  1244. X    register int hole;
  1245. X    int code;
  1246. X
  1247. X    /* Always get at least a byte */
  1248. X    getbuf = (getbuf << codlen) | (((long) cgetc(gcodefd)) << (hole = codlen - getbit));
  1249. X    getbit = 8 - hole;
  1250. X
  1251. X    /* If is not enough to supply codlen bits, get another byte */
  1252. X    if (getbit < 0)
  1253. X    {
  1254. X        getbuf |= ((long) cgetc(gcodefd)) << (hole - 8);
  1255. X        getbit += 8;
  1256. X    }
  1257. X
  1258. X    if (feof(gcodefd))
  1259. X    {    cerror("unexpected EOF on input file.");
  1260. X        return EOFCOD;
  1261. X    }
  1262. X
  1263. X    /* Skip spare or null codes */
  1264. X    if ((code = ((getbuf >> 8) & trgmsk)) == NULCOD || code == SPRCOD)
  1265. X        return getcode(gcodefd);    /* Skip this code, get next */
  1266. X    return code;
  1267. X}
  1268. X/* ---------------------------------------------------------------- */
  1269. X/*
  1270. X    Decode this code.
  1271. X*/
  1272. decode(code)
  1273. short code;
  1274. X{
  1275. X    register unsigned char *stackp;     /* Byte string stack pointer */
  1276. X    register struct entry *ep;
  1277. X
  1278. X    ep = &table[code];
  1279. X
  1280. X    if (code >= entry)
  1281. X    {
  1282. X        /* The ugly exception, "WsWsW" */
  1283. X        entflg = 1;
  1284. X        enterx(lastpr, finchar);
  1285. X    }
  1286. X
  1287. X    /* Mark corresponding table entry as referenced */
  1288. X    ep->predecessor |= REFERENCED;
  1289. X
  1290. X    /* Walk back the LZW table starting with this code */
  1291. X    stackp = stack;
  1292. X
  1293. X    /* Prevent overrun with corrupt files <crw> */
  1294. X    while (ep > &table[255])    /* i.e. code not atomic */
  1295. X    {
  1296. X        *stackp++ = ep->suffix;
  1297. X        ep = &table[(ep->predecessor)&0xfff];
  1298. X        if (stackp > stacklmt)
  1299. X        {
  1300. X            cerror("CRUNCHed file corrupt: aborting.");
  1301. X            okflag = 0;
  1302. X            return(entflg);
  1303. X        }
  1304. X    }
  1305. X
  1306. X    /* Then emit all bytes corresponding to this code in forward order */
  1307. X    send(finchar = (ep->suffix) & 0xff);    /*first byte*/
  1308. X
  1309. X    while (stackp > stack)            /*the rest*/
  1310. X        send(*--stackp);
  1311. X
  1312. X    return(entflg);
  1313. X}
  1314. X/* ----------------------------------------------------------------- */
  1315. X/*
  1316. X    Attempt to reassign an existing code which has been defined,
  1317. X      but never referenced.
  1318. X*/
  1319. void entfil(pred, suff)
  1320. int pred;        /* Table index of predecessor    */
  1321. int suff;        /* Suffix byte represented by this entry */
  1322. X{
  1323. X    auto int disp;
  1324. X    register struct entry *ep;
  1325. X    short *hash();
  1326. X    short *p;
  1327. X    p = hash(pred, suff, &disp);
  1328. X
  1329. X    /* Search the candidate codes (all those which hash from this new */
  1330. X    /*   predecessor and suffix) for an unreferenced one    */
  1331. X    while (*p != (short)EMPTY)
  1332. X    {
  1333. X            /* Candidate code */
  1334. X        ep = &table[*p];
  1335. X        if (((ep->predecessor) & REFERENCED) == 0)
  1336. X        {
  1337. X            /* Entry reassignable, so do it! */
  1338. X            ep->predecessor = pred;
  1339. X            ep->suffix = suff;
  1340. X            /* discontinue search */
  1341. X            break;
  1342. X        }
  1343. X        /* Candidate unsuitable - follow secondary hash chain */
  1344. X        /*  and keep searching    */
  1345. X        p += disp;
  1346. X        if (p < xlatbl || p > xlatbl + XLATBL_SIZE)
  1347. X            p += XLATBL_SIZE;
  1348. X    }
  1349. X}
  1350. X/* End of UNC.C */
  1351. END_OF_FILE
  1352. if test 11415 -ne `wc -c <'unc.c'`; then
  1353.     echo shar: \"'unc.c'\" unpacked with wrong size!
  1354. fi
  1355. # end of 'unc.c'
  1356. fi
  1357. if test -f 'unixfunc.c' -a "${1}" != "-c" ; then 
  1358.   echo shar: Will not clobber existing file \"'unixfunc.c'\"
  1359. else
  1360. echo shar: Extracting \"'unixfunc.c'\" \(1435 characters\)
  1361. sed "s/^X//" >'unixfunc.c' <<'END_OF_FILE'
  1362. X/*
  1363. UNIXFUNC.C - Unix functions module of CP/M File eXpress
  1364. Copyright 15 Dec 1991 by 
  1365. Carson Wilson
  1366. X1359 W. Greenleaf, #1D
  1367. Chicago, IL 60626
  1368. X
  1369. UUCP:    carson@sputnik.uucp
  1370. X    carson@ddsw1.MCS.COM
  1371. X
  1372. BBS:    Antelope Freeway, 1-708-455-0120
  1373. X*/
  1374. X
  1375. X#include "cfx.h"
  1376. X#include <termio.h>
  1377. X
  1378. struct    termio save, term;    /* terminal status buffer */
  1379. X
  1380. X/* ---------------------------------------------------------------- */
  1381. X/*
  1382. X    Select "raw" tty mode.
  1383. X*/
  1384. int ttyraw()
  1385. X{
  1386. X    if ( ioctl (0, TCGETA, &term) == -1) {
  1387. X        fprintf (stderr, "standard input not a tty\n");
  1388. X        exit (1);    
  1389. X    }
  1390. X
  1391. X    /* save old tty state */
  1392. X    save = term;
  1393. X
  1394. X    /* turn off canonical processing */
  1395. X    term.c_lflag &= ~ICANON;
  1396. X
  1397. X    /* zero out echo bit of c_lflag */
  1398. X    term.c_lflag &= ~ECHO;
  1399. X
  1400. X    /* set MIN and TIME to zero */
  1401. X    term.c_cc[VMIN] = 0;
  1402. X    term.c_cc[VTIME] = 0;
  1403. X
  1404. X    /* set new terminal state */
  1405. X    ioctl (0, TCSETA, &term);
  1406. X}
  1407. X/* ---------------------------------------------------------------- */
  1408. X/*
  1409. X    Restore tty state.
  1410. X*/
  1411. int ttyrestore()
  1412. X{
  1413. X    /* reset old tty state */
  1414. X    ioctl (0, TCSETA, &save);
  1415. X
  1416. X}
  1417. X/* ---------------------------------------------------------------- */
  1418. X/*
  1419. X    Translate CP/M filename to Unix
  1420. X*/
  1421. void unixfn(inputfn)
  1422. char *inputfn;
  1423. X{
  1424. X    char    tempfn[30];
  1425. X    char    *fnptr = tempfn;
  1426. X    char    *inputptr = inputfn;
  1427. X
  1428. X    *fnptr = '\0';
  1429. X    for ( ; *inputptr ; inputptr++)
  1430. X        if ((*inputptr & 0x7F) != ' ')
  1431. X            *fnptr++ = (tolower(*inputptr) & 0x7F);
  1432. X    *fnptr = '\0';
  1433. X    strcpy(inputfn, tempfn);
  1434. X}
  1435. X/* End of UNIXFUNC.C */
  1436. END_OF_FILE
  1437. if test 1435 -ne `wc -c <'unixfunc.c'`; then
  1438.     echo shar: \"'unixfunc.c'\" unpacked with wrong size!
  1439. fi
  1440. # end of 'unixfunc.c'
  1441. fi
  1442. if test -f 'usq.c' -a "${1}" != "-c" ; then 
  1443.   echo shar: Will not clobber existing file \"'usq.c'\"
  1444. else
  1445. echo shar: Extracting \"'usq.c'\" \(3526 characters\)
  1446. sed "s/^X//" >'usq.c' <<'END_OF_FILE'
  1447. X/*
  1448. USQ.C - Unsqueeze module of CP/M File eXpress
  1449. Copyright 20 Jan 1992 by 
  1450. Carson Wilson
  1451. X1359 W. Greenleaf, #1D
  1452. Chicago, IL 60626
  1453. X
  1454. UUCP:    carson@sputnik.uucp
  1455. X    ..!uunet!ddsw1!carson
  1456. X
  1457. BBS:    Antelope Freeway, 1-708-455-0120
  1458. X*/
  1459. X
  1460. X#include "cfx.h"
  1461. X
  1462. X/* Stuff for Huffman unsqueezing */
  1463. X
  1464. X#define SPEOF 256            /* special endfile token */
  1465. X#define NUMVALS 257            /* 256 data values plus SPEOF */
  1466. X
  1467. X#ifdef DUMBLINKER
  1468. X
  1469. struct nd                /* decoding tree */
  1470. X{
  1471. X    int child[2];            /* left, right */
  1472. X} *node;
  1473. X
  1474. X#else
  1475. X
  1476. struct nd                /* decoding tree */
  1477. X{
  1478. X    int child[2];            /* left, right */
  1479. X} node[NUMVALS];            /* use large buffer */
  1480. X
  1481. X#endif
  1482. X
  1483. static int bpos;            /* last bit position read */
  1484. static int curin;            /* last byte value read */
  1485. static int numnodes;            /* number of nodes in decode tree */
  1486. X
  1487. char *usqnptr;                /* global squeezed file name */
  1488. X
  1489. X/* ------------------------------------------------------------------ */
  1490. X
  1491. static int get_int(f)            /* get an integer */
  1492. XFILE *f;                /* file to get it from */
  1493. X{
  1494. X    int i;
  1495. X
  1496. X    i = cgetc(f);
  1497. X    return (short) (i | (cgetc(f) << 8));
  1498. X}
  1499. X/* ------------------------------------------------------------------ */
  1500. X
  1501. int init_usq(f)                /* initialize Huffman unsqueezing */
  1502. XFILE *f;                /* file containing squeezed data */
  1503. X{
  1504. X    int i;                /* node index */
  1505. X
  1506. X    bpos = 99;            /* force initial read */
  1507. X
  1508. X    numnodes = get_int(f);
  1509. X
  1510. X    if (numnodes < 0 || numnodes >= NUMVALS)
  1511. X    {    cerror("invalid decode tree.");
  1512. X        return (0);
  1513. X    }
  1514. X
  1515. X    /* initialize for possible empty tree (SPEOF only) */
  1516. X
  1517. X    node[0].child[0] = -(SPEOF + 1);
  1518. X    node[0].child[1] = -(SPEOF + 1);
  1519. X
  1520. X    for (i = 0; i < numnodes; ++i)    /* get decoding tree from file */
  1521. X    {    node[i].child[0] = get_int(f);
  1522. X        node[i].child[1] = get_int(f);
  1523. X    }
  1524. X    return (1);
  1525. X}
  1526. X/* ------------------------------------------------------------------ */
  1527. X
  1528. int getc_usq(f)                /* get byte from squeezed file */
  1529. XFILE *f;                /* file containing squeezed data */
  1530. X{
  1531. X    int i;                /* tree index */
  1532. X
  1533. X    /* follow bit stream in tree to a leaf */
  1534. X
  1535. X    for (i = 0; i >= 0; )        /* work down(up?) from root */
  1536. X    {    if (++bpos > 7)
  1537. X        {    if ((curin = cgetc(f)) == EOF)
  1538. X                return(EOF);
  1539. X            bpos = 0;
  1540. X
  1541. X            /* move a level deeper in tree */
  1542. X            i = node[i].child[1&curin];
  1543. X        }
  1544. X        else
  1545. X            i = node[i].child[1 & (curin >>= 1)];
  1546. X    }
  1547. X
  1548. X    /* decode fake node index to original data value */
  1549. X
  1550. X    i = -(i + 1);
  1551. X
  1552. X    /* decode special endfile token to normal EOF */
  1553. X
  1554. X    i = (i == SPEOF) ? EOF : i;
  1555. X    return i;
  1556. X}
  1557. X/* ==================================================================== */
  1558. X
  1559. void unsqueeze(usqfd, usqfn, usqflen)
  1560. XFILE *usqfd;
  1561. char *usqfn;
  1562. long usqflen;
  1563. X{
  1564. X    unsigned usqfcrc;
  1565. X    int tchar;
  1566. X    char *p;
  1567. X    char outfn[80];            /* space to build output file name   */
  1568. X
  1569. X    get_int(usqfd);            /* skip ID bytes */
  1570. X    usqfcrc = get_int(usqfd);
  1571. X    usqnptr = usqfn;
  1572. X
  1573. X    /* Extract and build output file name*/
  1574. X
  1575. X    for ( p = outfn; (*p = cgetc(usqfd)) != '\0' ; p++);
  1576. X#ifdef UNIX
  1577. X    unixfn(outfn);
  1578. X#endif
  1579. X    outcrlf(1);
  1580. X    printf("  --> %s", outfn);
  1581. X
  1582. X    *(cisubstr(outfn, ".") + 4) = '\0'; /*truncate non-name portion*/
  1583. X
  1584. X    if (diskout)
  1585. X    {    /* Open output file */
  1586. X        if ( 0 == (outfd = fopen( outfn, "wb")) )
  1587. X        {    cerror("can't create %s", outfn);
  1588. X            return;
  1589. X        }
  1590. X    }
  1591. X    else
  1592. X        outcrlf(2);
  1593. X#ifdef DUMBLINKER
  1594. X    /* Allocate storage now for the table (keeps load short) */
  1595. X    node = (struct nd *) malloc(NUMVALS * sizeof(struct nd));
  1596. X#endif
  1597. X    if (init_usq(usqfd) == 0)
  1598. X        return;
  1599. X
  1600. X    outreccount = 0;
  1601. X
  1602. X    while ((tchar = getc_usq(usqfd)) != EOF && (contin))
  1603. X        send(tchar);
  1604. X    cksum &= 0xFFFF;
  1605. X    if (usqfcrc != cksum)
  1606. X        cerror("checksum error: expected: %04xh actual: %04xh", usqfcrc, cksum);
  1607. X    free(node);
  1608. X}
  1609. X/* End of USQ.C */
  1610. END_OF_FILE
  1611. if test 3526 -ne `wc -c <'usq.c'`; then
  1612.     echo shar: \"'usq.c'\" unpacked with wrong size!
  1613. fi
  1614. # end of 'usq.c'
  1615. fi
  1616. echo shar: End of archive 1 \(of 2\).
  1617. cp /dev/null ark1isdone
  1618. MISSING=""
  1619. for I in 1 2 ; do
  1620.     if test ! -f ark${I}isdone ; then
  1621.     MISSING="${MISSING} ${I}"
  1622.     fi
  1623. done
  1624. if test "${MISSING}" = "" ; then
  1625.     echo You have unpacked both archives.
  1626.     rm -f ark[1-9]isdone
  1627. else
  1628.     echo You still need to unpack the following archives:
  1629.     echo "        " ${MISSING}
  1630. fi
  1631. ##  End of shell archive.
  1632. exit 0
  1633.  
  1634. exit 0 # Just in case...
  1635.