home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume28 / cfx / part02 < prev    next >
Encoding:
Text File  |  1992-02-02  |  53.2 KB  |  1,797 lines

  1. Newsgroups: comp.sources.misc
  2. From: carson@sputnik.uucp (Carson Wilson)
  3. Subject:  v28i013:  cfx - Cp/m File eXpress, v1.1.0, Part02/02
  4. Message-ID: <1992Feb3.031705.4652@sparky.imd.sterling.com>
  5. X-Md4-Signature: eb7446310c2eefc2371d058624dfb404
  6. Date: Mon, 3 Feb 1992 03:17:05 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: carson@sputnik.uucp (Carson Wilson)
  10. Posting-number: Volume 28, Issue 13
  11. Archive-name: cfx/part02
  12. Environment: UNIX, MS-DOS, PC
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of archive 2 (of 2)."
  21. # Contents:  cfx.c cfx.doc cfx.h cfx.hst cfx.man cfx.1
  22. # Wrapped by carson@sputnik on Sat Jan 25 10:39:45 1992
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f 'cfx.c' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'cfx.c'\"
  26. else
  27. echo shar: Extracting \"'cfx.c'\" \(18746 characters\)
  28. sed "s/^X//" >'cfx.c' <<'END_OF_FILE'
  29. X/*
  30. CFX.C - Main module of CP/M File eXpress
  31. Copyright 20 Jan 1992 by 
  32. Carson Wilson
  33. X1359 W. Greenleaf, #1D
  34. Chicago, IL 60626
  35. X
  36. UUCP:    carson@sputnik.uucp
  37. X    ..!uunet!ddsw1!carson
  38. X
  39. BBS:    Antelope Freeway, 1-708-455-0120
  40. X
  41. Version:    1.1
  42. Date:        25 Jan 92
  43. Author:        Copr. 1992 by Carson Wilson
  44. Changes:    Initial universal version.
  45. X        Normal exit now always returns 0.
  46. X        Added .GIF, .ZOO to file exclusion list.
  47. X        Minor cosmetic tweaks.
  48. X
  49. Notes:        Compiles under ISC SYSVR3.2 v2.2.1 SDS
  50. X          and with MSDOS Turbo C 2.01.
  51. X*/
  52. X/* ======================================================= */
  53. X
  54. X#include "cfx.h"
  55. X#include <sys/stat.h>
  56. X
  57. X/* External variables */
  58. X
  59. unsigned cksum;            /* Checksum of all bytes written to output */
  60. unsigned outreccount;        /* Number of bytes written to output record */
  61. unsigned long mlength;        /* library member length */
  62. X
  63. unsigned char repeat_flag;    /* So send can remember if repeat required*/
  64. long unclength;             /* global for library members */
  65. X
  66. char *infname;            /* Current input file name */
  67. XFILE *infd;            /* Currently open input file */
  68. XFILE *outfd;            /* Currently open output file */
  69. X
  70. X/* Command line flags */
  71. X
  72. int brief = 0;            /* -b brief output only */
  73. int cdline = 0;            /* -c command line argument (0..4) */
  74. int diskout = 0;        /* -d disk output flag */
  75. int uncompress = 1;        /* -n no uncompress flag */
  76. int info = 0;            /* -i info only flag */
  77. int prompt = 0;            /* -p prompt flag */
  78. time_t timelmt = 0;        /* -t time limit command line argument */
  79. int waitflag = 0;        /* -w wait for key at end of files */
  80. X
  81. X/* Internal flags */
  82. X
  83. int inlbr;            /* library file flag */
  84. int contin = 1;            /* Global abort flag */
  85. int scrline = 1;        /* Current screen line for [more] */
  86. int pause = 1;            /* Pause at each screenful */
  87. int infoflag;            /* Display directory info */
  88. X
  89. char membername[40] = "";
  90. X
  91. struct stat fsstruct;        /* file status buffer */
  92. struct tm *ftsptr;
  93. X
  94. time_t nowtime, starttime;    /* -t time buffers */
  95. X
  96. int fileyear, filemonth, fileday;
  97. X
  98. X/* ============================ MAIN PROGRAM =========================== */
  99. X
  100. int main(argc, argv)
  101. int argc;
  102. char *argv[];
  103. X{
  104. X    extern int optind;        /* pointer to remaining arguments */
  105. X    extern char *optarg;        /* pointer to current argument */
  106. X    extern int opterr;        /* getopt() control */
  107. X    int badopt = 0;
  108. X    int c;
  109. X    int fhandle;
  110. X
  111. X#ifdef UNIX
  112. X    char DOSSW = '-';
  113. X#else
  114. X    char DOSSW;            /* MSDOS command line switch */
  115. X    _AX = 0x3700;                   /* Get SW using DOS call 0x37 */
  116. X    geninterrupt(0x21);
  117. X    DOSSW = _DL;            /* save DOS "switch" character */
  118. X#endif
  119. X
  120. X    /* Process global variables */
  121. X    opterr = 0;            /* disallow getopt messages */
  122. X
  123. X    while ((c = getopt (argc, argv, "bBc:C:dDiIm:M:nNpPt:T:wW")) != EOF )
  124. X        switch (tolower(c))
  125. X        {
  126. X        case 'b' : brief = 1;
  127. X               break;
  128. X#ifndef UNIX
  129. X        case 'c' : cdline = atoi(optarg);
  130. X               if (strcmp(optarg, "0") && (!cdline))
  131. X                badopt = 1;    /* allow /c0 = console */
  132. X               break;
  133. X#endif
  134. X        case 'd' : diskout = 1;
  135. X               break;
  136. X        case 'i' : info = 1;        /* info only */
  137. X               break;
  138. X        case 'm' : strcpy(membername, optarg);
  139. X               break;
  140. X        case 'n' : uncompress = 0;
  141. X               break;
  142. X        case 'p' : prompt = 1;
  143. X               break;
  144. X        case 't' : timelmt = atoi(optarg);
  145. X               if (!timelmt)    /* -t 0 or illegal */
  146. X                badopt = 1;
  147. X               else
  148. X                timelmt *= 60;    /* in seconds */
  149. X               break;
  150. X        case 'w' : waitflag = 1;
  151. X               break;
  152. X        case '?' :
  153. X        default  : badopt = 1;
  154. X               break;
  155. X        }
  156. X
  157. X    if (badopt || (optind == argc))
  158. X    {       printf("\n%s - Cp/m File eXpress for %s, Rev. %s, Copr. 1992 by %s\n",
  159. X            PROGNAME, OSTYPE, VERS, AUTHOR);
  160. X        printf("  Usage:\n");
  161. X        printf("        %s [option ...] afn ...\n", PROGNAME);
  162. X        printf("  Options:\n");
  163. X        printf("        %cb       - brief output only\n", DOSSW);
  164. X#ifndef UNIX
  165. X        printf("        %cc n     - monitor COMn for carrier\n", DOSSW);
  166. X#endif
  167. X        printf("        %cd       - disk output\n", DOSSW);
  168. X        printf("        %ci       - display file info only\n", DOSSW);
  169. X        printf("        %cm \"afn\" - library member specification\n", DOSSW);
  170. X        printf("        %cn       - don't uncompress library members\n", DOSSW);
  171. X        printf("        %cp       - prompt before processing files\n", DOSSW);
  172. X        printf("        %ct n     - maximum minutes allowed\n", DOSSW);
  173. X        printf("        %cw       - wait after last file\n", DOSSW);
  174. X#ifdef UNIX
  175. X        printf("\n");
  176. X#endif
  177. X        exit(0);
  178. X    }
  179. X#ifdef UNIX
  180. X    ttyraw();            /* select raw tty input */
  181. X#endif
  182. X    if (timelmt)            /* -t option */
  183. X           time(&starttime);    /* log start time */
  184. X
  185. X    /* Do all the files specified */
  186. X    argv += optind;
  187. X    argc -= optind;            /* subtract */
  188. X    while (argc--)
  189. X    {    inlbr = 0;
  190. X        infname = *argv++;
  191. X        /* Open input file */
  192. X        tryopen:
  193. X        if ( 0 == (infd = fopen(infname, "rb")) )
  194. X        {    if (!strchr(infname, '.'))
  195. X            {
  196. X                infname = strcat(infname, LBREXT);
  197. X                goto tryopen;
  198. X            }
  199. X            else
  200. X            {    outcrlf(1);
  201. X                printf("  %s: can't open file \"%s\".", PROGNAME, infname);
  202. X                outcrlf(1);
  203. X            }
  204. X        }
  205. X        else
  206. X        {    /* preload file datestamp */
  207. X            fhandle = fileno(infd);
  208. X            fstat(fhandle, &fsstruct);
  209. X            ftsptr = localtime(&fsstruct.st_mtime);
  210. X            fileyear = ftsptr->tm_year;
  211. X            filemonth = ftsptr->tm_mon;
  212. X            fileday = ftsptr->tm_mday;
  213. X            infoflag = info;
  214. X            outcrlf(1);        /* count linefeeds */
  215. X            printf(" File Name    Length   Method     Date");
  216. X            outcrlf(1);
  217. X            printf("============  ======  ========  ========");
  218. X            process(infd, infname, fsstruct.st_size);
  219. X            fclose(infd);
  220. X        }
  221. X        outcrlf(1);
  222. X    }
  223. X    checkwait();
  224. X    quit();            /* done */
  225. X    return(0);        /* else compiler warning */
  226. X}
  227. X/* ---------------------------------------------------------------- */
  228. X/*
  229. X    Process a single file.
  230. X*/
  231. void process(procfd, procfn, procfs)
  232. XFILE *procfd;            /* opened file descriptor */
  233. char *procfn;            /* name of opened file    */
  234. long procfs;
  235. X{
  236. X    int mresult;
  237. X    int procch;
  238. X    char *procptr;
  239. X
  240. X    /* Upcase name */
  241. X#ifndef UNIX
  242. X    stupcase(procfn);
  243. X#endif
  244. X    /* Strip leading modifiers */
  245. X    procptr = strrchr(procfn, DIRSEPCHAR);
  246. X    if (procptr++ == NULLCHARPTR)        /* DIRSEPCHAR not found */
  247. X    {    procptr = strrchr(procfn, ':');
  248. X            if (procptr++ == NULLCHARPTR)    /* ':' not found */
  249. X                procptr = procfn;
  250. X    }
  251. X    procfn = procptr;
  252. X    outcrlf(1);
  253. X    printf("%-12s  %6u  ", procfn, procfs);
  254. X
  255. X    mresult = method(procfd, procfn, procfs);
  256. X    switch (mresult)
  257. X    {
  258. X    case 0 :
  259. X    case 1 : printf("%s", " Stored ");
  260. X         break;
  261. X    case 2 :
  262. X    case 3 : printf("%s", "Squeezed");
  263. X         break;
  264. X    case 4 :
  265. X    case 5 : printf("%s", "Crunched");
  266. X         break;
  267. X    case 6 :
  268. X    case 7 : printf("%s", " Cr-lzh ");
  269. X         break;
  270. X    case 8 : printf("%s", "Library ");
  271. X         break;
  272. X    }
  273. X    /* print date */
  274. X    printf("  %02d-%02d-%02d", filemonth, fileday, fileyear);
  275. X
  276. X    if (mresult == 8)             /* library file */
  277. X    {    /* don't show initial info on lbrs in lbrs */
  278. X        if (infoflag && inlbr && !info)
  279. X            goto alldone;
  280. X        inlbr = 1;
  281. X        outcrlf(2);
  282. X        printf("member name   length   method     date");
  283. X        outcrlf(1);
  284. X        printf("------------  ------  --------  --------");
  285. X        lbr(procfd);
  286. X        if (infoflag)
  287. X            goto alldone;
  288. X        else
  289. X            goto filedone;
  290. X    }
  291. X
  292. X    if (infoflag)
  293. X        goto alldone;
  294. X
  295. X    if (!diskout)
  296. X    {    if ((mresult == 1) || (mresult == 3) || (mresult == 5) ||
  297. X            (mresult == 7) ||
  298. X            ((mresult) && (!uncompress)))
  299. X        {    printf("  Can't display binary file.");
  300. X            goto alldone;
  301. X        }
  302. X        else
  303. X            outfd = stdout;        /* default */
  304. X    }
  305. X    else if (!inlbr)
  306. X        if ( (mresult == 0) || (mresult == 1) || !uncompress )
  307. X        {    printf("  Input and output files identical.");
  308. X            goto alldone;
  309. X        }
  310. X
  311. X    if (prompt)
  312. X    {    scrline = 1;            /* reset [more] flag */
  313. X        printf("  %s (y/N/q)? ", (diskout ? "Extract" : "View"));
  314. X        procch = toupper(mgetch(WAIT));
  315. X        if (isprint(procch))
  316. X            printf("%c ", procch);
  317. X        switch (procch)
  318. X        { case 3   :            /* ^C, ^K, ^N */
  319. X          case 11  :
  320. X          case 14  :
  321. X          case 'Q' : cfabort();        /* abort */
  322. X                 break;
  323. X          case 'Y' : scrline = 1;
  324. X                 break;
  325. X          default  : goto alldone;
  326. X        }
  327. X    }
  328. X    cksum = 0;
  329. X    if (!diskout)
  330. X    {    if (prompt)
  331. X            outcrlf(1);
  332. X        printf("  [^c=quit ^x=next file ^z=eof]");
  333. X    }
  334. X
  335. X    if (uncompress && ((mresult == 2) || (mresult == 3)))
  336. X        /* squeezed */
  337. X        unsqueeze(procfd, procfn, procfs);
  338. X    else if (uncompress && ((mresult == 4) || (mresult == 5)))
  339. X            /* crunched */
  340. X        uncrunch(procfd, procfn, procfs);
  341. X    else if (uncompress && ((mresult == 6) || (mresult == 7)))
  342. X        /* LZH encoded */
  343. X        unlzh(procfd, procfn, procfs);
  344. X    else
  345. X    {    if (diskout)
  346. X        {
  347. X#ifdef UNIX
  348. X            unixfn(procfn);
  349. X#endif
  350. X            outfd = fopen(procfn, "wb");
  351. X            outreccount = 0;
  352. X        }
  353. X        else
  354. X            outcrlf(2);
  355. X        while (((procch = cgetc(procfd)) != EOF) && (contin))
  356. X            output(procch, outfd);
  357. X    }
  358. X    /* All done this file */
  359. X    filedone:
  360. X    if (diskout)              /* Don't "close" console! */
  361. X    {
  362. X#ifndef UNIX
  363. X        /* A fixup for MSDOS: Make CP/M files even sector size */
  364. X        while(outreccount)
  365. X            output(0x1a, outfd); /* pad with EOFs */
  366. X#endif
  367. X        fclose(outfd);
  368. X    }
  369. X    alldone:
  370. X    pause = 1;
  371. X}
  372. X/* ---------------------------------------------------------------- */
  373. X/*
  374. X    Determine file storage method.
  375. X    0 = normal file
  376. X    1 = binary file         (per file EXTent)
  377. X    2 = squeezed normal file
  378. X    3 = squeezed binary file ( "    "    "   )
  379. X    4 = crunched normal file
  380. X    5 = crunched binary file ( "    "    "   )
  381. X    6 = LZH normal file
  382. X    7 = LZH binary file     ( "    "    "   )
  383. X    8 = library file
  384. X*/
  385. int method(mfd, mfn, mfsize)
  386. XFILE *mfd;
  387. char *mfn;
  388. long mfsize;
  389. X{
  390. X    long mmarker;
  391. X    char *mptr, *mtptr;
  392. X    int byte1, byte2;
  393. X    int mresult;        /* result code */
  394. X    char mname[100];
  395. X
  396. X    mname[0] = '\0';
  397. X    mresult = 0;        /* normal file */
  398. X
  399. X    /* Mark place */
  400. X    mmarker = ftell(mfd);
  401. X
  402. X    if (islbr(mfd) && (mfsize > 128))
  403. X        return (8);    /* Novosielski .LBR format */
  404. X
  405. X    /* Get crunched/squeezed/LZH signature.  If found, use */
  406. X    /*  the embedded filename instead of the command line spec. */
  407. X    /*  for binary file detection. */
  408. X
  409. X    mtptr = mname;        /* point to temp. storage */
  410. X    byte1 = getc(mfd);
  411. X    byte2 = getc(mfd);
  412. X    if (feof(mfd) || (mfsize < 5))
  413. X    {    fseek(mfd, mmarker, SEEK_SET);    /* restore pointer */
  414. X        goto checkext;        /* too short for signature */
  415. X    }
  416. X    else if ((byte1 == 0x76) && (byte2 == 0xFD))
  417. X    {    /* point to un-LZHed filespec */
  418. X        mresult = 6;
  419. X        for ( (getw(mfd)) ;
  420. X            (*mtptr = getc(mfd)) != '\0'; mtptr++);
  421. X        mtptr = mname;
  422. X    }
  423. X    else if ((byte1 == 0x76) && (byte2 == 0xFE))
  424. X    {    /* point to uncrunched filespec */
  425. X        mresult = 4;
  426. X        for ( ; (*mtptr = (getc(mfd)) & 0x7F) != '\0'; mtptr++)
  427. X            if (*mtptr == 1)
  428. X                *mtptr = '\0';
  429. X        mtptr = mname;
  430. X    }
  431. X    else if ((byte1 == 0x76) && (byte2 == 0xFF))
  432. X    {    /* point to unsqueezed filespec */
  433. X        mresult = 2;
  434. X        for ( (getw(mfd)) ;
  435. X            (*mtptr = getc(mfd)) != '\0'; mtptr++);
  436. X        mtptr = mname;
  437. X    }
  438. X    else    /* no signature found */
  439. checkext:
  440. X#ifdef UNIX
  441. X    {    strcpy(mname, mfn);        /* Convert possibly mixed */
  442. X        stupcase(mname);        /*  or lower case for    */
  443. X        mtptr = mname;            /*  testing, and point to it */
  444. X    }
  445. X#else
  446. X        mtptr = mfn;            /* Point to input filespec */
  447. X#endif
  448. X    mptr = (char *) strchr(mtptr, '.');    /* find extent, if any */
  449. X    fseek(mfd, mmarker, SEEK_SET);        /* restore file pointer */
  450. X
  451. X    if (mptr != NULL)
  452. X        if (!strncmp(mptr, ".OBJ", 4) ||
  453. X#ifdef UNIX
  454. X            !strncmp(mptr, ".Z\0", 3) ||
  455. X#endif
  456. X            !strncmp(mptr, ".COM", 4) ||
  457. X            !strncmp(mptr, ".EXE", 4) ||
  458. X            !strncmp(mptr, ".BIN", 4) ||
  459. X            !strncmp(mptr, ".ARC", 4) ||
  460. X            !strncmp(mptr, ".ZIP", 4) ||
  461. X            !strncmp(mptr, ".ARK", 4) ||
  462. X            !strncmp(mptr, ".REL", 4) ||
  463. X            !strncmp(mptr, ".SLR", 4) ||
  464. X            !strncmp(mptr, ".HDR", 4) ||
  465. X            !strncmp(mptr, ".CFG", 4) ||
  466. X            !strncmp(mptr, ".SCN", 4) ||
  467. X            !strncmp(mptr, ".LBR", 4) ||    /* compressed .LBR */
  468. X            !strncmp(mptr, ".ZDK", 4) ||
  469. X            !strncmp(mptr, ".OVR", 4) ||
  470. X            !strncmp(mptr, ".Z3T", 4) ||
  471. X            !strncmp(mptr, ".CHN", 4) ||
  472. X            !strncmp(mptr, ".CIM", 4) ||
  473. X            !strncmp(mptr, ".3OM", 4) ||
  474. X            !strncmp(mptr, ".4OM", 4) ||
  475. X            !strncmp(mptr, ".T4C", 4) ||
  476. X            !strncmp(mptr, ".DAT", 4) ||
  477. X            !strncmp(mptr, ".GIF", 4) ||
  478. X            !strncmp(mptr, ".ZOO", 4) ||
  479. X            !strncmp(mptr, ".ZRL", 4) ||
  480. X            !strncmp(mptr, ".ZRL", 4) ||
  481. X            !strncmp(mptr, ".ZRL", 4) ||
  482. X            !strncmp(mptr, ".ZRL", 4) ||
  483. X            !strncmp(mptr, ".ZRL", 4) ||
  484. X            !strncmp(mptr, ".ZRL", 4) ||
  485. X            !strncmp(mptr, ".ZRL", 4))
  486. X            mresult++;            /* binary file */
  487. X    return (mresult);
  488. X}
  489. X/* ---------------------------------------------------------------- */
  490. X/*
  491. X    Determine whether file is library.  0 = not library.
  492. X*/
  493. int islbr(lbrfd)
  494. XFILE *lbrfd;
  495. X{
  496. X    long lbrmarker;
  497. X    int lbrresult;
  498. X    struct direntry islbrent;
  499. X
  500. X    lbrresult = 0;
  501. X    /* Mark place */
  502. X    lbrmarker = ftell(lbrfd);
  503. X
  504. X    if ((fread(&islbrent, sizeof(islbrent), 1, lbrfd)) < 1)
  505. X        ;
  506. X    else
  507. X        if ((islbrent.status == '\0') &&
  508. X            (strcmp(islbrent.name, "           ") == 0) &&
  509. X            (islbrent.index == 0))
  510. X        {       lbrresult = 1;
  511. X            xferndate(islbrent.credate, islbrent.moddate);
  512. X        }
  513. X
  514. X    fseek(lbrfd, lbrmarker, SEEK_SET);    /* restore pointer */
  515. X    return (lbrresult);
  516. X}
  517. X/* ---------------------------------------------------------------- */
  518. X/*
  519. X    Transfers given Novosielski datestamps to global fileyear, 
  520. X      filemonth, and fileday variables.  Use modify datestamp by 
  521. X      default; if modify unavailable use create datestamp; if neither 
  522. X      available set date to zero.
  523. X    Novosielski dates are in days since 12/31/77, or 0 if undefined.
  524. X*/
  525. void xferndate(ncdate, nmdate)
  526. unsigned short int ncdate;
  527. unsigned short int nmdate;
  528. X{
  529. X    time_t xferval;
  530. X
  531. X    if (!nmdate)            /* no modify datestamp */
  532. X        nmdate = ncdate;    /* fallback to create datestamp */
  533. X    if (!nmdate)            /* no datestamps */
  534. X    {    fileyear = filemonth = fileday = 0;
  535. X        return;
  536. X    }
  537. X        xferval = nmdate * 60L * 60L * 24L; /* seconds since 12/31/77 */
  538. X    xferval += 252392400L;           /* seconds since 01/01/70 */
  539. X    ftsptr = localtime(&xferval);
  540. X    fileyear = ftsptr->tm_year;
  541. X    filemonth = ftsptr->tm_mon;
  542. X    fileday = ftsptr->tm_mday;
  543. X}
  544. X/* ---------------------------------------------------------------- */
  545. X/*
  546. X    Write a byte to output file.
  547. X    Repeat byte (0x90) expanded here.
  548. X    Checksumming of output stream done here.
  549. X*/
  550. void send(c)
  551. register unsigned char c;
  552. X{
  553. X    static unsigned char savec;    /* Previous byte put to output */
  554. X
  555. X    /* Repeat flag may have been set by previous call */
  556. X    if (repeat_flag)
  557. X    {
  558. X        /* Repeat flag was set - emit (c-1) copies of savec    */
  559. X        /*  or (if c is zero), emit the repeat byte itself    */
  560. X        repeat_flag = 0;
  561. X        if (c)
  562. X        {
  563. X            cksum += (savec & 0xff) * (c - 1);
  564. X            while (--c)
  565. X                output(savec, outfd);
  566. X        }
  567. X        else
  568. X        {
  569. X            output(REPEAT_CHARACTER, outfd);
  570. X            cksum += REPEAT_CHARACTER;
  571. X        }
  572. X    }
  573. X    else
  574. X        /*normal case - emit c or set repeat flag*/
  575. X        if (c == REPEAT_CHARACTER)
  576. X            repeat_flag++;
  577. X        else
  578. X        {
  579. X            output(savec = c, outfd);
  580. X            cksum += (c & 0xff);
  581. X        }
  582. X}
  583. X/* ----------------------------------------------------------------- */
  584. X/*
  585. X    Output to screen or file, checking for abort during screen output.
  586. X*/
  587. void output(ch, fd)
  588. int ch;
  589. XFILE *fd;
  590. X{
  591. X    int tchar;
  592. X
  593. X    if (diskout)        /* No checking during disk output */
  594. X    {    if (putc(ch, fd) == EOF)
  595. X        {    cerror("error writing to file.");
  596. X            cfabort();        /* disk output broken */
  597. X        }
  598. X        else
  599. X            outreccount = (outreccount + 1) & 127;
  600. X        return;
  601. X    }
  602. X    else if (!contin)    /* allows seek to next library member */
  603. X        return;
  604. X
  605. X    ch &= 0x7F;
  606. X    if (ch != '\07')    /* no bells please */
  607. X        putc(ch, fd);
  608. X
  609. X    if (ch == '\n')
  610. X    {
  611. X        tchar = 0;
  612. X        if ((scrline++ > ROWS - 3) && (pause))
  613. X        {    scrline = 1;
  614. X              printf(" [more] ");
  615. X            tchar = mgetch(WAIT);
  616. X            printf("\r       \r");
  617. X        }
  618. X        else
  619. X            tchar = mgetch(NOWAIT);
  620. X
  621. X        if (toupper(tchar) == 'Q')
  622. X        {    cfabort();
  623. X            return;
  624. X        }
  625. X
  626. X        switch (tchar & 0x1F)        /* c, C --> ^C, etc. */
  627. X        { case 3  :            /* ^C, ^K */
  628. X          case 11 : cfabort();        /* exit program */
  629. X                break;
  630. X          case 24 : contin = 0;        /* ^X next file */
  631. X                break;
  632. X          case 26 : pause = 0;        /* ^Z zip to EOF */
  633. X                break;
  634. X        }
  635. X    }
  636. X}
  637. X/* ---------------------------------------------------------------- */
  638. X/*
  639. X    Send CRLFs to console, causing output() to count lines.
  640. X*/
  641. void outcrlf(times)
  642. int times;
  643. X{
  644. X    contin = 1;        /* always print */
  645. X    while(times--)
  646. X    {    output('\r', stdout);
  647. X        output('\n', stdout);
  648. X    }
  649. X}
  650. X/* ---------------------------------------------------------------- */
  651. X/*
  652. X    Get / test for character / monitor for carrier loss (if cdline).
  653. X*/
  654. int mgetch(keywait)
  655. int keywait;
  656. X{
  657. X    int result = 0, comresult;
  658. X
  659. X    do
  660. X    {    if (timelmt)    /* see if time expired */
  661. X        {    time(&nowtime);
  662. X            if ((nowtime - starttime) > timelmt)
  663. X            {       printf(
  664. X            "\n  %s: %d-minute time limit exceeded.\n",
  665. X                    PROGNAME, timelmt / 60);
  666. X                quit();
  667. X            }
  668. X        }
  669. X#ifdef UNIX
  670. X        if (keywait)
  671. X        {    result = getchar();
  672. X            if (result < 0)
  673. X                result = 0;
  674. X        }
  675. X#else
  676. X        if (cdline)    /* check for carrier */
  677. X        {    comresult = bioscom(3, 0, cdline-1);
  678. X            if ((comresult & 0x80) == 0)
  679. X                quit();        /* no carrier; abort */
  680. X            else if (comresult & 0x100)    /* COM data ready */
  681. X                return(bioscom(2, 0, cdline-1));
  682. X        }
  683. X        if (bioskey(1))            /* also poll console */
  684. X            result = bioskey(0);
  685. X#endif
  686. X    }
  687. X    while (!result && keywait);    /* if !keywait, just poll once */
  688. X    return (result);
  689. X}
  690. X/* ---------------------------------------------------------------- */
  691. X/*
  692. X    Custom input routine, checks for end of library member
  693. X*/
  694. int cgetc(stream)
  695. XFILE *stream;
  696. X{
  697. X    if (inlbr)
  698. X        if (mlength-- == 0)    /* library member length */
  699. X        {    contin = 0;
  700. X            return (EOF);
  701. X        }
  702. X    return (getc(stream));
  703. X}
  704. X/* ---------------------------------------------------------------- */
  705. X/*
  706. X    Print error message.
  707. X*/
  708. void cerror(message1, message2, message3, message4)
  709. char *message1, *message2, *message3, *message4;
  710. X{
  711. X    outcrlf(1);
  712. X    fprintf(stderr, "  %s: ", PROGNAME);
  713. X    fprintf(stderr, message1, message2, message3, message4);
  714. X    return;
  715. X}
  716. X/* ---------------------------------------------------------------- */
  717. X/*
  718. X    Program exits.
  719. X*/
  720. void quit()
  721. X{
  722. X#ifdef UNIX
  723. X    printf("\n");
  724. X    ttyrestore();        /* restore tty */
  725. X#endif
  726. X    exit (0);        /* no errors */
  727. X}
  728. X/* ---------------------------------------------------------------- */
  729. X/*
  730. X    Abort program.
  731. X*/
  732. void cfabort()
  733. X{
  734. X    printf("\n [abort]\n");
  735. X    checkwait();
  736. X    quit();
  737. X}
  738. X/* ---------------------------------------------------------------- */
  739. X/*
  740. X    Wait for keystroke (-w option)
  741. X*/
  742. void checkwait()
  743. X{
  744. X    if (waitflag)
  745. X    {    printf(" Strike any key -- ");
  746. X        mgetch(WAIT);
  747. X        printf("\n");
  748. X    }
  749. X}
  750. X/* ---------------------------------------------------------------- */
  751. X/*
  752. X    Translate string to uppercase, strip high bits
  753. X*/
  754. void stupcase(stptr)
  755. char *stptr;
  756. X{
  757. X    while (*stptr != '\0')
  758. X        *stptr++ = (toupper(*stptr) & 0x7F);
  759. X}
  760. X/* ---------------------------------------------------------------- */
  761. X/*
  762. X cisubstr(string, token) searches for lower case token in string s
  763. X returns pointer to token within string if found, NULL otherwise
  764. X*/
  765. X
  766. char *cisubstr(s, t)
  767. char *s, *t;
  768. X{
  769. X        char *ss, *tt;
  770. X        /* search for first char of token */
  771. X        for (ss = s; *s; s++)
  772. X                if (*s == *t)
  773. X                        /* compare token with substring */
  774. X            for (ss = s, tt = t; ; )
  775. X            {    if (*tt == 0)
  776. X                                        return s;
  777. X                                if (*ss++ != *tt++)
  778. X                                        break;
  779. X                        }
  780. X        return NULL;
  781. X}
  782. X/* End of CFX.C */
  783. END_OF_FILE
  784. if test 18746 -ne `wc -c <'cfx.c'`; then
  785.     echo shar: \"'cfx.c'\" unpacked with wrong size!
  786. fi
  787. # end of 'cfx.c'
  788. fi
  789. if test -f 'cfx.doc' -a "${1}" != "-c" ; then 
  790.   echo shar: Will not clobber existing file \"'cfx.doc'\"
  791. else
  792. echo shar: Extracting \"'cfx.doc'\" \(18018 characters\)
  793. sed "s/^X//" >'cfx.doc' <<'END_OF_FILE'
  794. X                     CFX - Cp/m File eXpress
  795. X                         User's Manual
  796. X             Copyright 4 January 92 by Carson Wilson
  797. X
  798. X
  799. X                          - CONTENTS -
  800. X
  801. X     1  PURPOSE.
  802. X     2  USAGE.
  803. X          2.1  Invocation.
  804. X               2.1.1  Help Screen.
  805. X               2.1.2  File Specification
  806. X               2.1.3  Command Line Options.
  807. X                    2.1.3.0  Option B - Brief Output Only.
  808. X                    2.1.3.1  Option C - Monitor COMn for Carrier.
  809. X                    2.1.3.2  Option D - Disk Output.
  810. X                    2.1.3.3  Option I - Display File Info Only.
  811. X                    2.1.3.4  Option M - Library Member
  812. X                             Specification.
  813. X                    2.1.3.5  Option N - Don't Uncompress Library
  814. X                             Files.
  815. X                    2.1.3.6  Option P - Prompt Before Processing
  816. X                             Files.
  817. X                    2.1.3.7  Option T - Maximum Minutes Allowed.
  818. X                    2.1.3.8  Option W - Wait After Last File.
  819. X               2.1.4  Combined Command Lines.
  820. X          2.2  Output Files to Screen.
  821. X          2.3  Errors.
  822. X     3  APPLICATION NOTES.
  823. X          3.1  BBS Usage.
  824. X          3.2  Local Usage.
  825. X     4  KNOWN BUGS.
  826. X     5  COPYRIGHT.
  827. X     6  DEVELOPMENT OF CFX.
  828. X     7  ABOUT THE AUTHOR.
  829. X
  830. X
  831. X                            ---------
  832. X
  833. X1  PURPOSE.
  834. X
  835. As its name suggests, CFX is a tool intended to allow quick 
  836. access to CP/M files.  While CFX will operate on standard ASCII 
  837. files, its main strength is its ability access files stored with 
  838. the special archiving and compression methods native to the CP/M 
  839. operating system.  Specifically, CFX can handle files compressed 
  840. with Roger Warren's LZH utilities, Steve Greenberg's CRUNCH 
  841. utilities, "squeezed" files, and archives built using Gary 
  842. Novosielski's Library definition.  
  843. X
  844. Typically, CP/M files stored using these protocols can be 
  845. identified by the three letter file extent as follows:
  846. X
  847. X     Extent   Storage method
  848. X     ------   --------------
  849. X     .?Y?     LZH compression
  850. X     .?Z?     Crunched
  851. X     .?Q?     Squeezed
  852. X     .LBR     Library
  853. X
  854. Notes:
  855. X  1. Much of what follows applies only to the MSDOS version of
  856. X     CFX.  If you are using CFX on a Unix system, please refer to
  857. X     the file cfx.1 or cfx.man for usage information.
  858. X
  859. X  1. Library members themselves may be stored under one of the 
  860. X     above methods (e.g., crunched library members are common).  
  861. X     CFX can extract compressed library members 
  862. X     directly to screen or disk.  It can also process library 
  863. X     members which are themselves libraries in one step.  
  864. X     However, CFX cannot presently extract members from 
  865. X     compressed library files in a single step; you must first 
  866. X     run CFX on the compressed library file and then invoke CFX 
  867. X     again on the uncompressed library file to access library 
  868. X     members.
  869. X
  870. X  2. Though LZH, crunched, and squeezed files usually have the 
  871. X     extents mentioned above, they are more reliably identified 
  872. X     by means of a unique signature at the start of the file.  
  873. X     CFX uses this signature to identify the compression method 
  874. X     in all cases.  Following the signature check, CFX 
  875. X     additionally uses the following standard file extensions to 
  876. X     identify files which cannot be displayed to the screen:
  877. X
  878. X     .OBJ, .COM, .EXE, .BIN, .ARC, .ARK, .ZIP, .REL, .SLR, .CFG, 
  879. X     .SCN, .LBR, .ZDK, .OVR, .Z3T, .CHN, .CIM, .3OM, .4OM, .T4C, 
  880. X     .DAT, .ZRL
  881. X
  882. X     You can add or remove entries from this list of extensions 
  883. X     using a binary file patcher.  The default extensions reside 
  884. X     at or near offset 53A0h in CFX.EXE (compiled MSDOS version 
  885. X     only), and the last few entries are all ".ZRL"  By overwriting 
  886. X     a ZRL entry with an extension of your choosing, you can prevent 
  887. X     CFX from displaying files and library members of this type.  
  888. X     To allow display of one of the above file types, simply 
  889. X     overwrite its entry with one of the other extensions from the 
  890. X     list.
  891. X
  892. X  3. CFX cannot access members of .ARC, .ZIP, .ZOO, or other 
  893. X     common MSDOS file archives.  Plenty of utilities are already 
  894. X     available for this purpose.
  895. X
  896. X
  897. X2  USAGE.
  898. z
  899. X     2.1  Invocation.
  900. X
  901. CFX is invoked as:
  902. X
  903. X     CFX [option ...] [afn ...]
  904. X
  905. where CFX is the name of the CFX executable file.
  906. X
  907. X          2.1.1  Help Screen.
  908. X
  909. If no command line parameters are given, the following help 
  910. screen appears:
  911. X
  912. CFX - Cp/m File eXpress, Version x.x, Copr. 1992 by Carson Wilson
  913. X  Usage:
  914. X        CFX [option ...] afn ...
  915. X  Options:
  916. X        /b       - brief output only
  917. X        /c n     - monitor COMn for carrier
  918. X        /d       - disk output
  919. X        /i       - display directory information
  920. X        /m "afn" - library member specification
  921. X        /n       - don't uncompress library members
  922. X        /p       - prompt before processing files
  923. X        /t n     - maximum minutes allowed
  924. X        /w       - wait after last file
  925. X
  926. The "/" character in the above help screen is the current MSDOS 
  927. X"switch" character, and may change depending on your 
  928. installation.
  929. X
  930. X          2.1.2  File Specification
  931. X
  932. CFX can be used on one or many files at once, depending on the 
  933. command line arguments it is invoked with.  File compression and 
  934. archiving methods are detected "on the fly" by CFX, and the 
  935. proper decompression or library access operations 
  936. performed as needed.  This makes CFX suitable for use as an 
  937. extension to many existing MSDOS applications, such as file 
  938. viewers or BBS programs (see USAGE EXAMPLES, below).
  939. X
  940. XFiles can be specified using single or multiple ambiguous or 
  941. unambiguous filespecs, and filespecs may include path 
  942. information.  If command line options are also given, file 
  943. specifications must appear LAST on the command line.  When 
  944. specifying library files, the .LBR extent is optional.
  945. X
  946. XExamples:
  947. X
  948. Command                           Results
  949. X-------                           -------
  950. CFX *.dzc                         View all files in current 
  951. X                                  directory with extension "DZC".
  952. X
  953. CFX a:\backup\test.bat            View TEST.BAT in directory 
  954. X                                  BACKUP on drive A:.
  955. X
  956. CFX *.lbr ..\*.lbr                View all files with extension 
  957. X                                  "LBR" in the current and parent 
  958. X                                  directories.
  959. X
  960. CFX mylbr                         View MYLBR.LBR in current 
  961. X                                  directory.
  962. X
  963. X
  964. X          2.1.3  Command Line Options.
  965. X
  966. CFX command line options are specified using the current MSDOS 
  967. X"switch" character (normally "/"), or "-" under Unix systems.  
  968. Under MSDOS, to specify more than one option you must use the 
  969. switch character once before each option.  Options must come 
  970. BEFORE file specifications (if any) in the command line, [and 
  971. under MSDOS, MUST BE SEPARATED BY SPACES] (see examples below).
  972. X
  973. X               2.1.3.0  Option B - Brief Output Only.
  974. X
  975. When displaying a library file, CFX normally displays a complete 
  976. library directory before further processing occurs.  Option B 
  977. suppresses the initial directory display.  Useful for slow 
  978. terminals or to save screen space.
  979. X
  980. X               2.1.3.1  Option C - Monitor COMn for Carrier.
  981. X
  982. MSDOS version only.
  983. Option C causes CFX to monitor one of your computer's serial 
  984. ports for a carrier signal after each line is displayed and when 
  985. waiting for input from a user.  If no carrier is present, CFX 
  986. immediately exits.  This is intended for remote applications of 
  987. CFX in which loss of carrier should normally cause CFX's parent 
  988. program(s) to resume control and prepare for another phone call.  
  989. As a special case, /C 0 specifies no carrier detection, causing 
  990. CFX to operate as though no /C option had been specified.
  991. X
  992. XExample:
  993. X
  994. Command                           Result
  995. X-------                           ------
  996. CFX /C1 test.fil                  Display TEST.FIL and monitor 
  997. X                                  COM1 for carrier.
  998. X
  999. X               2.1.3.2  Option D - Disk Output.  
  1000. X
  1001. Option D causes CFX to extract files to disk.  Compressed files 
  1002. are extracted to the filenames stored at file compression time.  
  1003. XFiles are extracted to the current directory.  
  1004. X
  1005. X               2.1.3.3  Option I - Display File Info Only.
  1006. X
  1007. Option I causes CFX to display file information only.  This 
  1008. overrides most other options.
  1009. X
  1010. X               2.1.3.4  Option M - Library Member Specification.
  1011. X
  1012. Normally CFX process all members of specified library files.  
  1013. Option M allows you to specify a subset of library members for 
  1014. processing.  Unlike the global file specification, the library 
  1015. member specification is limited to one ambiguous or unambiguous 
  1016. parameter.  If an ambiguous member specification is used, it must 
  1017. be enclosed in double quotes ("").  Example:
  1018. X
  1019. Command                           Result
  1020. X-------                           ------
  1021. CFX /M "*.dzc" *.lbr              Display all library members 
  1022. X                                  with the extent "DZC" in the 
  1023. X                                  current directory.
  1024. X
  1025. X               2.1.3.5  Option N - Don't Uncompress Library Files.
  1026. X
  1027. Option N is intended for use in conjunction with option D (Disk 
  1028. output), and tells CFX not to uncompress library members when 
  1029. extracting them to disk.  Attempts to display compressed files 
  1030. using option N will result in the message "can't display binary 
  1031. file." 
  1032. X
  1033. X               2.1.3.6  Option P - Prompt Before Processing Files.
  1034. X
  1035. If the Prompt option is specified, CFX displays the selected 
  1036. file's name, compression method and datestamp to the screen and 
  1037. prompts the user before displaying each matched file.  Example:
  1038. X
  1039. X File Name    Length   Method     Date
  1040. X------------  ------  --------  --------
  1041. CFX.DOC         7064   Stored   06-01-91  View (y/N/q)? 
  1042. X
  1043. A response of Y or y causes CFX to display the file's contents.  
  1044. Responses of Q, q, control-c, control-x, or control-k cause CFX 
  1045. to abort and return to the parent environment.  Any other 
  1046. response causes CFX to skip to the next specified file.
  1047. X
  1048. X               2.1.3.7  Option T - Maximum Minutes Allowed.
  1049. X
  1050. Option T is intended for use on remote systems which limit the 
  1051. amount of connect time a caller is allowed.  Once the specified 
  1052. number of minutes has elapsed, CFX unconditionally displays the 
  1053. message
  1054. X
  1055. X  CFX: x-minute time limit exceeded.
  1056. X
  1057. and returns control to the parent environment.
  1058. X
  1059. X               2.1.3.8  Option W - Wait After Last File.
  1060. X
  1061. Option W simply causes CFX to pause and wait for a keystroke 
  1062. before returning control to the parent program or operating 
  1063. system.  This is useful if you invoked CFX from within a shell 
  1064. X(such as LIST) which overwrites screen contents after invoking 
  1065. CFX.
  1066. X
  1067. X          2.1.4  Combined Command Lines.
  1068. X
  1069. CFX provides a great deal of flexibility by allowing combinations 
  1070. of options and file specifications to be given in a single 
  1071. command.  Here are some examples:
  1072. X
  1073. Command                           Result
  1074. X-------                           ------
  1075. CFX /D /N big.lbr                 Extract all members of BIG.LBR 
  1076. X                                  to disk without uncompressing 
  1077. X                                  them.
  1078. X
  1079. CFX /I *.?z? *.?q? *.lbr          Display information only on all 
  1080. X                                  crunched, squeezed, and library 
  1081. X                                  files in current directory.
  1082. X
  1083. CFX /P /M "*.d?c" *.lbr *.d?c     Display all files and library 
  1084. X                                  members in the current 
  1085. X                                  directory with the extent 
  1086. X                                  "D?C," prompting the user for 
  1087. X                                  each one.
  1088. X
  1089. X     2.2  Output Files to Screen.
  1090. X
  1091. Unless the Disk Output option is specified, CFX always extracts 
  1092. CP/M text files to the screen.  Binary files are skipped with the 
  1093. message "can't display binary file."  Text files are paged 22 
  1094. lines at a time.  When 22 lines have been written to the screen, 
  1095. CFX pauses, displays the message "[more]", and awaits input from 
  1096. the keyboard.  Keyboard inputs of C, control-c, Q, K, or 
  1097. control-k cause CFX to abort and return control to the parent 
  1098. environment.  Inputs of X or control-x cause CFX to skip to the 
  1099. next specified file, if any (or quit if not).  Inputs of Z or 
  1100. control-z cause CFX to scroll the rest of the file past without 
  1101. pausing (useful in viewing the end of a file).  Any other input 
  1102. causes CFX to display the next page of output to the screen.
  1103. X
  1104. When extracting files to the screen, high bits are stripped, so 
  1105. WordStar and other types of files which store special meanings in 
  1106. bit seven of a character should display properly.  Also, the 
  1107. X"bell" character (binary 7) is skipped when outputting files to 
  1108. the screen. All 8 bits are preserved during disk output.
  1109. X
  1110. X     2.3  Errors.
  1111. X
  1112. Most error messages are self-explanatory.  Some confusion may 
  1113. result from CFX's flexible command syntax.  For example, if you 
  1114. try to extract a compressed file which is not a library member to 
  1115. disk without uncompressing it, you are actually trying to copy a 
  1116. file to itself.  In this event, CFX will skip the specified file 
  1117. and display the message
  1118. X
  1119. X  input and output files identical
  1120. X
  1121. In fact, the current version of CFX will display this message any 
  1122. time the NAMES of the input and output files are identical, even 
  1123. if they reside in different directories.  This is a bug, but one 
  1124. easily gotten around with the MSDOS COPY or XCOPY commands.
  1125. X
  1126. X
  1127. X3  APPLICATION NOTES.
  1128. X
  1129. Because of its flexibly command line syntax, CFX can easily be 
  1130. called from within other programs to process CP/M files, 
  1131. returning control when finished. Note that in order to execute 
  1132. CFX as a subtask, your program must provide access to the MSDOS 
  1133. command line.  Most current BBS programs and many other 
  1134. applications such as LIST and VDE provide this capability.
  1135. X
  1136. X     3.1  BBS Usage.
  1137. X
  1138. A prime example of CFX's use is with MSDOS BBS applications.  
  1139. Using the C, P, and T options, CFX can display the contents of 
  1140. CP/M files to remote callers, monitoring for loss of carrier and 
  1141. timing out after a specified amount of time has been exceeded.  
  1142. The current version of CFX will NOT direct its output to the 
  1143. modem as do the Samuel H. Smith's popular ZIPTV and ARCTV file 
  1144. display utilities.  Rather, CFX relies on MSDOS I/O redirection 
  1145. to achieve this task.  You can redirect CFX output entirely to 
  1146. the serial port using the COMx device, or obtain GATEWAY.SYS, 
  1147. which allows program output to be split between a COM port and 
  1148. the local console (see the file GATEWAY2.ZIP, found on many 
  1149. bulletin boards).
  1150. X
  1151. Many MSDOS BBS systems implement remote file viewing through 
  1152. MSDOS BATCH files created by the sysop.  Here are some sample 
  1153. BATCH commands which tell CFX to display the file given as the 
  1154. first parameter, monitoring COM1 for loss of carrier and 
  1155. returning control to the BBS program after 10 minutes:
  1156. X
  1157. X     Using MSDOS COM1:
  1158. X
  1159. X          CFX /C 1 /P /T 10 %1 < COM1 > COM1
  1160. X
  1161. X     Using GATEWAY.SYS:
  1162. X
  1163. X          CFX /C 1 /P /T 10 %1 < GATE1 > GATE1
  1164. X
  1165. If you are running RBBS-PC, you probably want to change "%1" in 
  1166. the above examples to "[1]".  This causes RBBS-PC to shell 
  1167. directly to the first line of the BATCH file rather than to the 
  1168. BATCH file itself, and in practice has proven to be the more 
  1169. reliable approach.  You can also substitute "/C [3]" for "/C 1".  
  1170. This will allow local use of CFX, since [3] is substituted with 
  1171. the number of the COM line RBBS is using, or 0 if RBBS is being 
  1172. used locally.
  1173. X
  1174. Note: when used remotely, control-C does not cause CFX to abort, 
  1175. though this signal still operates on the local console.
  1176. X
  1177. X     3.2  Local Usage.
  1178. X
  1179. CFX can also be used to access CP/M files from within other MSDOS 
  1180. programs.  A good example is its ability to display CP/M files 
  1181. from within Vernon Buerg's popular LIST utility.  LIST allows you 
  1182. to patch in the name of your favorite text editor for invocation 
  1183. on the pointed-to file with LIST's E command.  By substituting 
  1184. the name of CFX at the location dedicated to your editor's name, 
  1185. you can create a version of LIST which will display any 
  1186. pointed-to CP/M (LZH, crunched, library, or squeezed) file using 
  1187. LIST's E command.  See LIST.DOC for instructions on patching 
  1188. LIST.COM.
  1189. X
  1190. X
  1191. X4  KNOWN BUGS.
  1192. X
  1193. X  1. If a wildcarded argument to the /m option is used, the 
  1194. X     argument must be quoted ("") to avoid expansion by the 
  1195. X     command line parser.
  1196. X
  1197. X  2. Does not display embedded file datestamps.
  1198. X
  1199. X  3. Does not set datestamps of output files.
  1200. X
  1201. X  4. Not yet extensively tested with nested .LBR files.
  1202. X
  1203. X
  1204. X5  COPYRIGHT.
  1205. X
  1206. Consider this is a "free sample" of my best programming work; for 
  1207. more you may have to pay.  Programmers must eat.  CFX and its 
  1208. documentation are copyright 1992 by Carson Wilson.  As long as 
  1209. you don't charge money to others for the use of CFX, you don't 
  1210. owe me any money either.  Otherwise please contact me regarding a 
  1211. license to use CFX commercially.
  1212. X
  1213. Also, if you wish to incorporate CFX's source code into a 
  1214. project of your own, I'd appreciate it if you would contact me 
  1215. first.  There are two reasons for this: 1) I may have corrected 
  1216. errors in the source code since this release, and 2) I may 
  1217. already be working on a project similar to yours.  In either 
  1218. case, we are both better off if we pool our efforts.
  1219. X
  1220. X
  1221. X6  DEVELOPMENT OF CFX.
  1222. X
  1223. Most of the design work on CFX done with Borland's Turbo C 
  1224. version 2.01.  It is written entirely in the C language, and 
  1225. should be portable to other systems with standard C compilers.
  1226. X
  1227. X
  1228. X7  ABOUT THE AUTHOR.
  1229. X
  1230. Carson Wilson is a doctoral candidate in Political Science at 
  1231. Loyola University of Chicago.  He has also spent quite a bit of 
  1232. time learning to program CP/M, MSDOS, and Unix systems.  Please 
  1233. address all correspondence to
  1234. X
  1235. X     Carson Wilson
  1236. X     1359 W. Greenleaf, #1D
  1237. X     Chicago, IL 60626
  1238. X
  1239. X              - or -
  1240. X
  1241. X     carson@sputnik.uucp
  1242. X
  1243. X              - or - 
  1244. X
  1245. X     Carson Wilson
  1246. X     Antelope Freeway RBBS
  1247. X     708-455-0120, 24 hours, 3/12/2400 baud, Franklin Park, IL.
  1248. X
  1249. Any and all comments and suggestions will be appreciated.
  1250. END_OF_FILE
  1251. if test 18018 -ne `wc -c <'cfx.doc'`; then
  1252.     echo shar: \"'cfx.doc'\" unpacked with wrong size!
  1253. fi
  1254. # end of 'cfx.doc'
  1255. fi
  1256. if test -f 'cfx.h' -a "${1}" != "-c" ; then 
  1257.   echo shar: Will not clobber existing file \"'cfx.h'\"
  1258. else
  1259. echo shar: Extracting \"'cfx.h'\" \(2974 characters\)
  1260. sed "s/^X//" >'cfx.h' <<'END_OF_FILE'
  1261. X/*
  1262. CFX.H - Include module of CP/M File eXpress
  1263. Copyright 20 Jan 1992 by 
  1264. Carson Wilson
  1265. X1359 W. Greenleaf, #1D
  1266. Chicago, IL 60626
  1267. X
  1268. UUCP:    carson@sputnik.uucp
  1269. X    ..!uunet!ddsw1!carson
  1270. X
  1271. BBS:    Antelope Freeway, 1-708-455-0120
  1272. X*/
  1273. X
  1274. X#include <stdio.h>
  1275. X#include <ctype.h>
  1276. X#include <string.h>
  1277. X#include <setjmp.h>
  1278. X#include <time.h>
  1279. X
  1280. X#ifdef UNIX
  1281. X# define OSTYPE "Unix"
  1282. X# define LBREXT ".lbr"
  1283. X# define DIRSEPCHAR '/'
  1284. X#else
  1285. X# include <dos.h>
  1286. X# include <io.h>
  1287. X# define OSTYPE "MSDOS"
  1288. X# define LBREXT ".LBR"
  1289. X# define DIRSEPCHAR '\\'
  1290. X
  1291. X /* Define this if linker makes a huge executable image containing
  1292. X      mostly zeros (big tables will instead be allocated at run time):
  1293. X */
  1294. X# define DUMBLINKER
  1295. X#endif
  1296. X
  1297. X#define ROWS 24
  1298. X
  1299. X/ * ======= NOTHING BENEATH THIS LINE SHOULD NEED TO BE CHANGED ======= */
  1300. X
  1301. X/* Strings for prompts, etc */
  1302. X
  1303. X#define PROGNAME "CFX"
  1304. X#define    VERS "1.1"
  1305. X#define    AUTHOR "Carson Wilson"
  1306. X
  1307. X/* Following byte is repeat count */
  1308. X
  1309. X#define    REPEAT_CHARACTER 0x90
  1310. X
  1311. X#define NULLCHARPTR (char *) NULL
  1312. X
  1313. X/* For mgetch() */
  1314. X#define WAIT 1
  1315. X#define NOWAIT 0
  1316. X
  1317. extern unsigned cksum;            /* Checksum of all bytes written to output file*/
  1318. extern unsigned outreccount;        /* Number of bytes written to output record */
  1319. extern unsigned long mlength;        /* current library member length */
  1320. X
  1321. extern char *infname;            /* Currently open input file's name */
  1322. extern FILE *infd;            /* Currently open input file */
  1323. extern FILE *outfd;            /* Currently open output file */
  1324. X
  1325. X/* Command line flags */
  1326. X
  1327. extern int brief;            /* -b brief flag */
  1328. extern int diskout;            /* -d diskout flag */
  1329. extern int info;            /* -i file info */
  1330. extern int uncompress;            /* -n uncompress flag */
  1331. X
  1332. extern unsigned char repeat_flag;    /* So send can remember if repeat required*/
  1333. X
  1334. extern char membername[];
  1335. X
  1336. X/* Internal flags */
  1337. X
  1338. extern int inlbr;            /* in library file flag */
  1339. extern int infoflag;            /* show info only */
  1340. X
  1341. extern unsigned long mlength;    /* library member's uncompressed size */
  1342. X
  1343. X/* .LBR directory entry format */
  1344. X
  1345. struct direntry {
  1346. X    char status;
  1347. X    char name[8];
  1348. X    char ext[3];
  1349. X    unsigned short int index, length, crc;
  1350. X    unsigned short int credate, moddate, cretime, modtime;
  1351. X    char pad;
  1352. X    char filler[5];
  1353. X};
  1354. X
  1355. extern int contin;            /* global abort flag */
  1356. X
  1357. extern jmp_buf jumpbuf;            /* for longjmp() */
  1358. X
  1359. extern long unclength;                 /* global for library members */
  1360. X
  1361. extern int getopt();            /* From Turbo C package */
  1362. X
  1363. extern void outcrlf();                  /* globals */
  1364. extern time_t filetime;
  1365. extern void xferndate();
  1366. extern void quit();
  1367. extern void process();
  1368. extern void unsqueeze();
  1369. extern void uncrunch();
  1370. extern void unlzh();
  1371. extern void lbr();
  1372. extern void stupcase();
  1373. extern void output();
  1374. extern char *cisubstr();
  1375. extern void send();
  1376. extern void enterx();
  1377. extern void intram();
  1378. extern void figure();
  1379. extern void entfil();
  1380. extern void checkwait();
  1381. extern void cerror();
  1382. extern void cfabort();
  1383. extern void unixfn();
  1384. X
  1385. extern int ttyraw();            /* Unix globals */
  1386. extern int ttyrestore();
  1387. extern void unixfn();
  1388. X
  1389. X/* End of CFX.H */
  1390. END_OF_FILE
  1391. if test 2974 -ne `wc -c <'cfx.h'`; then
  1392.     echo shar: \"'cfx.h'\" unpacked with wrong size!
  1393. fi
  1394. # end of 'cfx.h'
  1395. fi
  1396. if test -f 'cfx.hst' -a "${1}" != "-c" ; then 
  1397.   echo shar: Will not clobber existing file \"'cfx.hst'\"
  1398. else
  1399. echo shar: Extracting \"'cfx.hst'\" \(2616 characters\)
  1400. sed "s/^X//" >'cfx.hst' <<'END_OF_FILE'
  1401. Version:    1.0
  1402. Date:        12 Dec 91
  1403. Author:        Copr. 1991 by Carson Wilson
  1404. Changes:    Initial public MSDOS release.
  1405. X        Now always exits with return code of zero (0).
  1406. X        'N' key no longer aborts file displays.
  1407. X        'Q' key now aborts file displays.
  1408. X
  1409. Version:    0.9
  1410. Date:        2 Nov 91
  1411. Author:        Copr. 1991 by Carson Wilson
  1412. Changes:    Fixed bug which caused CFX to skip library members preceding
  1413. X          libraries within libraries after displaying initial
  1414. X          information screen.
  1415. X        Corrected parsing of /b command line option.
  1416. X
  1417. Version:    0.8
  1418. Date:        26 Oct 91
  1419. Author:        Carson Wilson
  1420. Changes:    [Thanks to Jay Sage for the following two suggestions:]
  1421. X        Now displays full library directory info before processing
  1422. X          members by default.  Use new /b option to suppress this
  1423. X          display.  /i option still specifies information only.
  1424. X        Now displays brief summary of viewing commands before
  1425. X          displaying files.
  1426. X        Now uses "===..." to distinguish file information headers
  1427. X          from "---..." library headers.
  1428. X        Fixed bug which caused output error when /p and /d options
  1429. X          were used and user refused file extraction.
  1430. X
  1431. Version:    0.7
  1432. Date:        14 Sep 91
  1433. Author:        Carson Wilson
  1434. Changes:    Added LZH file handling (thanks to Roger Warren).
  1435. X        Now checks for files of type .LBR if no filetype was
  1436. X          specified and file not found.  To force filename only,
  1437. X          use a "." at the end of the name.
  1438. X        ^C, ^K, ^N now synonyms for "q" at "View?" prompt.
  1439. X        Now tests Squeezed file checksum.
  1440. X        Now pads output with 1A hex to make file size equivalent to
  1441. X          the next CP/M 128-byte boundary.
  1442. X        Now more bulletproof.
  1443. X
  1444. Version:    0.6
  1445. Date:        14 Jun 91
  1446. Author:        Carson Wilson
  1447. Changes:    Added several new exclusion filetypes (note: patch location
  1448. X          may have changed).
  1449. X        Added /w option to wait for keystroke following last file.
  1450. X        Now reports date of 00-00-00 instead of the MSDOS file datestamp
  1451. X          if library member datestamps are missing.
  1452. X        Removed redundant [more] prompt during prompted file selection.
  1453. X        Fixed bug which prevented /m option from working with multiple
  1454. X          library files.
  1455. X        Displays now use fewer linefeeds.
  1456. X        Now aborts on n, N, ^N as well as ^C, ^K.
  1457. X        BELL characters in files suppressed (won't activate speaker).
  1458. X
  1459. Version:    0.5
  1460. Date:        31 May 91
  1461. Author:        Carson Wilson
  1462. Notes:        If a wildcarded argument to the -m option is used, the
  1463. X          argument must be quoted ("") to avoid expansion by the
  1464. X          command line parser.
  1465. X        Does not display embedded CRUNCHED datestamps.
  1466. X        There may be a bug in the Borland unixtodos() function: dates
  1467. X          before the mid '80's seem to generate invalid results.
  1468. X          Therefore library datestamps before 1981 may not display
  1469. X          properly.
  1470. END_OF_FILE
  1471. if test 2616 -ne `wc -c <'cfx.hst'`; then
  1472.     echo shar: \"'cfx.hst'\" unpacked with wrong size!
  1473. fi
  1474. # end of 'cfx.hst'
  1475. fi
  1476. if test -f 'cfx.man' -a "${1}" != "-c" ; then 
  1477.   echo shar: Will not clobber existing file \"'cfx.man'\"
  1478. else
  1479. echo shar: Extracting \"'cfx.man'\" \(3919 characters\)
  1480. sed "s/^X//" >'cfx.man' <<'END_OF_FILE'
  1481. X
  1482. X
  1483. X
  1484. X      cfx(1)                             cfx(1)
  1485. X
  1486. X
  1487. X
  1488. X      NAME
  1489. X           cfx - CP/M File eXpress
  1490. X
  1491. X      SYNOPSIS
  1492. X           cfx [-bdinpw] [-c n] [-m    afn] [-t minutes] [files ...]
  1493. X
  1494. X      DESCRIPTION
  1495. X           Cfx provides convenient access to the various file archiving
  1496. X           methods presently associated with computers based on Digital
  1497. X           Research's CP/M operating system    and its    descendants.  By
  1498. X           default,    cfx steps through the target file and extracts all
  1499. X           human-readable information to the screen.  File extraction
  1500. X           is also supported as a command line option.
  1501. X
  1502. X           The following types of archives are supported (note that    the
  1503. X           file extents given below    are merely conventions;    cfx reads a
  1504. X           file's data to distinguish its archive type):
  1505. X
  1506. X           Extent  Typical archive type
  1507. X
  1508. X           .lbr    Novosielski library format file.     This format is
  1509. X               similar in purpose to the familiar MS-DOS .arc and
  1510. X               .zip archives.  A set of    related    files is stored    as
  1511. X               a single    "library" for convenience and efficiency.
  1512. X               The format is comprised of a binary directory one or
  1513. X               more 128-byte CP/M records in length, followed
  1514. X               sequentially by one or more member files, also com-
  1515. X               prised of one or    more CP/M records.
  1516. X
  1517. X           .?q?    Squeezed    files.    Squeezed files contain Huffman-
  1518. X               encoded text or binary data.  Squeezing has gener-
  1519. X               ally been replaced more efficient compression meth-
  1520. X               ods.  The first two bytes of CP/M squeezed files    are
  1521. X               guaranteed to be    76 and FF hex, respectively.
  1522. X
  1523. X           .?z?    Crunched    files.    Crunching is similar to    squeezing,
  1524. X               but uses    the Lempel-Ziv-Welch algorithm,    adapted    for
  1525. X               CP/M use    by Steve Greenberg.  The first two bytes of
  1526. X               CP/M crunched files are guaranteed to be    76 and FE
  1527. X               hex, respectively.
  1528. X
  1529. X           .?y?    LZH-compressed files.  LZH-compression uses a combi-
  1530. X               nation of Lempel-Ziv-Welch and Huffman techniques.
  1531. X               The first two bytes of CP/M LZH files are guaranteed
  1532. X               to be 76    and FD hex, respectively.
  1533. X
  1534. X           Cfx will    also display non-compressed (ASCII) files.  High
  1535. X           bits are    stripped during    display, but not during    extraction,
  1536. X           so WordStar and other forms of text which store information
  1537. X           in 8-bit    form are handled reliably.
  1538. X
  1539. X      OPTIONS
  1540. X           -b    Brief output only.  When processing library (.lbr)
  1541. X
  1542. X
  1543. X
  1544. X      Rev. 1.1               01-20-92                 Page 1
  1545. X
  1546. X
  1547. X
  1548. X
  1549. X
  1550. X      cfx(1)                             cfx(1)
  1551. X
  1552. X
  1553. X
  1554. X            files, suppress    initial    directory display.
  1555. X
  1556. X           -c n    Monitor    COM n for carrier (MSDOS only).
  1557. X
  1558. X           -d    Extract    files to current disk directory.  Com-
  1559. X            pressed    files are extracted to the filenames stored
  1560. X            at file    compression time.  (See    option -n).
  1561. X
  1562. X           -i    Display    file information only.    Overrides most
  1563. X            other options.
  1564. X
  1565. X           -m afn    Specify    a subset of library members for    processing.
  1566. X            Limited    to one ambiguous or unambiguous    parameter.
  1567. X
  1568. X           -n    Don't uncompress library file members.    Intended
  1569. X            for use    in conjunction with option -d (disk out-
  1570. X            put).
  1571. X
  1572. X           -p    Display    file name, compression method and datestamp
  1573. X            to the screen and prompt the user before processing
  1574. X            each file.
  1575. X
  1576. X           -t minutes
  1577. X            Allow only minutes time.  Intended for use on
  1578. X            remote systems which limit the amount of connect
  1579. X            time a caller is allowed.
  1580. X
  1581. X           -w    Wait for keystroke before returning control to the
  1582. X            parent environment.
  1583. X
  1584. X      BUGS
  1585. X           Screen length fixed at 24 rows.
  1586. X
  1587. X           Does not    prompt before overwriting files.
  1588. X
  1589. X           Does not    display    embedded file datestamps.
  1590. X
  1591. X           Does not    restore    datestamps of output files.
  1592. X
  1593. X           Not yet extensively tested with nested .LBR files.
  1594. X
  1595. X      SEE ALSO
  1596. X           Cfx User's Manual, arc(1), unzip(1), compress(1), pack(1).
  1597. X
  1598. X      AUTHOR
  1599. X           Carson Wilson
  1600. X           ..!uunet!ddsw1!carson
  1601. X           carson@sputnik.uucp
  1602. X
  1603. X
  1604. X
  1605. X
  1606. X
  1607. X
  1608. X
  1609. X
  1610. X      Rev. 1.1               01-20-92                 Page 2
  1611. X
  1612. X
  1613. END_OF_FILE
  1614. if test 3919 -ne `wc -c <'cfx.man'`; then
  1615.     echo shar: \"'cfx.man'\" unpacked with wrong size!
  1616. fi
  1617. # end of 'cfx.man'
  1618. fi
  1619. if test -f 'cfx.1' -a "${1}" != "-c" ; then 
  1620.   echo shar: Will not clobber existing file \"'cfx.1'\"
  1621. else
  1622. echo shar: Extracting \"'cfx.1'\" \(3485 characters\)
  1623. sed "s/^X//" >'cfx.1' <<'END_OF_FILE'
  1624. X.TH cfx 1 01-20-92 "Rev. 1.1"
  1625. X.SH NAME
  1626. cfx \- CP/M File eXpress
  1627. X.SH SYNOPSIS
  1628. X.B cfx
  1629. X[-bdinpw] [-c
  1630. X.IR n ]
  1631. X[-m
  1632. X.IR afn ]
  1633. X[-t
  1634. X.IR minutes ]
  1635. X[files ...]
  1636. X.SH DESCRIPTION
  1637. X.I Cfx
  1638. provides convenient access to the various file archiving methods 
  1639. presently associated with computers based on Digital Research's
  1640. X.I CP/M
  1641. operating system and its descendants.
  1642. By default,
  1643. X.I cfx
  1644. steps through the target file and extracts all human-readable 
  1645. information to the screen.
  1646. XFile extraction is also supported as a command line option.
  1647. X.PP
  1648. The following types of archives are supported
  1649. X(note that the file extents given below are merely conventions;
  1650. X.I cfx
  1651. reads a file's data to distinguish its archive type):
  1652. X.TP 12
  1653. X.B Extent
  1654. X.B Typical archive type
  1655. X.TP
  1656. X.B .lbr
  1657. Novosielski 
  1658. X.I library
  1659. format file.
  1660. This format is similar in purpose to the familiar MS-DOS 
  1661. X.I .arc
  1662. and 
  1663. X.I .zip
  1664. archives.
  1665. A set of related files is stored as a single "library"
  1666. for convenience and efficiency.
  1667. The format is comprised of a binary
  1668. X.I directory
  1669. one or more 128-byte CP/M 
  1670. X.I records
  1671. in length, followed sequentially by one or more 
  1672. X.I member
  1673. files, also comprised of one or more CP/M records.
  1674. X.TP
  1675. X.B .?q?
  1676. X.I Squeezed
  1677. files.
  1678. Squeezed
  1679. files contain Huffman-encoded text or binary data.
  1680. Squeezing
  1681. has generally been replaced more efficient compression 
  1682. methods.
  1683. The first two bytes of CP/M squeezed files are guaranteed to be 
  1684. X76 and FF hex, respectively.
  1685. X.TP
  1686. X.B .?z?
  1687. X.I Crunched
  1688. files.
  1689. Crunching is similar to squeezing, but uses the Lempel-Ziv-Welch 
  1690. algorithm, adapted for CP/M use by Steve Greenberg.
  1691. The first two bytes of CP/M crunched files are guaranteed to be 
  1692. X76 and FE hex, respectively.
  1693. X.TP
  1694. X.B .?y?
  1695. X.IR LZH -compressed
  1696. files.
  1697. LZH-compression uses a combination of Lempel-Ziv-Welch and 
  1698. Huffman techniques.
  1699. The first two bytes of CP/M LZH files are guaranteed to be 76 
  1700. and FD hex, respectively.
  1701. X.PP
  1702. X.I Cfx
  1703. will also display non-compressed (ASCII) files.
  1704. High bits are stripped during display, but not during 
  1705. extraction, so WordStar and other forms of text which store 
  1706. information in 8-bit form are handled reliably.
  1707. X.SH OPTIONS
  1708. X.TP 13
  1709. X.B \-b
  1710. Brief output only.
  1711. When processing library (.lbr) files, suppress initial directory 
  1712. display.
  1713. X.TP 13
  1714. X.BI \-c "\ n"
  1715. Monitor COM
  1716. X.I n
  1717. for carrier (MSDOS only).
  1718. X.TP
  1719. X.B \-d
  1720. XExtract files to current disk directory.
  1721. Compressed files are extracted to the filenames stored 
  1722. at file compression time.
  1723. X(See option -n).
  1724. X.TP
  1725. X.B \-i
  1726. Display file information only.
  1727. Overrides most other options.
  1728. X.TP
  1729. X.BI \-m "\ afn"
  1730. Specify a subset of library members for processing.
  1731. Limited to one ambiguous or unambiguous parameter.
  1732. X.TP
  1733. X.B \-n
  1734. Don't uncompress library file members.
  1735. Intended for use in conjunction with option -d (disk 
  1736. output).
  1737. X.TP
  1738. X.B \-p
  1739. Display file name, compression method and datestamp to the 
  1740. screen and prompt the user before processing each file.
  1741. X.TP
  1742. X.BI \-t "\ minutes"
  1743. Allow only
  1744. X.I minutes
  1745. time.
  1746. Intended for use on remote systems which limit the 
  1747. amount of connect time a caller is allowed.
  1748. X.TP
  1749. X.B \-w
  1750. Wait for keystroke before returning control to the parent 
  1751. environment.
  1752. X.SH BUGS
  1753. X.TP
  1754. Screen length fixed at 24 rows.
  1755. X.TP
  1756. Does not prompt before overwriting files.
  1757. X.TP
  1758. Does not display embedded file datestamps.
  1759. X.TP
  1760. Does not restore datestamps of output files.
  1761. X.TP
  1762. Not yet extensively tested with nested .LBR files.
  1763. X.SH "SEE ALSO"
  1764. Cfx User's Manual,
  1765. arc(1), unzip(1),
  1766. compress(1), pack(1).
  1767. X.SH AUTHOR
  1768. X.nf
  1769. Carson Wilson
  1770. X.I ..!uunet!ddsw1!carson
  1771. X.I carson\@sputnik.uucp
  1772. END_OF_FILE
  1773. if test 3485 -ne `wc -c <'cfx.1'`; then
  1774.     echo shar: \"'cfx.1'\" unpacked with wrong size!
  1775. fi
  1776. # end of 'cfx.1'
  1777. fi
  1778. echo shar: End of archive 2 \(of 2\).
  1779. cp /dev/null ark2isdone
  1780. MISSING=""
  1781. for I in 1 2 ; do
  1782.     if test ! -f ark${I}isdone ; then
  1783.     MISSING="${MISSING} ${I}"
  1784.     fi
  1785. done
  1786. if test "${MISSING}" = "" ; then
  1787.     echo You have unpacked both archives.
  1788.     rm -f ark[1-9]isdone
  1789. else
  1790.     echo You still need to unpack the following archives:
  1791.     echo "        " ${MISSING}
  1792. fi
  1793. ##  End of shell archive.
  1794. exit 0
  1795.  
  1796. exit 0 # Just in case...
  1797.