home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / xyz.lzh / ftz.c < prev    next >
Text File  |  1995-08-18  |  77KB  |  2,619 lines

  1. /*
  2.    Printed form of this source is Copyright (C) 1995 Coriolis
  3.    Group, Inc.  All rights reserved.  Individual users may
  4.    make printed copies for their own personal use.
  5.  
  6.    All other forms are Copyright (C) 1995 Tim Kientzle. All
  7.    rights reserved.
  8.  
  9. Redistribution in source or binary form is permitted only under
  10. the following conditions:
  11. 1. If you own a copy of `The Working Programmer's Guide To Serial
  12.    Protocols,' then you may redistribute this code as part of
  13.    a complete application program under the conditions
  14.    described in that book.  (See pages xiv, xv.)  In any case,
  15.    you must abide by terms 4-7 below.
  16. 2. Otherwise, if you have received this code as a part of an
  17.    application program, it may only be redistributed with the
  18.    complete source of that program, under whatever conditions
  19.    apply to redistribution of that program as a whole.
  20. 3. If you have received this source code by some other means,
  21.    you may not redistribute it without explicit written
  22.    permission from Tim Kientzle.
  23. 4. All advertising materials mentioning features or use of this
  24.    software must prominently display the following acknowledgement:
  25.       This product is partially based on source code appearing in
  26.       `The Working Programmer's Guide to Serial Protocols,'
  27.       Copyright (C) 1995 Coriolis Group, Inc. and Tim Kientzle.
  28. 5. All programs using this source code must display the above
  29.    acknowledgement prominently in the program documentation
  30.    and user interface.
  31. 6. Neither the name of the Tim Kientzle nor the Coriolis Group, Inc.,
  32.    may be used to endorse or promote products derived from this
  33.    software without specific prior written permission.
  34. 7. Any redistribution in source form must retain the above copyright
  35.    notice, this list of conditions, and the disclaimer below.
  36.  
  37. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  38. WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  39. OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  40. IN NO EVENT SHALL TIM KIENTZLE OR THE CORIOLIS GROUP BE LIABLE FOR
  41. ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  42. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  43. GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  44. INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  45. IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  46. OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  47. IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  48.  
  49. */
  50.  
  51. #define I_CAN_SAMPLE (1)
  52. #define I_CAN_FULL_DUPLEX (1)
  53. #define I_CAN_OVERLAP_DISK (1)
  54. #define I_CAN_SEND_BREAK (1) \
  55.  
  56. #define ATTENTION (NULL)
  57. #define CR (0x0d)
  58. #define LF (0x0a)
  59. #define DLE (0x10)
  60. #define XON (0x11)
  61. #define XOFF (0x13)
  62. #define CAN (0x18)
  63. #define DEL (0x7F)
  64. #define SetIgnore(c)(pZ->classify[c]|= 1)
  65. #define TestIgnore(c)(pZ->classify[c]&1)
  66. #define SetEncode(c)(pZ->classify[c]|= 2)
  67. #define TestEncode(c)(pZ->classify[c]&2) \
  68.  
  69. #define ZRQINIT (0)
  70. #define ZRINIT (1)
  71. #define ZSINIT (2)
  72. #define ZACK (3)
  73. #define ZFILE (4)
  74. #define ZSKIP (5)
  75. #define ZNAK (6)
  76. #define ZABORT (7)
  77. #define ZFIN (8)
  78. #define ZRPOS (9)
  79. #define ZDATA (10)
  80. #define ZEOF (11)
  81. #define ZFERR (12)
  82. #define ZCRC (13)
  83. #define ZCHALLENGE (14)
  84. #define ZCOMPL (15)
  85. #define ZCAN (16)
  86. #define ZFREECNT (17)
  87. #define ZCOMMAND (18)
  88. #define ZSTDERR (19)
  89. #define DebugPacket(debug,type,arg) \
  90. DebugString((debug),zPacketName[(type)]); \
  91. DebugString((debug),"("); \
  92. DebugIntHex((debug),(arg)); \
  93. DebugString((debug),")");
  94. #define CONV_BINARY (0x01000000)
  95. #define CONV_TEXT (0x02000000)
  96. #define CONV_RESUME (0x03000000)
  97. #define CONV_MASK (0xFF000000U)
  98. #define MAN_SKNOLOC (0x00800000)
  99. #define MAN_NEW_LONG (0x00010000)
  100. #define MAN_CRC_LENGTH (0x00020000)
  101. #define MAN_APPEND (0x00030000)
  102. #define MAN_REPLACE (0x00040000)
  103. #define MAN_NEW (0x00050000)
  104. #define MAN_DATE_LENGTH (0x00060000)
  105. #define MAN_NONEXISTENT (0x00070000)
  106. #define MAN_MASK (0x007F0000)
  107. #define TRAN_LZW (0x00000100)
  108. #define TRAN_CRYPT (0x00000200)
  109. #define TRAN_RLE (0x00000300)
  110. #define TRAN_MASK (0x0000FF00)
  111. #define EXTEN_SPARSE (0x00000040)
  112. #define EXTEN_MASK (0x000000FF)
  113. #define CAN_FULL_DUPLEX (0x01000000)
  114. #define CAN_OVERLAP_DISK (0x02000000)
  115. #define CAN_SEND_BREAK (0x04000000)
  116. #define KNOW_CRYPT (0x08000000)
  117. #define KNOW_LZW (0x10000000)
  118. #define KNOW_CRC32 (0x20000000)
  119. #define ESCAPE_CONTROLS (0x40000000)
  120. #define ESCAPE_8BIT (0x80000000)
  121. #define StsRet(expr)do{int tmpErrorVal= (expr); \
  122. if(tmpErrorVal!=zOK)return StsWarn(tmpErrorVal); \
  123. }while(FALSE)
  124. #define StsWarn(s)((pZ->debug)?ZDebugWarn(pZ,(s),__FILE__,__LINE__):(s))
  125. #define debugWarn (1)
  126. #define debugPacket (2)
  127. #define debugPacketErr (4)
  128. #define debugPacketLowLevel (8)
  129. #define debugCache (16)
  130. #define debugAttr (32)
  131. #define debugInit (64)
  132. #define debugEncoding (256)
  133. #define debugSerial (512)
  134. #define SendingCrc(pBuff,length,crc) \
  135. ((pZ->sendingCrc32)?ZCrc32((pBuff),(length),(crc)):ZCrc16((pBuff),(length),(crc)))
  136. #define ZReadByteWithTimeout(pZ,timeout,pByte) \
  137. (((pZ)->serialBufferRead<(pZ)->serialBufferLimit)? \
  138. (*(pByte)= *((pZ)->serialBufferRead++),zOK): \
  139. (ZReadByteWithTimeoutFcn((pZ),(timeout),(pByte))))
  140. #define SetDecode(c)(pZ->classify[c]|= 4)
  141. #define TestDecode(c)(pZ->classify[c]&4)
  142. #define DEFAULT_WINDOW_SIZE (100000)
  143. #define ACK_INTERVAL_MIN 512
  144. #define ACK_INTERVAL_MAX 16384
  145. #define HasLimits(flags)(!((flags)&(CAN_FULL_DUPLEX|CAN_OVERLAP_DISK)))
  146. #define HALF_DUPLEX_BURST 1024
  147. #define CloseDataPacket(pZ) \
  148. if(pZ->txPacketType==ZDATA) \
  149. StsRet(ZSendFileDataPacket(pZ,&window,0,TRUE,FALSE))
  150. #define BufferFree (window.size-(window.endFilePos-pZ->receivePosition)) \
  151.  
  152. #define ZSendZRINIT(pZ)ZSendHexHeader(pZ,ZRINIT,pZ->myReceiverFlags)
  153. #define IsWhitespace(c)((c==' ')||(c=='\t')||(c=='\r')||(c=='\n')||(c=='\f'))
  154. #include "ftdisk.h"
  155. #include "ftserial.h"
  156. #include "ftdebug.h"
  157. #include "ftprog.h"
  158. #include "ftz.h"
  159. #include <stddef.h>
  160. #include <time.h>
  161. #include <stdio.h>
  162. #ifdef _UCC
  163. #include <stdlib.h>
  164. #include <string.h>
  165. #else
  166. int     sprintf ();
  167. #endif
  168.  
  169. #ifndef TRUE
  170. #define TRUE 1
  171. #endif
  172. #ifndef FALSE
  173. #define FALSE 0
  174. #endif
  175. #ifndef NULL
  176. #define NULL  ((void *)0)
  177. #endif
  178. #define STATIC
  179. typedef unsigned char BYTE;
  180. typedef struct {
  181.    int     crc32;
  182.    int     timeout;
  183.    int     retries;
  184.    int     userCancel;
  185.    BYTE    attention[40];
  186.    unsigned long zrqinitFlags;
  187.    unsigned long senderFlags;
  188.    unsigned long receiverFlags;
  189.    unsigned long myZrqinitFlags;
  190.    unsigned long mySenderFlags;
  191.    unsigned long myReceiverFlags;
  192.    unsigned long fileFlags;
  193.    unsigned char classify[256];
  194.    int     sendingCrc32;
  195.    int     txPacketType;
  196.    int     receivingCrc32;
  197.    int     rxPacketType;
  198.    unsigned long rxPacketArg;
  199.    unsigned long sendPosition;
  200.    unsigned long receivePosition;
  201.    DEBUG   debug;
  202.    SERIAL_PORT port;
  203.    BYTE   *serialBuffer;
  204.    int     serialBufferSize;
  205.    BYTE   *serialBufferRead;
  206.    BYTE   *serialBufferLimit;
  207.    DISKFILE f;
  208.    long    fileSize;
  209.    const char **filenames;
  210.    int     currentFileName;
  211.    int     numFileNames;
  212.    int     fileType;
  213.    PROGRESS progress;
  214.    long    noiseLimit;
  215.    int     crashRecovery;
  216. } ZMODEM_PRIVATE;
  217. const char *zPacketName[] =
  218. {
  219.    "ZRQINIT", "ZRINIT", "ZSINIT", "ZACK", "ZFILE", "ZSKIP", "ZNAK",
  220.    "ZABORT", "ZFIN", "ZRPOS", "ZDATA", "ZEOF", "ZFERR", "ZCRC",
  221.    "ZCHALLENGE", "ZCOMPL", "ZCAN", "ZFREECNT", "ZCOMMAND", "ZSTDERR",
  222.    NULL, NULL, NULL
  223. };
  224. enum {
  225.    zOK = 0,
  226.    zFail,
  227.    zFailed,
  228.    zBadPacket,
  229.    zEndOfSession,
  230.    zEOF,
  231.    zTimeout,
  232.    zSkip
  233. };
  234. STATIC int ZDebugWarn
  235.         (ZMODEM_PRIVATE *pZ, const int s, const char *file, const int line) {
  236.    const char *msg = NULL;
  237.  
  238.    if (s != zOK) {
  239.       DebugBeginInternal (pZ->debug, debugWarn, file, line);
  240.       DebugString (pZ->debug, "?!?!?!:");
  241.    }
  242.    switch (s) {
  243.    case zOK:
  244.       return zOK;
  245.    case zFail:
  246.       msg = "zFail";
  247.       break;
  248.    case zFailed:
  249.       msg = "zFailed";
  250.       break;
  251.    case zBadPacket:
  252.       msg = "zBadPacket";
  253.       break;
  254.    case zEndOfSession:
  255.       msg = "zEndOfSession";
  256.       break;
  257.    case zEOF:
  258.       msg = "zEOF";
  259.       break;
  260.    case zTimeout:
  261.       msg = "zTimeout";
  262.       break;
  263.    }
  264.    if (msg != NULL)
  265.       DebugString (pZ->debug, msg);
  266.    else {
  267.       DebugString (pZ->debug, "Error ");
  268.       DebugInt (pZ->debug, s);
  269.    }
  270.    DebugEnd (pZ->debug);
  271.    return s;
  272. }
  273. STATIC void ZNewFile
  274.         (ZMODEM_PRIVATE *pZ) {
  275.    pZ->fileSize = -1;
  276.    pZ->sendPosition = 0;
  277.    pZ->receivePosition = 0;
  278. }
  279. STATIC unsigned short int zCrc16Table[256];
  280. STATIC unsigned long int zCrc32Table[256];
  281. STATIC void ZInitCrc
  282.         (void) {
  283.    static int crcDone = 0;
  284.    unsigned long i, j, crc;
  285.  
  286.    if (crcDone)
  287.       return;
  288.    for (i = 0; i < 256; i++) {
  289.       crc = (i << 8);
  290.       for (j = 0; j < 8; j++)
  291.          crc = (crc << 1) ^ ((crc & 0x8000) ? 0x1021 : 0);
  292.       zCrc16Table[i] = crc & 0xffff;
  293.    }
  294.    for (i = 0; i < 256; i++) {
  295.       crc = i;
  296.       for (j = 0; j < 8; j++)
  297.          crc = (crc >> 1) ^ ((crc & 1) ? 0xEDB88320U : 0);
  298.       zCrc32Table[i] = crc & 0xffffffffU;
  299.    }
  300.    crcDone = 1;
  301. }
  302. STATIC unsigned long ZCrc16
  303.         (const BYTE *buff, unsigned int length,
  304.          unsigned long crc) {
  305.    const BYTE *p = buff;
  306.  
  307.    while (length-- > 0)
  308.       crc = zCrc16Table[((crc >> 8) ^ *p++) & 0xFF] ^ (crc << 8);
  309.    return crc & 0xFFFF;
  310. }
  311. STATIC unsigned long ZCrc32
  312.         (const BYTE *buff,
  313.          unsigned int length, unsigned long crc) {
  314.    const BYTE *p = buff;
  315.  
  316.    crc = ~crc;
  317.    while (length-- > 0)
  318.       crc = zCrc32Table[(crc ^ *p++) & 0xFF] ^ ((crc >> 8) & 0xFFFFFF);
  319.    return ~crc;
  320. }
  321. STATIC void ZTimeToTm
  322.         (long s, struct tm *pT) {
  323.    long    m, h;
  324.    int     d, M, y;
  325.  
  326.    if (s <= 0) {
  327.       time_t  t = time (NULL);
  328.  
  329.       *pT = *localtime (&t);
  330.       return;
  331.    }
  332.    m = s / 60;
  333.    h = m / 60;
  334.    d = h / 24;
  335.    y = d / 365;
  336.    s %= 60;
  337.    m %= 60;
  338.    h %= 24;
  339.    d %= 365;
  340.    d -= (y + 1) / 4;
  341.    if (d < 0) {
  342.       y--;
  343.       d += 365;
  344.    }
  345.    pT->tm_sec = s;
  346.    pT->tm_min = m;
  347.    pT->tm_hour = h;
  348.    pT->tm_yday = d;
  349.    if (((y - 2) % 4 != 0) && (d >= 59))
  350.       d++;
  351.    if (d >= 60)
  352.       d++;
  353.    M = (d > 214) ? 7 : 0 + ((d % 214) / 61) * 2 + ((d % 214) % 61) / 31;
  354.    d = ((d % 214) % 61) % 31 + 1;
  355.    pT->tm_mday = d;
  356.    pT->tm_mon = M;
  357.    pT->tm_year = y + 70;
  358.    pT->tm_isdst = -1;
  359.    pT->tm_wday = -1;
  360. }
  361. STATIC long ZTime
  362.         (struct tm *pT) {
  363.    static const int mon[] =
  364.    {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
  365.    int     y = pT->tm_year - 70, M = pT->tm_mon;
  366.    int     d = pT->tm_mday - 1 + mon[M];
  367.  
  368.    if (((y + 2) % 4 != 0) & (M > 1))
  369.       d--;
  370.    d += (y + 1) / 4;
  371.    return (((((long) y) * 365 + d) * 24 + pT->tm_hour) * 60 + pT->tm_min) * 60
  372.          + pT->tm_sec;
  373. }
  374. STATIC void ZParseZRINIT
  375.         (ZMODEM_PRIVATE *pZ, unsigned long flags) {
  376.    pZ->receiverFlags = flags;
  377.    if (flags & KNOW_CRC32)
  378.       pZ->crc32 = TRUE;
  379.    if (flags & ESCAPE_CONTROLS) {
  380.       int     i;
  381.  
  382.       SetEncode (DEL);
  383.       SetEncode (DEL | 0x80);
  384.       SetIgnore (DEL);
  385.       SetIgnore (DEL | 0x80);
  386.       for (i = 0; i < 32; i++) {
  387.          SetEncode (i);
  388.          SetIgnore (i);
  389.       }
  390.       for (i = 128; i < 160; i++) {
  391.          SetEncode (i);
  392.          SetIgnore (i);
  393.       }
  394.       pZ->mySenderFlags |= ESCAPE_CONTROLS;
  395.    }
  396. }
  397. STATIC void ZParseZSINIT
  398.         (ZMODEM_PRIVATE *pZ, unsigned long flags) {
  399.    pZ->senderFlags = flags;
  400.    if (flags & ESCAPE_CONTROLS) {
  401.       int     i;
  402.  
  403.       SetEncode (DEL);
  404.       SetEncode (DEL | 0x80);
  405.       SetIgnore (DEL);
  406.       SetIgnore (DEL | 0x80);
  407.       for (i = 0; i < 32; i++) {
  408.          SetEncode (i);
  409.          SetIgnore (i);
  410.       }
  411.       for (i = 128; i < 160; i++) {
  412.          SetEncode (i);
  413.          SetIgnore (i);
  414.       }
  415.       pZ->myReceiverFlags |= ESCAPE_CONTROLS;
  416.    }
  417. }
  418. STATIC int ZReadBytesWithTimeout
  419.         (ZMODEM_PRIVATE *pZ, int timeout,
  420.          BYTE *pBuffer, unsigned long *pLength) {
  421.    int     err, returnVal = zOK;
  422.    unsigned long lengthRead = 0;
  423.    unsigned long lengthToRead = *pLength;
  424.  
  425.    if (pZ->serialBufferRead < pZ->serialBufferLimit) {
  426.       lengthRead = pZ->serialBufferLimit - pZ->serialBufferRead;
  427.       if (lengthRead > lengthToRead)
  428.          lengthRead = lengthToRead;
  429.       memcpy (pBuffer, pZ->serialBufferRead, lengthRead);
  430.       pZ->serialBufferRead += lengthRead;
  431.       pBuffer += lengthRead;
  432.       lengthToRead -= lengthRead;
  433.    }
  434.    if ((lengthToRead > 0) && (lengthToRead < pZ->serialBufferSize)) {
  435.       *pLength = pZ->serialBufferSize;
  436.       pZ->serialBufferRead = pZ->serialBufferLimit = pZ->serialBuffer;
  437.       err = SerialReadWithTimeout (pZ->port, 0, pZ->serialBuffer, pLength);
  438.       pZ->serialBufferLimit += *pLength;
  439.       switch (err) {
  440.       case serialOK:
  441.          returnVal = zOK;
  442.          break;
  443.       case serialTimeout:
  444.          returnVal = zOK;
  445.          break;
  446.       case serialUserCancel:
  447.          pZ->userCancel = TRUE;
  448.          returnVal = zFail;
  449.          break;
  450.       case serialFrame:
  451.          returnVal = zBadPacket;
  452.          break;
  453.       default:
  454.          return StsWarn (zFailed);
  455.       }
  456.       if (pZ->serialBufferRead < pZ->serialBufferLimit) {
  457.          lengthRead = pZ->serialBufferLimit - pZ->serialBufferRead;
  458.          if (lengthRead > lengthToRead)
  459.             lengthRead = lengthToRead;
  460.          memcpy (pBuffer, pZ->serialBufferRead, lengthRead);
  461.          pZ->serialBufferRead += lengthRead;
  462.          pBuffer += lengthRead;
  463.          lengthToRead -= lengthRead;
  464.       }
  465.    }
  466.    if ((lengthToRead > 0) && (returnVal == zOK)) {
  467.       *pLength = lengthToRead;
  468.       err = SerialReadWithTimeout (pZ->port, timeout, pBuffer, pLength);
  469.       switch (err) {
  470.       case serialOK:
  471.          returnVal = zOK;
  472.          break;
  473.       case serialTimeout:
  474.          returnVal = zTimeout;
  475.          break;
  476.       case serialUserCancel:
  477.          pZ->userCancel = TRUE;
  478.          returnVal = zFail;
  479.          break;
  480.       case serialFrame:
  481.          returnVal = zBadPacket;
  482.          break;
  483.       default:
  484.          return StsWarn (zFailed);
  485.       }
  486.       lengthRead += *pLength;
  487.    }
  488.    if (pZ->userCancel)
  489.       return StsWarn (zFail);
  490.    *pLength = lengthRead;
  491.    return returnVal;
  492. }
  493. STATIC int ZSendBytes
  494.         (ZMODEM_PRIVATE *pZ, const BYTE *pBuffer, unsigned length) {
  495.    int     err, returnVal;
  496.  
  497.    err = SerialSend (pZ->port, pBuffer, length);
  498.    switch (err) {
  499.    case serialOK:
  500.       returnVal = zOK;
  501.       break;
  502.    case serialUserCancel:
  503.       pZ->userCancel = TRUE;
  504.       returnVal = zFail;
  505.       break;
  506.    default:
  507.       return StsWarn (zFailed);
  508.    }
  509.    if (pZ->userCancel)
  510.       return StsWarn (zFail);
  511.    return StsWarn (returnVal);
  512. }
  513. STATIC int ZWaitForSentBytes
  514.         (ZMODEM_PRIVATE *pZ) {
  515.    int     err, returnVal;
  516.  
  517.    if (pZ->userCancel)
  518.       return StsWarn (zFail);
  519.    err = SerialWaitForSentBytes (pZ->port);
  520.    switch (err) {
  521.    case serialOK:
  522.       returnVal = zOK;
  523.       break;
  524.    case serialUserCancel:
  525.       pZ->userCancel = TRUE;
  526.       returnVal = zFail;
  527.       break;
  528.    default:
  529.       return StsWarn (zFailed);
  530.    }
  531.    if (pZ->userCancel)
  532.       return StsWarn (zFail);
  533.    return StsWarn (returnVal);
  534. }
  535. STATIC int ZSendByte
  536.         (ZMODEM_PRIVATE *pZ, BYTE b) {
  537.    return StsWarn (ZSendBytes (pZ, &b, 1));
  538. }
  539. STATIC int ZReadByteWithTimeoutFcn
  540.         (ZMODEM_PRIVATE *pZ, int timeout,
  541.          BYTE *pByte) {
  542.    unsigned long count = 1;
  543.  
  544.    return ZReadBytesWithTimeout (pZ, timeout, pByte, &count);
  545. }
  546. STATIC int ZGobble
  547.         (ZMODEM_PRIVATE *pZ, int timeout) {
  548.    int     err;
  549.    BYTE    junk[50];
  550.    unsigned long junkSize = sizeof (junk);
  551.  
  552.    do {
  553.       err = ZReadBytesWithTimeout (pZ, timeout, junk, &junkSize);
  554.       if (err == zBadPacket)
  555.          err = zOK;
  556.    } while (err == zOK);
  557.    if (err == zTimeout)
  558.       return zOK;
  559.    return StsWarn (err);
  560. }
  561. STATIC int ZSendBreak
  562.         (ZMODEM_PRIVATE *pZ) {
  563.    int     returnVal;
  564.    int     err = SerialSendBreak (pZ->port);
  565.  
  566.    switch (err) {
  567.    case serialOK:
  568.       returnVal = zOK;
  569.       break;
  570.    case serialUserCancel:
  571.       pZ->userCancel = TRUE;
  572.       returnVal = zFail;
  573.       break;
  574.    default:
  575.       return StsWarn (zFailed);
  576.    }
  577.    if (pZ->userCancel)
  578.       return StsWarn (zFail);
  579.    return StsWarn (returnVal);
  580. }
  581. STATIC int ZPause
  582.         (ZMODEM_PRIVATE *pZ) {
  583.    int     returnVal;
  584.    int     err = SerialPause (pZ->port, 1);
  585.  
  586.    switch (err) {
  587.    case serialOK:
  588.       returnVal = zOK;
  589.       break;
  590.    case serialUserCancel:
  591.       pZ->userCancel = TRUE;
  592.       returnVal = zFail;
  593.       break;
  594.    default:
  595.       return StsWarn (zFailed);
  596.    }
  597.    if (pZ->userCancel)
  598.       return StsWarn (zFail);
  599.    return StsWarn (returnVal);
  600. }
  601. STATIC int ZFileReadOpenNext
  602.         (ZMODEM_PRIVATE *pZ, int fileType) {
  603.    while (1) {
  604.       if (pZ->currentFileName == pZ->numFileNames)
  605.          return zEndOfSession;
  606.       switch (DiskReadOpen (&pZ->f, pZ->filenames[pZ->currentFileName++],
  607.                             fileType)) {
  608.       case diskOK:
  609.          DiskFileSize (pZ->f, &(pZ->fileSize));
  610.          return zOK;
  611.       case diskCantRead:
  612.       case diskNoSuchFile:
  613.          break;
  614.       default:
  615.          return zFail;
  616.       }
  617.    }
  618. }
  619. STATIC int ZFileRead
  620.         (ZMODEM_PRIVATE *pZ, BYTE *pBuffer, unsigned long *pLength) {
  621.    int     returnVal;
  622.  
  623.    switch (DiskRead (pZ->f, pBuffer, *pLength, pLength)) {
  624.    case diskOK:
  625.       returnVal = zOK;
  626.       break;
  627.    case diskEOF:
  628.       returnVal = zEOF;
  629.       break;
  630.    default:
  631.       returnVal = zFail;
  632.       break;
  633.    }
  634.    return returnVal;
  635. }
  636. STATIC int ZFileReadSkip
  637.         (ZMODEM_PRIVATE *pZ, unsigned long length) {
  638.    BYTE    buff[500];
  639.  
  640.    while (length > 0) {
  641.       unsigned long readSize = sizeof (buff);
  642.  
  643.       if (readSize > length)
  644.          readSize = length;
  645.       StsRet (ZFileRead (pZ, buff, &readSize));
  646.       length -= readSize;
  647.    }
  648.    return zOK;
  649. }
  650. STATIC int ZFileReadClose
  651.         (ZMODEM_PRIVATE *pZ) {
  652.    int     returnVal;
  653.  
  654.    switch (DiskReadClose (pZ->f)) {
  655.    case diskOK:
  656.       returnVal = zOK;
  657.       break;
  658.    default:
  659.       returnVal = zFail;
  660.       break;
  661.    }
  662.    pZ->f = NULL;
  663.    return returnVal;
  664. }
  665. STATIC int ZFileWriteOpen
  666.         (ZMODEM_PRIVATE *pZ, BYTE *pBuffer, unsigned length) {
  667.    const char *fileName = (char *) pBuffer;
  668.    long    fileMode = -1;
  669.    long    fileSize = -1;
  670.    struct tm fileDate;
  671.    int     fileType;
  672.    int     err;
  673.  
  674.    ((void) length);
  675.    if ((fileName == NULL) || (*fileName == 0))
  676.       fileName = "zmodem.000\0\0";
  677.    {
  678.       time_t  t = time (NULL);
  679.  
  680.       fileDate = *localtime (&t);
  681.    }
  682.    {
  683.       const char *p = fileName;
  684.  
  685.       p += strlen (p) + 1;
  686.       if (*p) {
  687.          fileSize = atoi (p);
  688.          while ((*p) && (*p != ' '))
  689.             p++;
  690.          if (*p)
  691.             p++;
  692.       }
  693.       if (*p) {
  694.          long    fileDateSeconds = 0;
  695.  
  696.          while ((*p) && (*p != ' ')) {
  697.             fileDateSeconds = fileDateSeconds * 8 + (*p) - '0';
  698.             p++;
  699.          }
  700.          ZTimeToTm (fileDateSeconds, &fileDate);
  701.          if (*p)
  702.             p++;
  703.       }
  704.       if (*p) {
  705.          fileMode = 0;
  706.          while ((*p) && (*p != ' ')) {
  707.             fileMode = fileMode * 8 + (*p) - '0';
  708.             p++;
  709.          }
  710.          if (*p)
  711.             p++;
  712.       }
  713.    }
  714.    if (DiskWriteInit (&pZ->f, pZ->debug))
  715.       return StsWarn (zFail);
  716.    if (DiskWriteName (pZ->f, fileName))
  717.       return StsWarn (zFail);
  718.    pZ->fileSize = fileSize;
  719.    if (DiskWriteSize (pZ->f, fileSize))
  720.       return StsWarn (zFail);
  721.    if (DiskWriteDate (pZ->f, &fileDate))
  722.       return StsWarn (zFail);
  723.    if (DiskWriteMode (pZ->f, fileMode))
  724.       return StsWarn (zFail);
  725.    fileType = pZ->fileType;
  726.    if (fileType == diskFileUnknown) {
  727.       switch (pZ->fileFlags & CONV_MASK) {
  728.       case 0:
  729.          break;
  730.       case CONV_BINARY:
  731.          fileType = diskFileBinary;
  732.          break;
  733.       case CONV_TEXT:
  734.          fileType = diskFileText;
  735.          break;
  736.       case CONV_RESUME:
  737.          fileType = diskFileBinary;
  738.          break;
  739.       default:
  740.          if (pZ->debug) {
  741.             DebugBegin (pZ->debug, debugAttr);
  742.             DebugString (pZ->debug, "Unknown conversion option: ");
  743.             DebugIntHex (pZ->debug, pZ->fileFlags & CONV_MASK);
  744.             DebugEnd (pZ->debug);
  745.          }
  746.       }
  747.    }
  748.    if (DiskWriteType (pZ->f, fileType))
  749.       return StsWarn (zFail);
  750.    if (pZ->fileFlags & MAN_SKNOLOC) {
  751.       DISKFILE fTmp;
  752.  
  753.       err = DiskReadOpen (&fTmp, fileName, diskFileUnknown);
  754.       if (err == diskNoSuchFile)
  755.          return StsWarn (zSkip);
  756.       DiskReadClose (fTmp);
  757.    }
  758.    switch (pZ->fileFlags & MAN_MASK) {
  759.    case MAN_APPEND:
  760.       err = DiskAppendOpen (pZ->f);
  761.       break;
  762.    case MAN_REPLACE:
  763.       err = DiskReplaceOpen (pZ->f);
  764.       break;
  765.    default:
  766.       err = DiskWriteOpen (pZ->f);
  767.       break;
  768.    }
  769.    if (err == diskError)
  770.       return StsWarn (zSkip);
  771.    else if (err != diskOK)
  772.       return StsWarn (zFail);
  773.    return zOK;
  774. }
  775. STATIC int ZFileWrite
  776.         (ZMODEM_PRIVATE *pZ, const BYTE *pBuffer,
  777.          unsigned long length) {
  778.    switch (DiskWrite (pZ->f, pBuffer, length)) {
  779.    case diskOK:
  780.       return zOK;
  781.    default:
  782.       return zFail;
  783.    }
  784. }
  785. STATIC int ZFileWriteClose
  786.         (ZMODEM_PRIVATE *pZ) {
  787.    int     returnVal;
  788.  
  789.    switch (DiskWriteClose (pZ->f)) {
  790.    case diskOK:
  791.       returnVal = zOK;
  792.       break;
  793.    default:
  794.       returnVal = zFail;
  795.       break;
  796.    }
  797.    pZ->f = NULL;
  798.    return returnVal;
  799. }
  800. STATIC long ZFileSize
  801.         (ZMODEM_PRIVATE *pZ) {
  802.    long    size;
  803.  
  804.    if (pZ->f == NULL)
  805.       return -1;
  806.    else if (DiskFileSize (pZ->f, &size))
  807.       return -1;
  808.    else
  809.       return size;
  810. }
  811. STATIC unsigned long ZFileSystemFree
  812.         (ZMODEM_PRIVATE *pZ, unsigned long *pFreeCount) {
  813.    ((void) pZ);
  814.    *pFreeCount = 0L;
  815.    return zOK;
  816. }
  817. STATIC int ZFileCRC
  818.         (ZMODEM_PRIVATE *pZ, unsigned long numberBytes, unsigned long *pCrc) {
  819.    DISKFILE fTmp;
  820.    BYTE    buff[4096];
  821.    unsigned long crc = 0;
  822.    const char *fileName;
  823.    int     err;
  824.  
  825.    *pCrc = 0;
  826.    DiskFileName (pZ->f, &fileName);
  827.    err = DiskReadOpen (&fTmp, fileName, diskFileBinary);
  828.    if (err != diskOK)
  829.       return StsWarn (zFail);
  830.    while (numberBytes > 0) {
  831.       unsigned long numberRead = numberBytes;
  832.  
  833.       if (numberRead > sizeof (buff))
  834.          numberRead = sizeof (buff);
  835.       err = DiskRead (fTmp, buff, numberRead, &numberRead);
  836.       if (err != diskOK)
  837.          return StsWarn (zFail);
  838.       crc = ZCrc32 (buff, numberRead, crc);
  839.       numberBytes -= numberRead;
  840.    }
  841.    DiskReadClose (fTmp);
  842.    *pCrc = crc;
  843.    return zOK;
  844. }
  845. enum {
  846.    stsNegotiating = progNegotiating,
  847.    stsNewFile = progNewFile,
  848.    stsSending = progSending,
  849.    stsReceiving = progReceiving,
  850.    stsEnding = progEnding,
  851.    stsEOF = progEOF,
  852.    stsDone = progDone,
  853.    stsFailed = progFailed,
  854.    stsCancelled = progCancelled,
  855.    stsSkipped = progSkipped
  856. };
  857. STATIC void 
  858. ZProgress (ZMODEM_PRIVATE *pZ, int status)
  859. {
  860.    if (pZ->f) {
  861.       const char *fileName = NULL;
  862.       int     fileType = diskFileUnknown;
  863.  
  864.       DiskFileName (pZ->f, &fileName);
  865.       ProgressFileName (pZ->progress, fileName);
  866.       DiskFileType (pZ->f, &fileType);
  867.       ProgressFileType (pZ->progress, fileType);
  868.    } else {
  869.       ProgressFileName (pZ->progress, NULL);
  870.    }
  871.    ProgressFileSize (pZ->progress, pZ->fileSize);
  872.    ProgressFilePosition (pZ->progress, pZ->receivePosition);
  873.    ProgressReport (pZ->progress, status);
  874. }
  875. STATIC int ZSendEncodeBytes
  876.         (ZMODEM_PRIVATE *pZ, const BYTE *pBuffer,
  877.          unsigned int length) {
  878.    BYTE    buff[100];
  879.    unsigned buffPos;
  880.    int     buffFree;
  881.  
  882.    if (pZ->debug) {
  883.       DebugBegin (pZ->debug, debugPacketLowLevel | debugEncoding);
  884.       DebugString (pZ->debug, "ZSendEncodeBytes: encoding ");
  885.       DebugUInt (pZ->debug, length);
  886.       DebugString (pZ->debug, " bytes: ``");
  887.       if (length > 30) {
  888.          DebugStringCount (pZ->debug, (const char *) pBuffer, 30);
  889.          DebugString (pZ->debug, "...");
  890.       } else {
  891.          DebugStringCount (pZ->debug, (const char *) pBuffer, length);
  892.          DebugString (pZ->debug, "''");
  893.       }
  894.       DebugEnd (pZ->debug);
  895.    }
  896.    while (length > 0) {
  897.       buffPos = 0;
  898.       buffFree = sizeof (buff) - 5;
  899.       while ((buffFree > 0) && (length > 0)) {
  900.          int     c = *pBuffer++;
  901.  
  902.          length--;
  903.          if (TestEncode (c)) {
  904.             buff[buffPos++] = CAN;
  905.             if (c == 0x7F)
  906.                buff[buffPos++] = 'l';
  907.             else if (c == 0xFF)
  908.                buff[buffPos++] = 'm';
  909.             else
  910.                buff[buffPos++] = c | 0x40;
  911.             buffFree -= 2;
  912.          } else {
  913.             buff[buffPos++] = c;
  914.             buffFree--;
  915.          }
  916.       }
  917.       StsRet (ZSendBytes (pZ, buff, buffPos));
  918.    }
  919.    return zOK;
  920. }
  921. STATIC int ZSendHexBytes
  922.         (ZMODEM_PRIVATE *pZ, BYTE *pBuffer, int length) {
  923.    BYTE    buff[100];
  924.    unsigned buffPos;
  925.    int     buffFree;
  926.    static const char digits[] = "0123456789abcdef";
  927.  
  928.    while (length > 0) {
  929.       buffPos = 0;
  930.       buffFree = sizeof (buff) - 2;
  931.       while ((length-- > 0) && (buffFree > 0)) {
  932.          int     c = *pBuffer++;
  933.  
  934.          buff[buffPos++] = digits[(c >> 4) & 15];
  935.          buff[buffPos++] = digits[c & 15];
  936.          buffFree -= 2;
  937.       }
  938.       StsRet (ZSendBytes (pZ, buff, buffPos));
  939.    }
  940.    return zOK;
  941. }
  942. STATIC BYTE zDecode[256];
  943. STATIC int ZReadDecodeBytes
  944.         (ZMODEM_PRIVATE *pZ, int timeout, BYTE *pBuffer, int *pLength) {
  945.    BYTE    byte;
  946.    int     sawCAN = FALSE;
  947.    int     lengthDesired = *pLength;
  948.    int     canCount = 0;
  949.  
  950.    while (1) {
  951.       StsRet (ZReadByteWithTimeout (pZ, timeout, &byte));
  952.       if (TestIgnore (byte)) {
  953.       } else if (byte == CAN) {
  954.          if (sawCAN) {
  955.             canCount++;
  956.             if (canCount >= 5)
  957.                return StsWarn (zFailed);
  958.          } else {
  959.             canCount = 1;
  960.             sawCAN = TRUE;
  961.          }
  962.       } else if (sawCAN) {
  963.          sawCAN = FALSE;
  964.          if (TestDecode (byte))
  965.             *pBuffer++ = zDecode[byte];
  966.          else {
  967.             *pLength -= lengthDesired;
  968.             return StsWarn (zBadPacket);
  969.          }
  970.          lengthDesired--;
  971.       } else {
  972.          *pBuffer++ = byte;
  973.          lengthDesired--;
  974.       }
  975.       if (lengthDesired == 0)
  976.          return zOK;
  977.    }
  978. }
  979. STATIC int ZReadDecodeHexBytes
  980.         (ZMODEM_PRIVATE *pZ, int timeout, BYTE *pBuffer,
  981.          int *pLength) {
  982.    BYTE    byte;
  983.    int     lengthDesired = *pLength;
  984.    int     evenOdd = 0;
  985.  
  986.    while (1) {
  987.       int     digit = -1;
  988.  
  989.       StsRet (ZReadByteWithTimeout (pZ, timeout, &byte));
  990.       byte &= 0x7F;
  991.       if ((byte >= '0') && (byte <= '9'))
  992.          digit = byte - '0';
  993.       else if ((byte >= 'a') && (byte <= 'f'))
  994.          digit = byte - 'a' + 10;
  995.       else if (!TestIgnore (byte))
  996.          return StsWarn (zBadPacket);
  997.       if (digit >= 0) {
  998.          if (evenOdd) {
  999.             *pBuffer++ |= digit;
  1000.             lengthDesired--;
  1001.          } else
  1002.             *pBuffer = digit << 4;
  1003.          evenOdd = !evenOdd;
  1004.       }
  1005.       if (lengthDesired == 0)
  1006.          return zOK;
  1007.    }
  1008. }
  1009. STATIC int ZSendAttention
  1010.         (ZMODEM_PRIVATE *pZ) {
  1011.    BYTE   *pB = pZ->attention;
  1012.  
  1013.    while (TRUE) {
  1014.       switch (*pB) {
  1015.       case 0:
  1016.          return zOK;
  1017.       case 0xDD:
  1018.          ZSendBreak (pZ);
  1019.          break;
  1020.       case 0xDE:
  1021.          ZPause (pZ);
  1022.          break;
  1023.       default:
  1024.          StsRet (ZSendByte (pZ, *pB));
  1025.          break;
  1026.       }
  1027.       pB++;
  1028.    }
  1029. }
  1030. STATIC int ZSendCAN
  1031.         (ZMODEM_PRIVATE *pZ) {
  1032.    static const BYTE cancel[] =
  1033.    {CAN, CAN, CAN, CAN, CAN, CAN, CAN, CAN, CAN, CAN, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
  1034.  
  1035.    return ZSendBytes (pZ, cancel, sizeof (cancel) / sizeof (cancel[0]));
  1036. }
  1037. STATIC int ZSendHexHeader
  1038.         (ZMODEM_PRIVATE *pZ, int headerType, unsigned long arg) {
  1039.    BYTE    headerStart[] =
  1040.    {'*', '*', CAN, 'B'};
  1041.    BYTE    headerData[7];
  1042.    BYTE    headerEnd[] =
  1043.    {CR, LF, XON};
  1044.  
  1045.    pZ->txPacketType = headerType;
  1046.    if (pZ->debug) {
  1047.       DebugBegin (pZ->debug, debugPacket);
  1048.       DebugString (pZ->debug, "Sending hex header ");
  1049.       DebugPacket (pZ->debug, headerType, arg);
  1050.       DebugEnd (pZ->debug);
  1051.    }
  1052.    if (headerType == ZCAN)
  1053.       return ZSendCAN (pZ);
  1054.    headerData[0] = headerType;
  1055.    headerData[1] = arg & 0xFF;
  1056.    headerData[2] = (arg >> 8) & 0xFF;
  1057.    headerData[3] = (arg >> 16) & 0xFF;
  1058.    headerData[4] = (arg >> 24) & 0xFF;
  1059.    {
  1060.       short   crc = ZCrc16 (headerData, 5, 0);
  1061.  
  1062.       headerData[5] = (crc >> 8) & 0xFF;
  1063.       headerData[6] = crc & 0xFF;
  1064.    }
  1065.    StsRet (ZSendBytes (pZ, headerStart, sizeof (headerStart)));
  1066.    StsRet (ZSendHexBytes (pZ, headerData, sizeof (headerData)));
  1067.    if ((headerType == ZACK) || (headerType == ZFIN))
  1068.       StsRet (ZSendBytes (pZ, headerEnd, 2));
  1069.    else
  1070.       StsRet (ZSendBytes (pZ, headerEnd, 3));
  1071.    StsRet (ZWaitForSentBytes (pZ));
  1072.    return zOK;
  1073. }
  1074. STATIC int ZSendHeader
  1075.         (ZMODEM_PRIVATE *pZ, int headerType, unsigned long arg) {
  1076.    BYTE    headerStart[] =
  1077.    {'*', CAN, 'A'};
  1078.    BYTE    headerData[9];
  1079.    unsigned headerLength = 7;
  1080.  
  1081.    pZ->txPacketType = headerType;
  1082.    if (pZ->debug) {
  1083.       DebugBegin (pZ->debug, debugPacket);
  1084.       DebugString (pZ->debug, "Sending binary header ");
  1085.       DebugPacket (pZ->debug, headerType, arg);
  1086.       DebugEnd (pZ->debug);
  1087.    }
  1088.    if (headerType == ZCAN)
  1089.       return ZSendCAN (pZ);
  1090.    headerData[0] = headerType;
  1091.    headerData[1] = arg & 0xFF;
  1092.    headerData[2] = (arg >> 8) & 0xFF;
  1093.    headerData[3] = (arg >> 16) & 0xFF;
  1094.    headerData[4] = (arg >> 24) & 0xFF;
  1095.    if (pZ->crc32) {
  1096.       unsigned long crc = ZCrc32 (headerData, 5, 0);
  1097.  
  1098.       headerData[5] = crc & 0xFF;
  1099.       headerData[6] = (crc >> 8) & 0xFF;
  1100.       headerData[7] = (crc >> 16) & 0xFF;
  1101.       headerData[8] = (crc >> 24) & 0xFF;
  1102.       headerStart[2] = 'C';
  1103.       headerLength = 9;
  1104.       pZ->sendingCrc32 = TRUE;
  1105.    } else {
  1106.       unsigned short crc = ZCrc16 (headerData, 5, 0);
  1107.  
  1108.       headerData[5] = (crc >> 8) & 0xFF;
  1109.       headerData[6] = crc & 0xFF;
  1110.       pZ->sendingCrc32 = FALSE;
  1111.    }
  1112.    StsRet (ZSendBytes (pZ, headerStart, sizeof (headerStart)));
  1113.    StsRet (ZSendEncodeBytes (pZ, headerData, headerLength));
  1114.    StsRet (ZWaitForSentBytes (pZ));
  1115.    return zOK;
  1116. }
  1117. STATIC int ZReadHeader
  1118.         (ZMODEM_PRIVATE *pZ, int timeout) {
  1119.    BYTE    pad = 0, sync = 0, headerType = 0;
  1120.    BYTE    packet[15];
  1121.    int     canCount = 0;
  1122.    int     length;
  1123.    int     err;
  1124.    unsigned long crc;
  1125.    unsigned long arg;
  1126.    int     noiseCount = 0;
  1127.  
  1128.    do {
  1129.       err = ZReadByteWithTimeout (pZ, timeout, &pad);
  1130.       if ((err != zOK) && (err != zBadPacket))
  1131.          return err;
  1132.       if (err == zOK) {
  1133.          if (noiseCount++ > pZ->noiseLimit)
  1134.             return StsWarn (zBadPacket);
  1135.          if (pad == CAN) {
  1136.             if (++canCount >= 5) {
  1137.                pZ->rxPacketType = ZCAN;
  1138.                return StsWarn (zFailed);
  1139.             }
  1140.          } else
  1141.             canCount = 0;
  1142.       }
  1143.    } while (pad != '*');
  1144.    headerType = '*';
  1145.    do {
  1146.       pad = sync;
  1147.       sync = headerType;
  1148.       StsRet (ZReadByteWithTimeout (pZ, 2, &headerType));
  1149.       if (noiseCount++ > pZ->noiseLimit)
  1150.          return StsWarn (zBadPacket);
  1151.       if (headerType == CAN) {
  1152.          if (++canCount >= 5) {
  1153.             pZ->rxPacketType = ZCAN;
  1154.             return StsWarn (zFail);
  1155.          }
  1156.       } else
  1157.          canCount = 0;
  1158.    } while ((pad != '*') || (sync != CAN) || ((headerType != 'A')
  1159.                             && (headerType != 'B') && (headerType != 'C')));
  1160.    switch (headerType) {
  1161.    case 'A':
  1162.       pZ->receivingCrc32 = FALSE;
  1163.       length = 1 + 4 + 2;
  1164.       StsRet (ZReadDecodeBytes (pZ, 2, packet, &length));
  1165.       break;
  1166.    case 'B':
  1167.       pZ->receivingCrc32 = FALSE;
  1168.       length = 1 + 4 + 2;
  1169.       StsRet (ZReadDecodeHexBytes (pZ, 2, packet, &length));
  1170.       break;
  1171.    case 'C':
  1172.       pZ->receivingCrc32 = TRUE;
  1173.       length = 1 + 4 + 4;
  1174.       StsRet (ZReadDecodeBytes (pZ, 2, packet, &length));
  1175.       break;
  1176.    }
  1177.    arg = ((packet[4] * 256L + packet[3]) * 256 + packet[2]) * 256 + packet[1];
  1178.    if (pZ->debug) {
  1179.       DebugBegin (pZ->debug, debugPacket);
  1180.       DebugString (pZ->debug, "Read packet: ");
  1181.       switch (headerType) {
  1182.       case 'A':
  1183.          DebugString (pZ->debug, "Bin16 ");
  1184.          break;
  1185.       case 'B':
  1186.          DebugString (pZ->debug, "Hex16 ");
  1187.          break;
  1188.       case 'C':
  1189.          DebugString (pZ->debug, "Bin32 ");
  1190.          break;
  1191.       }
  1192.       DebugPacket (pZ->debug, packet[0], arg);
  1193.       if (pZ->receivingCrc32)
  1194.          crc = ((packet[8] * 256L + packet[7]) * 256 + packet[6]) * 256 + packet[5];
  1195.       else
  1196.          crc = (packet[5] * 256 + packet[6]) & 0xFFFF;
  1197.       DebugString (pZ->debug, " crc:");
  1198.       DebugIntHex (pZ->debug, crc);
  1199.       DebugEnd (pZ->debug);
  1200.    }
  1201.    if (pZ->receivingCrc32) {
  1202.       crc = ((packet[8] * 256L + packet[7]) * 256 + packet[6]) * 256 + packet[5];
  1203.       if (crc != ZCrc32 (packet, 5, 0)) {
  1204.          DebugBegin (pZ->debug, debugPacketLowLevel | debugPacketErr);
  1205.          DebugString (pZ->debug, "Computed CRC: ");
  1206.          DebugIntHex (pZ->debug, ZCrc32 (packet, 5, 0));
  1207.          DebugEnd (pZ->debug);
  1208.          return StsWarn (zBadPacket);
  1209.       }
  1210.    } else {
  1211.       crc = (packet[5] * 256 + packet[6]) & 0xFFFF;
  1212.       if (crc != ZCrc16 (packet, 5, 0)) {
  1213.          DebugBegin (pZ->debug, debugPacketLowLevel | debugPacketErr);
  1214.          DebugString (pZ->debug, "Computed CRC: ");
  1215.          DebugIntHex (pZ->debug, ZCrc16 (packet, 5, 0));
  1216.          DebugEnd (pZ->debug);
  1217.          return StsWarn (zBadPacket);
  1218.       }
  1219.    }
  1220.    pZ->rxPacketType = packet[0];
  1221.    pZ->rxPacketArg = arg;
  1222.    if (pZ->rxPacketType == ZABORT)
  1223.       return zFail;
  1224.    return zOK;
  1225. }
  1226. STATIC int ZSendCrcEscape
  1227.         (ZMODEM_PRIVATE *pZ, unsigned long crc,
  1228.          int packetEnd, int needAck) {
  1229.    unsigned char crcBuff[4];
  1230.    BYTE    crcEscape;
  1231.  
  1232.    if (packetEnd)
  1233.       pZ->txPacketType = -1;
  1234.    if (needAck) {
  1235.       if (packetEnd)
  1236.          crcEscape = 'k';
  1237.       else
  1238.          crcEscape = 'j';
  1239.    } else {
  1240.       if (packetEnd)
  1241.          crcEscape = 'h';
  1242.       else
  1243.          crcEscape = 'i';
  1244.    }
  1245.    StsRet (ZSendByte (pZ, CAN));
  1246.    StsRet (ZSendByte (pZ, crcEscape));
  1247.    if (pZ->sendingCrc32) {
  1248.       crc = ZCrc32 (&crcEscape, 1, crc);
  1249.       crcBuff[0] = crc & 0xFF;
  1250.       crcBuff[1] = (crc >> 8) & 0xFF;
  1251.       crcBuff[2] = (crc >> 16) & 0xFF;
  1252.       crcBuff[3] = (crc >> 24) & 0xFF;
  1253.       StsRet (ZSendEncodeBytes (pZ, crcBuff, 4));
  1254.    } else {
  1255.       crc = ZCrc16 (&crcEscape, 1, crc);
  1256.       crcBuff[0] = (crc >> 8) & 0xFF;
  1257.       crcBuff[1] = crc & 0xFF;
  1258.       StsRet (ZSendEncodeBytes (pZ, crcBuff, 2));
  1259.    }
  1260.    return StsWarn (ZWaitForSentBytes (pZ));
  1261. }
  1262. STATIC int ZReceivePacketData
  1263.         (ZMODEM_PRIVATE *pZ, BYTE *pBuffer, unsigned int *pLength) {
  1264.    BYTE    byte;
  1265.    BYTE   *pB = pBuffer;
  1266.    int     sawCAN = FALSE;
  1267.    int     canCount = 0;
  1268.  
  1269.    *pLength = 0;
  1270.    while (1) {
  1271.       StsRet (ZReadByteWithTimeout (pZ, pZ->timeout, &byte));
  1272.       if (TestIgnore (byte)) {
  1273.       } else if (byte == CAN) {
  1274.          if (sawCAN) {
  1275.             canCount++;
  1276.             if (canCount >= 5)
  1277.                return StsWarn (zFailed);
  1278.          } else {
  1279.             canCount = 1;
  1280.             sawCAN = TRUE;
  1281.          }
  1282.       } else if (sawCAN) {
  1283.          sawCAN = FALSE;
  1284.          if (TestDecode (byte))
  1285.             *pB++ = zDecode[byte];
  1286.          else
  1287.             break;
  1288.          (*pLength)++;
  1289.       } else {
  1290.          *pB++ = byte;
  1291.          sawCAN = FALSE;
  1292.          (*pLength)++;
  1293.       }
  1294.       if (*pLength > 1024)
  1295.          return StsWarn (zBadPacket);
  1296.    }
  1297.    switch (byte) {
  1298.    case 'h':
  1299.    case 'i':
  1300.    case 'j':
  1301.       if (pZ->debug) {
  1302.          DebugBegin (pZ->debug, debugEncoding | debugWarn);
  1303.          DebugString (pZ->debug, "Non-conforming CRC escape: CAN ");
  1304.          DebugChar (pZ->debug, byte);
  1305.          DebugEnd (pZ->debug);
  1306.       }
  1307.    case 'k':
  1308.       break;
  1309.    default:
  1310.       if (pZ->debug) {
  1311.          DebugBegin (pZ->debug, debugEncoding | debugWarn);
  1312.          DebugString (pZ->debug, "Illegal CAN sequence: CAN ");
  1313.          DebugChar (pZ->debug, byte);
  1314.          DebugEnd (pZ->debug);
  1315.       }
  1316.       return StsWarn (zBadPacket);
  1317.    }
  1318.    {
  1319.       unsigned long crc, txCrc;
  1320.  
  1321.       if (pZ->receivingCrc32) {
  1322.          crc = ZCrc32 (pBuffer, *pLength, 0);
  1323.          crc = ZCrc32 (&byte, 1, crc);
  1324.       } else {
  1325.          crc = ZCrc16 (pBuffer, *pLength, 0);
  1326.          crc = ZCrc16 (&byte, 1, crc);
  1327.       }
  1328.       {
  1329.          BYTE    crcBuff[4];
  1330.          int     crcLength;
  1331.  
  1332.          if (pZ->receivingCrc32)
  1333.             crcLength = 4;
  1334.          else
  1335.             crcLength = 2;
  1336.          StsRet (ZReadDecodeBytes (pZ, pZ->timeout, crcBuff, &crcLength));
  1337.          if (pZ->receivingCrc32)
  1338.             txCrc = ((crcBuff[3] * 256L + crcBuff[2]) * 256
  1339.                      + crcBuff[1]) * 256 + crcBuff[0];
  1340.          else
  1341.             txCrc = crcBuff[0] * 256 + crcBuff[1];
  1342.       }
  1343.       if (crc != txCrc)
  1344.          return StsWarn (zBadPacket);
  1345.    }
  1346.    if (pZ->debug) {
  1347.       DebugBegin (pZ->debug, debugPacket);
  1348.       DebugString (pZ->debug, "Received data following packet: ");
  1349.       DebugUInt (pZ->debug, *pLength);
  1350.       DebugString (pZ->debug, " bytes");
  1351.       DebugEnd (pZ->debug);
  1352.    }
  1353.    return zOK;
  1354. }
  1355. STATIC int ZReceiveStream
  1356.         (ZMODEM_PRIVATE *pZ, BYTE *buff) {
  1357.    BYTE   *pBuff = buff;
  1358.    unsigned length = 0;
  1359.    int     packetEnd, needAck;
  1360.    BYTE    byte;
  1361.    int     byteDecoded;
  1362.    int     sawCAN = FALSE;
  1363.    int     canCount = 0;
  1364.  
  1365.    while (length < 1025) {
  1366.       StsRet (ZReadByteWithTimeout (pZ, pZ->timeout, &byte));
  1367.       byteDecoded = -1;
  1368.       if (TestIgnore (byte)) {
  1369.       } else if (byte == CAN) {
  1370.          if (sawCAN) {
  1371.             canCount++;
  1372.             if (canCount >= 5)
  1373.                return zFailed;
  1374.          } else {
  1375.             canCount = 1;
  1376.             sawCAN = TRUE;
  1377.          }
  1378.       } else if (sawCAN) {
  1379.          sawCAN = FALSE;
  1380.          if (TestDecode (byte))
  1381.             byteDecoded = zDecode[byte];
  1382.          else {
  1383.             {
  1384.                unsigned long crc, txCrc;
  1385.  
  1386.                switch (byte) {
  1387.                case 'h':
  1388.                   packetEnd = TRUE;
  1389.                   needAck = FALSE;
  1390.                   break;
  1391.                case 'i':
  1392.                   packetEnd = FALSE;
  1393.                   needAck = FALSE;
  1394.                   break;
  1395.                case 'j':
  1396.                   packetEnd = FALSE;
  1397.                   needAck = TRUE;
  1398.                   break;
  1399.                case 'k':
  1400.                   packetEnd = TRUE;
  1401.                   needAck = TRUE;
  1402.                   break;
  1403.                default:
  1404.                   if (pZ->debug) {
  1405.                      DebugBegin (pZ->debug, debugEncoding | debugWarn);
  1406.                      DebugString (pZ->debug, "Illegal CAN sequence: CAN ");
  1407.                      DebugChar (pZ->debug, byte);
  1408.                      DebugEnd (pZ->debug);
  1409.                   }
  1410.                   return StsWarn (zBadPacket);
  1411.                }
  1412.                if (pZ->receivingCrc32) {
  1413.                   crc = ZCrc32 (buff, length, 0);
  1414.                   crc = ZCrc32 (&byte, 1, crc);
  1415.                } else {
  1416.                   crc = ZCrc16 (buff, length, 0);
  1417.                   crc = ZCrc16 (&byte, 1, crc);
  1418.                }
  1419.                {
  1420.                   BYTE    crcBuff[4];
  1421.                   int     crcLength;
  1422.  
  1423.                   if (pZ->receivingCrc32)
  1424.                      crcLength = 4;
  1425.                   else
  1426.                      crcLength = 2;
  1427.                   StsRet (ZReadDecodeBytes (pZ, pZ->timeout, crcBuff, &crcLength));
  1428.                   if (pZ->receivingCrc32)
  1429.                      txCrc = ((crcBuff[3] * 256L + crcBuff[2]) * 256
  1430.                               + crcBuff[1]) * 256 + crcBuff[0];
  1431.                   else
  1432.                      txCrc = crcBuff[0] * 256 + crcBuff[1];
  1433.                }
  1434.                if (crc != txCrc) {
  1435.                   if (pZ->debug) {
  1436.                      DebugBegin (pZ->debug, debugPacketLowLevel | debugPacketErr);
  1437.                      DebugString (pZ->debug, "Erroneous data: ");
  1438.                      DebugStringCount (pZ->debug, (const char *) buff, length);
  1439.                      DebugEnd (pZ->debug);
  1440.                      DebugBegin (pZ->debug, debugPacketLowLevel | debugPacketErr);
  1441.                      DebugString (pZ->debug, "terminator: ");
  1442.                      DebugChar (pZ->debug, byte);
  1443.                      DebugString (pZ->debug, "length of data: ");
  1444.                      DebugUInt (pZ->debug, length);
  1445.                      DebugString (pZ->debug, ", CRC received: ");
  1446.                      DebugIntHex (pZ->debug, txCrc);
  1447.                      DebugString (pZ->debug, ", CRC calculated: ");
  1448.                      DebugIntHex (pZ->debug, crc);
  1449.                      DebugEnd (pZ->debug);
  1450.                   }
  1451.                   return StsWarn (zBadPacket);
  1452.                }
  1453.             }
  1454.             if (pZ->sendPosition + length > pZ->receivePosition) {
  1455.                BYTE   *pDataBegin = buff + pZ->receivePosition - pZ->sendPosition;
  1456.                unsigned long dataLength = length - pZ->receivePosition + pZ->sendPosition;
  1457.  
  1458.                pZ->receivePosition += dataLength;
  1459. #if I_CAN_OVERLAP_DISK
  1460.                if (needAck)
  1461.                   ZSendHexHeader (pZ, ZACK, pZ->receivePosition);
  1462.                StsRet (ZFileWrite (pZ, pDataBegin, dataLength));
  1463. #else
  1464.                StsRet (ZFileWrite (pZ, pDataBegin, dataLength));
  1465.                if (needAck)
  1466.                   ZSendHexHeader (pZ, ZACK, pZ->receivePosition);
  1467. #endif
  1468.             }
  1469.             pZ->sendPosition += length;
  1470.             ZProgress (pZ, stsReceiving);
  1471.             if (packetEnd)
  1472.                return zOK;
  1473.             length = 0;
  1474.             pBuff = buff;
  1475.          }
  1476.       } else {
  1477.          byteDecoded = byte;
  1478.          sawCAN = FALSE;
  1479.       }
  1480.       if (byteDecoded >= 0) {
  1481.          *pBuff++ = byteDecoded;
  1482.          length++;
  1483.       }
  1484.    }
  1485.    if (pZ->debug) {
  1486.       DebugBegin (pZ->debug, debugPacketErr | debugWarn);
  1487.       DebugString (pZ->debug, "Data CRC not seen, buffer overflow");
  1488.       DebugEnd (pZ->debug);
  1489.    }
  1490.    return StsWarn (zBadPacket);
  1491. }
  1492. typedef struct {
  1493.    int     atEOF;
  1494.    BYTE   *data;
  1495.    unsigned long size;
  1496.    unsigned long startFilePos;
  1497.    unsigned long endFilePos;
  1498.    BYTE   *pStart;
  1499.    BYTE   *pEnd;
  1500. } WINDOW;
  1501. STATIC int ZInitWindow
  1502.         (ZMODEM_PRIVATE *pZ, WINDOW * pWindow, long size, long startPos) {
  1503.    int     err;
  1504.  
  1505.    pWindow->startFilePos = startPos;
  1506.    pWindow->endFilePos = startPos;
  1507.    pWindow->atEOF = FALSE;
  1508.    pWindow->data = NULL;
  1509.    err = ZFileReadSkip (pZ, startPos);
  1510.    if (err == zEOF) {
  1511.       pWindow->atEOF = TRUE;
  1512.       return zOK;
  1513.    } else
  1514.       StsRet (err);
  1515.    while ((pWindow->data == NULL) && (size > 256)) {
  1516.       pWindow->size = size;
  1517.       pWindow->data = malloc (pWindow->size);
  1518.       size /= 2;
  1519.       pWindow->pStart = pWindow->data;
  1520.       pWindow->pEnd = pWindow->data;
  1521.    }
  1522.    if (pWindow->data == NULL)
  1523.       return zFail;
  1524.    else
  1525.       return zOK;
  1526. }
  1527. STATIC int ZSendFillWindow
  1528.         (ZMODEM_PRIVATE *pZ, WINDOW * pWindow, long readLimit) {
  1529.    int     err = zOK;
  1530.  
  1531.    if (pZ->debug) {
  1532.       DebugBegin (pZ->debug, debugCache);
  1533.       DebugString (pZ->debug, "Filling window: readLimit = ");
  1534.       DebugUInt (pZ->debug, readLimit);
  1535.       DebugEnd (pZ->debug);
  1536.       DebugBegin (pZ->debug, debugCache);
  1537.       DebugString (pZ->debug, "Window: startFP: ");
  1538.       DebugUInt (pZ->debug, pWindow->startFilePos);
  1539.       DebugString (pZ->debug, " endFP: ");
  1540.       DebugUInt (pZ->debug, pWindow->endFilePos);
  1541.       DebugString (pZ->debug, " start: ");
  1542.       DebugPtr (pZ->debug, pWindow->pStart);
  1543.       DebugString (pZ->debug, " end: ");
  1544.       DebugPtr (pZ->debug, pWindow->pEnd);
  1545.       if (pWindow->atEOF)
  1546.          DebugString (pZ->debug, " (atEOF)");
  1547.       DebugEnd (pZ->debug);
  1548.    }
  1549.    if ((pWindow->endFilePos - pWindow->startFilePos) >= pWindow->size)
  1550.       return zOK;
  1551.    if (pWindow->atEOF)
  1552.       return zEOF;
  1553.    if (pWindow->pStart <= pWindow->pEnd) {
  1554.       unsigned long readLength = pWindow->size - (pWindow->pEnd - pWindow->data);
  1555.  
  1556.       if (pZ->debug) {
  1557.          DebugBegin (pZ->debug, debugCache);
  1558.          DebugString (pZ->debug, "Adjusting read: target Length: ");
  1559.          DebugUInt (pZ->debug, readLength);
  1560.          DebugString (pZ->debug, " limit: ");
  1561.          DebugUInt (pZ->debug, readLimit);
  1562.          DebugEnd (pZ->debug);
  1563.       }
  1564.       if (readLength > readLimit)
  1565.          readLength = readLimit;
  1566.       if (readLength > 0) {
  1567.          err = ZFileRead (pZ, pWindow->pEnd, &readLength);
  1568.          if (err == zOK) {
  1569.             pWindow->endFilePos += readLength;
  1570.             pWindow->pEnd += readLength;
  1571.             readLimit -= readLength;
  1572.             if ((pWindow->pEnd - pWindow->data) >= pWindow->size)
  1573.                pWindow->pEnd = pWindow->data;
  1574.          }
  1575.       }
  1576.    }
  1577.    if ((err == zOK) && (pWindow->pEnd < pWindow->pStart)) {
  1578.       unsigned long readLength = pWindow->pStart - pWindow->pEnd;
  1579.  
  1580.       if (readLength > readLimit)
  1581.          readLength = readLimit;
  1582.       if (readLength > 0) {
  1583.          err = ZFileRead (pZ, pWindow->pEnd, &readLength);
  1584.          if (err == zOK) {
  1585.             pWindow->endFilePos += readLength;
  1586.             pWindow->pEnd += readLength;
  1587.          }
  1588.       }
  1589.    }
  1590.    if (err == zEOF)
  1591.       pWindow->atEOF = TRUE;
  1592.    return StsWarn (err);
  1593. }
  1594. STATIC int ZSendFileDataPacket
  1595.         (ZMODEM_PRIVATE *pZ, WINDOW * pWindow,
  1596.          unsigned size, int endOfPacket, int needAck) {
  1597.    unsigned long crc = 0L;
  1598.    unsigned packetLength = size;
  1599.    BYTE   *packetStart;
  1600.  
  1601.    if (pZ->txPacketType != ZDATA)
  1602.       StsRet (ZSendHeader (pZ, ZDATA, pZ->sendPosition));
  1603.    packetStart = pWindow->pStart + (pZ->sendPosition - pWindow->startFilePos);
  1604.    if ((packetStart - pWindow->data) >= pWindow->size)
  1605.       packetStart -= pWindow->size;
  1606.    if ((pZ->sendPosition + packetLength) > pWindow->endFilePos)
  1607.       packetLength = pWindow->endFilePos - pZ->sendPosition;
  1608.    if ((packetStart - pWindow->data + packetLength) >= pWindow->size)
  1609.       packetLength = pWindow->data + pWindow->size - packetStart;
  1610.    if (packetLength > 0) {
  1611.       StsRet (ZSendEncodeBytes (pZ, packetStart, packetLength));
  1612.       crc = SendingCrc (packetStart, packetLength, 0);
  1613.    }
  1614.    StsRet (ZSendCrcEscape (pZ, crc, endOfPacket, needAck));
  1615.    if (pZ->debug) {
  1616.       DebugBegin (pZ->debug, debugPacketLowLevel);
  1617.       DebugString (pZ->debug, "Sent file data: ");
  1618.       DebugUInt (pZ->debug, packetLength);
  1619.       DebugString (pZ->debug, " bytes starting at ");
  1620.       DebugIntHex (pZ->debug, pZ->sendPosition);
  1621.       if (endOfPacket)
  1622.          DebugString (pZ->debug, " (packetEnd)");
  1623.       if (needAck)
  1624.          DebugString (pZ->debug, " (needAck)");
  1625.       DebugEnd (pZ->debug);
  1626.    }
  1627.    pZ->sendPosition += packetLength;
  1628.    return zOK;
  1629. }
  1630. STATIC int ZSendFileData
  1631.         (ZMODEM_PRIVATE *pZ, long startPos) {
  1632.    int     err = zTimeout;
  1633.    long    refillInterval = 4096;
  1634.    WINDOW  window;
  1635.    int     retries = pZ->retries;
  1636.    unsigned crcInterval = 1024;
  1637.    unsigned long ackInterval = 8192;
  1638.    unsigned long lastAck = 0;
  1639.    unsigned long burstLength = 0;
  1640.    unsigned long lastBlock = 0;
  1641.    unsigned long windowSize = 0;
  1642.    int     block = FALSE;
  1643.    int     blocked = FALSE;
  1644.    long    lastReposition = 0;
  1645.    int     repositionCount = 0;
  1646.  
  1647.    StsRet (ZInitWindow (pZ, &window, DEFAULT_WINDOW_SIZE, startPos));
  1648.    pZ->sendPosition = startPos;
  1649.    pZ->receivePosition = startPos;
  1650.    windowSize = window.size;
  1651.    ackInterval = ZFileSize (pZ) / 100;
  1652.    if (ackInterval < ACK_INTERVAL_MIN)
  1653.       ackInterval = ACK_INTERVAL_MIN;
  1654.    if (ackInterval > ACK_INTERVAL_MAX)
  1655.       ackInterval = ACK_INTERVAL_MAX;
  1656.    burstLength = pZ->receiverFlags & 0xFFFF;
  1657.    if (HasLimits (pZ->receiverFlags) || !I_CAN_SAMPLE) {
  1658.       if (burstLength == 0)
  1659.          burstLength = HALF_DUPLEX_BURST;
  1660.       ackInterval = burstLength * 2;
  1661.    }
  1662.    crcInterval = 1024;
  1663.    if (crcInterval > ackInterval)
  1664.       crcInterval = ackInterval;
  1665.    while (TRUE) {
  1666.       do {
  1667.          if (pZ->debug) {
  1668.             if (block || blocked) {
  1669.                DebugBegin (pZ->debug, debugPacket);
  1670.                DebugString (pZ->debug, blocked ? "Window blocked"
  1671.                             : "Window set to block");
  1672.                DebugEnd (pZ->debug);
  1673.             }
  1674.          }
  1675.          err = StsWarn (ZReadHeader (pZ, blocked ? pZ->timeout : block ? 2 : 0));
  1676.          switch (err) {
  1677.          case zTimeout:
  1678.             if (blocked)
  1679.                retries--;
  1680.             break;
  1681.          case zBadPacket:
  1682.             block = TRUE;
  1683.             if (blocked)
  1684.                retries--;
  1685.             break;
  1686.          case zOK:
  1687.             retries = pZ->retries;
  1688.             break;
  1689.          default:
  1690.             if (window.data)
  1691.                free (window.data);
  1692.             return StsWarn (err);
  1693.          }
  1694.          if (retries <= 0) {
  1695.             if (window.data)
  1696.                free (window.data);
  1697.             return StsWarn (zFail);
  1698.          }
  1699.          if (err == zOK) {
  1700.             switch (pZ->rxPacketType) {
  1701.             case ZRPOS:
  1702.                if ((pZ->rxPacketArg >= pZ->receivePosition) &&
  1703.                    (pZ->rxPacketArg <= window.endFilePos)) {
  1704.                   pZ->receivePosition = pZ->rxPacketArg;
  1705.                   lastBlock -= (pZ->sendPosition - pZ->rxPacketArg);
  1706.                   CloseDataPacket (pZ);
  1707.                   pZ->sendPosition = pZ->rxPacketArg;
  1708.                   if (pZ->sendPosition == lastReposition)
  1709.                      repositionCount++;
  1710.                   else
  1711.                      repositionCount = 1;
  1712.                   lastReposition = pZ->sendPosition;
  1713.                   if (repositionCount > 4) {
  1714.                      if (crcInterval > 32) {
  1715.                         crcInterval /= 2;
  1716.                         repositionCount = 0;
  1717.                      } else if (repositionCount > pZ->retries) {
  1718.                         if (window.data)
  1719.                            free (window.data);
  1720.                         return StsWarn (zFail);
  1721.                      }
  1722.                   }
  1723.                   block = TRUE;
  1724.                   blocked = FALSE;
  1725.                } else {
  1726.                   block = TRUE;
  1727.                   blocked = FALSE;
  1728.                   DebugBegin (pZ->debug, debugWarn);
  1729.                   DebugString (pZ->debug, "Bogus ZRPOS");
  1730.                   DebugEnd (pZ->debug);
  1731.                }
  1732.                break;
  1733.             case ZACK:
  1734.                if ((pZ->rxPacketArg >= pZ->receivePosition)
  1735.                    && (pZ->rxPacketArg <= window.endFilePos)) {
  1736.                   pZ->receivePosition = pZ->rxPacketArg;
  1737.                   if (pZ->receivePosition == pZ->sendPosition) {
  1738.                      if (blocked)
  1739.                         lastBlock = pZ->sendPosition;
  1740.                      block = blocked = FALSE;
  1741.                   }
  1742.                   if (repositionCount-- < -4) {
  1743.                      crcInterval *= 2;
  1744.                      repositionCount = 0;
  1745.                   }
  1746.                } else {
  1747.                   block = TRUE;
  1748.                   blocked = FALSE;
  1749.                   DebugBegin (pZ->debug, debugWarn);
  1750.                   DebugString (pZ->debug, "Bogus ZACK");
  1751.                   DebugEnd (pZ->debug);
  1752.                }
  1753.                break;
  1754.             case ZRINIT:
  1755.                ZParseZRINIT (pZ, pZ->rxPacketArg);
  1756.                if (window.atEOF
  1757.                    && (pZ->sendPosition >= window.endFilePos)) {
  1758.                   pZ->receivePosition = pZ->sendPosition;
  1759.                   ZProgress (pZ, stsSending);
  1760.                   if (window.data)
  1761.                      free (window.data);
  1762.                   return zOK;
  1763.                } else {
  1764.                   block = TRUE;
  1765.                   blocked = FALSE;
  1766.                   DebugBegin (pZ->debug, debugWarn);
  1767.                   DebugString (pZ->debug, "Bogus ZRINIT");
  1768.                   DebugEnd (pZ->debug);
  1769.                }
  1770.                break;
  1771.             case ZNAK:
  1772.                CloseDataPacket (pZ);
  1773.                pZ->sendPosition = pZ->receivePosition;
  1774.                block = TRUE;
  1775.                blocked = FALSE;
  1776.                break;
  1777.             default:
  1778.                block = TRUE;
  1779.                blocked = FALSE;
  1780.                break;
  1781.             }
  1782.             ZProgress (pZ, stsSending);
  1783.          }
  1784.          if (crcInterval > 1024)
  1785.             crcInterval = 1024;
  1786.          if (crcInterval > ackInterval)
  1787.             crcInterval = ackInterval;
  1788.          if ((burstLength > 0) && (crcInterval > burstLength / 4))
  1789.             crcInterval = burstLength / 4;
  1790.          if (pZ->sendPosition - pZ->receivePosition >= windowSize)
  1791.             block = blocked = TRUE;
  1792.          if ((burstLength > 0)
  1793.              && (pZ->sendPosition + crcInterval > lastBlock + burstLength))
  1794.             block = blocked = TRUE;
  1795.       } while ((err == zOK) || (blocked));
  1796.       if ((!window.atEOF)
  1797.           && (pZ->sendPosition + 1500 > window.endFilePos)
  1798.           && (BufferFree >= refillInterval)) {
  1799.          window.pStart += (pZ->receivePosition - window.startFilePos);
  1800.          if ((window.pStart - window.data) > window.size)
  1801.             window.pStart -= window.size;
  1802.          window.startFilePos = pZ->receivePosition;
  1803.          err = ZSendFillWindow (pZ, &window, refillInterval);
  1804.          if ((err != zEOF) && (err != zOK)) {
  1805.             if (window.data)
  1806.                free (window.data);
  1807.             return StsWarn (err);
  1808.          }
  1809.       }
  1810.       if (window.atEOF && (pZ->sendPosition + crcInterval >= window.endFilePos)) {
  1811.          while (pZ->sendPosition < window.endFilePos)
  1812.             StsRet (ZSendFileDataPacket (pZ, &window, crcInterval, TRUE, FALSE));
  1813.          if (pZ->txPacketType == ZDATA)
  1814.             StsRet (ZSendCrcEscape (pZ, 0, TRUE, FALSE));
  1815.          StsRet (ZSendHeader (pZ, ZEOF, window.endFilePos));
  1816.          block = TRUE;
  1817.       } else {
  1818.          if (pZ->sendPosition + crcInterval - lastAck >= ackInterval) {
  1819.             StsRet (ZSendFileDataPacket (pZ, &window, crcInterval, block, TRUE));
  1820.             lastAck = pZ->sendPosition;
  1821.          } else {
  1822.             StsRet (ZSendFileDataPacket (pZ, &window, crcInterval, block, block));
  1823.             if (block)
  1824.                lastAck = pZ->sendPosition;
  1825.          }
  1826.       }
  1827.       blocked = block;
  1828.    }
  1829. }
  1830. STATIC int ZSendGetZRINIT
  1831.         (ZMODEM_PRIVATE *pZ) {
  1832.    int     timeout = 0;
  1833.    int     retries = pZ->retries;
  1834.    int     err;
  1835.  
  1836.    do {
  1837.       err = ZReadHeader (pZ, timeout);
  1838.       timeout = pZ->timeout;
  1839.       switch (err) {
  1840.       case zOK:
  1841.          if (pZ->rxPacketType == ZRINIT) {
  1842.             ZParseZRINIT (pZ, pZ->rxPacketArg);
  1843.             break;
  1844.          } else
  1845.             err = zBadPacket;
  1846.       case zTimeout:
  1847.       case zBadPacket:
  1848.          StsRet (ZSendHexHeader (pZ, ZRQINIT, pZ->myZrqinitFlags));
  1849.          if (retries-- <= 0)
  1850.             return StsWarn (zFailed);
  1851.          break;
  1852.       default:
  1853.          return StsWarn (err);
  1854.       }
  1855.    } while (err != zOK);
  1856.    return StsWarn (err);
  1857. }
  1858. STATIC int ZSendZSINIT
  1859.         (ZMODEM_PRIVATE *pZ) {
  1860.    int     retries = pZ->retries;
  1861.    int     err;
  1862.  
  1863.    if ((pZ->mySenderFlags == 0) && (ATTENTION == NULL))
  1864.       return zOK;
  1865.    do {
  1866.       StsRet (ZSendHeader (pZ, ZSINIT, pZ->mySenderFlags));
  1867. #ifdef ATTENTION
  1868.       {
  1869.          unsigned long crc;
  1870.  
  1871.          StsRet (ZSendEncodeBytes (pZ, ATTENTION, strlen (ATTENTION)));
  1872.          crc = SendingCrc (ATTENTION, strlen (ATTENTION), 0);
  1873.          StsRet (ZSendCrcEscape (pZ, crc, TRUE, TRUE));
  1874.       }
  1875. #else
  1876.       StsRet (ZSendCrcEscape (pZ, 0, TRUE, TRUE));
  1877. #endif
  1878.       err = ZReadHeader (pZ, pZ->timeout);
  1879.       switch (err) {
  1880.       case zOK:
  1881.          if (pZ->rxPacketType == ZACK)
  1882.             break;
  1883.          else
  1884.             err = zBadPacket;
  1885.       case zTimeout:
  1886.       case zBadPacket:
  1887.          if (retries-- <= 0)
  1888.             return StsWarn (zFail);
  1889.          break;
  1890.       default:
  1891.          return StsWarn (err);
  1892.       }
  1893.    } while (err != zOK);
  1894.    return StsWarn (err);
  1895. }
  1896. STATIC int ZSendEndSession
  1897.         (ZMODEM_PRIVATE *pZ) {
  1898.    int     retries = pZ->retries;
  1899.    int     err;
  1900.  
  1901.    do {
  1902.       StsRet (ZSendHexHeader (pZ, ZFIN, 0));
  1903.       err = ZReadHeader (pZ, pZ->timeout);
  1904.       switch (err) {
  1905.       case zOK:
  1906.          if (pZ->rxPacketType == ZFIN)
  1907.             break;
  1908.          else
  1909.             err = zBadPacket;
  1910.       case zTimeout:
  1911.       case zBadPacket:
  1912.          if (retries-- < 0)
  1913.             return StsWarn (zOK);
  1914.          break;
  1915.       default:
  1916.          return StsWarn (zOK);
  1917.       }
  1918.    } while (err != zOK);
  1919.    ZSendBytes (pZ, (const BYTE *) "OO", 2);
  1920.    return zOK;
  1921. }
  1922. STATIC int ZSendZFile
  1923.         (ZMODEM_PRIVATE *pZ) {
  1924.    const char *fileName = NULL;
  1925.    long    fileSize = -1;
  1926.    int     fileType = diskFileUnknown;
  1927.    long    fileMode = -1;
  1928.    struct tm fileDate;
  1929.    BYTE    data[1024];
  1930.    unsigned length = 128;
  1931.    unsigned long options = pZ->fileFlags;
  1932.    char   *p = (char *) data;
  1933.  
  1934.    if (pZ->f) {
  1935.       DiskFileName (pZ->f, &fileName);
  1936.       fileSize = pZ->fileSize;
  1937.       DiskFileType (pZ->f, &fileType);
  1938.       DiskFileMode (pZ->f, &fileMode);
  1939.       DiskFileDate (pZ->f, &fileDate);
  1940.    }
  1941.    if ((options & CONV_MASK) == 0)
  1942.       if ((fileType == diskFileBinary) || (fileType == diskFileUnknown))
  1943.          if (pZ->crashRecovery)
  1944.             options |= CONV_RESUME;
  1945.          else
  1946.             options |= CONV_BINARY;
  1947.       else
  1948.          options |= CONV_TEXT;
  1949.    StsRet (ZSendHeader (pZ, ZFILE, options));
  1950.    memset (data, 0, sizeof (data));
  1951.    if (fileName && fileName[0]) {
  1952.       strcpy (p, fileName);
  1953.       p += strlen (p) + 1;
  1954.       if (fileSize >= 0) {
  1955.          sprintf (p, "%ld", fileSize);
  1956.          p += strlen (p);
  1957.          sprintf (p, " %lo", ZTime (&(fileDate)));
  1958.          p += strlen (p);
  1959.          if (fileMode >= 0) {
  1960.             sprintf (p, " %lo", fileMode);
  1961.             p += strlen (p);
  1962.          }
  1963.       }
  1964.    }
  1965.    length = p - (char *) data;
  1966.    StsRet (ZSendEncodeBytes (pZ, data, length));
  1967.    {
  1968.       unsigned long crc = SendingCrc (data, length, 0);
  1969.  
  1970.       return StsWarn (ZSendCrcEscape (pZ, crc, TRUE, TRUE));
  1971.    }
  1972. }
  1973. STATIC int ZSendFile
  1974.         (ZMODEM_PRIVATE *pZ) {
  1975.    int     err = zOK;
  1976.    long    startPosition = 0;
  1977.  
  1978.    ZProgress (pZ, stsNewFile);
  1979.    do {
  1980.       StsRet (ZSendZFile (pZ));
  1981.       err = ZReadHeader (pZ, pZ->timeout * 5);
  1982.       if (err == zOK) {
  1983.          switch (pZ->rxPacketType) {
  1984.          case ZSKIP:
  1985.             ZProgress (pZ, stsSkipped);
  1986.             return zOK;
  1987.          case ZRPOS:
  1988.             startPosition = pZ->rxPacketArg;
  1989.             break;
  1990.          case ZCRC:
  1991.             break;
  1992.          case ZRINIT:
  1993.             ZParseZRINIT (pZ, pZ->rxPacketArg);
  1994.             break;
  1995.          case ZNAK:
  1996.             break;
  1997.          default:
  1998.             break;
  1999.          }
  2000.       } else if ((err != zTimeout) && (err != zBadPacket))
  2001.          return StsWarn (err);
  2002.    } while ((err != zOK)
  2003.             || ((pZ->rxPacketType != ZRPOS) && (pZ->rxPacketType != ZCRC)));
  2004.    if (pZ->rxPacketType == ZCRC) {
  2005.       unsigned long crc;
  2006.  
  2007.       err = ZFileCRC (pZ, pZ->rxPacketArg, &crc);
  2008.       if (err == zFail)
  2009.          crc = 0;
  2010.       do {
  2011.          StsRet (ZSendHexHeader (pZ, ZCRC, crc));
  2012.          err = ZReadHeader (pZ, pZ->timeout * 5);
  2013.          if (err == zOK) {
  2014.             switch (pZ->rxPacketType) {
  2015.             case ZSKIP:
  2016.                return zOK;
  2017.             case ZRPOS:
  2018.                startPosition = pZ->rxPacketArg;
  2019.                break;
  2020.             case ZCRC:
  2021.                break;
  2022.             case ZNAK:
  2023.                break;
  2024.             default:
  2025.                break;
  2026.             }
  2027.          } else if ((err != zTimeout) && (err != zBadPacket))
  2028.             return StsWarn (err);
  2029.       } while ((err != zOK) || (pZ->rxPacketType != ZRPOS));
  2030.    }
  2031.    ZProgress (pZ, stsSending);
  2032.    StsRet (ZSendFileData (pZ, startPosition));
  2033.    ZProgress (pZ, stsEOF);
  2034.    return StsWarn (err);
  2035. }
  2036. STATIC int ZReceiveFile
  2037.         (ZMODEM_PRIVATE *pZ, BYTE *buff,
  2038.          unsigned fileInfoLength) {
  2039.    int     err = zOK;
  2040.    unsigned length;
  2041.    int     repositionCount;
  2042.    unsigned long lastReposition;
  2043.  
  2044.    ZNewFile (pZ);
  2045.    pZ->receivePosition = 0;
  2046.    if (pZ->debug) {
  2047.       char   *p = (char *) buff;
  2048.  
  2049.       DebugBegin (pZ->debug, debugPacket);
  2050.       DebugString (pZ->debug, "Read ZFILE Data: options: ");
  2051.       DebugIntHex (pZ->debug, pZ->fileFlags);
  2052.       DebugString (pZ->debug, " filename: ``");
  2053.       DebugString (pZ->debug, p);
  2054.       DebugString (pZ->debug, "'' File attributes: ");
  2055.       DebugString (pZ->debug, p + strlen (p) + 1);
  2056.       DebugEnd (pZ->debug);
  2057.    }
  2058.    err = StsWarn (ZFileWriteOpen (pZ, buff, fileInfoLength));
  2059.    if (err == zSkip) {
  2060.       ZProgress (pZ, stsSkipped);
  2061.       ZSendHexHeader (pZ, ZSKIP, 0);
  2062.       return zOK;
  2063.    }
  2064.    if (err != zOK) {
  2065.       StsWarn (ZSendHexHeader (pZ, ZFERR, 0));
  2066.       return zOK;
  2067.    }
  2068.    StsRet (ZSendHexHeader (pZ, ZRPOS, pZ->receivePosition));
  2069.    ZProgress (pZ, stsNewFile);
  2070.    lastReposition = pZ->receivePosition;
  2071.    repositionCount = 0;
  2072.    while (1) {
  2073.       err = StsWarn (ZReadHeader (pZ, pZ->timeout));
  2074.       if ((err == zTimeout) || (err == zBadPacket)) {
  2075.          ZSendAttention (pZ);
  2076.          ZGobble (pZ, 0);
  2077.          ZSendHexHeader (pZ, ZRPOS, pZ->receivePosition);
  2078.          if (pZ->receivePosition == lastReposition)
  2079.             repositionCount++;
  2080.          else {
  2081.             lastReposition = pZ->receivePosition;
  2082.             repositionCount = 1;
  2083.          }
  2084.       } else if (err != zOK) {
  2085.          return StsWarn (err);
  2086.       } else {
  2087.          switch (pZ->rxPacketType) {
  2088.          case ZFILE:
  2089.             length = 1024;
  2090.             StsWarn (ZReceivePacketData (pZ, buff, &length));
  2091.             ZSendHexHeader (pZ, ZRPOS, pZ->receivePosition);
  2092.             break;
  2093.          case ZEOF:
  2094.             if (pZ->rxPacketArg == pZ->receivePosition) {
  2095.                ZProgress (pZ, stsEOF);
  2096.                StsRet (ZFileWriteClose (pZ));
  2097.                ZSendHexHeader (pZ, ZRINIT, pZ->myReceiverFlags);
  2098.                return zOK;
  2099.             } else {
  2100.                ZSendHexHeader (pZ, ZRPOS, pZ->receivePosition);
  2101.                if (pZ->receivePosition == lastReposition)
  2102.                   repositionCount++;
  2103.                else {
  2104.                   lastReposition = pZ->receivePosition;
  2105.                   repositionCount = 1;
  2106.                }
  2107.             }
  2108.             break;
  2109.          case ZDATA:
  2110.             pZ->sendPosition = pZ->rxPacketArg;
  2111.             err = StsWarn (ZReceiveStream (pZ, buff));
  2112.             if (err == zOK)
  2113.                break;
  2114.             if ((err != zBadPacket) && (err != zTimeout))
  2115.                return StsWarn (err);
  2116.             ZSendAttention (pZ);
  2117.          default:
  2118.             ZGobble (pZ, 0);
  2119.             ZSendHexHeader (pZ, ZRPOS, pZ->receivePosition);
  2120.             if (pZ->receivePosition == lastReposition)
  2121.                repositionCount++;
  2122.             else {
  2123.                lastReposition = pZ->receivePosition;
  2124.                repositionCount = 1;
  2125.             }
  2126.             break;
  2127.          }
  2128.       }
  2129.       if (repositionCount > 2 * pZ->retries) {
  2130.          if (pZ->debug) {
  2131.             DebugBegin (pZ->debug, debugWarn);
  2132.             DebugString (pZ->debug, "No progress, terminating transfer...");
  2133.             DebugEnd (pZ->debug);
  2134.          }
  2135.          return StsWarn (zFail);
  2136.       }
  2137.    }
  2138. }
  2139. STATIC int ZSendFiles
  2140.         (ZMODEM_PRIVATE *pZ) {
  2141.    int     err = zOK;
  2142.  
  2143.    ZNewFile (pZ);
  2144.    ZProgress (pZ, stsNegotiating);
  2145.    ZSendBytes (pZ, (const BYTE *) "rz\r", 3);
  2146.    err = ZSendGetZRINIT (pZ);
  2147.    if (err == zOK)
  2148.       err = ZSendZSINIT (pZ);
  2149.    while (err == zOK) {
  2150.       err = ZFileReadOpenNext (pZ, pZ->fileType);
  2151.       if (err == zOK) {
  2152.          err = ZSendFile (pZ);
  2153.          ZFileReadClose (pZ);
  2154.          ZNewFile (pZ);
  2155.       }
  2156.    }
  2157.    ZProgress (pZ, stsEnding);
  2158.    if (err == zEndOfSession)
  2159.       err = ZSendEndSession (pZ);
  2160.    if (err == zFail) {
  2161.       ZSendHeader (pZ, ZCAN, 0);
  2162.       ZGobble (pZ, 2);
  2163.       err = zFailed;
  2164.    }
  2165.    if (err == zOK)
  2166.       ZProgress (pZ, stsDone);
  2167.    else if (pZ->userCancel)
  2168.       ZProgress (pZ, stsCancelled);
  2169.    else
  2170.       ZProgress (pZ, stsFailed);
  2171.    return StsWarn (err);
  2172. }
  2173. STATIC int ZReceive
  2174.         (ZMODEM_PRIVATE *pZ) {
  2175.    BYTE    buff[1200];
  2176.    int     retries = pZ->retries;
  2177.    int     err;
  2178.  
  2179.    err = ZSendZRINIT (pZ);
  2180.    while (err == zOK) {
  2181.       ZProgress (pZ, stsNegotiating);
  2182.       err = ZReadHeader (pZ, pZ->timeout);
  2183.       if ((err == zTimeout) || (err == zBadPacket)) {
  2184.          retries--;
  2185.          if (retries == 0)
  2186.             err = zFail;
  2187.          else
  2188.             err = ZSendZRINIT (pZ);
  2189.       } else if (err == zOK) {
  2190.          retries = pZ->retries;
  2191.          switch (pZ->rxPacketType) {
  2192.          case ZRQINIT:
  2193.             err = ZSendZRINIT (pZ);
  2194.             break;
  2195.          case ZRINIT:
  2196.             err = ZGobble (pZ, 2);
  2197.             break;
  2198.          case ZSINIT:
  2199.             ZParseZSINIT (pZ, pZ->rxPacketArg);
  2200.             err = ZSendHexHeader (pZ, ZACK, 0);
  2201.             break;
  2202.          case ZFILE:
  2203.             pZ->fileFlags = pZ->rxPacketArg;
  2204.             {
  2205.                unsigned length;
  2206.  
  2207.                err = ZReceivePacketData (pZ, buff, &length);
  2208.                if (err == zOK)
  2209.                   err = ZReceiveFile (pZ, buff, length);
  2210.                else
  2211.                   err = ZSendZRINIT (pZ);
  2212.             }
  2213.             break;
  2214.          case ZEOF:
  2215.             err = ZSendZRINIT (pZ);
  2216.             break;
  2217.          case ZFREECNT:
  2218.             {
  2219.                unsigned long freeCount = 0;
  2220.  
  2221.                StsRet (ZFileSystemFree (pZ, &freeCount));
  2222.                err = ZSendHexHeader (pZ, ZACK, freeCount);
  2223.             }
  2224.             break;
  2225.          case ZCOMMAND:
  2226.             {
  2227.                unsigned length;
  2228.                unsigned completion = 0;
  2229.  
  2230.                err = ZReceivePacketData (pZ, buff, &length);
  2231.                if (err == zOK) {
  2232.                   char   *command = (char *) buff;
  2233.  
  2234.                   command[length] = 0;
  2235.                   {
  2236.                      if (pZ->rxPacketArg & (0x01000000)) {
  2237.                         if (pZ->debug) {
  2238.                            DebugBegin (pZ->debug, debugPacket);
  2239.                            DebugString (pZ->debug, "Immediate command: ");
  2240.                            DebugString (pZ->debug, command);
  2241.                            DebugEnd (pZ->debug);
  2242.                         }
  2243.                      } else {
  2244.                         if (pZ->debug) {
  2245.                            DebugBegin (pZ->debug, debugPacket);
  2246.                            DebugString (pZ->debug, "Normal command: ");
  2247.                            DebugString (pZ->debug, command);
  2248.                            DebugEnd (pZ->debug);
  2249.                         }
  2250.                         if (command[0] == '!') {
  2251.                            completion = system (command + 1);
  2252.                         } else {
  2253.                            if ((command[0] == 's') && (command[1] == 'z') && (command[2] == ' ')) {
  2254.                               char   *p = command + 2;
  2255.                               char   *names[32];
  2256.                               int     numberNames = 0;
  2257.  
  2258.                               while (*p) {
  2259.                                  while (IsWhitespace (*p))
  2260.                                     p++;
  2261.                                  if (*p)
  2262.                                     names[numberNames++] = p;
  2263.                                  while (*p && !IsWhitespace (*p))
  2264.                                     p++;
  2265.                                  if (*p)
  2266.                                     *p++ = 0;
  2267.                               }
  2268.                               err = ZModemSend ((ZMODEM) pZ, (const char **) names, numberNames);
  2269.                               if (err)
  2270.                                  completion = 1;
  2271.                               else
  2272.                                  completion = 0;
  2273.                            } else {
  2274.                               completion = 1;
  2275.                            }
  2276.                         }
  2277.                      }
  2278.                   }
  2279.                } else if ((err == zTimeout) || (err == zBadPacket)) {
  2280.                   err = ZSendHexHeader (pZ, ZNAK, 0);
  2281.                   break;
  2282.                } else
  2283.                   return StsWarn (err);
  2284.                ZGobble (pZ, 0);
  2285.                do {
  2286.                   StsRet (ZSendHexHeader (pZ, ZCOMPL, completion));
  2287.                   err = ZReadHeader (pZ, pZ->timeout);
  2288.                   if ((err != zOK) && (err != zBadPacket) && (err != zTimeout))
  2289.                      return StsWarn (err);
  2290.                } while ((err != zOK) || (pZ->rxPacketType != ZFIN));
  2291.             }
  2292.          case ZFIN:
  2293.             err = ZSendHexHeader (pZ, ZFIN, 0);
  2294.             {
  2295.                BYTE    overAndOut;
  2296.                int     oCount = 0;
  2297.  
  2298.                while (err == zOK) {
  2299.                   err = ZReadByteWithTimeout (pZ, pZ->timeout,
  2300.                                               &overAndOut);
  2301.                   if (err == zTimeout)
  2302.                      err = zEndOfSession;
  2303.                   else if (err == zOK) {
  2304.                      if (overAndOut == 'O') {
  2305.                         if (++oCount >= 2)
  2306.                            err = zEndOfSession;
  2307.                      } else if (overAndOut == '*')
  2308.                         break;
  2309.                      else
  2310.                         oCount = 0;
  2311.                   } else if (err == zBadPacket) {
  2312.                      err = zOK;
  2313.                   } else
  2314.                      return StsWarn (err);
  2315.                }
  2316.             }
  2317.             break;
  2318.          case ZCAN:
  2319.             err = zFailed;
  2320.             break;
  2321.          case ZABORT:
  2322.             err = zFail;
  2323.             break;
  2324.          default:
  2325.             err = ZSendHexHeader (pZ, ZNAK, 0);
  2326.             break;
  2327.          }
  2328.       }
  2329.    }
  2330.    if (err == zEndOfSession)
  2331.       err = zOK;
  2332.    if (err == zFail) {
  2333.       ZSendHeader (pZ, ZCAN, 0);
  2334.       ZGobble (pZ, 2);
  2335.       err = zFailed;
  2336.    }
  2337.    if (err == zOK)
  2338.       ZProgress (pZ, stsDone);
  2339.    else if (pZ->userCancel)
  2340.       ZProgress (pZ, stsCancelled);
  2341.    else
  2342.       ZProgress (pZ, stsFailed);
  2343.    return StsWarn (err);
  2344. }
  2345. STATIC int ZSendZCommand
  2346.         (ZMODEM_PRIVATE *pZ, int immediate, const char *cmd) {
  2347.    int     err;
  2348.    int     retries = pZ->retries;
  2349.    size_t  cmdLength = strlen (cmd) + 1;
  2350.    unsigned long crc = SendingCrc ((const BYTE *) cmd, cmdLength, 0);
  2351.  
  2352.    do {
  2353.       StsRet (ZSendHeader (pZ, ZCOMMAND, (immediate) ? 1U : 0U));
  2354.       StsRet (ZSendEncodeBytes (pZ, (const BYTE *) cmd, cmdLength));
  2355.       StsRet (ZSendCrcEscape (pZ, crc, TRUE, TRUE));
  2356.       err = ZReadHeader (pZ, (immediate) ? (pZ->timeout) : (pZ->timeout * 5));
  2357.       if ((err == zTimeout) || (err == zBadPacket)) {
  2358.          retries--;
  2359.          if (retries == 0)
  2360.             return StsWarn (zFail);
  2361.       } else if (err != zOK)
  2362.          return StsWarn (err);
  2363.       else {
  2364.          retries = pZ->retries;
  2365.          switch (pZ->rxPacketType) {
  2366.          case ZCOMPL:
  2367.             return zEndOfSession;
  2368.          case ZRINIT:
  2369.             break;
  2370.          case ZNAK:
  2371.             break;
  2372.          case ZRQINIT:
  2373.             if ((pZ->rxPacketArg >> 24) & 0xFF == ZCOMMAND) {
  2374.                StsRet (ZSendHeader (pZ, ZNAK, 0));
  2375.             } else {
  2376.                int     packetType = pZ->rxPacketType;
  2377.                int     packetArg = pZ->rxPacketArg;
  2378.  
  2379.                err = ZReceive (pZ);
  2380.                pZ->rxPacketType = packetType;
  2381.                pZ->rxPacketArg = packetArg;
  2382.                if (err != zOK)
  2383.                   return StsWarn (err);
  2384.                ZProgress (pZ, stsEnding);
  2385.             }
  2386.             break;
  2387.          default:
  2388.             if (pZ->debug) {
  2389.                DebugBegin (pZ->debug, debugWarn);
  2390.                DebugString (pZ->debug, "Unexpected response to ZCOMMAND :");
  2391.                DebugPacket (pZ->debug, pZ->rxPacketType, pZ->rxPacketArg);
  2392.                DebugEnd (pZ->debug);
  2393.             }
  2394.             break;
  2395.          }
  2396.       }
  2397.    } while ((err != zOK) || (pZ->rxPacketType != ZRQINIT));
  2398.    while (TRUE) {
  2399.       err = ZReadHeader (pZ, (immediate) ? (pZ->timeout) : (pZ->timeout * 5));
  2400.       if ((err == zTimeout) || (err == zBadPacket)) {
  2401.          retries--;
  2402.          if (retries == 0)
  2403.             return StsWarn (zFail);
  2404.       } else if (err != zOK)
  2405.          return StsWarn (err);
  2406.       else {
  2407.          retries = pZ->retries;
  2408.          switch (pZ->rxPacketType) {
  2409.          case ZCOMPL:
  2410.             return zEndOfSession;
  2411.          case ZFIN:
  2412.             StsRet (ZSendHexHeader (pZ, ZFIN, 0));
  2413.             break;
  2414.          default:
  2415.             if (pZ->debug) {
  2416.                DebugBegin (pZ->debug, debugWarn);
  2417.                DebugString (pZ->debug,
  2418.                             "Unexpected packet after recursive receive:");
  2419.                DebugPacket (pZ->debug, pZ->rxPacketType, pZ->rxPacketArg);
  2420.                DebugEnd (pZ->debug);
  2421.             }
  2422.             break;
  2423.          }
  2424.       }
  2425.    }
  2426. }
  2427. STATIC int ZSendCommand
  2428.         (ZMODEM_PRIVATE *pZ, int immediate, const char *cmd) {
  2429.    int     err = zOK;
  2430.  
  2431.    pZ->myZrqinitFlags = ZCOMMAND << 24;
  2432.    ZNewFile (pZ);
  2433.    ZProgress (pZ, stsNegotiating);
  2434.    ZSendBytes (pZ, (const BYTE *) "rz\r", 3);
  2435.    err = ZSendGetZRINIT (pZ);
  2436.    if (err == zOK)
  2437.       err = ZSendZSINIT (pZ);
  2438.    err = ZSendZCommand (pZ, immediate, cmd);
  2439.    ZProgress (pZ, stsEnding);
  2440.    if (err == zEndOfSession)
  2441.       err = ZSendEndSession (pZ);
  2442.    if (err == zFail) {
  2443.       ZSendHeader (pZ, ZCAN, 0);
  2444.       ZGobble (pZ, 2);
  2445.       err = zFailed;
  2446.    }
  2447.    if (err == zOK)
  2448.       ZProgress (pZ, stsDone);
  2449.    else if (pZ->userCancel)
  2450.       ZProgress (pZ, stsCancelled);
  2451.    else
  2452.       ZProgress (pZ, stsFailed);
  2453.    return StsWarn (err);
  2454. }
  2455. int     ZModemInit
  2456.         (ZMODEM *ppZ, SERIAL_PORT port) {
  2457.    ZMODEM_PRIVATE *pZ;
  2458.  
  2459.    pZ = malloc (sizeof (*pZ));
  2460.    if (pZ == NULL)
  2461.       return 1;
  2462.    memset (pZ, 0, sizeof (*pZ));
  2463.    pZ->crc32 = FALSE;
  2464.    pZ->timeout = 10;
  2465.    pZ->retries = 10;
  2466.    pZ->userCancel = FALSE;
  2467.    pZ->attention[0] = 0;
  2468.    pZ->senderFlags = 0;
  2469.    pZ->zrqinitFlags = 0;
  2470.    pZ->receiverFlags = 0;
  2471.    pZ->myZrqinitFlags = 0;
  2472.    pZ->mySenderFlags = 0;
  2473.    pZ->myReceiverFlags = KNOW_CRC32;
  2474. #if I_CAN_FULL_DUPLEX
  2475.    pZ->myReceiverFlags |= CAN_FULL_DUPLEX;
  2476. #endif
  2477. #if I_CAN_OVERLAP_DISK
  2478.    pZ->myReceiverFlags |= CAN_OVERLAP_DISK;
  2479. #endif
  2480. #if I_CAN_SEND_BREAK
  2481.    pZ->myReceiverFlags |= CAN_SEND_BREAK;
  2482. #endif
  2483.    pZ->fileFlags = 0;
  2484.    {
  2485.       memset (pZ->classify, 0, sizeof (pZ->classify));
  2486.       SetEncode (CAN);
  2487.       SetEncode (XON);
  2488.       SetEncode (XON | 0x80);
  2489.       SetEncode (XOFF);
  2490.       SetEncode (XOFF | 0x80);
  2491.       SetEncode (DLE);
  2492.       SetEncode (DLE | 0x80);
  2493.       SetIgnore (XON);
  2494.       SetIgnore (XON | 0x80);
  2495.       SetIgnore (XOFF);
  2496.       SetIgnore (XOFF | 0x80);
  2497.    }
  2498.    pZ->sendingCrc32 = FALSE;
  2499.    pZ->txPacketType = -1;
  2500.    pZ->receivingCrc32 = FALSE;
  2501.    pZ->rxPacketType = -1;
  2502.    pZ->rxPacketArg = 0;
  2503.    pZ->sendPosition = 0;
  2504.    pZ->receivePosition = 0;
  2505.    pZ->debug = NULL;
  2506.    ZInitCrc ();
  2507.    pZ->port = NULL;
  2508.    pZ->serialBuffer = malloc (256);
  2509.    if (pZ->serialBuffer == NULL)
  2510.       return 1;
  2511.    pZ->serialBufferSize = 256;
  2512.    pZ->serialBufferRead = pZ->serialBuffer;
  2513.    pZ->serialBufferLimit = pZ->serialBuffer;
  2514.    pZ->f = NULL;
  2515.    pZ->fileSize = -1;
  2516.    pZ->filenames = NULL;
  2517.    pZ->currentFileName = 0;
  2518.    pZ->numFileNames = 0;
  2519.    pZ->fileType = diskFileUnknown;
  2520.    pZ->progress = NULL;
  2521.    {
  2522.       int     i;
  2523.  
  2524.       for (i = 0x40; i < 0x60; i++)
  2525.          SetDecode (i);
  2526.       for (i = 0xc0; i < 0xe0; i++)
  2527.          SetDecode (i);
  2528.       SetDecode ('l');
  2529.       SetDecode ('m');
  2530.    }
  2531.    {
  2532.       int     i;
  2533.  
  2534.       for (i = 0; i < 256; i++)
  2535.          zDecode[i] = 0;
  2536.       for (i = 0x40; i < 0x60; i++)
  2537.          zDecode[i] = i & 0xBF;
  2538.       for (i = 0xc0; i < 0xe0; i++)
  2539.          zDecode[i] = i & 0xBF;
  2540.       zDecode['l'] = 0x7F;
  2541.       zDecode['m'] = 0xFF;
  2542.    }
  2543.    pZ->noiseLimit = 25000;
  2544.    pZ->crashRecovery = FALSE;
  2545.    pZ->port = port;
  2546.    *ppZ = pZ;
  2547.    return 0;
  2548. }
  2549. int     ZModemDestroy
  2550.         (ZMODEM zPublic) {
  2551.    ZMODEM_PRIVATE *pZ = (ZMODEM_PRIVATE *) zPublic;
  2552.  
  2553.    if (pZ->serialBuffer)
  2554.       free (pZ->serialBuffer);
  2555.    free (zPublic);
  2556.    return zOK;
  2557. }
  2558. int     ZModemSetDebug
  2559.         (ZMODEM zPublic, DEBUG debug) {
  2560.    ZMODEM_PRIVATE *pZ = (ZMODEM_PRIVATE *) zPublic;
  2561.  
  2562.    pZ->debug = debug;
  2563.    return zOK;
  2564. }
  2565. int     ZModemSetProgress
  2566.         (ZMODEM zPublic, PROGRESS progress) {
  2567.    ZMODEM_PRIVATE *pZ = (ZMODEM_PRIVATE *) zPublic;
  2568.  
  2569.    pZ->progress = progress;
  2570.    return zOK;
  2571. }
  2572. int     ZModemSetFileType
  2573.         (ZMODEM zPublic, int fileType) {
  2574.    ZMODEM_PRIVATE *pZ = (ZMODEM_PRIVATE *) zPublic;
  2575.  
  2576.    pZ->fileType = fileType;
  2577.    return zOK;
  2578. }
  2579. int     ZModemCancel
  2580.         (ZMODEM zPublic) {
  2581.    ZMODEM_PRIVATE *pZ = (ZMODEM_PRIVATE *) zPublic;
  2582.  
  2583.    pZ->userCancel = TRUE;
  2584.    return zOK;
  2585. }
  2586. int     ZModemReceive
  2587.         (ZMODEM zPublic) {
  2588.    ZMODEM_PRIVATE *pZ = (ZMODEM_PRIVATE *) zPublic;
  2589.    int     returnVal = 0;
  2590.  
  2591.    ProgressReceiving (pZ->progress);
  2592.    if (ZReceive (pZ) != zOK)
  2593.       returnVal = 1;
  2594.    return returnVal;
  2595. }
  2596. int     ZModemSend
  2597.         (ZMODEM zPublic, const char *filenames[], int count) {
  2598.    ZMODEM_PRIVATE *pZ = (ZMODEM_PRIVATE *) zPublic;
  2599.    int     returnVal = 0;
  2600.  
  2601.    pZ->currentFileName = 0;
  2602.    pZ->filenames = filenames;
  2603.    pZ->numFileNames = count;
  2604.    ProgressSending (pZ->progress);
  2605.    if (ZSendFiles (pZ) != zOK)
  2606.       returnVal = 1;
  2607.    return returnVal;
  2608. }
  2609. int     ZModemSendCommand
  2610.         (ZMODEM zPublic, const char *command) {
  2611.    ZMODEM_PRIVATE *pZ = (ZMODEM_PRIVATE *) zPublic;
  2612.    int     returnVal = 0;
  2613.  
  2614.    ProgressSending (pZ->progress);
  2615.    if (ZSendCommand (pZ, 0, command) != zOK)
  2616.       returnVal = 1;
  2617.    return returnVal;
  2618. }
  2619.