home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / LO241SRV.ZIP / ZMISC.C < prev    next >
C/C++ Source or Header  |  1998-05-17  |  18KB  |  648 lines

  1.  
  2. // LoraBBS Version 2.41 Free Edition
  3. // Copyright (C) 1987-98 Marco Maccaferri
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include <stdio.h>
  20. #include <string.h>
  21.  
  22. #include <cxl\cxlwin.h>
  23.  
  24. #include "zmodem.h"
  25. #include "lsetup.h"
  26. #include "sched.h"
  27. #include "msgapi.h"
  28. #include "externs.h"
  29. #include "prototyp.h"
  30.  
  31. static int Rxtype;                               /* Type of header received                 */
  32.  
  33. static char hex[] = "0123456789abcdef";
  34.  
  35. /* Send a byte as two hex digits */
  36. #define Z_PUTHEX(i,c) {i=(c);SENDBYTE(hex[((i)&0xF0)>>4]);SENDBYTE(hex[(i)&0xF]);}
  37.  
  38. /*--------------------------------------------------------------------------*/
  39. /* Private routines                                                         */
  40. /*--------------------------------------------------------------------------*/
  41. static int _Z_GetBinaryHeader (unsigned char *);
  42. static int _Z_32GetBinaryHeader (unsigned char *);
  43. static int _Z_GetHexHeader (unsigned char *);
  44. static int _Z_GetHex (void);
  45. static int _Z_TimedRead (void);
  46. static long _Z_PullLongFromHeader (unsigned char *);
  47.  
  48. void show_loc (l, w)
  49. unsigned long l;
  50. unsigned int w;
  51. {
  52.    char j[100];
  53.  
  54.    sprintf (j, "Ofs=%ld Retries=%d        ", l, w);
  55.  
  56.    if (caller || emulator) {
  57.       wgotoxy (1, 37);
  58.       wputs (j);
  59.    }
  60.    else
  61.       wprints (10, 37, WHITE|_BLACK, j);
  62. }
  63.  
  64. void z_message (s)
  65. char *s;
  66. {
  67.    if (caller || emulator) {
  68.       if (s)
  69.          {
  70.          wgotoxy (1, 27);
  71.          wputs (s);
  72.          }
  73.       wputs ("              ");
  74.    }
  75.    else {
  76.       wprints (10, 27, WHITE|_BLACK, s);
  77.       wprints (10, 27 + strlen (s), WHITE|_BLACK, "              ");
  78.    }
  79. }
  80.  
  81. int Z_GetByte (tenths)
  82. int tenths;
  83. {
  84.    long timeout, timerset ();
  85.  
  86.    if (PEEKBYTE () >= 0)
  87.       return (MODEM_IN ());
  88.  
  89.    timeout = timerset (tenths * 10);
  90.  
  91.    do
  92.       {
  93.       if (PEEKBYTE () >= 0)
  94.          return MODEM_IN ();
  95.  
  96.       if (!(MODEM_STATUS () & carrier_mask))
  97.          return RCDO;
  98.  
  99.       if (local_kbd == 0x1B)
  100.          {
  101.          local_kbd = -1;
  102.          return -1;
  103.          }
  104.  
  105.       time_release ();
  106.       }
  107.    while (!timeup (timeout));
  108.  
  109.    return TIMEOUT;
  110. }
  111.  
  112. /*--------------------------------------------------------------------------*/
  113. /* Z PUT STRING                                                             */
  114. /* Send a string to the modem, processing for \336 (sleep 1 sec)            */
  115. /* and \335 (break signal, ignored)                                         */
  116. /*--------------------------------------------------------------------------*/
  117. void Z_PutString (s)
  118. register unsigned char *s;
  119. {
  120.    register int c;
  121.  
  122.    while (*s)
  123.       {
  124.       switch (c = *s++)
  125.          {
  126.          case '\336':
  127.             big_pause (2);
  128.          case '\335':
  129. /* Should send a break on this */
  130.             break;
  131.          default:
  132.             SENDBYTE ((unsigned char) c);
  133.          }                                       /* switch */
  134.  
  135.       }                                          /* while */
  136.  
  137.    Z_UncorkTransmitter ();                       /* Make sure all is well */
  138. }                                                /* Z_PutString */
  139.  
  140. /*--------------------------------------------------------------------------*/
  141. /* Z SEND HEX HEADER                                                        */
  142. /* Send ZMODEM HEX header hdr of type type                                  */
  143. /*--------------------------------------------------------------------------*/
  144. void Z_SendHexHeader (type, hdr)
  145. unsigned int type;
  146. register unsigned char *hdr;
  147. {
  148.    register int n;
  149.    register int i;
  150.    register word crc;
  151.  
  152. #ifdef DEBUG
  153.    show_debug_name ("Z_SendHexHeader");
  154. #endif
  155.  
  156.    Z_UncorkTransmitter ();                       /* Get our transmitter going */
  157.  
  158.    SENDBYTE (ZPAD);
  159.    SENDBYTE (ZPAD);
  160.    SENDBYTE (ZDLE);
  161.    SENDBYTE (ZHEX);
  162.    Z_PUTHEX (i, type);
  163.  
  164.    Crc32t = 0;
  165.    crc = Z_UpdateCRC (type, 0);
  166.    for (n = 4; --n >= 0;)
  167.       {
  168.       Z_PUTHEX (i, (*hdr));
  169.       crc = Z_UpdateCRC (((unsigned short) (*hdr++)), crc);
  170.       }
  171.    Z_PUTHEX (i, (crc >> 8));
  172.    Z_PUTHEX (i, crc);
  173.  
  174.    /* Make it printable on remote machine */
  175.    SENDBYTE ('\r');
  176.    SENDBYTE ('\n');
  177.  
  178.    /* Uncork the remote in case a fake XOFF has stopped data flow */
  179.    if (type != ZFIN && type != ZACK)
  180.       SENDBYTE (021);
  181.  
  182.    if (!CARRIER)
  183.       CLEAR_OUTBOUND ();
  184.  
  185. }                                                /* Z_SendHexHeader */
  186.  
  187. /*--------------------------------------------------------------------------*/
  188. /* Z UNCORK TRANSMITTER                                                     */
  189. /* Wait a reasonable amount of time for transmitter buffer to clear.        */
  190. /*   When it does, or when time runs out, turn XON/XOFF off then on.        */
  191. /*   This should release a transmitter stuck by line errors.                */
  192. /*--------------------------------------------------------------------------*/
  193.  
  194. void Z_UncorkTransmitter ()
  195. {
  196.    long t, timerset ();
  197.  
  198.    if (!OUT_EMPTY ())
  199.       {
  200.       t = timerset (5 * Rxtimeout);              /* Wait for silence */
  201.       while (!timeup (t) && !OUT_EMPTY () && CARRIER)
  202.          time_release ();                        /* Give up slice while */
  203.                                                  /* waiting  */
  204.       }
  205.    XON_DISABLE ();                               /* Uncork the transmitter */
  206.    XON_ENABLE ();
  207. }
  208.  
  209.  
  210. /*--------------------------------------------------------------------------*/
  211. /* Z GET HEADER                                                             */
  212. /* Read a ZMODEM header to hdr, either binary or hex.                       */
  213. /*   On success, set Zmodem to 1 and return type of header.                 */
  214. /*   Otherwise return negative on error                                     */
  215. /*--------------------------------------------------------------------------*/
  216. int Z_GetHeader (hdr)
  217. byte *hdr;
  218. {
  219.  
  220.    register int c;
  221.    register int n;
  222.    int cancount;
  223.  
  224. #ifdef DEBUG
  225.    show_debug_name ("Z_GetHeader");
  226. #endif
  227.  
  228.    n = rate;                                     /* Max characters before
  229.                                                   * start of frame */
  230.    cancount = 5;
  231.  
  232. Again:
  233.  
  234.    if (local_kbd == 0x1B)
  235.       {
  236.       local_kbd = -1;
  237.       send_can ();
  238.       status_line (msgtxt[M_KBD_MSG]);
  239.       return ZCAN;
  240.       }
  241.  
  242.    Rxframeind = Rxtype = 0;
  243.  
  244.    switch (c = _Z_TimedRead ())
  245.       {
  246.       case ZPAD:
  247.       case ZPAD | 0200:
  248.          /*-----------------------------------------------*/
  249.          /* This is what we want.                         */
  250.          /*-----------------------------------------------*/
  251.          break;
  252.  
  253.       case RCDO:
  254.       case TIMEOUT:
  255.          goto Done;
  256.  
  257.       case CAN:
  258.  
  259.    GotCan:
  260.  
  261.          if (--cancount <= 0)
  262.             {
  263.             c = ZCAN;
  264.             goto Done;
  265.             }
  266.          switch (c = Z_GetByte (1))
  267.             {
  268.             case TIMEOUT:
  269.                goto Again;
  270.  
  271.             case ZCRCW:
  272.                c = ERROR;
  273.                /* fallthrough... */
  274.  
  275.             case RCDO:
  276.                goto Done;
  277.  
  278.             case CAN:
  279.                if (--cancount <= 0)
  280.                   {
  281.                   c = ZCAN;
  282.                   goto Done;
  283.                   }
  284.                goto Again;
  285.             }
  286.          /* fallthrough... */
  287.  
  288.       default:
  289.  
  290.    Agn2:
  291.  
  292.          if (--n <= 0)
  293.             {
  294.             status_line (msgtxt[M_FUBAR_MSG]);
  295.             return ERROR;
  296.             }
  297.  
  298.          if (c != CAN)
  299.             cancount = 5;
  300.          goto Again;
  301.  
  302.       }                                          /* switch */
  303.  
  304.    cancount = 5;
  305.  
  306. Splat:
  307.  
  308.    switch (c = _Z_TimedRead ())
  309.       {
  310.       case ZDLE:
  311.          /*-----------------------------------------------*/
  312.          /* This is what we want.                         */
  313.          /*-----------------------------------------------*/
  314.          break;
  315.  
  316.       case ZPAD:
  317.          goto Splat;
  318.  
  319.       case RCDO:
  320.       case TIMEOUT:
  321.          goto Done;
  322.  
  323.       default:
  324.          goto Agn2;
  325.  
  326.       }                                          /* switch */
  327.  
  328.  
  329.    switch (c = _Z_TimedRead ())
  330.       {
  331.  
  332.       case ZBIN:
  333.          Rxframeind = ZBIN;
  334.          Crc32 = 0;
  335.          c = _Z_GetBinaryHeader (hdr);
  336.          break;
  337.  
  338.       case ZBIN32:
  339.          Crc32 = Rxframeind = ZBIN32;
  340.          c = _Z_32GetBinaryHeader (hdr);
  341.          break;
  342.  
  343.       case ZHEX:
  344.          Rxframeind = ZHEX;
  345.          Crc32 = 0;
  346.          c = _Z_GetHexHeader (hdr);
  347.          break;
  348.  
  349.       case CAN:
  350.          goto GotCan;
  351.  
  352.       case RCDO:
  353.       case TIMEOUT:
  354.          goto Done;
  355.  
  356.       default:
  357.          goto Agn2;
  358.  
  359.       }                                          /* switch */
  360.  
  361.    Rxpos = _Z_PullLongFromHeader (hdr);
  362.  
  363. Done:
  364.  
  365.    return c;
  366. }                                                /* Z_GetHeader */
  367.  
  368. /*--------------------------------------------------------------------------*/
  369. /* Z GET BINARY HEADER                                                      */
  370. /* Receive a binary style header (type and position)                        */
  371. /*--------------------------------------------------------------------------*/
  372. static int _Z_GetBinaryHeader (hdr)
  373. register unsigned char *hdr;
  374. {
  375.    register int c;
  376.    register unsigned int crc;
  377.    register int n;
  378.  
  379. #ifdef DEBUG
  380.    show_debug_name ("Z_GetBinaryHeader");
  381. #endif
  382.  
  383.    if ((c = Z_GetZDL ()) & ~0xFF)
  384.       return c;
  385.    Rxtype = c;
  386.    crc = Z_UpdateCRC (c, 0);
  387.  
  388.    for (n = 4; --n >= 0;)
  389.       {
  390.       if ((c = Z_GetZDL ()) & ~0xFF)
  391.          return c;
  392.       crc = Z_UpdateCRC (c, crc);
  393.       *hdr++ = (unsigned char) (c & 0xff);
  394.       }
  395.    if ((c = Z_GetZDL ()) & ~0xFF)
  396.       return c;
  397.  
  398.    crc = Z_UpdateCRC (c, crc);
  399.    if ((c = Z_GetZDL ()) & ~0xFF)
  400.       return c;
  401.  
  402.    crc = Z_UpdateCRC (c, crc);
  403.    if (crc & 0xFFFF)
  404.       {
  405.       z_message (msgtxt[M_CRC_MSG]);
  406.       return ERROR;
  407.       }
  408.  
  409.    return Rxtype;
  410. }                                                /* _Z_GetBinaryHeader */
  411.  
  412.  
  413. /*--------------------------------------------------------------------------*/
  414. /* Z GET BINARY HEADER with 32 bit CRC                                      */
  415. /* Receive a binary style header (type and position)                        */
  416. /*--------------------------------------------------------------------------*/
  417. static int _Z_32GetBinaryHeader (hdr)
  418. register unsigned char *hdr;
  419. {
  420.    register int c;
  421.    register unsigned long crc;
  422.    register int n;
  423.  
  424. #ifdef DEBUG
  425.    show_debug_name ("Z_32GetBinaryHeader");
  426. #endif
  427.  
  428.    if ((c = Z_GetZDL ()) & ~0xFF)
  429.       return c;
  430.    Rxtype = c;
  431.    crc = 0xFFFFFFFFL;
  432.    crc = Z_32UpdateCRC (c, crc);
  433.  
  434.    for (n = 4; --n >= 0;)
  435.       {
  436.       if ((c = Z_GetZDL ()) & ~0xFF)
  437.          return c;
  438.       crc = Z_32UpdateCRC (c, crc);
  439.       *hdr++ = (unsigned char) (c & 0xff);
  440.       }
  441.  
  442.    for (n = 4; --n >= 0;)
  443.       {
  444.       if ((c = Z_GetZDL ()) & ~0xFF)
  445.          return c;
  446.  
  447.       crc = Z_32UpdateCRC (c, crc);
  448.       }
  449.  
  450.    if (crc != 0xDEBB20E3L)
  451.       {
  452.       z_message (msgtxt[M_CRC_MSG]);
  453.       return ERROR;
  454.       }
  455.  
  456.    return Rxtype;
  457. }                                                /* _Z_32GetBinaryHeader */
  458.  
  459. /*--------------------------------------------------------------------------*/
  460. /* Z GET HEX HEADER                                                         */
  461. /* Receive a hex style header (type and position)                           */
  462. /*--------------------------------------------------------------------------*/
  463. static int _Z_GetHexHeader (hdr)
  464. register unsigned char *hdr;
  465. {
  466.    register int c;
  467.    register unsigned int crc;
  468.    register int n;
  469.  
  470. #ifdef DEBUG
  471.    show_debug_name ("Z_GetHexHeader");
  472. #endif
  473.  
  474.    if ((c = _Z_GetHex ()) < 0)
  475.       return c;
  476.    Rxtype = c;
  477.    crc = Z_UpdateCRC (c, 0);
  478.  
  479.    for (n = 4; --n >= 0;)
  480.       {
  481.       if ((c = _Z_GetHex ()) < 0)
  482.          return c;
  483.       crc = Z_UpdateCRC (c, crc);
  484.       *hdr++ = (unsigned char) c;
  485.       }
  486.  
  487.    if ((c = _Z_GetHex ()) < 0)
  488.       return c;
  489.    crc = Z_UpdateCRC (c, crc);
  490.    if ((c = _Z_GetHex ()) < 0)
  491.       return c;
  492.    crc = Z_UpdateCRC (c, crc);
  493.    if (crc & 0xFFFF)
  494.       {
  495.       z_message (msgtxt[M_CRC_MSG]);
  496.       return ERROR;
  497.       }
  498.    if (Z_GetByte (1) == '\r')
  499.       Z_GetByte (1);                             /* Throw away possible cr/lf */
  500.  
  501.    return Rxtype;
  502. }
  503.  
  504. /*--------------------------------------------------------------------------*/
  505. /* Z GET HEX                                                                */
  506. /* Decode two lower case hex digits into an 8 bit byte value                */
  507. /*--------------------------------------------------------------------------*/
  508. static int _Z_GetHex ()
  509. {
  510.    register int c, n;
  511.  
  512. #ifdef DEBUG
  513.    show_debug_name ("Z_GetHex");
  514. #endif
  515.  
  516.    if ((n = _Z_TimedRead ()) < 0)
  517.       return n;
  518.    n -= '0';
  519.    if (n > 9)
  520.       n -= ('a' - ':');
  521.    if (n & ~0xF)
  522.       return ERROR;
  523.  
  524.    if ((c = _Z_TimedRead ()) < 0)
  525.       return c;
  526.    c -= '0';
  527.    if (c > 9)
  528.       c -= ('a' - ':');
  529.    if (c & ~0xF)
  530.       return ERROR;
  531.  
  532.    return ((n << 4) | c);
  533. }
  534.  
  535. /*--------------------------------------------------------------------------*/
  536. /* Z GET ZDL                                                                */
  537. /* Read a byte, checking for ZMODEM escape encoding                         */
  538. /* including CAN*5 which represents a quick abort                           */
  539. /*--------------------------------------------------------------------------*/
  540. int Z_GetZDL ()
  541. {
  542.    register int c;
  543.  
  544.    if ((c = Z_GetByte (Rxtimeout)) != ZDLE)
  545.       return c;
  546.  
  547.    switch (c = Z_GetByte (Rxtimeout))
  548.       {
  549.       case CAN:
  550.          return ((c = Z_GetByte (Rxtimeout)) < 0) ? c :
  551.             ((c == CAN) && ((c = Z_GetByte (Rxtimeout)) < 0)) ? c :
  552.             ((c == CAN) && ((c = Z_GetByte (Rxtimeout)) < 0)) ? c : (GOTCAN);
  553.  
  554.       case ZCRCE:
  555.       case ZCRCG:
  556.       case ZCRCQ:
  557.       case ZCRCW:
  558.          return (c | GOTOR);
  559.  
  560.       case ZRUB0:
  561.          return 0x7F;
  562.  
  563.       case ZRUB1:
  564.          return 0xFF;
  565.  
  566.       default:
  567.          return (c < 0) ? c :
  568.             ((c & 0x60) == 0x40) ? (c ^ 0x40) : ERROR;
  569.  
  570.       }                                          /* switch */
  571. }                                                /* Z_GetZDL */
  572.  
  573. /*--------------------------------------------------------------------------*/
  574. /* Z TIMED READ                                                             */
  575. /* Read a character from the modem line with timeout.                       */
  576. /*  Eat parity, XON and XOFF characters.                                    */
  577. /*--------------------------------------------------------------------------*/
  578. static int _Z_TimedRead ()
  579. {
  580.    register int c;
  581.  
  582. #ifdef DEBUG
  583.    show_debug_name ("Z_TimedRead");
  584. #endif
  585.  
  586.    for (;;)
  587.       {
  588.       if ((c = Z_GetByte (Rxtimeout)) < 0)
  589.          return c;
  590.  
  591.       switch (c &= 0x7F)
  592.          {
  593.          case XON:
  594.          case XOFF:
  595.             continue;
  596.  
  597.          default:
  598.             if (!(c & 0x60))
  599.                continue;
  600.  
  601.          case '\r':
  602.          case '\n':
  603.          case ZDLE:
  604.             return c;
  605.          }                                       /* switch */
  606.  
  607.       }                                          /* for */
  608. }                                                /* _Z_TimedRead */
  609.  
  610. /*--------------------------------------------------------------------------*/
  611. /* Z LONG TO HEADER                                                         */
  612. /* Store long integer pos in Txhdr                                          */
  613. /*--------------------------------------------------------------------------*/
  614. void Z_PutLongIntoHeader (pos)
  615. long pos;
  616. {
  617. #ifndef GENERIC
  618.    *((long *) Txhdr) = pos;
  619. #else
  620.    Txhdr[ZP0] = pos;
  621.    Txhdr[ZP1] = pos >> 8;
  622.    Txhdr[ZP2] = pos >> 16;
  623.    Txhdr[ZP3] = pos >> 24;
  624. #endif
  625. }                                                /* Z_PutLongIntoHeader */
  626.  
  627. /*--------------------------------------------------------------------------*/
  628. /* Z PULL LONG FROM HEADER                                                  */
  629. /* Recover a long integer from a header                                     */
  630. /*--------------------------------------------------------------------------*/
  631. static long _Z_PullLongFromHeader (hdr)
  632. unsigned char *hdr;
  633. {
  634. #ifndef GENERIC
  635.    if (hdr);
  636.    return (*((long *) Rxhdr)); /*PLF Fri  05-05-1989  06:42:41 */
  637. #else
  638.    long l;
  639.  
  640.    l = hdr[ZP3];
  641.    l = (l << 8) | hdr[ZP2];
  642.    l = (l << 8) | hdr[ZP1];
  643.    l = (l << 8) | hdr[ZP0];
  644.    return l;
  645. #endif
  646. }                                                /* _Z_PullLongFromHeader */
  647.  
  648.