home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / MISC / OS2 / BSRCP240.ZIP / ZMISC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-26  |  17.1 KB  |  725 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, timerset ();
  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. register unsigned char *s;
  195. {
  196.    register unsigned int c;
  197.  
  198.    while (*s)
  199.       {
  200.       switch (c = *s++)
  201.          {
  202.          case '\336':
  203.             big_pause (2);
  204.          case '\335':
  205. /* Should send a break on this */
  206.             break;
  207.          default:
  208.             SENDBYTE ((unsigned char) c);
  209.          }                                         /* switch */
  210.  
  211.       }                                          /* while */
  212.  
  213.    Z_UncorkTransmitter ();                         /* Make sure all is well */
  214. }                                                 /* Z_PutString */
  215.  
  216. /*--------------------------------------------------------------------------*/
  217. /* Z SEND HEX HEADER                                                        */
  218. /* Send ZMODEM HEX header hdr of type type                                    */
  219. /*--------------------------------------------------------------------------*/
  220. void Z_SendHexHeader (type, hdr)
  221. unsigned int type;
  222. register unsigned char *hdr;
  223. {
  224.    register int n;
  225.    register int i;
  226.    register word crc;
  227.  
  228. #ifdef DEBUG
  229.    show_debug_name ("Z_SendHexHeader");
  230. #endif
  231.  
  232.    Z_UncorkTransmitter ();                         /* Get our transmitter going */
  233.  
  234.    SENDBYTE (ZPAD);
  235.    SENDBYTE (ZPAD);
  236.    SENDBYTE (ZDLE);
  237.    SENDBYTE (ZHEX);
  238.    Z_PUTHEX (i, type);
  239.  
  240.    Crc32t = 0;
  241.    crc = Z_UpdateCRC (type, 0);
  242.    for (n = 4; --n >= 0;)
  243.       {
  244.       Z_PUTHEX (i, (*hdr));
  245.       crc = Z_UpdateCRC (((unsigned short) (*hdr++)), crc);
  246.       }
  247.    Z_PUTHEX (i, (crc >> 8));
  248.    Z_PUTHEX (i, crc);
  249.  
  250.    /* Make it printable on remote machine */
  251.    SENDBYTE ('\r');
  252.    SENDBYTE ('\n');
  253.  
  254.    /* Uncork the remote in case a fake XOFF has stopped data flow */
  255.    if (type != ZFIN && type != ZACK)
  256.       SENDBYTE (021);
  257.  
  258.    if (!CARRIER)
  259.       CLEAR_OUTBOUND ();
  260.  
  261. }                                                 /* Z_SendHexHeader */
  262.  
  263. /*--------------------------------------------------------------------------*/
  264. /* Z UNCORK TRANSMITTER                                                     */
  265. /* Wait a reasonable amount of time for transmitter buffer to clear.        */
  266. /*     When it does, or when time runs out, turn XON/XOFF off then on.        */
  267. /*     This should release a transmitter stuck by line errors.                */
  268. /*--------------------------------------------------------------------------*/
  269.  
  270. void Z_UncorkTransmitter ()
  271. {
  272.    long t, timerset ();
  273.  
  274.    if (!OUT_EMPTY ())
  275.       {
  276.       t = timerset (5 * Rxtimeout);              /* Wait for silence */
  277.       while (!timeup (t) && !OUT_EMPTY () && CARRIER)
  278.          time_release ();                         /* Give up slice while
  279.                                                   * waiting  */
  280.       }
  281.    XON_DISABLE ();                                 /* Uncork the transmitter */
  282.    XON_ENABLE ();
  283. }
  284.  
  285.  
  286. /*--------------------------------------------------------------------------*/
  287. /* Z GET HEADER                                                             */
  288. /* Read a ZMODEM header to hdr, either binary or hex.                        */
  289. /*     On success, set Zmodem to 1 and return type of header.                 */
  290. /*     Otherwise return negative on error                                     */
  291. /*--------------------------------------------------------------------------*/
  292. int Z_GetHeader (hdr)
  293. byte *hdr;
  294. {
  295.  
  296.    register int c;
  297.    register int n;
  298.    int cancount;
  299.  
  300. #ifdef DEBUG
  301.    show_debug_name ("Z_GetHeader");
  302. #endif
  303.  
  304.    n = cur_baud;                                 /* Max characters before
  305.                                                   * start of frame */
  306.    cancount = 5;
  307.  
  308. Again:
  309.  
  310.    if (got_ESC ())
  311.       {
  312.       send_can ();
  313.       z_log (msgtxt[M_KBD_MSG]);
  314.       return ZCAN;
  315.       }
  316.  
  317.    Rxframeind = Rxtype = 0;
  318.  
  319.    switch (c = _Z_TimedRead ())
  320.       {
  321.       case ZPAD:
  322.       case ZPAD | 0200:
  323.          /*-----------------------------------------------*/
  324.          /* This is what we want.                          */
  325.          /*-----------------------------------------------*/
  326.          break;
  327.  
  328.       case RCDO:
  329.       case TIMEOUT:
  330.          goto Done;
  331.  
  332.       case CAN:
  333.  
  334.    GotCan:
  335.  
  336.          if (--cancount <= 0)
  337.             {
  338.             c = ZCAN;
  339.             goto Done;
  340.             }
  341.          switch (c = Z_GetByte (1))
  342.             {
  343.             case TIMEOUT:
  344.                goto Again;
  345.  
  346.             case ZCRCW:
  347.                c = ERROR;
  348.                /* fallthrough... */
  349.  
  350.             case RCDO:
  351.                goto Done;
  352.  
  353.             case CAN:
  354.                if (--cancount <= 0)
  355.                   {
  356.                   c = ZCAN;
  357.                   goto Done;
  358.                   }
  359.                goto Again;
  360.             }
  361.          /* fallthrough... */
  362.  
  363.       default:
  364.  
  365.    Agn2:
  366.  
  367.          if (--n <= 0)
  368.             {
  369.             z_log (msgtxt[M_FUBAR_MSG]);
  370.             return ERROR;
  371.             }
  372.  
  373.          if (c != CAN)
  374.             cancount = 5;
  375.          goto Again;
  376.  
  377.       }                                          /* switch */
  378.  
  379.    cancount = 5;
  380.  
  381. Splat:
  382.  
  383.    switch (c = _Z_TimedRead ())
  384.       {
  385.       case ZDLE:
  386.          /*-----------------------------------------------*/
  387.          /* This is what we want.                          */
  388.          /*-----------------------------------------------*/
  389.          break;
  390.  
  391.       case ZPAD:
  392.          goto Splat;
  393.  
  394.       case RCDO:
  395.       case TIMEOUT:
  396.          goto Done;
  397.  
  398.       default:
  399.          goto Agn2;
  400.  
  401.       }                                          /* switch */
  402.  
  403.  
  404.    switch (c = _Z_TimedRead ())
  405.       {
  406.  
  407.       case ZBIN:
  408.          Rxframeind = ZBIN;
  409.          Crc32 = 0;
  410.          c = _Z_GetBinaryHeader (hdr);
  411.          break;
  412.  
  413.       case ZBIN32:
  414.          Crc32 = Rxframeind = ZBIN32;
  415.          c = _Z_32GetBinaryHeader (hdr);
  416.          break;
  417.  
  418.       case ZHEX:
  419.          Rxframeind = ZHEX;
  420.          Crc32 = 0;
  421.          c = _Z_GetHexHeader (hdr);
  422.          break;
  423.  
  424.       case CAN:
  425.          goto GotCan;
  426.  
  427.       case RCDO:
  428.       case TIMEOUT:
  429.          goto Done;
  430.  
  431.       default:
  432.          goto Agn2;
  433.  
  434.       }                                          /* switch */
  435.  
  436.    Rxpos = _Z_PullLongFromHeader (hdr);
  437.  
  438. Done:
  439.  
  440.    return c;
  441. }                                                 /* Z_GetHeader */
  442.  
  443. /*--------------------------------------------------------------------------*/
  444. /* Z GET BINARY HEADER                                                        */
  445. /* Receive a binary style header (type and position)                        */
  446. /*--------------------------------------------------------------------------*/
  447. static int _Z_GetBinaryHeader (hdr)
  448. register unsigned char *hdr;
  449. {
  450.    register int c;
  451.    register unsigned int crc;
  452.    register int n;
  453.  
  454. #ifdef DEBUG
  455.    show_debug_name ("Z_GetBinaryHeader");
  456. #endif
  457.  
  458.    if ((c = Z_GetZDL ()) & ~0xFF)
  459.       return c;
  460.    Rxtype = c;
  461.    crc = Z_UpdateCRC (c, 0);
  462.  
  463.    for (n = 4; --n >= 0;)
  464.       {
  465.       if ((c = Z_GetZDL ()) & ~0xFF)
  466.          return c;
  467.       crc = Z_UpdateCRC (c, crc);
  468.       *hdr++ = (unsigned char) (c & 0xff);
  469.       }
  470.    if ((c = Z_GetZDL ()) & ~0xFF)
  471.       return c;
  472.  
  473.    crc = Z_UpdateCRC (c, crc);
  474.    if ((c = Z_GetZDL ()) & ~0xFF)
  475.       return c;
  476.  
  477.    crc = Z_UpdateCRC (c, crc);
  478.    if (crc & 0xFFFF)
  479.       {
  480.       z_message (msgtxt[M_CRC_MSG]);
  481.       return ERROR;
  482.       }
  483.  
  484.    return Rxtype;
  485. }                                                 /* _Z_GetBinaryHeader */
  486.  
  487.  
  488. /*--------------------------------------------------------------------------*/
  489. /* Z GET BINARY HEADER with 32 bit CRC                                        */
  490. /* Receive a binary style header (type and position)                        */
  491. /*--------------------------------------------------------------------------*/
  492. static int _Z_32GetBinaryHeader (hdr)
  493. register unsigned char *hdr;
  494. {
  495.    register int c;
  496.    register unsigned long crc;
  497.    register int n;
  498.  
  499. #ifdef DEBUG
  500.    show_debug_name ("Z_32GetBinaryHeader");
  501. #endif
  502.  
  503.    if ((c = Z_GetZDL ()) & ~0xFF)
  504.       return c;
  505.    Rxtype = c;
  506.    crc = 0xFFFFFFFF;
  507.    crc = Z_32UpdateCRC (c, crc);
  508.  
  509.    for (n = 4; --n >= 0;)
  510.       {
  511.       if ((c = Z_GetZDL ()) & ~0xFF)
  512.          return c;
  513.       crc = Z_32UpdateCRC (c, crc);
  514.       *hdr++ = (unsigned char) (c & 0xff);
  515.       }
  516.  
  517.    for (n = 4; --n >= 0;)
  518.       {
  519.       if ((c = Z_GetZDL ()) & ~0xFF)
  520.          return c;
  521.  
  522.       crc = Z_32UpdateCRC (c, crc);
  523.       }
  524.  
  525.    if (crc != 0xDEBB20E3)
  526.       {
  527.       z_message (msgtxt[M_CRC_MSG]);
  528.       return ERROR;
  529.       }
  530.  
  531.    return Rxtype;
  532. }                                                 /* _Z_32GetBinaryHeader */
  533.  
  534. /*--------------------------------------------------------------------------*/
  535. /* Z GET HEX HEADER                                                         */
  536. /* Receive a hex style header (type and position)                            */
  537. /*--------------------------------------------------------------------------*/
  538. static int _Z_GetHexHeader (hdr)
  539. register unsigned char *hdr;
  540. {
  541.    register int c;
  542.    register unsigned int crc;
  543.    register int n;
  544.  
  545. #ifdef DEBUG
  546.    show_debug_name ("Z_GetHexHeader");
  547. #endif
  548.  
  549.    if ((c = _Z_GetHex ()) < 0)
  550.       return c;
  551.    Rxtype = c;
  552.    crc = Z_UpdateCRC (c, 0);
  553.  
  554.    for (n = 4; --n >= 0;)
  555.       {
  556.       if ((c = _Z_GetHex ()) < 0)
  557.          return c;
  558.       crc = Z_UpdateCRC (c, crc);
  559.       *hdr++ = (unsigned char) c;
  560.       }
  561.  
  562.    if ((c = _Z_GetHex ()) < 0)
  563.       return c;
  564.    crc = Z_UpdateCRC (c, crc);
  565.    if ((c = _Z_GetHex ()) < 0)
  566.       return c;
  567.    crc = Z_UpdateCRC (c, crc);
  568.    if (crc & 0xFFFF)
  569.       {
  570.       z_message (msgtxt[M_CRC_MSG]);
  571.       return ERROR;
  572.       }
  573.    if (Z_GetByte (1) == '\r')
  574.       Z_GetByte (1);                             /* Throw away possible cr/lf */
  575.  
  576.    return Rxtype;
  577. }
  578.  
  579. /*--------------------------------------------------------------------------*/
  580. /* Z GET HEX                                                                */
  581. /* Decode two lower case hex digits into an 8 bit byte value                */
  582. /*--------------------------------------------------------------------------*/
  583. static int _Z_GetHex ()
  584. {
  585.    register int c, n;
  586.  
  587. #ifdef DEBUG
  588.    show_debug_name ("Z_GetHex");
  589. #endif
  590.  
  591.    if ((n = _Z_TimedRead ()) < 0)
  592.       return n;
  593.    n -= '0';
  594.    if (n > 9)
  595.       n -= ('a' - ':');
  596.    if (n & ~0xF)
  597.       return ERROR;
  598.  
  599.    if ((c = _Z_TimedRead ()) < 0)
  600.       return c;
  601.    c -= '0';
  602.    if (c > 9)
  603.       c -= ('a' - ':');
  604.    if (c & ~0xF)
  605.       return ERROR;
  606.  
  607.    return ((n << 4) | c);
  608. }
  609.  
  610. /*--------------------------------------------------------------------------*/
  611. /* Z GET ZDL                                                                */
  612. /* Read a byte, checking for ZMODEM escape encoding                         */
  613. /* including CAN*5 which represents a quick abort                            */
  614. /*--------------------------------------------------------------------------*/
  615. int Z_GetZDL ()
  616. {
  617.    register int c;
  618.  
  619.    if ((c = Z_GetByte (Rxtimeout)) != ZDLE)
  620.       return c;
  621.  
  622.    switch (c = Z_GetByte (Rxtimeout))
  623.       {
  624.       case CAN:
  625.          return ((c = Z_GetByte (Rxtimeout)) < 0) ? c :
  626.             ((c == CAN) && ((c = Z_GetByte (Rxtimeout)) < 0)) ? c :
  627.             ((c == CAN) && ((c = Z_GetByte (Rxtimeout)) < 0)) ? c : (GOTCAN);
  628.  
  629.       case ZCRCE:
  630.       case ZCRCG:
  631.       case ZCRCQ:
  632.       case ZCRCW:
  633.          return (c | GOTOR);
  634.  
  635.       case ZRUB0:
  636.          return 0x7F;
  637.  
  638.       case ZRUB1:
  639.          return 0xFF;
  640.  
  641.       default:
  642.          return (c < 0) ? c :
  643.             ((c & 0x60) == 0x40) ? (c ^ 0x40) : ERROR;
  644.  
  645.       }                                          /* switch */
  646. }                                                 /* Z_GetZDL */
  647.  
  648. /*--------------------------------------------------------------------------*/
  649. /* Z TIMED READ                                                             */
  650. /* Read a character from the modem line with timeout.                        */
  651. /*    Eat parity, XON and XOFF characters.                                    */
  652. /*--------------------------------------------------------------------------*/
  653. static int _Z_TimedRead ()
  654. {
  655.    register int c;
  656.  
  657. #ifdef DEBUG
  658.    show_debug_name ("Z_TimedRead");
  659. #endif
  660.  
  661.    for (;;)
  662.       {
  663.       if ((c = Z_GetByte (Rxtimeout)) < 0)
  664.          return c;
  665.  
  666.       switch (c &= 0x7F)
  667.          {
  668.          case XON:
  669.          case XOFF:
  670.             continue;
  671.  
  672.          default:
  673.             if (!(c & 0x60))
  674.                continue;
  675.  
  676.          case '\r':
  677.          case '\n':
  678.          case ZDLE:
  679.             return c;
  680.          }                                         /* switch */
  681.  
  682.       }                                          /* for */
  683. }                                                 /* _Z_TimedRead */
  684.  
  685. /*--------------------------------------------------------------------------*/
  686. /* Z LONG TO HEADER                                                         */
  687. /* Store long integer pos in Txhdr                                            */
  688. /*--------------------------------------------------------------------------*/
  689. void Z_PutLongIntoHeader (pos)
  690. long pos;
  691. {
  692. #ifndef GENERIC
  693.    *((long *) Txhdr) = pos;
  694. #else
  695.    Txhdr[ZP0] = pos;
  696.    Txhdr[ZP1] = pos >> 8;
  697.    Txhdr[ZP2] = pos >> 16;
  698.    Txhdr[ZP3] = pos >> 24;
  699. #endif
  700. }                                                 /* Z_PutLongIntoHeader */
  701.  
  702. /*--------------------------------------------------------------------------*/
  703. /* Z PULL LONG FROM HEADER                                                    */
  704. /* Recover a long integer from a header                                     */
  705. /*--------------------------------------------------------------------------*/
  706. static long _Z_PullLongFromHeader (hdr)
  707. unsigned char *hdr;
  708. {
  709. #ifndef GENERIC
  710.    return (*((long *) Rxhdr)); /*PLF Fri  05-05-1989  06:42:41 */
  711.    hdr;                        /*PLF Fri  05-05-1989  06:42:59 ; Trick to
  712.                                 * keep /W3 happy */
  713. #else
  714.    long l;
  715.  
  716.    l = hdr[ZP3];
  717.    l = (l << 8) | hdr[ZP2];
  718.    l = (l << 8) | hdr[ZP1];
  719.    l = (l << 8) | hdr[ZP0];
  720.    return l;
  721. #endif
  722. }                                                 /* _Z_PullLongFromHeader */
  723.  
  724. /* END OF FILE: zmisc.c */
  725.