home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / BTMTSRC3.ZIP / ZMISC.C < prev    next >
Text File  |  1991-08-15  |  18KB  |  724 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. #include <sys\types.h>
  50. #include <sys\stat.h>
  51. #include <stdio.h>
  52. #include <fcntl.h>
  53. #include <ctype.h>
  54. #include <conio.h>
  55.  
  56. #ifdef __TURBOC__
  57. #include <alloc.h>
  58. #else
  59. #include <malloc.h>
  60. #endif
  61.  
  62. #include "com.h"
  63. #include "xfer.h"
  64. #include "zmodem.h"
  65. #include "keybd.h"
  66. #include "sbuf.h"
  67. #include "sched.h"
  68. #include "externs.h"
  69. #include "prototyp.h"
  70.  
  71.  
  72. static int Rxtype;                                 /* Type of header received                 */
  73.  
  74. static char hex[] = "0123456789abcdef";
  75.  
  76. /* Send a byte as two hex digits */
  77. #define Z_PUTHEX(i,c)    {i = (c); SENDBYTE(hex[((i) & 0xf0) >> 4]); SENDBYTE(hex[(i) & 0xf]); }
  78.  
  79. /*--------------------------------------------------------------------------*/
  80. /* Private routines                                                         */
  81. /*--------------------------------------------------------------------------*/
  82. static int _Z_GetBinaryHeader (unsigned char *);
  83. static int _Z_32GetBinaryHeader (unsigned char *);
  84. static int _Z_GetHexHeader (unsigned char *);
  85. static int _Z_GetHex (void);
  86. static int _Z_TimedRead (void);
  87. static long _Z_PullLongFromHeader (unsigned char *);
  88.  
  89. void z_message (s)
  90. byte *s;
  91. {
  92.    if (fullscreen && un_attended)
  93.       {
  94.       if (s)
  95.          {
  96.          sb_move (filewin, 2, 27);
  97.          sb_puts (filewin, s);
  98.          }
  99.       sb_puts (filewin, "              ");
  100.       sb_show ();
  101.       }
  102.    else
  103.       {
  104.       gotoxy (locate_x + 20, locate_y);
  105.       if (s)
  106.          {
  107.          cputs (s);
  108.          }
  109.       cputs ("               ");
  110.       }
  111. }
  112.  
  113. void z_log (s)
  114. char *s;
  115. {
  116.    word x, y;
  117.  
  118.    z_message (s);
  119.  
  120.    x = locate_x;
  121.    y = locate_y;
  122.    status_line (s);                              /* also does disk file
  123.                                                   * logging */
  124.    locate_x = x;
  125.    locate_y = y;
  126. }
  127.  
  128. void show_loc (l, w)
  129. unsigned long l;
  130. unsigned int w;
  131. {
  132.    char j[100];
  133.  
  134.    if (fullscreen && un_attended)
  135.       {
  136.       sb_move (filewin, 2, 37);
  137.       sprintf (j, "Ofs=%ld Retries=%d        ", l, w);
  138.       sb_puts (filewin, j);
  139.       sb_show ();
  140.       }
  141.    else
  142.       {
  143.       gotoxy (locate_x + 35, locate_y);
  144.       printf ("Ofs=%ld Retries=%d        ", l, w);
  145.       }
  146. }
  147.  
  148. /*--------------------------------------------------------------------------*/
  149. /* Z GET BYTE                                                                */
  150. /* Get a byte from the modem;                                                */
  151. /* return TIMEOUT if no read within timeout tenths,                         */
  152. /* return RCDO if carrier lost                                                */
  153. /*--------------------------------------------------------------------------*/
  154. int Z_GetByte (tenths)
  155. int tenths;
  156. {
  157.    register int time_val = 0;
  158.    register int i;
  159.    long timeout;
  160.  
  161.    if (PEEKBYTE () >= 0)
  162.       return (MODEM_IN ());
  163.  
  164.    timeout = timerset (tenths * 10);
  165.  
  166.    do
  167.       {
  168.       if (PEEKBYTE () >= 0)
  169.          return MODEM_IN ();
  170.  
  171. #ifndef OS_2
  172.       if (!((i = MODEM_STATUS) & carrier_mask))
  173. #else
  174.       if (!((i = MODEM_STATUS) & carrier_mask))
  175. #endif
  176.          return RCDO;
  177.  
  178.       if (got_ESC ())
  179.          return -1;
  180.  
  181.       time_release ();
  182.       }
  183.    while (!timeup (timeout));
  184.  
  185.    return TIMEOUT;
  186. }
  187.  
  188. /*--------------------------------------------------------------------------*/
  189. /* Z PUT STRING                                                             */
  190. /* Send a string to the modem, processing for \336 (sleep 1 sec)            */
  191. /* and \335 (break signal, ignored)                                         */
  192. /*--------------------------------------------------------------------------*/
  193. void Z_PutString (s)
  194. unsigned char *s;
  195.     {
  196.     while (*s)
  197.         {
  198.         switch ((unsigned int)*s)
  199.             {
  200.             case (unsigned int)'\336':
  201.                 big_pause (2);
  202.                 break;
  203.             case (unsigned int)'\335':
  204.                 /* Should send a break on this */
  205.                 break;
  206.             default:
  207.                 SENDBYTE(*s);
  208.                 break;
  209.             }
  210.         ++s;
  211.         }                                          /* while */
  212.     Z_UncorkTransmitter ();                         /* Make sure all is well */
  213.     }                                                 /* Z_PutString */
  214.  
  215. /*--------------------------------------------------------------------------*/
  216. /* Z SEND HEX HEADER                                                        */
  217. /* Send ZMODEM HEX header hdr of type type                                    */
  218. /*--------------------------------------------------------------------------*/
  219. void Z_SendHexHeader (type, hdr)
  220. unsigned int type;
  221. register unsigned char *hdr;
  222. {
  223.    register int n;
  224.    register int i;
  225.    register word crc;
  226.  
  227. #ifdef DEBUG
  228.    show_debug_name ("Z_SendHexHeader");
  229. #endif
  230.  
  231.    Z_UncorkTransmitter ();                         /* Get our transmitter going */
  232.  
  233.    SENDBYTE (ZPAD);
  234.    SENDBYTE (ZPAD);
  235.    SENDBYTE (ZDLE);
  236.    SENDBYTE (ZHEX);
  237.    Z_PUTHEX (i, type);
  238.  
  239.    Crc32t = 0;
  240.    crc = Z_UpdateCRC (type, 0);
  241.    for (n = 4; --n >= 0;)
  242.       {
  243.       Z_PUTHEX (i, (*hdr));
  244.       crc = Z_UpdateCRC (((unsigned short) (*hdr++)), crc);
  245.       }
  246.    Z_PUTHEX (i, (crc >> 8));
  247.    Z_PUTHEX (i, crc);
  248.  
  249.    /* Make it printable on remote machine */
  250.    SENDBYTE ('\r');
  251.    SENDBYTE ('\n');
  252.  
  253.    /* Uncork the remote in case a fake XOFF has stopped data flow */
  254.    if (type != ZFIN && type != ZACK)
  255.       SENDBYTE (021);
  256.  
  257.    if (!CARRIER)
  258.       CLEAR_OUTBOUND ();
  259.  
  260. }                                                 /* Z_SendHexHeader */
  261.  
  262. /*--------------------------------------------------------------------------*/
  263. /* Z UNCORK TRANSMITTER                                                     */
  264. /* Wait a reasonable amount of time for transmitter buffer to clear.        */
  265. /*     When it does, or when time runs out, turn XON/XOFF off then on.        */
  266. /*     This should release a transmitter stuck by line errors.                */
  267. /*--------------------------------------------------------------------------*/
  268.  
  269. void Z_UncorkTransmitter ()
  270. {
  271.    long t;
  272.  
  273.    if (!OUT_EMPTY ())
  274.       {
  275.       t = timerset (5 * Rxtimeout);              /* Wait for silence */
  276.       while (!timeup (t) && !OUT_EMPTY () && CARRIER)
  277.          time_release ();                         /* Give up slice while
  278.                                                   * waiting  */
  279.       }
  280.    XON_DISABLE ();                                 /* Uncork the transmitter */
  281.    XON_ENABLE ();
  282. }
  283.  
  284.  
  285. /*--------------------------------------------------------------------------*/
  286. /* Z GET HEADER                                                             */
  287. /* Read a ZMODEM header to hdr, either binary or hex.                        */
  288. /*     On success, set Zmodem to 1 and return type of header.                 */
  289. /*     Otherwise return negative on error                                     */
  290. /*--------------------------------------------------------------------------*/
  291. int Z_GetHeader (hdr)
  292. byte *hdr;
  293. {
  294.  
  295.    register int c;
  296.    register int n;
  297.    int cancount;
  298.  
  299. #ifdef DEBUG
  300.    show_debug_name ("Z_GetHeader");
  301. #endif
  302.  
  303.    n = cur_baud;                                 /* Max characters before
  304.                                                   * start of frame */
  305.    cancount = 5;
  306.  
  307. Again:
  308.  
  309.    if (got_ESC ())
  310.       {
  311.       send_can ();
  312.       z_log (msgtxt[M_KBD_MSG]);
  313.       return ZCAN;
  314.       }
  315.  
  316.    Rxframeind = Rxtype = 0;
  317.  
  318.    switch (c = _Z_TimedRead ())
  319.       {
  320.       case ZPAD:
  321.       case ZPAD | 0200:
  322.          /*-----------------------------------------------*/
  323.          /* This is what we want.                          */
  324.          /*-----------------------------------------------*/
  325.          break;
  326.  
  327.       case RCDO:
  328.       case TIMEOUT:
  329.          goto Done;
  330.  
  331.       case CAN:
  332.  
  333.    GotCan:
  334.  
  335.          if (--cancount <= 0)
  336.             {
  337.             c = ZCAN;
  338.             goto Done;
  339.             }
  340.          switch (c = Z_GetByte (1))
  341.             {
  342.             case TIMEOUT:
  343.                goto Again;
  344.  
  345.             case ZCRCW:
  346.                c = ERROR;
  347.                /* fallthrough... */
  348.  
  349.             case RCDO:
  350.                goto Done;
  351.  
  352.             case CAN:
  353.                if (--cancount <= 0)
  354.                   {
  355.                   c = ZCAN;
  356.                   goto Done;
  357.                   }
  358.                goto Again;
  359.             }
  360.          /* fallthrough... */
  361.  
  362.       default:
  363.  
  364.    Agn2:
  365.  
  366.          if (--n <= 0)
  367.             {
  368.             z_log (msgtxt[M_FUBAR_MSG]);
  369.             return ERROR;
  370.             }
  371.  
  372.          if (c != CAN)
  373.             cancount = 5;
  374.          goto Again;
  375.  
  376.       }                                          /* switch */
  377.  
  378.    cancount = 5;
  379.  
  380. Splat:
  381.  
  382.    switch (c = _Z_TimedRead ())
  383.       {
  384.       case ZDLE:
  385.          /*-----------------------------------------------*/
  386.          /* This is what we want.                          */
  387.          /*-----------------------------------------------*/
  388.          break;
  389.  
  390.       case ZPAD:
  391.          goto Splat;
  392.  
  393.       case RCDO:
  394.       case TIMEOUT:
  395.          goto Done;
  396.  
  397.       default:
  398.          goto Agn2;
  399.  
  400.       }                                          /* switch */
  401.  
  402.  
  403.    switch (c = _Z_TimedRead ())
  404.       {
  405.  
  406.       case ZBIN:
  407.          Rxframeind = ZBIN;
  408.          Crc32 = 0;
  409.          c = _Z_GetBinaryHeader (hdr);
  410.          break;
  411.  
  412.       case ZBIN32:
  413.          Crc32 = Rxframeind = ZBIN32;
  414.          c = _Z_32GetBinaryHeader (hdr);
  415.          break;
  416.  
  417.       case ZHEX:
  418.          Rxframeind = ZHEX;
  419.          Crc32 = 0;
  420.          c = _Z_GetHexHeader (hdr);
  421.          break;
  422.  
  423.       case CAN:
  424.          goto GotCan;
  425.  
  426.       case RCDO:
  427.       case TIMEOUT:
  428.          goto Done;
  429.  
  430.       default:
  431.          goto Agn2;
  432.  
  433.       }                                          /* switch */
  434.  
  435.    Rxpos = _Z_PullLongFromHeader (hdr);
  436.  
  437. Done:
  438.  
  439.    return c;
  440. }                                                 /* Z_GetHeader */
  441.  
  442. /*--------------------------------------------------------------------------*/
  443. /* Z GET BINARY HEADER                                                        */
  444. /* Receive a binary style header (type and position)                        */
  445. /*--------------------------------------------------------------------------*/
  446. static int _Z_GetBinaryHeader (hdr)
  447. register unsigned char *hdr;
  448. {
  449.    register int c;
  450.    register unsigned int crc;
  451.    register int n;
  452.  
  453. #ifdef DEBUG
  454.    show_debug_name ("Z_GetBinaryHeader");
  455. #endif
  456.  
  457.    if ((c = Z_GetZDL ()) & ~0xFF)
  458.       return c;
  459.    Rxtype = c;
  460.    crc = Z_UpdateCRC (c, 0);
  461.  
  462.    for (n = 4; --n >= 0;)
  463.       {
  464.       if ((c = Z_GetZDL ()) & ~0xFF)
  465.          return c;
  466.       crc = Z_UpdateCRC (c, crc);
  467.       *hdr++ = (unsigned char) (c & 0xff);
  468.       }
  469.    if ((c = Z_GetZDL ()) & ~0xFF)
  470.       return c;
  471.  
  472.    crc = Z_UpdateCRC (c, crc);
  473.    if ((c = Z_GetZDL ()) & ~0xFF)
  474.       return c;
  475.  
  476.    crc = Z_UpdateCRC (c, crc);
  477.    if (crc & 0xFFFF)
  478.       {
  479.       z_message (msgtxt[M_CRC_MSG]);
  480.       return ERROR;
  481.       }
  482.  
  483.    return Rxtype;
  484. }                                                 /* _Z_GetBinaryHeader */
  485.  
  486.  
  487. /*--------------------------------------------------------------------------*/
  488. /* Z GET BINARY HEADER with 32 bit CRC                                        */
  489. /* Receive a binary style header (type and position)                        */
  490. /*--------------------------------------------------------------------------*/
  491. static int _Z_32GetBinaryHeader (hdr)
  492. register unsigned char *hdr;
  493. {
  494.    register int c;
  495.    register unsigned long crc;
  496.    register int n;
  497.  
  498. #ifdef DEBUG
  499.    show_debug_name ("Z_32GetBinaryHeader");
  500. #endif
  501.  
  502.    if ((c = Z_GetZDL ()) & ~0xFF)
  503.       return c;
  504.    Rxtype = c;
  505.    crc = 0xFFFFFFFF;
  506.    crc = Z_32UpdateCRC (c, crc);
  507.  
  508.    for (n = 4; --n >= 0;)
  509.       {
  510.       if ((c = Z_GetZDL ()) & ~0xFF)
  511.          return c;
  512.       crc = Z_32UpdateCRC (c, crc);
  513.       *hdr++ = (unsigned char) (c & 0xff);
  514.       }
  515.  
  516.    for (n = 4; --n >= 0;)
  517.       {
  518.       if ((c = Z_GetZDL ()) & ~0xFF)
  519.          return c;
  520.  
  521.       crc = Z_32UpdateCRC (c, crc);
  522.       }
  523.  
  524.    if (crc != 0xDEBB20E3)
  525.       {
  526.       z_message (msgtxt[M_CRC_MSG]);
  527.       return ERROR;
  528.       }
  529.  
  530.    return Rxtype;
  531. }                                                 /* _Z_32GetBinaryHeader */
  532.  
  533. /*--------------------------------------------------------------------------*/
  534. /* Z GET HEX HEADER                                                         */
  535. /* Receive a hex style header (type and position)                            */
  536. /*--------------------------------------------------------------------------*/
  537. static int _Z_GetHexHeader (hdr)
  538. register unsigned char *hdr;
  539. {
  540.    register int c;
  541.    register unsigned int crc;
  542.    register int n;
  543.  
  544. #ifdef DEBUG
  545.    show_debug_name ("Z_GetHexHeader");
  546. #endif
  547.  
  548.    if ((c = _Z_GetHex ()) < 0)
  549.       return c;
  550.    Rxtype = c;
  551.    crc = Z_UpdateCRC (c, 0);
  552.  
  553.    for (n = 4; --n >= 0;)
  554.       {
  555.       if ((c = _Z_GetHex ()) < 0)
  556.          return c;
  557.       crc = Z_UpdateCRC (c, crc);
  558.       *hdr++ = (unsigned char) c;
  559.       }
  560.  
  561.    if ((c = _Z_GetHex ()) < 0)
  562.       return c;
  563.    crc = Z_UpdateCRC (c, crc);
  564.    if ((c = _Z_GetHex ()) < 0)
  565.       return c;
  566.    crc = Z_UpdateCRC (c, crc);
  567.    if (crc & 0xFFFF)
  568.       {
  569.       z_message (msgtxt[M_CRC_MSG]);
  570.       return ERROR;
  571.       }
  572.    if (Z_GetByte (1) == '\r')
  573.       Z_GetByte (1);                             /* Throw away possible cr/lf */
  574.  
  575.    return Rxtype;
  576. }
  577.  
  578. /*--------------------------------------------------------------------------*/
  579. /* Z GET HEX                                                                */
  580. /* Decode two lower case hex digits into an 8 bit byte value                */
  581. /*--------------------------------------------------------------------------*/
  582. static int _Z_GetHex ()
  583. {
  584.    register int c, n;
  585.  
  586. #ifdef DEBUG
  587.    show_debug_name ("Z_GetHex");
  588. #endif
  589.  
  590.    if ((n = _Z_TimedRead ()) < 0)
  591.       return n;
  592.    n -= '0';
  593.    if (n > 9)
  594.       n -= ('a' - ':');
  595.    if (n & ~0xF)
  596.       return ERROR;
  597.  
  598.    if ((c = _Z_TimedRead ()) < 0)
  599.       return c;
  600.    c -= '0';
  601.    if (c > 9)
  602.       c -= ('a' - ':');
  603.    if (c & ~0xF)
  604.       return ERROR;
  605.  
  606.    return ((n << 4) | c);
  607. }
  608.  
  609. /*--------------------------------------------------------------------------*/
  610. /* Z GET ZDL                                                                */
  611. /* Read a byte, checking for ZMODEM escape encoding                         */
  612. /* including CAN*5 which represents a quick abort                            */
  613. /*--------------------------------------------------------------------------*/
  614. int Z_GetZDL ()
  615. {
  616.    register int c;
  617.  
  618.    if ((c = Z_GetByte (Rxtimeout)) != ZDLE)
  619.       return c;
  620.  
  621.    switch (c = Z_GetByte (Rxtimeout))
  622.       {
  623.       case CAN:
  624.          return ((c = Z_GetByte (Rxtimeout)) < 0) ? c :
  625.             ((c == CAN) && ((c = Z_GetByte (Rxtimeout)) < 0)) ? c :
  626.             ((c == CAN) && ((c = Z_GetByte (Rxtimeout)) < 0)) ? c : (GOTCAN);
  627.  
  628.       case ZCRCE:
  629.       case ZCRCG:
  630.       case ZCRCQ:
  631.       case ZCRCW:
  632.          return (c | GOTOR);
  633.  
  634.       case ZRUB0:
  635.          return 0x7F;
  636.  
  637.       case ZRUB1:
  638.          return 0xFF;
  639.  
  640.       default:
  641.          return (c < 0) ? c : ((c & 0x60) == 0x40) ? (c ^ 0x40) : ERROR;
  642.  
  643.       }                                          /* switch */
  644. }                                                 /* Z_GetZDL */
  645.  
  646. /*--------------------------------------------------------------------------*/
  647. /* Z TIMED READ                                                             */
  648. /* Read a character from the modem line with timeout.                        */
  649. /*    Eat parity, XON and XOFF characters.                                    */
  650. /*--------------------------------------------------------------------------*/
  651. static int _Z_TimedRead ()
  652. {
  653.    register int c;
  654.  
  655. #ifdef DEBUG
  656.    show_debug_name ("Z_TimedRead");
  657. #endif
  658.  
  659.    for (;;)
  660.       {
  661.       if ((c = Z_GetByte (Rxtimeout)) < 0)
  662.          return c;
  663.  
  664.       switch (c &= 0x7F)
  665.          {
  666.          case XON:
  667.          case XOFF:
  668.             continue;
  669.  
  670.          default:
  671.             if (!(c & 0x60))
  672.                continue;
  673.  
  674.          case '\r':
  675.          case '\n':
  676.          case ZDLE:
  677.             return c;
  678.          }                                         /* switch */
  679.  
  680.       }                                          /* for */
  681. }                                                 /* _Z_TimedRead */
  682.  
  683. /*--------------------------------------------------------------------------*/
  684. /* Z LONG TO HEADER                                                         */
  685. /* Store long integer pos in Txhdr                                            */
  686. /*--------------------------------------------------------------------------*/
  687. void Z_PutLongIntoHeader (pos)
  688. long pos;
  689. {
  690. #ifndef GENERIC
  691.    *((long *) Txhdr) = pos;
  692. #else
  693.    Txhdr[ZP0] = pos;
  694.    Txhdr[ZP1] = pos >> 8;
  695.    Txhdr[ZP2] = pos >> 16;
  696.    Txhdr[ZP3] = pos >> 24;
  697. #endif
  698. }                                                 /* Z_PutLongIntoHeader */
  699.  
  700. /*--------------------------------------------------------------------------*/
  701. /* Z PULL LONG FROM HEADER                                                    */
  702. /* Recover a long integer from a header                                     */
  703. /*--------------------------------------------------------------------------*/
  704. static long _Z_PullLongFromHeader (hdr)
  705. unsigned char *hdr;
  706. {
  707. #ifndef GENERIC
  708.    return (*((long *) Rxhdr)); /*PLF Fri  05-05-1989  06:42:41 */
  709.    hdr;                        /*PLF Fri  05-05-1989  06:42:59 ; Trick to
  710.                                 * keep /W3 happy */
  711. #else
  712.    long l;
  713.  
  714.    l = hdr[ZP3];
  715.    l = (l << 8) | hdr[ZP2];
  716.    l = (l << 8) | hdr[ZP1];
  717.    l = (l << 8) | hdr[ZP0];
  718.    return l;
  719. #endif
  720. }                                                 /* _Z_PullLongFromHeader */
  721.  
  722. /* END OF FILE: zmisc.c */
  723. 
  724.