home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / program / c / bts314b4 / zmisc.c < prev    next >
C/C++ Source or Header  |  1994-08-27  |  20KB  |  813 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                            */
  3. /*                                                                            */
  4. /*        ------------         Bit-Bucket Software, Co.                        */
  5. /*        \ 10001101 /         Writers and Distributors of                    */
  6. /*         \ 011110 /          Freely Available<tm> Software.                 */
  7. /*          \ 1011 /                                                            */
  8. /*           ------                                                            */
  9. /*                                                                            */
  10. /*    (C) Copyright 1987-90, Bit Bucket Software Co., a Delaware Corporation. */
  11. /*                                                                            */
  12. /*                                                                            */
  13. /*                   Zmodem routines used by Zsend and Zreceive                */
  14. /*                                                                            */
  15. /*                                                                            */
  16. /*      For complete    details  of the licensing restrictions, please refer    */
  17. /*      to the License  agreement,  which  is published in its entirety in    */
  18. /*      the MAKEFILE and BT.C, and also contained in the file LICENSE.240.    */
  19. /*                                                                            */
  20. /*      USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  21. /*      BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  22. /*      THIS    AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,    OR IF YOU DO    */
  23. /*      NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  24. /*      SOFTWARE CO.    AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  25. /*      SHOULD YOU  PROCEED TO USE THIS FILE    WITHOUT HAVING    ACCEPTED THE    */
  26. /*      TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  27. /*      AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.        */
  28. /*                                                                            */
  29. /*                                                                            */
  30. /* You can contact Bit Bucket Software Co. at any one of the following        */
  31. /* addresses:                                                                */
  32. /*                                                                            */
  33. /* Bit Bucket Software Co.          FidoNet  1:104/501, 1:132/491, 1:141/491    */
  34. /* P.O. Box 460398                  AlterNet 7:491/0                            */
  35. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  36. /*                                  Internet f491.n132.z1.fidonet.org         */
  37. /*                                                                            */
  38. /* Please feel free to contact us at any time to share your comments about    */
  39. /* our software and/or licensing policies.                                    */
  40. /*                                                                            */
  41. /*                                                                            */
  42. /*    This module is based largely on a similar module in OPUS-CBCS V1.03b.    */
  43. /*    The original work is (C) Copyright 1986, Wynn Wagner III. The original    */
  44. /*    authors have graciously allowed us to use their code in this work.        */
  45. /*                                                                            */
  46. /*--------------------------------------------------------------------------*/
  47.  
  48. /*      */
  49. /* Warning! Do NOT detab this file since there are lots of spaces within "" */
  50.  
  51. #ifdef __TOS__
  52. #include <ext.h>
  53. #else
  54. #include <sys\types.h>
  55. #include <sys\stat.h>
  56. #include <fcntl.h>
  57. #endif
  58. #include <stdio.h>
  59. #include <ctype.h>
  60. #include <conio.h>
  61.  
  62. #if defined(__TURBOC__)
  63. #ifndef __TOS__
  64. #include <alloc.h>
  65. #endif
  66. #elif !defined(LATTICE)
  67. #include <malloc.h>
  68. #endif
  69.  
  70. #include "bink.h"
  71. #include "msgs.h"
  72. #include "sbuf.h"
  73. #include "zmodem.h"
  74. #include "com.h"
  75. #include "vfossil.h"
  76. #include "session.h"
  77.  
  78. /*
  79.  * Data
  80.  */
  81.  
  82. char Rxhdr[4];                                   /* Received header           */
  83. char Txhdr[4];                                   /* Transmitted header        */
  84.  
  85. #ifndef GENERIC
  86. long *RXlong = (long *) &Rxhdr[0];
  87. long *TXlong = (long *) &Txhdr[0];
  88.  
  89. #endif
  90. long Rxpos;                                      /* Received file position    */
  91. int Txfcs32;                                     /* TURE means send binary
  92.                                                   * frames with 32 bit FCS    */
  93. int Crc32t;                                      /* Display flag indicating
  94.                                                   * 32 bit CRC being sent */
  95. int Crc32;                                       /* Display flag indicating
  96.                                                   * 32 bit CRC being received */
  97. int Znulls;                                      /* # of nulls to send at
  98.                                                   * beginning of ZDATA hdr     */
  99.  
  100. int Rxtimeout;                                   /* Tenths of seconds to wait
  101.                                                   * for something          */
  102. int Rxframeind;                                  /* ZBIN ZBIN32,ZHEX type of
  103.                                                   * frame received */
  104.  
  105. char *Filename;                                  /* Name of the file being
  106.                                                   * up/downloaded             */
  107.  
  108. int szmdm;
  109.  
  110. size_t z_size = 0;
  111.  
  112.  
  113. static int Rxtype;                                 /* Type of header received                 */
  114.  
  115. static char hex[] = "0123456789abcdef";
  116.  
  117. /* Send a byte as two hex digits */
  118. #define Z_PUTHEX(i,c) {i=(c);SENDBYTE(hex[((i)&0xF0)>>4]);SENDBYTE(hex[(i)&0xF]);}
  119.  
  120. /*--------------------------------------------------------------------------*/
  121. /* Private routines                                                         */
  122. /*--------------------------------------------------------------------------*/
  123. static int _Z_GetBinaryHeader (unsigned char *);
  124. static int _Z_32GetBinaryHeader (unsigned char *);
  125. static int _Z_GetHexHeader (unsigned char *);
  126. static int _Z_GetHex (void);
  127. static int _Z_TimedRead (void);
  128. static long _Z_PullLongFromHeader (unsigned char *);
  129.  
  130. void z_message (s)
  131. byte *s;
  132. {
  133.    if (fullscreen && un_attended)
  134.       {
  135.       if (s)
  136.          {
  137.          sb_move (filewin, 2, 27);
  138.          sb_puts (filewin, s);
  139.          }
  140.       sb_puts (filewin, "              ");
  141.       sb_show ();
  142.       }
  143.    else
  144.       {
  145.       gotoxy (locate_x + 20, locate_y);
  146.       if (s)
  147.          {
  148.          cputs (s);
  149.          }
  150.       cputs ("               ");
  151.       }
  152. }
  153.  
  154. void z_log (s)
  155. char *s;
  156. {
  157.    word x, y;
  158.  
  159.    z_message (s);
  160.  
  161.    x = locate_x;
  162.    y = locate_y;
  163.    status_line (s);                              /* also does disk file
  164.                                                   * logging */
  165.    locate_x = x;
  166.    locate_y = y;
  167. }
  168.  
  169. void show_loc (l, w)
  170. unsigned long l;
  171. unsigned int w;
  172. {
  173.    char j[100];
  174.  
  175.    if (fullscreen && un_attended)
  176.       {
  177.       sb_move (filewin, 2, 37);
  178.       sprintf (j, "Ofs=%ld Retries=%d        ", l, w);
  179.       sb_puts (filewin, j);
  180.       sb_show ();
  181.       }
  182.    else
  183.       {
  184.       gotoxy (locate_x + 35, locate_y);
  185.       printf ("Ofs=%ld Retries=%d        ", l, w);
  186.       }
  187. }
  188.  
  189. /*--------------------------------------------------------------------------*/
  190. /* Z GET BYTE                                                                */
  191. /* Get a byte from the modem;                                                */
  192. /* return TIMEOUT if no read within timeout tenths,                         */
  193. /* return RCDO if carrier lost                                                */
  194. /*--------------------------------------------------------------------------*/
  195. int Z_GetByte (tenths)
  196. int tenths;
  197. {
  198. /*     register int time_val = 0; */
  199. #ifndef ATARIST
  200.    register int i;
  201. #endif   
  202.    long timeout;
  203.    timeout = 0;
  204.  
  205.    if ((PEEKBYTE () == ZPAD) && szmdm)
  206.         SENDBYTE (021);
  207.      szmdm = 0;
  208.    if (PEEKBYTE () >= 0)
  209.       return (MODEM_IN ());
  210.  
  211.  
  212.    timeout = timerset ((long)tenths * 30);
  213.  
  214. /*    status_line ("!Test 1 in get byte");
  215.     status_line ("!Peekbyte is %d", PEEKBYTE);
  216.     status_line ("!Modemin is %d", MODEM_IN);
  217. */
  218.  
  219.    do
  220.       {
  221.    if ((PEEKBYTE () == ZPAD) && szmdm)
  222.         SENDBYTE (021);
  223.      szmdm = 0;
  224.       if (PEEKBYTE () >= 0)
  225.          return (MODEM_IN ());
  226.  
  227. /*     status_line ("!Test 3 in get byte");
  228.       status_line ("!Peekbyte is %d", PEEKBYTE);
  229.       status_line ("!Modemin is %d", MODEM_IN);
  230. */
  231.  
  232. #if defined(ATARIST)
  233.       if(!CARRIER)
  234. #elif defined(OS_2)
  235.       if (!((i = MODEM_STATUS) & carrier_mask))
  236. #else
  237.       if (!((i = MODEM_STATUS ()) & carrier_mask))
  238. #endif
  239.          return RCDO;
  240.  
  241.       if (got_ESC ())
  242.          return -1;
  243.  
  244.       time_release ();
  245.       }
  246.    while (!timeup (timeout));
  247.    status_line ("!Timeout in Getbyte");
  248.    return TIMEOUT;
  249. }
  250.  
  251. /*--------------------------------------------------------------------------*/
  252. /* Z PUT STRING                                                             */
  253. /* Send a string to the modem, processing for \336 (sleep 1 sec)            */
  254. /* and \335 (break signal, ignored)                                         */
  255. /*--------------------------------------------------------------------------*/
  256. void Z_PutString (s)
  257. register unsigned char *s;
  258. {
  259.    register int c;
  260.  
  261.    while (*s)
  262.       {
  263.       switch (c = *s++)
  264.          {
  265.          case '\336':
  266.             big_pause (2);
  267.          case '\335':
  268. /* Should send a break on this */
  269.             break;
  270.          default:
  271.             SENDBYTE ((unsigned char) c);
  272.          }                                         /* switch */
  273.  
  274.       }                                          /* while */
  275.  
  276.    Z_UncorkTransmitter ();                         /* Make sure all is well */
  277. }                                                 /* Z_PutString */
  278.  
  279. /*--------------------------------------------------------------------------*/
  280. /* Z SEND HEX HEADER                                                        */
  281. /* Send ZMODEM HEX header hdr of type type                                    */
  282. /*--------------------------------------------------------------------------*/
  283. void Z_SendHexHeader (type, hdr)
  284. unsigned int type;
  285. register unsigned char *hdr;
  286. {
  287.    register int n;
  288.    register int i;
  289.    register word crc;
  290.  
  291. #ifdef ZDEBUG
  292.     if(debugging_log)
  293.            show_debug_name ("Z_SendHexHeader");
  294. #endif
  295.  
  296.  
  297.    Z_UncorkTransmitter ();                         /* Get our transmitter going */
  298.  
  299.    SENDBYTE (ZPAD);
  300.    SENDBYTE (ZPAD);
  301.    SENDBYTE (ZDLE);
  302.    SENDBYTE (ZHEX);
  303.    Z_PUTHEX (i, type);
  304. #ifdef ZDEBUG
  305.     if(debugging_log)
  306.         status_line(">Puthex type %02x", type);
  307. #endif
  308.  
  309.    Crc32t = 0;
  310.    crc = Z_UpdateCRC (type, 0);
  311.    for (n = 4; --n >= 0;)
  312.       {
  313.       Z_PUTHEX (i, (*hdr));
  314.       crc = Z_UpdateCRC (*hdr++, crc);
  315.       }
  316.    Z_PUTHEX (i, (crc >> 8));
  317.    Z_PUTHEX (i, crc);
  318. #ifdef ZDEBUG
  319.     if(debugging_log)
  320.         status_line(">Puthex CRC %04x", crc);
  321. #endif
  322.  
  323.  
  324.    /* Make it printable on remote machine */
  325.    SENDBYTE ('\r');
  326.    SENDBYTE ('\n');
  327.  
  328.    /* Uncork the remote in case a fake XOFF has stopped data flow */
  329.    if (type != ZFIN && type != ZACK)
  330.       SENDBYTE (021);
  331.  
  332.    if (!CARRIER)
  333.       CLEAR_OUTBOUND ();
  334.  
  335. }                                                 /* Z_SendHexHeader */
  336.  
  337. /*--------------------------------------------------------------------------*/
  338. /* Z UNCORK TRANSMITTER                                                     */
  339. /* Wait a reasonable amount of time for transmitter buffer to clear.        */
  340. /*     When it does, or when time runs out, turn XON/XOFF off then on.        */
  341. /*     This should release a transmitter stuck by line errors.                */
  342. /*--------------------------------------------------------------------------*/
  343.  
  344. void Z_UncorkTransmitter ()
  345. {
  346.    long t;
  347.  
  348.    if (!OUT_EMPTY ())
  349.       {
  350.       t = timerset ((long)5 * Rxtimeout);              /* Wait for silence */
  351.       while (!timeup (t) && !OUT_EMPTY () && CARRIER)
  352.          time_release ();                         /* Give up slice while
  353.                                                   * waiting  */
  354.       }
  355.    XON_DISABLE ();                                 /* Uncork the transmitter */
  356.    XON_ENABLE ();
  357. }
  358.  
  359.  
  360. /*--------------------------------------------------------------------------*/
  361. /* Z GET HEADER                                                             */
  362. /* Read a ZMODEM header to hdr, either binary or hex.                        */
  363. /*     On success, set Zmodem to 1 and return type of header.                 */
  364. /*     Otherwise return negative on error                                     */
  365. /*--------------------------------------------------------------------------*/
  366. int Z_GetHeader (byte *hdr)
  367. {
  368.  
  369.    register int c;
  370.    register long n;        /* 38400 baud is bigger than 0x8000!!!! */
  371.    int cancount;
  372.  
  373. #ifdef ZDEBUG
  374.     if(debugging_log)
  375.            show_debug_name ("Z_GetHeader");
  376. #endif
  377.  
  378.    n = cur_baud;                                 /* Max characters before
  379.                                                   * start of frame */
  380.    cancount = 5;
  381.  
  382. Again:
  383.  
  384.    if (got_ESC ())
  385.       {
  386.       send_can ();
  387.       z_log (msgtxt[M_KBD_MSG]);
  388.       return ZCAN;
  389.       }
  390.  
  391.    Rxframeind = Rxtype = 0;
  392.  
  393.    switch (c = _Z_TimedRead ())
  394.       {
  395.       case ZPAD:
  396.       case ZPAD | 0200:
  397.          /*-----------------------------------------------*/
  398.          /* This is what we want.                          */
  399.          /*-----------------------------------------------*/
  400.          break;
  401.  
  402.       case RCDO:
  403.       case TIMEOUT:
  404.          goto Done;
  405.  
  406.       case CAN:
  407.  
  408.    GotCan:
  409.  
  410.          if (--cancount <= 0)
  411.             {
  412.             c = ZCAN;
  413.             goto Done;
  414.             }
  415.          switch (c = Z_GetByte (1))
  416.             {
  417.             case TIMEOUT:
  418.                goto Again;
  419.  
  420.             case ZCRCW:
  421.                c = ERROR;
  422.                /* fallthrough... */
  423.  
  424.             case RCDO:
  425.                goto Done;
  426.  
  427.             case CAN:
  428.                if (--cancount <= 0)
  429.                   {
  430.                   c = ZCAN;
  431.                   goto Done;
  432.                   }
  433.                goto Again;
  434.             }
  435.          /* fallthrough... */
  436.  
  437.       default:
  438.  
  439.    Agn2:
  440.  
  441.          if (--n <= 0)
  442.             {
  443.             z_log (msgtxt[M_FUBAR_MSG]);
  444.             return ERROR;
  445.             }
  446.  
  447.          if (c != CAN)
  448.             cancount = 5;
  449.          goto Again;
  450.  
  451.       }                                          /* switch */
  452.  
  453.    cancount = 5;
  454.  
  455. Splat:
  456.  
  457.    switch (c = _Z_TimedRead ())
  458.       {
  459.       case ZDLE:
  460.          /*-----------------------------------------------*/
  461.          /* This is what we want.                          */
  462.          /*-----------------------------------------------*/
  463.          break;
  464.  
  465.       case ZPAD:
  466.          goto Splat;
  467.  
  468.       case RCDO:
  469.       case TIMEOUT:
  470.          goto Done;
  471.  
  472.       default:
  473.          goto Agn2;
  474.  
  475.       }                                          /* switch */
  476.  
  477.  
  478.    switch (c = _Z_TimedRead ())
  479.       {
  480.  
  481.       case ZBIN:
  482.          Rxframeind = ZBIN;
  483.          Crc32 = 0;
  484.          c = _Z_GetBinaryHeader (hdr);
  485.          break;
  486.  
  487.       case ZBIN32:
  488.          Crc32 = Rxframeind = ZBIN32;
  489.          c = _Z_32GetBinaryHeader (hdr);
  490.          break;
  491.  
  492.       case ZHEX:
  493.          Rxframeind = ZHEX;
  494.          Crc32 = 0;
  495.          c = _Z_GetHexHeader (hdr);
  496.          break;
  497.  
  498.       case CAN:
  499.          goto GotCan;
  500.  
  501.       case RCDO:
  502.       case TIMEOUT:
  503.          goto Done;
  504.  
  505.       default:
  506.          goto Agn2;
  507.  
  508.       }                                          /* switch */
  509.  
  510.    Rxpos = _Z_PullLongFromHeader (hdr);
  511.  
  512. Done:
  513.  
  514. #ifdef ZDEBUG
  515.     if(debugging_log)
  516.         status_line(">Z_GetHeader returning %d", c);
  517. #endif
  518.  
  519.    return c;
  520. }                                                 /* Z_GetHeader */
  521.  
  522. /*--------------------------------------------------------------------------*/
  523. /* Z GET BINARY HEADER                                                        */
  524. /* Receive a binary style header (type and position)                        */
  525. /*--------------------------------------------------------------------------*/
  526. static int _Z_GetBinaryHeader (hdr)
  527. register unsigned char *hdr;
  528. {
  529.    register int c;
  530.    register unsigned int crc;
  531.    register int n;
  532.  
  533. #ifdef ZDEBUG
  534.     if(debugging_log)
  535.            show_debug_name ("Z_GetBinaryHeader");
  536. #endif
  537.  
  538.    if ((c = Z_GetZDL ()) & ~0xFF)
  539.       return c;
  540.    Rxtype = c;
  541.    crc = Z_UpdateCRC (c, 0);
  542.  
  543.    for (n = 4; --n >= 0;)
  544.       {
  545.       if ((c = Z_GetZDL ()) & ~0xFF)
  546.          return c;
  547.       crc = Z_UpdateCRC (c, crc);
  548.       *hdr++ = (unsigned char) (c & 0xff);
  549.       }
  550.    if ((c = Z_GetZDL ()) & ~0xFF)
  551.       return c;
  552.  
  553.    crc = Z_UpdateCRC (c, crc);
  554.    if ((c = Z_GetZDL ()) & ~0xFF)
  555.       return c;
  556.  
  557.    crc = Z_UpdateCRC (c, crc);
  558.    if (crc & 0xFFFF)
  559.       {
  560.       z_message (msgtxt[M_CRC_MSG]);
  561.       return ERROR;
  562.       }
  563.  
  564.    return Rxtype;
  565. }                                                 /* _Z_GetBinaryHeader */
  566.  
  567.  
  568. /*--------------------------------------------------------------------------*/
  569. /* Z GET BINARY HEADER with 32 bit CRC                                        */
  570. /* Receive a binary style header (type and position)                        */
  571. /*--------------------------------------------------------------------------*/
  572. static int _Z_32GetBinaryHeader (hdr)
  573. register unsigned char *hdr;
  574. {
  575.    register int c;
  576.    register unsigned long crc;
  577.    register int n;
  578.  
  579. #ifdef ZDEBUG
  580.     if(debugging_log)
  581.        show_debug_name ("Z_32GetBinaryHeader");
  582. #endif
  583.  
  584.    if ((c = Z_GetZDL ()) & ~0xFF)
  585.       return c;
  586.    Rxtype = c;
  587.    crc = 0xFFFFFFFF;
  588.    crc = Z_32UpdateCRC (c, crc);
  589.  
  590.    for (n = 4; --n >= 0;)
  591.       {
  592.       if ((c = Z_GetZDL ()) & ~0xFF)
  593.          return c;
  594.       crc = Z_32UpdateCRC (c, crc);
  595.       *hdr++ = (unsigned char) (c & 0xff);
  596.       }
  597.  
  598.    for (n = 4; --n >= 0;)
  599.       {
  600.       if ((c = Z_GetZDL ()) & ~0xFF)
  601.          return c;
  602.  
  603.       crc = Z_32UpdateCRC (c, crc);
  604.       }
  605.  
  606.    if (crc != 0xDEBB20E3)
  607.       {
  608.       z_message (msgtxt[M_CRC_MSG]);
  609.       return ERROR;
  610.       }
  611.  
  612.    return Rxtype;
  613. }                                                 /* _Z_32GetBinaryHeader */
  614.  
  615. /*--------------------------------------------------------------------------*/
  616. /* Z GET HEX HEADER                                                         */
  617. /* Receive a hex style header (type and position)                            */
  618. /*--------------------------------------------------------------------------*/
  619. static int _Z_GetHexHeader (hdr)
  620. register unsigned char *hdr;
  621. {
  622.    register int c;
  623.    register unsigned int crc;
  624.    register int n;
  625.  
  626. #ifdef ZDEBUG
  627.     if(debugging_log)
  628.        show_debug_name ("Z_GetHexHeader");
  629. #endif
  630.  
  631.    if ((c = _Z_GetHex ()) < 0)
  632.       return c;
  633.    Rxtype = c;
  634.    crc = Z_UpdateCRC (c, 0);
  635.  
  636.    for (n = 4; --n >= 0;)
  637.       {
  638.       if ((c = _Z_GetHex ()) < 0)
  639.          return c;
  640.       crc = Z_UpdateCRC (c, crc);
  641.       *hdr++ = (unsigned char) c;
  642.       }
  643.  
  644.    if ((c = _Z_GetHex ()) < 0)
  645.       return c;
  646.    crc = Z_UpdateCRC (c, crc);
  647.    if ((c = _Z_GetHex ()) < 0)
  648.       return c;
  649.    crc = Z_UpdateCRC (c, crc);
  650.    if (crc & 0xFFFF)
  651.       {
  652.       z_message (msgtxt[M_CRC_MSG]);
  653.       return ERROR;
  654.       }
  655.    if (Z_GetByte (1) == '\r')
  656.       Z_GetByte (1);                             /* Throw away possible cr/lf */
  657.  
  658.    return Rxtype;
  659. }
  660.  
  661. /*--------------------------------------------------------------------------*/
  662. /* Z GET HEX                                                                */
  663. /* Decode two lower case hex digits into an 8 bit byte value                */
  664. /*--------------------------------------------------------------------------*/
  665. static int _Z_GetHex ()
  666. {
  667.    register int c, n;
  668.  
  669. #ifdef ZDEBUG
  670.     if(debugging_log)
  671.            show_debug_name ("Z_GetHex");
  672. #endif
  673.  
  674.    if ((n = _Z_TimedRead ()) < 0)
  675.       return n;
  676.    n -= '0';
  677.    if (n > 9)
  678.       n -= ('a' - ':');
  679.    if (n & ~0xF)
  680.       return ERROR;
  681.  
  682.    if ((c = _Z_TimedRead ()) < 0)
  683.       return c;
  684.    c -= '0';
  685.    if (c > 9)
  686.       c -= ('a' - ':');
  687.    if (c & ~0xF)
  688.       return ERROR;
  689.  
  690. #ifdef ZDEBUG
  691.     if(debugging_log)
  692.        status_line(">Z_GotHex %x%x", n, c);
  693. #endif
  694.    return ((n << 4) | c);
  695. }
  696.  
  697. /*--------------------------------------------------------------------------*/
  698. /* Z GET ZDL                                                                */
  699. /* Read a byte, checking for ZMODEM escape encoding                         */
  700. /* including CAN*5 which represents a quick abort                            */
  701. /*--------------------------------------------------------------------------*/
  702. int Z_GetZDL ()
  703. {
  704.    register int c;
  705.  
  706.    if ((c = Z_GetByte (Rxtimeout)) != ZDLE)
  707.       return c;
  708.  
  709.    switch (c = Z_GetByte (Rxtimeout))
  710.       {
  711.       case CAN:
  712.          return ((c = Z_GetByte (Rxtimeout)) < 0) ? c :
  713.             ((c == CAN) && ((c = Z_GetByte (Rxtimeout)) < 0)) ? c :
  714.             ((c == CAN) && ((c = Z_GetByte (Rxtimeout)) < 0)) ? c : (GOTCAN);
  715.  
  716.       case ZCRCE:
  717.       case ZCRCG:
  718.       case ZCRCQ:
  719.       case ZCRCW:
  720.          return (c | GOTOR);
  721.  
  722.       case ZRUB0:
  723.          return 0x7F;
  724.  
  725.       case ZRUB1:
  726.          return 0xFF;
  727.  
  728.       default:
  729.          return (c < 0) ? c :
  730.             ((c & 0x60) == 0x40) ? (c ^ 0x40) : ERROR;
  731.  
  732.       }                                          /* switch */
  733. }                                                 /* Z_GetZDL */
  734.  
  735. /*--------------------------------------------------------------------------*/
  736. /* Z TIMED READ                                                             */
  737. /* Read a character from the modem line with timeout.                        */
  738. /*    Eat parity, XON and XOFF characters.                                    */
  739. /*--------------------------------------------------------------------------*/
  740. static int _Z_TimedRead ()
  741. {
  742.    register int c;
  743.  
  744. #ifdef ZDEBUG
  745.     if(debugging_log)
  746.            show_debug_name ("Z_TimedRead");
  747. #endif
  748.  
  749.    for (;;)
  750.       {
  751.       if ((c = Z_GetByte (Rxtimeout)) < 0)
  752.          return c;
  753.  
  754.       switch (c &= 0x7F)
  755.          {
  756.          case XON:
  757.          case XOFF:
  758.             continue;
  759.  
  760.          default:
  761.             if (!(c & 0x60))
  762.                continue;
  763.  
  764.          case '\r':
  765.          case '\n':
  766.          case ZDLE:
  767.             return c;
  768.          }                                         /* switch */
  769.  
  770.       }                                          /* for */
  771. }                                                 /* _Z_TimedRead */
  772.  
  773. /*--------------------------------------------------------------------------*/
  774. /* Z LONG TO HEADER                                                         */
  775. /* Store long integer pos in Txhdr                                            */
  776. /*--------------------------------------------------------------------------*/
  777. void Z_PutLongIntoHeader (pos)
  778. long pos;
  779. {
  780. #ifndef GENERIC
  781.    *((long *) Txhdr) = pos;
  782. #else
  783.    Txhdr[ZP0] = pos;
  784.    Txhdr[ZP1] = pos >> 8;
  785.    Txhdr[ZP2] = pos >> 16;
  786.    Txhdr[ZP3] = pos >> 24;
  787. #endif
  788. }                                                 /* Z_PutLongIntoHeader */
  789.  
  790. /*--------------------------------------------------------------------------*/
  791. /* Z PULL LONG FROM HEADER                                                    */
  792. /* Recover a long integer from a header                                     */
  793. /*--------------------------------------------------------------------------*/
  794. static long _Z_PullLongFromHeader (hdr)
  795. unsigned char *hdr;
  796. {
  797. #ifndef GENERIC
  798.    return (*((long *) Rxhdr)); /*PLF Fri  05-05-1989  06:42:41 */
  799.    /* hdr; */                    /*PLF Fri    05-05-1989    06:42:59 ; Trick to
  800.                                  * keep /W3 happy */
  801. #else
  802.    long l;
  803.  
  804.    l = hdr[ZP3];
  805.    l = (l << 8) | hdr[ZP2];
  806.    l = (l << 8) | hdr[ZP1];
  807.    l = (l << 8) | hdr[ZP0];
  808.    return l;
  809. #endif
  810. }                                                 /* _Z_PullLongFromHeader */
  811.  
  812. /* END OF FILE: zmisc.c */
  813.