home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / xyz.lzh / ftk.c < prev    next >
Text File  |  1995-08-18  |  79KB  |  2,517 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 StsRet(expr)do{int tmpErrorVal= (expr); \
  52. if(tmpErrorVal!=kOK)return StsWarn(tmpErrorVal); \
  53. }while(FALSE)
  54. #define StsWarn(s)((pK->debug)?KDebugWarn(pK,(s),__FILE__,__LINE__):(s))
  55. #define debugWarn (1)
  56. #define debugPacket (2)
  57. #define debugPacketErr (4)
  58. #define debugPacketLowLevel (8)
  59. #define debugCache (16)
  60. #define debugAttr (32)
  61. #define debugInit (64)
  62. #define debugEncoding (256)
  63. #define FILE_BUFFER_SIZE (8000)
  64. #define SetControl(b)(pK->classify[b]|= 1)
  65. #define NeedsControl(b)(pK->classify[b]&1)
  66. #define SwapSlots(p1,p2){ \
  67. EXCHANGE e= pK->exchange[(p1)&63]; \
  68. pK->exchange[(p1)&63]= pK->exchange[(p2)&63]; \
  69. pK->exchange[(p2)&63]= e; \
  70. }
  71. #define MALLOC_LIMIT (300000)
  72. #include "ftdisk.h"
  73. #include "ftserial.h"
  74. #include "ftdebug.h"
  75. #include "ftprog.h"
  76. #include "ftk.h"
  77. #include <stddef.h>
  78. size_t  strlen (const char *s1);
  79. void   *memset (void *, int, size_t);
  80. void   *memcpy (void *, const void *, size_t);
  81. void   *malloc (size_t);
  82. void    free (void *);
  83.  
  84. #ifndef TRUE
  85. #define TRUE 1
  86. #endif
  87. #ifndef FALSE
  88. #define FALSE 0
  89. #endif
  90. #ifndef NULL
  91. #define NULL  ((void *)0)
  92. #endif
  93. #define STATIC
  94. typedef unsigned char BYTE;
  95. typedef struct {
  96.    BYTE   *myPacket;
  97.    BYTE   *yourPacket;
  98.    unsigned long myPacketLength;
  99.    unsigned long yourPacketLength;
  100.    long    sequence;
  101.    char    packetCheck;
  102.    BYTE    myPacketType;
  103.    BYTE    yourPacketType;
  104. } EXCHANGE;
  105. typedef struct {
  106.    int     sending;
  107.    int     userCancel;
  108.    DEBUG   debug;
  109.    SERIAL_PORT port;
  110.    DISKFILE f;
  111.    long    fileSize;
  112.    const char **filenames;
  113.    int     currentFileName;
  114.    int     numFileNames;
  115.    int     fileType;
  116.    PROGRESS progress;
  117.    unsigned long filePosition;
  118.    BYTE   *pFileBuffer;
  119.    int     fileBufferSize;
  120.    BYTE   *pFileThisChar;
  121.    BYTE   *pFileBufferLimit;
  122.    int     eofFlag;
  123.    int     lockingShift;
  124.    char    classify[256];
  125.    unsigned char encode[256];
  126.    unsigned char decode[256];
  127.    int     repeatStart;
  128.    int     repeatEnd;
  129.    int     num8bit;
  130.    BYTE    repeatByte[6];
  131.    int     repeatCount[6];
  132.    int     lockingFlip;
  133.    int     quoteNext;
  134.    char    packetCheck;
  135.    EXCHANGE exchange[64];
  136.    BYTE   *txPacket;
  137.    unsigned long txPacketLength;
  138.    BYTE   *rxPacket;
  139.    unsigned long rxPacketLength;
  140.    int     rxPacketSequence;
  141.    BYTE    rxPacketType;
  142.    int     currentWindowSize;
  143.    int     windowSize;
  144.    int     minCache;
  145.    int     maxUsed;
  146.    int     minUsed;
  147.    int     sequence;
  148.    int     retries;
  149.    BYTE   *rawBuffer;
  150.    long    rawBufferLength;
  151.    long    rawBufferPacketSize;
  152.    EXCHANGE spareExchange;
  153.    int     serverMode;
  154.    struct {
  155.       BYTE    prefixControl;
  156.       BYTE    prefix8bit;
  157.       BYTE    prefixRepeat;
  158.       char    preferredPacketCheck;
  159.       BYTE    sopCharacter;
  160.       long    maxPacketSize;
  161.       int     timeout;
  162.       int     padCount;
  163.       BYTE    padByte;
  164.       BYTE    packetTerminator;
  165.       BYTE    capabilities[5];
  166.    } my   , your;
  167. } KERMIT_PRIVATE;
  168. enum {
  169.    kOK = 0,
  170.    kFail,
  171.    kFailed,
  172.    kBadPacket,
  173.    kEndOfSession,
  174.    kEOF,
  175.    kTimeout
  176. };
  177. STATIC int KDebugWarn
  178.         (KERMIT_PRIVATE *pK, const int s, const char *file, const int line) {
  179.    const char *msg = NULL;
  180.  
  181.    if (s != kOK) {
  182.       DebugBeginInternal (pK->debug, debugWarn, file, line);
  183.       DebugString (pK->debug, "?!?!?!:");
  184.    }
  185.    switch (s) {
  186.    case kOK:
  187.       return kOK;
  188.    case kFail:
  189.       msg = "kFail";
  190.       break;
  191.    case kFailed:
  192.       msg = "kFailed";
  193.       break;
  194.    case kBadPacket:
  195.       msg = "kBadPacket";
  196.       break;
  197.    case kEndOfSession:
  198.       msg = "kEndOfSession";
  199.       break;
  200.    case kEOF:
  201.       msg = "kEOF";
  202.       break;
  203.    case kTimeout:
  204.       msg = "kTimeout";
  205.       break;
  206.    }
  207.    if (msg != NULL)
  208.       DebugString (pK->debug, msg);
  209.    else {
  210.       DebugString (pK->debug, "Error ");
  211.       DebugInt (pK->debug, s);
  212.    }
  213.    DebugEnd (pK->debug);
  214.    return s;
  215. }
  216. STATIC unsigned short int kCrc16Table[256];
  217. STATIC void KInitCrc
  218.         (void) {
  219.    static int crcDone = 0;
  220.    unsigned long i, j, crc;
  221.  
  222.    if (crcDone)
  223.       return;
  224.    for (i = 0; i < 256; i++) {
  225.       crc = i;
  226.       for (j = 0; j < 8; j++)
  227.          crc = (crc >> 1) ^ ((crc & 1) ? 0x8408 : 0);
  228.       kCrc16Table[i] = crc & 0xffff;
  229.    }
  230.    crcDone = 1;
  231. }
  232. STATIC unsigned short KCrc16
  233.         (const BYTE *buff, unsigned int length,
  234.          unsigned short crc) {
  235.    const BYTE *p = buff;
  236.  
  237.    while (length-- > 0)
  238.       crc = kCrc16Table[(crc ^ *p++) & 0xff] ^ (crc >> 8);
  239.    return crc & 0xffff;
  240. }
  241. STATIC int KReadBytesWithTimeout
  242.         (KERMIT_PRIVATE *pK, int timeout,
  243.          BYTE *pBuffer, unsigned long *pLength) {
  244.    int     s, returnVal = kOK;
  245.  
  246.    s = SerialReadWithTimeout (pK->port, timeout, pBuffer, pLength);
  247.    switch (s) {
  248.    case serialOK:
  249.       returnVal = kOK;
  250.       break;
  251.    case serialTimeout:
  252.       returnVal = kTimeout;
  253.       break;
  254.    case serialUserCancel:
  255.       pK->userCancel = TRUE;
  256.       returnVal = kFail;
  257.       break;
  258.    case serialFrame:
  259.       returnVal = kBadPacket;
  260.       break;
  261.    default:
  262.       return StsWarn (kFailed);
  263.    }
  264.    if (pK->userCancel)
  265.       return StsWarn (kFail);
  266.    return returnVal;
  267. }
  268. STATIC int KSendBytes
  269.         (KERMIT_PRIVATE *pK, const BYTE *pBuffer,
  270.          unsigned int length) {
  271.    int     s, returnVal;
  272.  
  273.    if (length == 0)
  274.       return kOK;
  275.    s = SerialSend (pK->port, pBuffer, length);
  276.    switch (s) {
  277.    case serialOK:
  278.       returnVal = kOK;
  279.       break;
  280.    case serialUserCancel:
  281.       pK->userCancel = TRUE;
  282.       returnVal = kFail;
  283.       break;
  284.    default:
  285.       return StsWarn (kFailed);
  286.    }
  287.    if (pK->userCancel)
  288.       return StsWarn (kFail);
  289.    return StsWarn (returnVal);
  290. }
  291. STATIC int KWaitForSentBytes
  292.         (KERMIT_PRIVATE *pK) {
  293.    int     s, returnVal;
  294.  
  295.    if (pK->userCancel)
  296.       return StsWarn (kFail);
  297.    s = SerialWaitForSentBytes (pK->port);
  298.    switch (s) {
  299.    case serialOK:
  300.       returnVal = kOK;
  301.       break;
  302.    case serialUserCancel:
  303.       pK->userCancel = TRUE;
  304.       returnVal = StsWarn (kFail);
  305.       break;
  306.    default:
  307.       return StsWarn (kFailed);
  308.    }
  309.    if (pK->userCancel)
  310.       return StsWarn (kFail);
  311.    return StsWarn (returnVal);
  312. }
  313. STATIC int KSendByte
  314.         (KERMIT_PRIVATE *pK, BYTE b) {
  315.    return StsWarn (KSendBytes (pK, &b, 1));
  316. }
  317. STATIC int KReadByteWithTimeout
  318.         (KERMIT_PRIVATE *pK, int timeout, BYTE *pByte) {
  319.    unsigned long count = 1;
  320.  
  321.    return KReadBytesWithTimeout (pK, timeout, pByte, &count);
  322. }
  323. STATIC int KFileReadOpenNext
  324.         (KERMIT_PRIVATE *pK, int fileType) {
  325.    while (1) {
  326.       if (pK->currentFileName == pK->numFileNames)
  327.          return kEndOfSession;
  328.       switch (DiskReadOpen (&pK->f, pK->filenames[pK->currentFileName++],
  329.                             fileType)) {
  330.       case diskOK:
  331.          DiskFileSize (pK->f, &(pK->fileSize));
  332.          return kOK;
  333.       case diskCantRead:
  334.       case diskNoSuchFile:
  335.          break;
  336.       default:
  337.          return StsWarn (kFail);
  338.       }
  339.    }
  340. }
  341. STATIC int KFileRead
  342.         (KERMIT_PRIVATE *pK, BYTE *pBuffer,
  343.          unsigned long *pLength) {
  344.    int     returnVal;
  345.  
  346.    switch (DiskRead (pK->f, pBuffer, *pLength, pLength)) {
  347.    case diskOK:
  348.       returnVal = kOK;
  349.       break;
  350.    case diskEOF:
  351.       returnVal = kEOF;
  352.       break;
  353.    default:
  354.       returnVal = StsWarn (kFail);
  355.       break;
  356.    }
  357.    return returnVal;
  358. }
  359. STATIC int KFileReadClose
  360.         (KERMIT_PRIVATE *pK) {
  361.    int     returnVal;
  362.  
  363.    switch (DiskReadClose (pK->f)) {
  364.    case diskOK:
  365.       returnVal = kOK;
  366.       break;
  367.    default:
  368.       returnVal = StsWarn (kFail);
  369.       break;
  370.    }
  371.    pK->f = NULL;
  372.    return returnVal;
  373. }
  374. STATIC int KFileWriteOpen
  375.         (KERMIT_PRIVATE *pK,
  376.          const char *fileName, int length, int fileType) {
  377.    ((void) length);
  378.    pK->fileSize = -1;
  379.    if (DiskWriteInit (&pK->f, pK->debug))
  380.       return StsWarn (kFail);
  381.    if (DiskWriteName (pK->f, fileName))
  382.       return StsWarn (kFail);
  383.    if (DiskWriteType (pK->f, fileType))
  384.       return StsWarn (kFail);
  385.    if (DiskWriteOpen (pK->f))
  386.       return StsWarn (kFail);
  387.    return kOK;
  388. }
  389. STATIC int KFileWrite
  390.         (KERMIT_PRIVATE *pK, const BYTE *pBuffer,
  391.          unsigned long length) {
  392.    switch (DiskWrite (pK->f, pBuffer, length)) {
  393.    case diskOK:
  394.       return kOK;
  395.    default:
  396.       return StsWarn (kFail);
  397.    }
  398. }
  399. STATIC int KFileWriteClose
  400.         (KERMIT_PRIVATE *pK) {
  401.    int     returnVal;
  402.  
  403.    switch (DiskWriteClose (pK->f)) {
  404.    case diskOK:
  405.       returnVal = kOK;
  406.       break;
  407.    default:
  408.       returnVal = StsWarn (kFail);
  409.       break;
  410.    }
  411.    pK->f = NULL;
  412.    return returnVal;
  413. }
  414. enum {
  415.    stsNegotiating = progNegotiating,
  416.    stsNewFile = progNewFile,
  417.    stsSending = progSending,
  418.    stsReceiving = progReceiving,
  419.    stsEnding = progEnding,
  420.    stsEOF = progEOF,
  421.    stsDone = progDone,
  422.    stsSkipped = progSkipped,
  423.    stsFailed = progFailed,
  424.    stsCancelled = progCancelled
  425. };
  426. STATIC void KProgress
  427.         (KERMIT_PRIVATE *pK, int status) {
  428.    if (pK->f) {
  429.       const char *fileName = NULL;
  430.       int     fileType = diskFileUnknown;
  431.  
  432.       DiskFileName (pK->f, &fileName);
  433.       ProgressFileName (pK->progress, fileName);
  434.       DiskFileType (pK->f, &fileType);
  435.       ProgressFileType (pK->progress, fileType);
  436.    } else {
  437.       ProgressFileName (pK->progress, NULL);
  438.    }
  439.    ProgressFileSize (pK->progress, pK->fileSize);
  440.    ProgressFilePosition (pK->progress, pK->filePosition);
  441.    ProgressReport (pK->progress, status);
  442. }
  443. STATIC int KFileReadEncode
  444.         (KERMIT_PRIVATE *pK, BYTE *pBuffer,
  445.          unsigned long *pLength, unsigned long *pRawLength) {
  446.    int     err;
  447.    long    length = (*pLength) -= 4;
  448.    BYTE    b;
  449.    int     repeatCount = 1;
  450.    BYTE   *pDiskBuffer = pK->pFileThisChar;
  451.    int     eofFlag = pK->eofFlag;
  452.    int     lockingFlip = pK->lockingFlip;
  453.    int     quoteNext = pK->quoteNext;
  454.  
  455.    if ((eofFlag > 1) && (pK->repeatStart == pK->repeatEnd))
  456.       return StsWarn (kEOF);
  457.    *pRawLength = 0;
  458.    DebugBegin (pK->debug, debugEncoding);
  459.    DebugString (pK->debug, "Beginning to encode for packet length ");
  460.    DebugInt (pK->debug, length);
  461.    DebugEnd (pK->debug);
  462.    while (length > 0) {
  463.       while ((pK->repeatEnd != pK->repeatStart) && (eofFlag < 2)) {
  464.          if (pDiskBuffer >= pK->pFileBufferLimit) {
  465.             if (eofFlag == 0) {
  466.                unsigned long bufferSize = pK->fileBufferSize - 1;
  467.  
  468.                err = KFileRead (pK, pK->pFileBuffer, &bufferSize);
  469.                pDiskBuffer = pK->pFileBuffer;
  470.                if (bufferSize > 0)
  471.                   pDiskBuffer[bufferSize] = ~pDiskBuffer[bufferSize - 1];
  472.                pK->pFileBufferLimit = pDiskBuffer + bufferSize;
  473.                pK->pFileThisChar = pDiskBuffer;
  474.                if (err == kEOF)
  475.                   eofFlag = 1;
  476.                else
  477.                   StsRet (err);
  478.             } else
  479.                eofFlag++;
  480.             if (eofFlag)
  481.                break;
  482.          }
  483.          b = *pDiskBuffer;
  484.          pK->repeatByte[pK->repeatEnd] = b;
  485.          if (b ^ lockingFlip)
  486.             pK->num8bit++;
  487.          repeatCount = 1;
  488.          if ((pDiskBuffer[1] == b) && (pK->my.prefixRepeat)) {
  489.             while (pDiskBuffer[repeatCount] == b)
  490.                repeatCount++;
  491.             if (repeatCount > 94)
  492.                repeatCount = 94;
  493.             if ((repeatCount == 2) && (!NeedsControl (b)))
  494.                repeatCount = 1;
  495.          }
  496.          pDiskBuffer += repeatCount;
  497.          pK->repeatCount[pK->repeatEnd] = repeatCount;
  498.          pK->repeatEnd++;
  499.          if (pK->repeatEnd >= (sizeof (pK->repeatByte) / sizeof (pK->repeatByte[0])))
  500.             pK->repeatEnd = 0;
  501.       }
  502.       if ((eofFlag > 1) && (pK->repeatStart == pK->repeatEnd))
  503.          break;
  504.       b = pK->repeatByte[pK->repeatStart];
  505.       repeatCount = pK->repeatCount[pK->repeatStart];
  506.       if (pK->lockingShift) {
  507.          b ^= lockingFlip;
  508.          if (quoteNext) {
  509.             quoteNext = FALSE;
  510.             pK->repeatStart++;
  511.             if (b ^ lockingFlip)
  512.                pK->num8bit--;
  513.             (*pRawLength) += repeatCount;
  514.          } else {
  515.             switch (b) {
  516.             case 14:
  517.             case 15:
  518.             case 16:
  519.                quoteNext = TRUE;
  520.                b = 16;
  521.                repeatCount = 1;
  522.                break;
  523.             default:
  524.                if ((pK->num8bit > 4) && (b & 0x80)) {
  525.                   pK->num8bit = 6 - pK->num8bit;
  526.                   lockingFlip ^= 0x80;
  527.                   b = (lockingFlip) ? 14 : 15;
  528.                   repeatCount = 1;
  529.                } else {
  530.                   pK->repeatStart++;
  531.                   if (b ^ lockingFlip)
  532.                      pK->num8bit--;
  533.                   (*pRawLength) += repeatCount;
  534.                }
  535.                break;
  536.             }
  537.          }
  538.       } else {
  539.          pK->repeatStart++;
  540.          if (b ^ lockingFlip)
  541.             pK->num8bit--;
  542.          (*pRawLength) += repeatCount;
  543.       }
  544.       if (pK->repeatStart >= (sizeof (pK->repeatByte) / sizeof (pK->repeatByte[0])))
  545.          pK->repeatStart = 0;
  546.       if (repeatCount > 0) {
  547.          if (repeatCount > 1) {
  548.             *pBuffer++ = pK->my.prefixRepeat;
  549.             *pBuffer++ = repeatCount + 32;
  550.             length -= 2;
  551.          }
  552.          if ((b & 0x80) && (pK->my.prefix8bit)) {
  553.             *pBuffer++ = pK->my.prefix8bit;
  554.             length--;
  555.             b &= 0x7f;
  556.          }
  557.          if (NeedsControl (b)) {
  558.             *pBuffer++ = pK->my.prefixControl;
  559.             length--;
  560.             b = pK->encode[b];
  561.          }
  562.          *pBuffer++ = b;
  563.          length--;
  564.       }
  565.    }
  566.    DebugBegin (pK->debug, debugEncoding);
  567.    DebugString (pK->debug, "Done encoding packet");
  568.    DebugInt (pK->debug, length);
  569.    DebugEnd (pK->debug);
  570.    pK->pFileThisChar = pDiskBuffer;
  571.    *pLength -= length;
  572.    pK->lockingFlip = lockingFlip;
  573.    pK->quoteNext = quoteNext;
  574.    pK->eofFlag = eofFlag;
  575.    return kOK;
  576. }
  577. STATIC int KFileWriteDecode
  578.         (KERMIT_PRIVATE *pK, const BYTE *pBuffer,
  579.          unsigned long length) {
  580.    BYTE    buff[500];
  581.    unsigned buffLength = 0;
  582.    int     mask = 0xff;
  583.    int     flip = 0;
  584.    int     repeatCount = 0;
  585.    int     lockingFlip = pK->lockingFlip & 0x80;
  586.    int     quoteNext = pK->quoteNext;
  587.    BYTE    b = 0;
  588.  
  589.    if (pK->your.prefix8bit)
  590.       mask = 0x7f;
  591.    while (length > 0) {
  592.       b = ((unsigned) (*pBuffer++)) & mask;
  593.       length--;
  594.       repeatCount = 1;
  595.       flip = 0;
  596.       if ((pK->your.prefixRepeat) && (b == pK->your.prefixRepeat)) {
  597.          repeatCount = (((unsigned) (*pBuffer++)) & 0x7f) - 32;
  598.          b = ((unsigned) (*pBuffer++)) & mask;
  599.          length -= 2;
  600.       }
  601.       if ((pK->your.prefix8bit) && (b == pK->your.prefix8bit)) {
  602.          flip ^= 0x80;
  603.          b = ((unsigned) (*pBuffer++)) & mask;
  604.          length--;
  605.       }
  606.       if (b == pK->your.prefixControl) {
  607.          b = pK->decode[((unsigned) (*pBuffer++)) & mask];
  608.          length--;
  609.       }
  610.       b ^= flip;
  611.       if (pK->lockingShift) {
  612.          if (!quoteNext) {
  613.             switch (b) {
  614.             case 14:
  615.                lockingFlip = 0x80;
  616.                repeatCount = 0;
  617.                break;
  618.             case 15:
  619.                lockingFlip = 0;
  620.                repeatCount = 0;
  621.                break;
  622.             case 16:
  623.                quoteNext = TRUE;
  624.                repeatCount = 0;
  625.                break;
  626.             }
  627.          } else
  628.             quoteNext = FALSE;
  629.       }
  630.       b ^= lockingFlip;
  631.       while (repeatCount > 0) {
  632.          buff[buffLength++] = b;
  633.          repeatCount--;
  634.          pK->filePosition++;
  635.          if (buffLength >= sizeof (buff)) {
  636.             StsRet (KFileWrite (pK, buff, buffLength));
  637.             buffLength = 0;
  638.          }
  639.       }
  640.    }
  641.    StsRet (KFileWrite (pK, buff, buffLength));
  642.    pK->lockingFlip = lockingFlip;
  643.    pK->quoteNext = quoteNext;
  644.    return kOK;
  645. }
  646. STATIC void KInitEncoding
  647.         (KERMIT_PRIVATE *pK) {
  648.    int     i;
  649.  
  650.    for (i = 0; i < 256; i++)
  651.       pK->classify[i] = 0;
  652.    for (i = 0; i < 32; i++) {
  653.       SetControl (i);
  654.       SetControl (i | 0x80);
  655.    }
  656.    SetControl (0x7f);
  657.    SetControl (0xff);
  658.    SetControl (pK->my.prefixControl);
  659.    if (pK->my.prefix8bit)
  660.       SetControl (pK->my.prefix8bit);
  661.    if (pK->my.prefixRepeat)
  662.       SetControl (pK->my.prefixRepeat);
  663.    for (i = 0; i < 256; i++)
  664.       pK->encode[i] = pK->decode[i] = i;
  665.    for (i = 0; i < 32; i++)
  666.       pK->encode[i] = i ^ 0x40;
  667.    pK->encode[0x7f] = 0x7f ^ 0x40;
  668.    for (i = 128; i < 160; i++)
  669.       pK->encode[i] = i ^ 0x40;
  670.    pK->encode[0xff] = 0xff ^ 0x40;
  671.    for (i = 0; i < 32; i++)
  672.       pK->decode[((unsigned) (pK->encode[i])) & 0xff] = i;
  673.    pK->decode[((unsigned) (pK->encode[0x7f])) & 0xff] = 0x7f;
  674.    for (i = 128; i < 160; i++)
  675.       pK->decode[((unsigned) (pK->encode[i])) & 0xff] = i;
  676.    pK->decode[((unsigned) (pK->encode[0xff])) & 0xff] = 0xff;
  677. }
  678. STATIC unsigned KCheckValue
  679.         (KERMIT_PRIVATE *pK,
  680.          char packetCheck, const BYTE *pData, unsigned int length,
  681.          int *pCheckValue) {
  682.    int     checkAccumulator;
  683.    int     finalCheck = 0;
  684.    int     i;
  685.  
  686.    if (pCheckValue)
  687.       checkAccumulator = *pCheckValue;
  688.    else
  689.       checkAccumulator = 0;
  690.    switch (packetCheck) {
  691.    case '1':
  692.       for (i = 0; i < length; i++)
  693.          checkAccumulator += pData[i];
  694.       finalCheck = checkAccumulator;
  695.       finalCheck += (finalCheck >> 6) & 3;
  696.       finalCheck &= 63;
  697.       break;
  698.    case 'B':
  699.    case '2':
  700.       for (i = 0; i < length; i++)
  701.          checkAccumulator += pData[i];
  702.       finalCheck = checkAccumulator & 0xfff;
  703.       break;
  704.    case '3':
  705.       checkAccumulator = KCrc16 (pData, length, checkAccumulator);
  706.       finalCheck = checkAccumulator;
  707.       break;
  708.    default:
  709.       if (pK->debug) {
  710.          DebugBegin (pK->debug, debugWarn);
  711.          DebugString (pK->debug, "Internal error: illegal packet check ");
  712.          DebugChar (pK->debug, packetCheck);
  713.          DebugInt (pK->debug, packetCheck);
  714.          DebugEnd (pK->debug);
  715.       }
  716.       break;
  717.    }
  718.    if (pCheckValue)
  719.       *pCheckValue = checkAccumulator;
  720.    return finalCheck;
  721. }
  722. STATIC int KSendPacket
  723.         (KERMIT_PRIVATE *pK, int sequence, BYTE type,
  724.          const BYTE *pData, unsigned long dataLength) {
  725.    int     checkAccumulator = 0;
  726.    int     checkValue;
  727.    int     packetCheckLength = pK->packetCheck - '0';
  728.  
  729.    if (pK->packetCheck == 'B')
  730.       packetCheckLength = 2;
  731.    {
  732.       int     i;
  733.  
  734.       for (i = 0; i < pK->my.padCount; i++) {
  735.          StsRet (KSendByte (pK, pK->my.padByte));
  736.       }
  737.    }
  738.    if (dataLength + packetCheckLength > 9024) {
  739.       BYTE    header[8];
  740.  
  741.       header[0] = pK->my.sopCharacter;
  742.       if (header[0] == 0xff)
  743.          header[0] = 0x01;
  744.       header[1] = 1 + 32;
  745.       header[2] = (sequence % 64) + 32;
  746.       header[3] = type;
  747.       header[4] = (dataLength + packetCheckLength) / 9025 + 32;
  748.       header[5] = ((dataLength + packetCheckLength) / 95) % 95 + 32;
  749.       header[6] = (dataLength + packetCheckLength) % 95 + 32;
  750.       header[7] = KCheckValue (pK, '1', header + 1, 6, NULL) + 32;
  751.       StsRet (KSendBytes (pK, header, 8));
  752.       KCheckValue (pK, pK->packetCheck, header + 1, 6, &checkAccumulator);
  753.    } else if (dataLength + packetCheckLength + 2 > 95) {
  754.       BYTE    header[7];
  755.  
  756.       header[0] = pK->my.sopCharacter;
  757.       if (header[0] == 0xff)
  758.          header[0] = 0x01;
  759.       header[1] = ' ';
  760.       header[2] = (sequence % 64) + 32;
  761.       header[3] = type;
  762.       header[4] = (dataLength + packetCheckLength) / 95 + 32;
  763.       header[5] = (dataLength + packetCheckLength) % 95 + 32;
  764.       header[6] = KCheckValue (pK, '1', header + 1, 5, NULL) + 32;
  765.       StsRet (KSendBytes (pK, header, 7));
  766.       KCheckValue (pK, pK->packetCheck, header + 1, 6, &checkAccumulator);
  767.    } else {
  768.       BYTE    header[4];
  769.  
  770.       header[0] = pK->my.sopCharacter;
  771.       if (header[0] == 0xff)
  772.          header[0] = 0x01;
  773.       header[1] = dataLength + 2 + packetCheckLength + 32;
  774.       header[2] = (sequence % 64) + 32;
  775.       header[3] = type;
  776.       StsRet (KSendBytes (pK, header, 4));
  777.       KCheckValue (pK, pK->packetCheck, header + 1, 3, &checkAccumulator);
  778.    }
  779.    StsRet (KSendBytes (pK, pData, dataLength));
  780.    checkValue = KCheckValue (pK, pK->packetCheck, pData, dataLength, &checkAccumulator);
  781.    switch (pK->packetCheck) {
  782.    case '3':
  783.       StsRet (KSendByte (pK, ((checkValue >> 12) & 15) + 32));
  784.    case '2':
  785.       StsRet (KSendByte (pK, ((checkValue >> 6) & 63) + 32));
  786.    case '1':
  787.       StsRet (KSendByte (pK, (checkValue & 63) + 32));
  788.       break;
  789.    case 'B':
  790.       StsRet (KSendByte (pK, ((checkValue >> 6) & 63) + 33));
  791.       StsRet (KSendByte (pK, (checkValue & 63) + 33));
  792.    }
  793.    StsRet (KSendByte (pK, pK->my.packetTerminator));
  794.    if (pK->debug) {
  795.       DebugBegin (pK->debug, debugPacket);
  796.       DebugString (pK->debug, "Sent #");
  797.       DebugInt (pK->debug, sequence);
  798.       DebugString (pK->debug, " type:");
  799.       DebugChar (pK->debug, type);
  800.       DebugString (pK->debug, " length:");
  801.       DebugUInt (pK->debug, dataLength);
  802.       DebugString (pK->debug, " check:");
  803.       DebugInt (pK->debug, checkValue);
  804.       DebugString (pK->debug, " ``");
  805.       if (dataLength < 40) {
  806.          DebugStringCount (pK->debug, (const char *) pData, dataLength);
  807.          DebugString (pK->debug, "''");
  808.       } else {
  809.          DebugStringCount (pK->debug, (const char *) pData, 37);
  810.          DebugString (pK->debug, "...");
  811.       }
  812.       DebugEnd (pK->debug);
  813.    }
  814.    StsRet (KWaitForSentBytes (pK));
  815.    return kOK;
  816. }
  817. STATIC unsigned KFindCheckValue
  818.         (KERMIT_PRIVATE *pK, BYTE *buffer,
  819.          long *pCheckValue, char packetCheck) {
  820.    BYTE   *check;
  821.    int     i;
  822.    long    checkValue = 0;
  823.    int     checkLength = packetCheck - '0';
  824.  
  825.    if (packetCheck == 'B')
  826.       checkLength = 2;
  827.    check = buffer - checkLength;
  828.    for (i = 0; i < checkLength; i++) {
  829.       int     thisValue = (check[i] & 0x7f) - 32;
  830.  
  831.       if (packetCheck == 'B')
  832.          thisValue -= 1;
  833.       if ((thisValue > 63) || (thisValue < 0)) {
  834.          if (pK->debug) {
  835.             DebugBegin (pK->debug, debugPacketErr);
  836.             DebugString (pK->debug, "Received illegal check character ");
  837.             DebugInt (pK->debug, check[i]);
  838.             DebugChar (pK->debug, check[i]);
  839.             DebugEnd (pK->debug);
  840.          }
  841.          return StsWarn (kBadPacket);
  842.       }
  843.       checkValue = (checkValue << 6) + thisValue;
  844.    }
  845.    *pCheckValue = checkValue;
  846.    return kOK;
  847. }
  848. STATIC int KReceivePacket
  849.         (KERMIT_PRIVATE *pK, int timeout,
  850.          BYTE *pBuffer, unsigned long *pDataLength,
  851.          BYTE *pType, int *pSequence) {
  852.    BYTE    header[10];
  853.    unsigned long headerLength = 3;
  854.    int     length, checkAccumulator = 0;
  855.    unsigned long rxDataLength;
  856.  
  857.    {
  858.       BYTE    mark;
  859.       BYTE    sopCharacter = pK->your.sopCharacter;
  860.       int     err;
  861.       int     i = 0;
  862.  
  863.       for (i = 0; i < 4; i++)
  864.          header[i] = 0xff;
  865.       do {
  866.          err = KReadByteWithTimeout (pK, timeout, &mark);
  867.          switch (err) {
  868.          case kOK:
  869.             mark &= 0x7f;
  870.             header[0] = header[1];
  871.             header[1] = header[2];
  872.             header[2] = header[3];
  873.             header[3] = mark;
  874.             if ((header[0] < 32) && (pK->your.sopCharacter == 0xff))
  875.                sopCharacter = header[0];
  876.             break;
  877.          case kBadPacket:
  878.             header[3] = 0x80;
  879.             break;
  880.          default:
  881.             return StsWarn (err);
  882.          }
  883.       } while ((header[0] != sopCharacter)
  884.                || (header[1] < 32) || (header[1] > 126)
  885.                || (header[2] < 32) || (header[2] > 95)
  886.                || (header[3] < 'A') || (header[3] > 'Z')
  887.                || (err != kOK));
  888.    }
  889.    length = header[1] - 32;
  890.    *pSequence = header[2] - 32;
  891.    *pType = header[3];
  892.    switch (length) {
  893.    case 0:
  894.    case 1:
  895.       {
  896.          headerLength = 3 + length;
  897.          StsRet (KReadBytesWithTimeout (pK, 3, header + 4, &headerLength));
  898.          headerLength += 4;
  899.          {
  900.             int     i = 4;
  901.  
  902.             for (; i < headerLength; i++)
  903.                header[i] &= 0x7f;
  904.          }
  905.          {
  906.             int     headerCheck = KCheckValue (pK, '1', header + 1, headerLength - 2, NULL);
  907.  
  908.             if (headerCheck != header[headerLength - 1] - 32) {
  909.                if (pK->debug) {
  910.                   DebugBegin (pK->debug, debugPacketErr);
  911.                   DebugString (pK->debug, "Wrong header check: received: ");
  912.                   DebugInt (pK->debug, header[headerLength - 1] - 32);
  913.                   DebugString (pK->debug, " computed: ");
  914.                   DebugInt (pK->debug, headerCheck);
  915.                   DebugEnd (pK->debug);
  916.                }
  917.                return kBadPacket;
  918.             }
  919.          }
  920.          checkAccumulator = 0;
  921.          KCheckValue (pK, pK->packetCheck, header + 1, headerLength - 1, &checkAccumulator);
  922.          rxDataLength = (header[4] - 32) * 95 + (header[5] - 32);
  923.          if (length == 1)
  924.             rxDataLength = rxDataLength * 95 + (header[6] - 32);
  925.          if (pK->debug) {
  926.             DebugBegin (pK->debug, debugPacketLowLevel);
  927.             DebugString (pK->debug, "Receiving extended packet, length: ");
  928.             DebugUInt (pK->debug, rxDataLength);
  929.             DebugEnd (pK->debug);
  930.          }
  931.       }
  932.       break;
  933.    case 2:
  934.       return StsWarn (kBadPacket);
  935.    default:
  936.       {
  937.          if (length < 2)
  938.             return StsWarn (kBadPacket);
  939.          rxDataLength = length - 2;
  940.          if (pK->debug) {
  941.             DebugBegin (pK->debug, debugPacketLowLevel);
  942.             DebugString (pK->debug, "Receiving normal packet #");
  943.             DebugInt (pK->debug, *pSequence);
  944.             DebugString (pK->debug, " data length: ");
  945.             DebugUInt (pK->debug, rxDataLength);
  946.             DebugString (pK->debug, " type: ");
  947.             DebugChar (pK->debug, *pType);
  948.             DebugEnd (pK->debug);
  949.          }
  950.          checkAccumulator = 0;
  951.          KCheckValue (pK, pK->packetCheck, header + 1, 3, &checkAccumulator);
  952.       }
  953.       break;
  954.    }
  955.    {
  956.       long    myCheck, rxCheck;
  957.       unsigned checkLength = pK->packetCheck - '0';
  958.  
  959.       if (pK->packetCheck == 'B')
  960.          checkLength = 2;
  961.       StsRet (KReadBytesWithTimeout (pK, 3, pBuffer, &rxDataLength));
  962.       if (rxDataLength < checkLength)
  963.          return StsWarn (kBadPacket);
  964.       myCheck = KCheckValue (pK, pK->packetCheck, pBuffer,
  965.                              rxDataLength - checkLength, &checkAccumulator);
  966.       StsRet (KFindCheckValue (pK, pBuffer + rxDataLength, &rxCheck,
  967.                                pK->packetCheck));
  968.       if (myCheck != rxCheck) {
  969.          if (pK->debug) {
  970.             DebugBegin (pK->debug, debugPacketErr);
  971.             DebugString (pK->debug, "Wrong packet check: received: ");
  972.             DebugInt (pK->debug, rxCheck);
  973.             DebugString (pK->debug, " computed: ");
  974.             DebugInt (pK->debug, myCheck);
  975.             DebugEnd (pK->debug);
  976.          }
  977.          return StsWarn (kBadPacket);
  978.       }
  979.       rxDataLength -= checkLength;
  980.    }
  981.    *pDataLength = rxDataLength;
  982.    if (pK->debug) {
  983.       DebugBegin (pK->debug, debugPacket);
  984.       DebugString (pK->debug, "Rcvd #");
  985.       DebugInt (pK->debug, *pSequence);
  986.       DebugString (pK->debug, " Type:");
  987.       DebugChar (pK->debug, *pType);
  988.       DebugString (pK->debug, " length:");
  989.       DebugUInt (pK->debug, *pDataLength);
  990.       DebugString (pK->debug, " ``");
  991.       if (*pDataLength < 40) {
  992.          DebugStringCount (pK->debug, (char *) pBuffer, *pDataLength);
  993.          DebugString (pK->debug, "''");
  994.       } else {
  995.          DebugStringCount (pK->debug, (char *) pBuffer, 37);
  996.          DebugString (pK->debug, "...");
  997.       }
  998.       DebugEnd (pK->debug);
  999.    }
  1000.    if (pK->your.sopCharacter == 0xff)
  1001.       pK->your.sopCharacter = header[0];
  1002.    if (pK->my.sopCharacter == 0xff)
  1003.       pK->my.sopCharacter = header[0];
  1004.    return kOK;
  1005. }
  1006. STATIC void KDumpCache
  1007.         (KERMIT_PRIVATE *pK) {
  1008.    int     i;
  1009.    char    c[2];
  1010.  
  1011.    c[0] = 0;
  1012.    c[1] = 0;
  1013.    DebugBegin (pK->debug, debugCache);
  1014.    DebugString (pK->debug, "   minCache = ");
  1015.    DebugInt (pK->debug, pK->minCache);
  1016.    DebugString (pK->debug, "   minUsed = ");
  1017.    DebugInt (pK->debug, pK->minUsed);
  1018.    DebugString (pK->debug, "   sequence = ");
  1019.    DebugInt (pK->debug, pK->sequence);
  1020.    DebugString (pK->debug, "   maxUsed = ");
  1021.    DebugInt (pK->debug, pK->maxUsed);
  1022.    DebugEnd (pK->debug);
  1023.    DebugBegin (pK->debug, debugCache);
  1024.    DebugString (pK->debug, "   ");
  1025.    for (i = 0; i < 64; i++) {
  1026.       c[0] = (i % 10) + '0';
  1027.       if ((pK->maxUsed & 63) == i)
  1028.          DebugString (pK->debug, "M");
  1029.       else if ((pK->minCache & 63) == i)
  1030.          DebugString (pK->debug, "m");
  1031.       else if ((pK->minUsed & 63) == i)
  1032.          DebugString (pK->debug, "U");
  1033.       else if ((pK->sequence & 63) == i)
  1034.          DebugString (pK->debug, "S");
  1035.       else if ((i % 5) == 0)
  1036.          DebugString (pK->debug, c);
  1037.       else
  1038.          DebugString (pK->debug, ".");
  1039.    }
  1040.    DebugEnd (pK->debug);
  1041.    DebugBegin (pK->debug, debugCache);
  1042.    DebugString (pK->debug, "Tx:");
  1043.    for (i = 0; i < 64; i++) {
  1044.       c[0] = ' ';
  1045.       if (pK->exchange[i].myPacketType != 0) {
  1046.          c[0] = pK->exchange[i].myPacketType;
  1047.          if (pK->exchange[i].myPacket == NULL)
  1048.             c[0] = c[0] + 32;
  1049.       } else if (pK->exchange[i].myPacket)
  1050.          c[0] = '.';
  1051.       DebugString (pK->debug, c);
  1052.    }
  1053.    DebugString (pK->debug, ":");
  1054.    DebugEnd (pK->debug);
  1055.    DebugBegin (pK->debug, debugCache);
  1056.    DebugString (pK->debug, "Rx:");
  1057.    for (i = 0; i < 64; i++) {
  1058.       c[0] = ' ';
  1059.       if (pK->exchange[i].yourPacketType != 0) {
  1060.          c[0] = pK->exchange[i].yourPacketType;
  1061.          if (pK->exchange[i].yourPacket == NULL)
  1062.             c[0] = c[0] + 32;
  1063.       } else if (pK->exchange[i].yourPacket)
  1064.          c[0] = '.';
  1065.       DebugString (pK->debug, c);
  1066.    }
  1067.    DebugString (pK->debug, ":");
  1068.    DebugEnd (pK->debug);
  1069.    {
  1070.       BYTE   *pThisBuffer = pK->rawBuffer;
  1071.       int     buffersRemaining = pK->rawBufferLength / pK->rawBufferPacketSize;
  1072.  
  1073.       while (buffersRemaining > 0) {
  1074.          int     j, count = 0;
  1075.  
  1076.          if (pThisBuffer == pK->spareExchange.myPacket)
  1077.             count++;
  1078.          if (pThisBuffer == pK->spareExchange.yourPacket)
  1079.             count++;
  1080.          for (j = 0; j < 64; j++) {
  1081.             if (pThisBuffer == pK->exchange[j].myPacket)
  1082.                count++;
  1083.             if (pThisBuffer == pK->exchange[j].yourPacket)
  1084.                count++;
  1085.          }
  1086.          if (count == 0) {
  1087.             DebugBegin (pK->debug, debugWarn);
  1088.             DebugString (pK->debug, "Cache buffer lost: address ");
  1089.             DebugPtr (pK->debug, pThisBuffer);
  1090.             if (pThisBuffer == pK->rxPacket)
  1091.                DebugString (pK->debug, " == pK->rxPacket");
  1092.             DebugEnd (pK->debug);
  1093.          } else if (count > 1) {
  1094.             DebugBegin (pK->debug, debugWarn);
  1095.             DebugString (pK->debug, "Cache buffer duplicated: address ");
  1096.             DebugPtr (pK->debug, pThisBuffer);
  1097.             DebugEnd (pK->debug);
  1098.          }
  1099.          pThisBuffer += pK->rawBufferPacketSize;
  1100.          buffersRemaining--;
  1101.       }
  1102.    }
  1103. }
  1104. STATIC void KResetSequence
  1105.         (KERMIT_PRIVATE *pK) {
  1106.    int     low = 0, high = 63;
  1107.  
  1108.    if (pK->debug) {
  1109.       KDumpCache (pK);
  1110.       DebugBegin (pK->debug, debugCache);
  1111.       DebugString (pK->debug, "Resetting cache...");
  1112.       DebugEnd (pK->debug);
  1113.    }
  1114.    while (low < high) {
  1115.       while (pK->exchange[low].myPacket != NULL)
  1116.          low++;
  1117.       while (pK->exchange[high].myPacket == NULL)
  1118.          high--;
  1119.       if (low < high)
  1120.          SwapSlots (low, high);
  1121.    }
  1122.    pK->maxUsed = -1;
  1123.    pK->minCache = 0;
  1124.    pK->minUsed = 0;
  1125.    pK->sequence = 0;
  1126.    KDumpCache (pK);
  1127. }
  1128. STATIC int KInitWindow
  1129.         (KERMIT_PRIVATE *pK) {
  1130.    unsigned long packetLimit;
  1131.    unsigned long packetCount = pK->windowSize + 1;
  1132.  
  1133.    if (pK->rawBuffer) {
  1134.       int     i;
  1135.  
  1136.       free (pK->rawBuffer);
  1137.       pK->txPacket = NULL;
  1138.       pK->rxPacket = NULL;
  1139.       pK->spareExchange.myPacket = NULL;
  1140.       pK->spareExchange.myPacketLength = 0;
  1141.       pK->spareExchange.myPacketType = 0;
  1142.       pK->spareExchange.yourPacket = NULL;
  1143.       pK->spareExchange.yourPacketLength = 0;
  1144.       pK->spareExchange.yourPacketType = 0;
  1145.       for (i = 0; i < 64; i++)
  1146.          pK->exchange[i] = pK->spareExchange;
  1147.    }
  1148.    packetLimit = pK->my.maxPacketSize;
  1149.    if (packetLimit < pK->your.maxPacketSize)
  1150.       packetLimit = pK->your.maxPacketSize;
  1151.    packetLimit += 100;
  1152.    if ((packetLimit * packetCount) < MALLOC_LIMIT)
  1153.       pK->rawBuffer = malloc (packetLimit * packetCount);
  1154.    while (pK->rawBuffer == NULL) {
  1155.       if (packetLimit > 200)
  1156.          packetLimit = (packetLimit * 2) / 3;
  1157.       else if (packetCount > 2)
  1158.          packetCount--;
  1159.       else
  1160.          return StsWarn (kFailed);
  1161.       if ((packetLimit * packetCount) < MALLOC_LIMIT)
  1162.          pK->rawBuffer = malloc (packetLimit * packetCount);
  1163.    }
  1164.    pK->rawBufferLength = packetLimit * packetCount;
  1165.    pK->rawBufferPacketSize = packetLimit;
  1166.    {
  1167.       BYTE   *pNextBuffer = pK->rawBuffer;
  1168.       int     i = 0;
  1169.       int     offset = (pK->sending ? packetLimit - 100 : 100);
  1170.  
  1171.       pK->spareExchange.myPacket = pNextBuffer;
  1172.       pK->spareExchange.yourPacket = pNextBuffer + offset;
  1173.       for (i = 0; i < packetCount - 1; i++) {
  1174.          pNextBuffer += packetLimit;
  1175.          pK->exchange[i].myPacket = pNextBuffer;
  1176.          pK->exchange[i].yourPacket = pNextBuffer + offset;
  1177.          pK->exchange[i].sequence = i;
  1178.       }
  1179.       pK->maxUsed = pK->minUsed;
  1180.       pK->txPacket = pK->spareExchange.myPacket;
  1181.       pK->txPacketLength = 0;
  1182.    }
  1183.    packetLimit -= 100;
  1184.    if (packetLimit < pK->my.maxPacketSize)
  1185.       pK->my.maxPacketSize = packetLimit;
  1186.    if (packetLimit < pK->your.maxPacketSize)
  1187.       pK->your.maxPacketSize = packetLimit;
  1188.    if ((pK->sending) && (pK->your.maxPacketSize > 95))
  1189.       pK->your.maxPacketSize = 95;
  1190.    if (!(pK->sending) && (pK->my.maxPacketSize > 95))
  1191.       pK->my.maxPacketSize = 95;
  1192.    if (packetCount <= pK->windowSize)
  1193.       pK->windowSize = packetCount - 1;
  1194.    if (pK->debug) {
  1195.       DebugBegin (pK->debug, debugCache);
  1196.       DebugString (pK->debug, "Allocated ");
  1197.       DebugUInt (pK->debug, packetCount);
  1198.       DebugString (pK->debug, " cache buffers of ");
  1199.       DebugUInt (pK->debug, packetLimit);
  1200.       DebugString (pK->debug, " bytes each.");
  1201.       DebugEnd (pK->debug);
  1202.       KDumpCache (pK);
  1203.    }
  1204.    return kOK;
  1205. }
  1206. STATIC int KReceivePacketCache
  1207.         (KERMIT_PRIVATE *pK, int timeout) {
  1208.    int     slot;
  1209.    int     sequence;
  1210.  
  1211.    StsRet (KReceivePacket (pK, timeout, pK->spareExchange.yourPacket,
  1212.                            &(pK->spareExchange.yourPacketLength),
  1213.                            &(pK->spareExchange.yourPacketType), &sequence));
  1214.    slot = sequence & 63;
  1215.    sequence = ((pK->maxUsed - 32) & (~63)) | slot;
  1216.    if (sequence < pK->maxUsed - 32)
  1217.       sequence += 64;
  1218.    if (sequence > pK->minUsed + 32)
  1219.       return StsWarn (kBadPacket);
  1220.    pK->rxPacketSequence = pK->spareExchange.sequence = sequence;
  1221.    pK->rxPacket = pK->spareExchange.yourPacket;
  1222.    pK->rxPacketLength = pK->spareExchange.yourPacketLength;
  1223.    pK->rxPacketType = pK->spareExchange.yourPacketType;
  1224.    if ((pK->minCache < pK->minUsed)
  1225.        && (pK->exchange[slot].yourPacket == NULL)
  1226.        && (pK->spareExchange.sequence >= pK->minUsed)) {
  1227.       if (pK->debug) {
  1228.          DebugBegin (pK->debug, debugCache);
  1229.          DebugString (pK->debug, "Adding new slot to window");
  1230.          DebugEnd (pK->debug);
  1231.       }
  1232.       SwapSlots (pK->minCache, slot);
  1233.       pK->minCache++;
  1234.       if (pK->spareExchange.sequence > pK->maxUsed)
  1235.          pK->maxUsed = pK->spareExchange.sequence;
  1236.    }
  1237.    if (pK->exchange[slot].yourPacket) {
  1238.       BYTE   *pTmp;
  1239.  
  1240.       if (pK->debug) {
  1241.          DebugBegin (pK->debug, debugCache);
  1242.          DebugString (pK->debug, "Putting received packet into slot ");
  1243.          DebugInt (pK->debug, slot);
  1244.          DebugEnd (pK->debug);
  1245.       }
  1246.       if (pK->spareExchange.sequence > pK->maxUsed)
  1247.          pK->maxUsed = pK->spareExchange.sequence;
  1248.       pTmp = pK->spareExchange.yourPacket;
  1249.       pK->spareExchange.yourPacket = pK->exchange[slot].yourPacket;
  1250.       pK->exchange[slot].yourPacket = pTmp;
  1251.       pK->exchange[slot].yourPacketLength = pK->spareExchange.yourPacketLength;
  1252.       pK->exchange[slot].yourPacketType = pK->spareExchange.yourPacketType;
  1253.       pK->exchange[slot].sequence = pK->spareExchange.sequence;
  1254.       pK->exchange[slot].packetCheck = pK->packetCheck;
  1255.       pK->spareExchange.yourPacketLength = 0;
  1256.       pK->spareExchange.yourPacketType = 0;
  1257.    } else {
  1258.       if (pK->debug) {
  1259.          DebugBegin (pK->debug, debugCache | debugWarn);
  1260.          DebugString (pK->debug, "Received packet ");
  1261.          DebugInt (pK->debug, pK->spareExchange.sequence);
  1262.          DebugChar (pK->debug, pK->spareExchange.yourPacketType);
  1263.          DebugString (pK->debug, " out of current window [");
  1264.          DebugInt (pK->debug, pK->minUsed);
  1265.          DebugString (pK->debug, ",");
  1266.          DebugInt (pK->debug, pK->maxUsed);
  1267.          DebugString (pK->debug, "]");
  1268.          DebugEnd (pK->debug);
  1269.       }
  1270.       if (pK->spareExchange.sequence > pK->minUsed) {
  1271.          return StsWarn (kBadPacket);
  1272.       } else {
  1273.          return StsWarn (kBadPacket);
  1274.       }
  1275.    }
  1276.    if (pK->debug)
  1277.       KDumpCache (pK);
  1278.    return kOK;
  1279. }
  1280. STATIC int KSendPacketFromCache
  1281.         (KERMIT_PRIVATE *pK, int slot) {
  1282.    slot &= 63;
  1283.    if ((pK->exchange[slot].myPacketType == 0) ||
  1284.        (pK->exchange[slot].myPacket == NULL)) {
  1285.       if (pK->debug) {
  1286.          DebugBegin (pK->debug, debugWarn | debugCache);
  1287.          DebugString (pK->debug, "Can't send packet from cache slot ");
  1288.          DebugInt (pK->debug, slot);
  1289.          DebugEnd (pK->debug);
  1290.       }
  1291.       return kOK;
  1292.    }
  1293.    if (pK->debug) {
  1294.       DebugBegin (pK->debug, debugCache);
  1295.       DebugString (pK->debug, "Sending packet from cache slot ");
  1296.       DebugInt (pK->debug, slot);
  1297.       DebugEnd (pK->debug);
  1298.    }
  1299.    return StsWarn (KSendPacket (pK, slot, pK->exchange[slot].myPacketType,
  1300.            pK->exchange[slot].myPacket, pK->exchange[slot].myPacketLength));
  1301. }
  1302. STATIC int KSendPacketReliable
  1303.         (KERMIT_PRIVATE *pK, BYTE type,
  1304.          const BYTE *pSendData, unsigned long sendDataLength) {
  1305.    int     retries = pK->retries;
  1306.    int     blocked = FALSE;
  1307.    int     err;
  1308.    int     slot = pK->sequence & 63;
  1309.    EXCHANGE *pThisExchange = &(pK->exchange[slot]);
  1310.  
  1311.    if (pThisExchange->myPacket == NULL) {
  1312.       if (pK->minCache < pK->minUsed) {
  1313.          if (pK->debug) {
  1314.             DebugBegin (pK->debug, debugCache);
  1315.             DebugString (pK->debug, "Adding new slot to window for packet to send");
  1316.             DebugEnd (pK->debug);
  1317.          }
  1318.          SwapSlots (pK->minCache, slot);
  1319.          pK->minCache++;
  1320.          pThisExchange->yourPacketType = 0;
  1321.       } else {
  1322.          if (pK->debug) {
  1323.             DebugBegin (pK->debug, debugWarn | debugCache);
  1324.             DebugString (pK->debug,
  1325.                  "Fatal Internal Error: window blocked before packet sent");
  1326.             DebugEnd (pK->debug);
  1327.             KDumpCache (pK);
  1328.          }
  1329.          return StsWarn (kFail);
  1330.       }
  1331.    }
  1332.    if (pSendData == pK->spareExchange.myPacket) {
  1333.       BYTE   *pTmp = pThisExchange->myPacket;
  1334.  
  1335.       pThisExchange->myPacket = pK->spareExchange.myPacket;
  1336.       pK->spareExchange.myPacket = pTmp;
  1337.    } else {
  1338.       memcpy (pThisExchange->myPacket, pSendData, sendDataLength);
  1339.    }
  1340.    if (pK->sequence > pK->maxUsed)
  1341.       pK->maxUsed = pK->sequence;
  1342.    pThisExchange->sequence = pK->sequence;
  1343.    pThisExchange->myPacketLength = sendDataLength;
  1344.    pThisExchange->myPacketType = type;
  1345.    pK->txPacket = pK->spareExchange.myPacket;
  1346.    pK->txPacketLength = 0;
  1347.    StsRet (KSendPacketFromCache (pK, slot));
  1348.    KDumpCache (pK);
  1349.    if (pK->minUsed <= pK->minCache)
  1350.       blocked = 1;
  1351.    if (pK->maxUsed - pK->minUsed + 1 >= pK->currentWindowSize)
  1352.       blocked = (pK->maxUsed - pK->minUsed + 1) - pK->currentWindowSize + 1;
  1353.    if (pK->debug) {
  1354.       if (blocked) {
  1355.          DebugBegin (pK->debug, debugCache);
  1356.          DebugString (pK->debug, "Need ");
  1357.          DebugInt (pK->debug, blocked);
  1358.          DebugString (pK->debug, " packets to unblock window.");
  1359.          DebugEnd (pK->debug);
  1360.       }
  1361.    }
  1362.    do {
  1363.       err = KReceivePacketCache (pK, blocked ? pK->my.timeout : 0);
  1364.       switch (err) {
  1365.       case kOK:
  1366.          switch (pK->rxPacketType) {
  1367.          case 'N':
  1368.             retries--;
  1369.             if (pK->exchange[pK->rxPacketSequence & 63].myPacketType != 0)
  1370.                StsRet (KSendPacketFromCache (pK, pK->rxPacketSequence));
  1371.             if (pK->currentWindowSize == 1)
  1372.                pK->exchange[(pK->rxPacketSequence - 1) & 63].yourPacketType = 'Y';
  1373.          case 'Y':
  1374.             if (pK->exchange[pK->minUsed & 63].yourPacketType != 'Y') {
  1375.                long    gap = pK->rxPacketSequence - pK->minUsed;
  1376.  
  1377.                if (gap == 1) {
  1378.                   StsRet (KSendPacketFromCache (pK, pK->minUsed));
  1379.                }
  1380.                if (gap == pK->currentWindowSize / 2) {
  1381.                   StsRet (KSendPacketFromCache (pK, pK->minUsed));
  1382.                }
  1383.                if (gap / 3 == pK->currentWindowSize / 4) {
  1384.                   StsRet (KSendPacketFromCache (pK, pK->minUsed));
  1385.                }
  1386.             }
  1387.             while ((pK->exchange[pK->minUsed & 63].yourPacketType == 'Y')
  1388.               && (pK->exchange[pK->minUsed & 63].sequence == pK->minUsed)) {
  1389.                pK->minUsed++;
  1390.                if (blocked > 0) {
  1391.                   blocked--;
  1392.                   if (pK->debug) {
  1393.                      DebugBegin (pK->debug, debugCache);
  1394.                      DebugString (pK->debug, "Need ");
  1395.                      DebugInt (pK->debug, blocked);
  1396.                      DebugString (pK->debug, " acknowledgements to unblock window");
  1397.                      DebugEnd (pK->debug);
  1398.                   }
  1399.                }
  1400.             }
  1401.             break;
  1402.          case 'E':
  1403.             if (pK->debug) {
  1404.                DebugBegin (pK->debug, debugWarn);
  1405.                DebugString (pK->debug, "Transfer terminated by remote: ``");
  1406.                DebugStringCount (pK->debug, (const char *) pK->rxPacket,
  1407.                                  pK->rxPacketLength);
  1408.                DebugString (pK->debug, "''");
  1409.                DebugEnd (pK->debug);
  1410.             }
  1411.             return StsWarn (kFailed);
  1412.          default:
  1413.             return StsWarn (kFail);
  1414.          }
  1415.          KDumpCache (pK);
  1416.          break;
  1417.       case kBadPacket:
  1418.       case kTimeout:
  1419.          if (blocked) {
  1420.             StsRet (KSendPacketFromCache (pK, pK->minUsed));
  1421.             retries--;
  1422.          }
  1423.          break;
  1424.       default:
  1425.          return StsWarn (err);
  1426.       }
  1427.       if (retries <= 0) {
  1428.          if (pK->debug) {
  1429.             DebugBegin (pK->debug, debugWarn);
  1430.             DebugString (pK->debug, "Too many retries");
  1431.             DebugEnd (pK->debug);
  1432.          }
  1433.          return StsWarn (kFail);
  1434.       }
  1435.    } while (blocked || (err == kOK));
  1436.    if (pK->exchange[pK->sequence & 63].yourPacketType &&
  1437.        (pK->exchange[pK->sequence & 63].sequence == pK->sequence)) {
  1438.       pK->rxPacket = pK->exchange[pK->sequence & 63].yourPacket;
  1439.       pK->rxPacketType = pK->exchange[pK->sequence & 63].yourPacketType;
  1440.       pK->rxPacketLength = pK->exchange[pK->sequence & 63].yourPacketLength;
  1441.    }
  1442.    pK->sequence++;
  1443.    if (err == kTimeout)
  1444.       return kOK;
  1445.    if (err == kBadPacket)
  1446.       return kOK;
  1447.    return StsWarn (err);
  1448. }
  1449. STATIC int KReceivePacketReliable
  1450.         (KERMIT_PRIVATE *pK) {
  1451.    int     retries = pK->retries;
  1452.    int     err;
  1453.    int     thisSlot = pK->sequence & 63;
  1454.    int     timeout = (pK->my.timeout >= 0) ? pK->my.timeout : 10;
  1455.  
  1456.    if ((pK->exchange[thisSlot].yourPacketType != 0)
  1457.        && (pK->exchange[thisSlot].sequence == pK->sequence)) {
  1458.       pK->rxPacket = pK->exchange[thisSlot].yourPacket;
  1459.       pK->rxPacketLength = pK->exchange[thisSlot].yourPacketLength;
  1460.       pK->rxPacketType = pK->exchange[thisSlot].yourPacketType;
  1461.       pK->rxPacketSequence = pK->exchange[thisSlot].sequence;
  1462.       return kOK;
  1463.    }
  1464.    while (TRUE) {
  1465.       err = KReceivePacketCache (pK, timeout);
  1466.       switch (err) {
  1467.       case kTimeout:
  1468.          if (pK->my.timeout < 0)
  1469.             break;
  1470.       case kBadPacket:
  1471.          StsRet (KSendPacket (pK, pK->sequence, 'N', NULL, 0));
  1472.          break;
  1473.       case kOK:
  1474.          if (pK->rxPacketType == 'E') {
  1475.             if (pK->debug) {
  1476.                DebugBegin (pK->debug, debugWarn);
  1477.                DebugString (pK->debug, "Transfer terminated by remote: ``");
  1478.                DebugStringCount (pK->debug, (const char *) pK->rxPacket,
  1479.                                  pK->rxPacketLength);
  1480.                DebugString (pK->debug, "''");
  1481.                DebugEnd (pK->debug);
  1482.             }
  1483.             return StsWarn (kFailed);
  1484.          }
  1485.          if ((pK->rxPacketSequence & 63) == (pK->sequence & 63)) {
  1486.             return kOK;
  1487.          } else {
  1488.             int     slot = pK->rxPacketSequence & 63;
  1489.  
  1490.             if (pK->exchange[slot].myPacketType == 0) {
  1491.                if (pK->rxPacketSequence < pK->minCache) {
  1492.                   if (pK->debug) {
  1493.                      DebugBegin (pK->debug, debugCache);
  1494.                      DebugString (pK->debug, "Synthesizing ACK "
  1495.                                   "for old packet #");
  1496.                      DebugInt (pK->debug, pK->rxPacketSequence);
  1497.                      DebugEnd (pK->debug);
  1498.                   }
  1499.                   KSendPacket (pK, pK->rxPacketSequence, 'Y', NULL, 0);
  1500.                }
  1501.             } else
  1502.                KSendPacketFromCache (pK, slot);
  1503.          }
  1504.          break;
  1505.       default:
  1506.          return StsWarn (err);
  1507.       }
  1508.       if (retries-- <= 0)
  1509.          return StsWarn (kFail);
  1510.    }
  1511. }
  1512. STATIC int KSendResponse
  1513.         (KERMIT_PRIVATE *pK, BYTE type,
  1514.          const BYTE *pResponse, unsigned long responseLength) {
  1515.    int     slot = pK->sequence & 63;
  1516.    EXCHANGE *pThisExchange = &(pK->exchange[slot]);
  1517.  
  1518.    if (pResponse == pK->spareExchange.myPacket) {
  1519.       BYTE   *pTmp = pThisExchange->myPacket;
  1520.  
  1521.       pThisExchange->myPacket = pK->spareExchange.myPacket;
  1522.       pK->spareExchange.myPacket = pTmp;
  1523.    } else
  1524.       memcpy (pThisExchange->myPacket, pResponse, responseLength);
  1525.    pThisExchange->myPacketLength = responseLength;
  1526.    pThisExchange->myPacketType = type;
  1527.    StsRet (KSendPacketFromCache (pK, slot));
  1528.    pK->sequence++;
  1529.    pK->minUsed = pK->sequence;
  1530.    pK->txPacket = pK->spareExchange.myPacket;
  1531.    return kOK;
  1532. }
  1533. STATIC int KSendFile
  1534.         (KERMIT_PRIVATE *pK) {
  1535.    int     err = kOK;
  1536.  
  1537.    {
  1538.       const char *fileName;
  1539.  
  1540.       DiskFileName (pK->f, &fileName);
  1541.       pK->filePosition = 0;
  1542.       KProgress (pK, stsNewFile);
  1543.       StsRet (KSendPacketReliable (pK, 'F', (const BYTE *) fileName, strlen (fileName)));
  1544.    }
  1545.    if (pK->your.capabilities[0] & 8) {
  1546.    }
  1547.    pK->currentWindowSize = pK->windowSize;
  1548.    do {
  1549.       unsigned long dataLength = pK->my.maxPacketSize;
  1550.       unsigned long rawLength;
  1551.       BYTE   *txBuffer = pK->txPacket;
  1552.  
  1553.       err = KFileReadEncode (pK, txBuffer, &dataLength, &rawLength);
  1554.       if (err == kOK) {
  1555.          StsRet (KSendPacketReliable (pK, 'D', txBuffer, dataLength));
  1556.          pK->filePosition += rawLength;
  1557.          KProgress (pK, stsSending);
  1558.          if (pK->rxPacketLength > 0) {
  1559.             if (pK->rxPacket[0] == 'X') {
  1560.                pK->currentWindowSize = 1;
  1561.                err = KSendPacketReliable (pK, 'Z', (const BYTE *) "D", 1);
  1562.                KProgress (pK, stsSkipped);
  1563.                return kOK;
  1564.             } else if (pK->rxPacket[0] == 'Z')
  1565.                err = kFail;
  1566.          }
  1567.       }
  1568.    } while (err == kOK);
  1569.    pK->currentWindowSize = 1;
  1570.    if (err == kEOF) {
  1571.       err = KSendPacketReliable (pK, 'Z', NULL, 0);
  1572.       KProgress (pK, stsEOF);
  1573.    } else {
  1574.       err = KSendPacketReliable (pK, 'Z', (const BYTE *) "D", 1);
  1575.    }
  1576.    return StsWarn (err);
  1577. }
  1578. STATIC int KSendInitiate
  1579.         (KERMIT_PRIVATE *);
  1580. STATIC int KSendFiles
  1581.         (KERMIT_PRIVATE *pK) {
  1582.    int     err;
  1583.  
  1584.    KResetSequence (pK);
  1585.    err = StsWarn (KSendInitiate (pK));
  1586.    while (err == kOK) {
  1587.       pK->eofFlag = 0;
  1588.       pK->repeatStart = 0;
  1589.       pK->repeatEnd = 1;
  1590.       pK->num8bit = 0;
  1591.       pK->repeatByte[0] = 0;
  1592.       pK->repeatCount[0] = 0;
  1593.       pK->lockingFlip = 0;
  1594.       pK->quoteNext = 0;
  1595.       err = KFileReadOpenNext (pK, diskFileUnknown);
  1596.       if (err == kOK) {
  1597.          err = KSendFile (pK);
  1598.          KFileReadClose (pK);
  1599.       }
  1600.    }
  1601.    if (err == kEndOfSession) {
  1602.       err = KSendPacketReliable (pK, 'B', NULL, 0);
  1603.    }
  1604.    if (err == kOK)
  1605.       KProgress (pK, stsDone);
  1606.    else if (pK->userCancel)
  1607.       KProgress (pK, stsCancelled);
  1608.    else
  1609.       KProgress (pK, stsFailed);
  1610.    return StsWarn (err);
  1611. }
  1612. STATIC int KReceiveFileData
  1613.         (KERMIT_PRIVATE *pK) {
  1614.    pK->filePosition = 0;
  1615.    pK->fileSize = -1;
  1616.    while (TRUE) {
  1617.       StsRet (KReceivePacketReliable (pK));
  1618.       switch (pK->rxPacketType) {
  1619.       case 'A':
  1620.          if (pK->debug) {
  1621.             const BYTE *p = pK->rxPacket;
  1622.             BYTE    attribute;
  1623.             int     length = pK->rxPacketLength;
  1624.             unsigned int attrLength;
  1625.             const char *attrValue;
  1626.  
  1627.             while (length > 0) {
  1628.                attribute = *p++;
  1629.                length--;
  1630.                attrLength = *p++ - 32;
  1631.                length--;
  1632.                attrValue = (const char *) p;
  1633.                p += attrLength;
  1634.                length -= attrLength;
  1635.                DebugBegin (pK->debug, debugAttr);
  1636.                DebugString (pK->debug, "Attribute: ");
  1637.                switch (attribute) {
  1638.                case '!':
  1639.                   DebugString (pK->debug, "Length in K:");
  1640.                   break;
  1641.                case '"':
  1642.                   DebugString (pK->debug, "Type:");
  1643.                   break;
  1644.                case '#':
  1645.                   DebugString (pK->debug, "Creation date:");
  1646.                   break;
  1647.                case '$':
  1648.                   DebugString (pK->debug, "Creator:");
  1649.                   break;
  1650.                case '%':
  1651.                   DebugString (pK->debug, "Account to charge:");
  1652.                   break;
  1653.                case '&':
  1654.                   DebugString (pK->debug, "Area to store file:");
  1655.                   break;
  1656.                case '\'':
  1657.                   DebugString (pK->debug, "Password for file storage area:");
  1658.                   break;
  1659.                case '(':
  1660.                   DebugString (pK->debug, "Block size:");
  1661.                   break;
  1662.                case ')':
  1663.                   DebugString (pK->debug, "Access:");
  1664.                   break;
  1665.                case '*':
  1666.                   DebugString (pK->debug, "Encoding:");
  1667.                   break;
  1668.                case '+':
  1669.                   DebugString (pK->debug, "Disposition:");
  1670.                   break;
  1671.                case ',':
  1672.                   DebugString (pK->debug, "Protection Code:");
  1673.                   break;
  1674.                case '-':
  1675.                   DebugString (pK->debug, "Generic Protection Code:");
  1676.                   break;
  1677.                case '.':
  1678.                   DebugString (pK->debug, "Originating system: ");
  1679.                   {
  1680.                      static struct {
  1681.                         char    vendor;
  1682.                         char    system;
  1683.                         const char *name;
  1684.                      } systems[] = {
  1685.                         {
  1686.                            'A', 0, "Apple computer"
  1687.                         },
  1688.                         {
  1689.                            'B', 0, "Sperry/Univac mainframe"
  1690.                         },
  1691.                         {
  1692.                            'C', 0, "CDC mainframe"
  1693.                         },
  1694.                         {
  1695.                            'D', 0, "DEC system"
  1696.                         },
  1697.                         {
  1698.                            'E', 0, "Honeywell mainframe"
  1699.                         },
  1700.                         {
  1701.                            'F', 0, "Data General"
  1702.                         },
  1703.                         {
  1704.                            'G', 0, "PR1ME"
  1705.                         },
  1706.                         {
  1707.                            'H', 0, "Hewlett-Packard"
  1708.                         },
  1709.                         {
  1710.                            'I', 0, "IBM mainframe"
  1711.                         },
  1712.                         {
  1713.                            'J', 0, "Tandy microcomputer, TRSDOS"
  1714.                         },
  1715.                         {
  1716.                            'K', 0, "Atari microcomputer"
  1717.                         },
  1718.                         {
  1719.                            'L', 0, "Commodore"
  1720.                         },
  1721.                         {
  1722.                            'M', 0, "Miscellaneous mainframe"
  1723.                         },
  1724.                         {
  1725.                            'N', 0, "Microcomputer or workstation"
  1726.                         },
  1727.                         {
  1728.                            'U', '1', "Unix"
  1729.                         },
  1730.                         {
  1731.                            'U', '8', "MS-DOS"
  1732.                         },
  1733.                         {
  1734.                            'U', 0, "Portable O/S"
  1735.                         },
  1736.                         {
  1737.                            0, 0, "Unrecognized system"
  1738.                         }
  1739.                      };
  1740.                      int     i = 0;
  1741.  
  1742.                      while (TRUE) {
  1743.                         if (systems[i].vendor == 0)
  1744.                            break;
  1745.                         if (systems[i].vendor == attrValue[0]) {
  1746.                            if (systems[i].system == 0)
  1747.                               break;
  1748.                            if ((systems[i].system == attrValue[1]) && (attrLength > 1))
  1749.                               break;
  1750.                         }
  1751.                         i++;
  1752.                      }
  1753.                      DebugString (pK->debug, systems[i].name);
  1754.                      DebugString (pK->debug, ": code ");
  1755.                   }
  1756.                   break;
  1757.                case '/':
  1758.                   DebugString (pK->debug, "Data format:");
  1759.                   break;
  1760.                case '0':
  1761.                   DebugString (pK->debug, "System-specific parameters:");
  1762.                   break;
  1763.                case '1':
  1764.                   DebugString (pK->debug, "Length in bytes:");
  1765.                   break;
  1766.                default:
  1767.                   DebugString (pK->debug, "Attribute ");
  1768.                   DebugChar (pK->debug, attribute);
  1769.                   break;
  1770.                }
  1771.                if (attrValue)
  1772.                   DebugStringCount (pK->debug, attrValue, attrLength);
  1773.                DebugEnd (pK->debug);
  1774.             }
  1775.          } {
  1776.             const BYTE *p = pK->rxPacket;
  1777.             BYTE    attribute;
  1778.             int     length = pK->rxPacketLength;
  1779.             int     attrLength;
  1780.             long    fileSize = -1;
  1781.             const char *attrValue;
  1782.  
  1783.             while (length > 0) {
  1784.                attribute = *p++;
  1785.                length--;
  1786.                attrLength = *p++ - 32;
  1787.                length--;
  1788.                attrValue = (const char *) p;
  1789.                p += attrLength;
  1790.                length -= attrLength;
  1791.                switch (attribute) {
  1792.                case '!':
  1793.                   {
  1794.                      long    num = 0;
  1795.                      int     i = 0;
  1796.  
  1797.                      for (; i < attrLength; i++)
  1798.                         num = num * 10 + attrValue[i] - '0';
  1799.                      if (fileSize == -1)
  1800.                         fileSize = num;
  1801.                   }
  1802.                   break;
  1803.                case '1':
  1804.                   {
  1805.                      long    num = 0;
  1806.                      int     i = 0;
  1807.  
  1808.                      for (; i < attrLength; i++)
  1809.                         num = num * 10 + attrValue[i] - '0';
  1810.                      fileSize = num;
  1811.                   }
  1812.                   break;
  1813.                default:
  1814.                   break;
  1815.                }
  1816.             }
  1817.             pK->fileSize = fileSize;
  1818.          }
  1819.          StsRet (KSendResponse (pK, 'Y', NULL, 0));
  1820.          break;
  1821.       case 'D':
  1822.          StsRet (KFileWriteDecode (pK, pK->rxPacket, pK->rxPacketLength));
  1823.          KProgress (pK, stsReceiving);
  1824.          if (pK->userCancel)
  1825.             StsRet (KSendResponse (pK, 'Y', (const BYTE *) "Z", 1));
  1826.          else
  1827.             StsRet (KSendResponse (pK, 'Y', NULL, 0));
  1828.          break;
  1829.       case 'Z':
  1830.          if ((pK->rxPacketLength > 0) && (pK->rxPacket[0] == 'D')) {
  1831.             KProgress (pK, stsSkipped);
  1832.          } else {
  1833.             KProgress (pK, stsEOF);
  1834.          }
  1835.          StsRet (KSendResponse (pK, 'Y', NULL, 0));
  1836.          return kOK;
  1837.       }
  1838.    }
  1839. }
  1840. STATIC int KReceiveFiles
  1841.         (KERMIT_PRIVATE *pK) {
  1842.    KProgress (pK, stsNegotiating);
  1843.    while (TRUE) {
  1844.       StsRet (KReceivePacketReliable (pK));
  1845.       switch (pK->rxPacketType) {
  1846.       case 'F':
  1847.          pK->rxPacket[pK->rxPacketLength] = 0;
  1848.          StsRet (KFileWriteOpen (pK, (const char *) pK->rxPacket, 0, diskFileUnknown));
  1849.          KProgress (pK, stsNewFile);
  1850.          pK->eofFlag = 0;
  1851.          pK->repeatStart = 0;
  1852.          pK->repeatEnd = 1;
  1853.          pK->num8bit = 0;
  1854.          pK->repeatByte[0] = 0;
  1855.          pK->repeatCount[0] = 0;
  1856.          pK->lockingFlip = 0;
  1857.          pK->quoteNext = 0;
  1858.          StsRet (KSendResponse (pK, 'Y', NULL, 0));
  1859.          StsRet (KReceiveFileData (pK));
  1860.          StsRet (KFileWriteClose (pK));
  1861.          break;
  1862.       case 'B':
  1863.          StsRet (KSendResponse (pK, 'Y', NULL, 0));
  1864.          KProgress (pK, stsDone);
  1865.          return kOK;
  1866.       }
  1867.    }
  1868. }
  1869. STATIC void KDumpInitString
  1870.         (KERMIT_PRIVATE *pK, BYTE *initString,
  1871.          unsigned initLength) {
  1872.    BYTE   *pExtended = NULL;
  1873.    int     extendedLength = 0;
  1874.    BYTE    capabilities[5] =
  1875.    {0, 0, 0, 0, 0};
  1876.  
  1877.    if (initLength > 0) {
  1878.       DebugBegin (pK->debug, debugInit);
  1879.       DebugString (pK->debug, "   1:");
  1880.       DebugChar (pK->debug, initString[0]);
  1881.       DebugString (pK->debug, " Max Packet Length =");
  1882.       DebugInt (pK->debug, initString[0] - 32);
  1883.       DebugEnd (pK->debug);
  1884.    }
  1885.    if (initLength > 1) {
  1886.       DebugBegin (pK->debug, debugInit);
  1887.       DebugString (pK->debug, "   2:");
  1888.       DebugChar (pK->debug, initString[1]);
  1889.       DebugString (pK->debug, " Timeout =");
  1890.       DebugInt (pK->debug, initString[1] - 32);
  1891.       DebugEnd (pK->debug);
  1892.    }
  1893.    if (initLength > 2) {
  1894.       DebugBegin (pK->debug, debugInit);
  1895.       DebugString (pK->debug, "   3:");
  1896.       DebugChar (pK->debug, initString[2]);
  1897.       DebugString (pK->debug, " Number Pad Characters =");
  1898.       DebugInt (pK->debug, initString[2] - 32);
  1899.       DebugEnd (pK->debug);
  1900.    }
  1901.    if (initLength > 3) {
  1902.       DebugBegin (pK->debug, debugInit);
  1903.       DebugString (pK->debug, "   4:");
  1904.       DebugChar (pK->debug, initString[3]);
  1905.       DebugString (pK->debug, " Pad Character =");
  1906.       DebugInt (pK->debug, initString[3] ^ 0x40);
  1907.       DebugChar (pK->debug, initString[3] ^ 0x40);
  1908.       DebugEnd (pK->debug);
  1909.    }
  1910.    if (initLength > 4) {
  1911.       DebugBegin (pK->debug, debugInit);
  1912.       DebugString (pK->debug, "   5:");
  1913.       DebugChar (pK->debug, initString[4]);
  1914.       DebugString (pK->debug, " Packet Terminator =");
  1915.       DebugInt (pK->debug, initString[4] - 32);
  1916.       DebugEnd (pK->debug);
  1917.    }
  1918.    if (initLength > 5) {
  1919.       DebugBegin (pK->debug, debugInit);
  1920.       DebugString (pK->debug, "   6:");
  1921.       DebugChar (pK->debug, initString[5]);
  1922.       DebugString (pK->debug, " Control prefix =");
  1923.       DebugInt (pK->debug, initString[5]);
  1924.       DebugChar (pK->debug, initString[5]);
  1925.       DebugEnd (pK->debug);
  1926.    }
  1927.    if (initLength > 6) {
  1928.       DebugBegin (pK->debug, debugInit);
  1929.       DebugString (pK->debug, "   7:");
  1930.       DebugChar (pK->debug, initString[6]);
  1931.       DebugString (pK->debug, " eighth-bit prefix =");
  1932.       DebugInt (pK->debug, initString[6]);
  1933.       DebugChar (pK->debug, initString[6]);
  1934.       DebugEnd (pK->debug);
  1935.    }
  1936.    if (initLength > 7) {
  1937.       DebugBegin (pK->debug, debugInit);
  1938.       DebugString (pK->debug, "   8:");
  1939.       DebugChar (pK->debug, initString[7]);
  1940.       DebugString (pK->debug, " Packet check type =");
  1941.       DebugInt (pK->debug, initString[7] - '0');
  1942.       DebugEnd (pK->debug);
  1943.    }
  1944.    if (initLength > 8) {
  1945.       DebugBegin (pK->debug, debugInit);
  1946.       DebugString (pK->debug, "   9:");
  1947.       DebugChar (pK->debug, initString[8]);
  1948.       DebugString (pK->debug, " Repeat prefix =");
  1949.       DebugInt (pK->debug, initString[8]);
  1950.       DebugChar (pK->debug, initString[8]);
  1951.       DebugEnd (pK->debug);
  1952.    }
  1953.    if (initLength > 9) {
  1954.       int     i = 0;
  1955.       BYTE    thisCapability;
  1956.  
  1957.       DebugBegin (pK->debug, debugInit);
  1958.       DebugString (pK->debug, "  Capabilities bitmap: ");
  1959.       do {
  1960.          thisCapability = initString[i + 9] - 32;
  1961.          if (i < sizeof (capabilities))
  1962.             capabilities[i] = thisCapability;
  1963.          i++;
  1964.          DebugIntHex (pK->debug, thisCapability);
  1965.          DebugChar (pK->debug, thisCapability + 32);
  1966.          DebugString (pK->debug, " ");
  1967.       } while ((i < sizeof (capabilities)) && (thisCapability & 1));
  1968.       pExtended = initString + i + 9;
  1969.       extendedLength = initLength - 9 - i;
  1970.       DebugEnd (pK->debug);
  1971.    } {
  1972.       DebugBegin (pK->debug, debugInit);
  1973.       DebugString (pK->debug, "  Capabilities enabled: ");
  1974.       if (capabilities[0] & 32)
  1975.          DebugString (pK->debug, " (Locking Shift)");
  1976.       if (capabilities[0] & 16)
  1977.          DebugString (pK->debug, " (Extra-Long Packets)");
  1978.       if (capabilities[0] & 8)
  1979.          DebugString (pK->debug, " (Attributes)");
  1980.       if (capabilities[0] & 4)
  1981.          DebugString (pK->debug, " (Windowing)");
  1982.       if (capabilities[0] & 2)
  1983.          DebugString (pK->debug, " (Long Packets)");
  1984.       DebugEnd (pK->debug);
  1985.    }
  1986.    if (extendedLength > 0) {
  1987.       DebugBegin (pK->debug, debugInit);
  1988.       DebugString (pK->debug, "    ");
  1989.       DebugChar (pK->debug, pExtended[0]);
  1990.       DebugString (pK->debug, " Window size =");
  1991.       DebugInt (pK->debug, pExtended[0] - 32);
  1992.       DebugEnd (pK->debug);
  1993.    }
  1994.    if (extendedLength > 2) {
  1995.       long    packetSize = (pExtended[1] - 32) * 95 + (pExtended[2] - 32);
  1996.  
  1997.       if (capabilities[0] & 16)
  1998.          packetSize *= 95;
  1999.       DebugBegin (pK->debug, debugInit);
  2000.       DebugString (pK->debug, "    ");
  2001.       DebugChar (pK->debug, pExtended[1]);
  2002.       DebugChar (pK->debug, pExtended[2]);
  2003.       DebugString (pK->debug, " Extended packet size =");
  2004.       DebugInt (pK->debug, packetSize);
  2005.       DebugEnd (pK->debug);
  2006.    }
  2007. }
  2008. STATIC void KParseYourInit
  2009.         (KERMIT_PRIVATE *pK, BYTE *yourInit,
  2010.          unsigned yourInitLength) {
  2011.    BYTE   *pYourExtended;
  2012.    int     yourExtendedLength;
  2013.    long    maxPacketSize;
  2014.  
  2015.    maxPacketSize = 89;
  2016.    if (yourInitLength > 0) {
  2017.       maxPacketSize = yourInit[0] - 32 - 5;
  2018.       if (maxPacketSize < 20)
  2019.          maxPacketSize = 20;
  2020.    }
  2021.    if (yourInitLength > 1)
  2022.       pK->my.timeout = yourInit[1] - 32;
  2023.    else
  2024.       pK->my.timeout = 10;
  2025.    if (yourInitLength > 2)
  2026.       pK->my.padCount = yourInit[2] - 32;
  2027.    else
  2028.       pK->my.padCount = 0;
  2029.    if (yourInitLength > 3)
  2030.       pK->my.padByte = yourInit[3] ^ 0x40;
  2031.    else
  2032.       pK->my.padByte = 0;
  2033.    if (yourInitLength > 4)
  2034.       pK->my.packetTerminator = yourInit[4] - 32;
  2035.    else
  2036.       pK->my.packetTerminator = 0x0D;
  2037.    if (yourInitLength > 5)
  2038.       pK->your.prefixControl = yourInit[5];
  2039.    else
  2040.       pK->your.prefixControl = '#';
  2041.    if (yourInitLength > 6) {
  2042.       char    mine = pK->my.prefix8bit;
  2043.       char    yours = yourInit[6];
  2044.  
  2045.       if (mine == 'Y')
  2046.          mine = yours;
  2047.       if (yours == 'Y')
  2048.          yours = mine;
  2049.       if (mine == yours) {
  2050.          if (mine < '!')
  2051.             yours = 0;
  2052.          if ((mine > '>') && (mine < '`'))
  2053.             yours = 0;
  2054.          if (mine > '&')
  2055.             yours = 0;
  2056.       } else
  2057.          yours = 0;
  2058.       pK->my.prefix8bit = yours;
  2059.       pK->your.prefix8bit = yours;
  2060.    } else {
  2061.       pK->my.prefix8bit = 0;
  2062.       pK->your.prefix8bit = 0;
  2063.    }
  2064.    if (yourInitLength > 7) {
  2065.       switch (yourInit[7]) {
  2066.       case '1':
  2067.       default:
  2068.          pK->your.preferredPacketCheck = '1';
  2069.          break;
  2070.       case '2':
  2071.       case '3':
  2072.       case 'B':
  2073.          pK->your.preferredPacketCheck = yourInit[7];
  2074.          break;
  2075.       }
  2076.    } else {
  2077.       pK->your.preferredPacketCheck = '1';
  2078.       pK->my.preferredPacketCheck = pK->your.preferredPacketCheck;
  2079.    }
  2080.    if (yourInitLength > 8) {
  2081.       pK->your.prefixRepeat = yourInit[8];
  2082.    } else
  2083.       pK->your.prefixRepeat = 0;
  2084.    if (pK->your.prefixRepeat == ' ')
  2085.       pK->your.prefixRepeat = 0;
  2086.    if (yourInitLength > 9) {
  2087.       int     i = 0;
  2088.       BYTE    thisCapability;
  2089.  
  2090.       do {
  2091.          thisCapability = yourInit[i + 9] - 32;
  2092.          if (i < sizeof (pK->your.capabilities))
  2093.             pK->your.capabilities[i] = thisCapability;
  2094.          i++;
  2095.       } while ((yourInitLength > i + 9) && (thisCapability & 1));
  2096.       pYourExtended = yourInit + (i + 9);
  2097.       yourExtendedLength = yourInitLength - (i + 9);
  2098.    } else {
  2099.       pYourExtended = NULL;
  2100.       yourExtendedLength = 0;
  2101.    }
  2102.    if (yourExtendedLength > 0) {
  2103.       int     windowSize = 1;
  2104.  
  2105.       if (pK->your.capabilities[0] & 4)
  2106.          windowSize = pYourExtended[0] - 32;
  2107.       if (windowSize < pK->windowSize) {
  2108.          pK->windowSize = windowSize;
  2109.          if (pK->debug) {
  2110.             DebugBegin (pK->debug, debugInit);
  2111.             DebugString (pK->debug, "Setting window size to ");
  2112.             DebugInt (pK->debug, windowSize);
  2113.             DebugEnd (pK->debug);
  2114.          }
  2115.       }
  2116.    } else
  2117.       pK->windowSize = 1;
  2118.    if (pK->your.capabilities[0] & 2) {
  2119.       if (yourExtendedLength > 2) {
  2120.          int     packetSize = (pYourExtended[1] - 32) * 95 + (pYourExtended[2] - 32);
  2121.  
  2122.          if (pK->your.capabilities[0] & 16)
  2123.             packetSize *= 95;
  2124.          packetSize -= 3;
  2125.          if (packetSize > maxPacketSize)
  2126.             maxPacketSize = packetSize;
  2127.       } else
  2128.          maxPacketSize = 497;
  2129.    }
  2130.    if (maxPacketSize < pK->my.maxPacketSize) {
  2131.       pK->my.maxPacketSize = maxPacketSize;
  2132.       if (pK->debug) {
  2133.          DebugBegin (pK->debug, debugInit);
  2134.          DebugString (pK->debug, "Setting maximum packet size to ");
  2135.          DebugInt (pK->debug, pK->my.maxPacketSize);
  2136.          DebugEnd (pK->debug);
  2137.       }
  2138.    }
  2139. }
  2140. STATIC void KBuildMyInit
  2141.         (KERMIT_PRIVATE *pK, BYTE *myInit,
  2142.          unsigned *pMyInitLength) {
  2143.    BYTE   *pMyExtended;
  2144.    int     myInitLength = 0;
  2145.  
  2146.    myInit[0] = ((pK->your.maxPacketSize > 94) ? 94 : pK->your.maxPacketSize) + 32;
  2147.    myInit[1] = pK->your.timeout + 32;
  2148.    myInit[2] = pK->your.padCount + 32;
  2149.    myInit[3] = pK->your.padByte ^ 0x40;
  2150.    myInit[4] = pK->your.packetTerminator + 32;
  2151.    myInit[5] = pK->my.prefixControl;
  2152.    if (pK->my.prefix8bit)
  2153.       myInit[6] = pK->my.prefix8bit;
  2154.    else
  2155.       myInit[6] = 'N';
  2156.    myInit[7] = pK->my.preferredPacketCheck;
  2157.    if (pK->my.prefixRepeat)
  2158.       myInit[8] = pK->my.prefixRepeat;
  2159.    else
  2160.       myInit[8] = ' ';
  2161.    pK->my.capabilities[0] = 0;
  2162.    pK->my.capabilities[0] |= 2;
  2163.    pK->my.capabilities[0] |= 4;
  2164.    pK->my.capabilities[0] |= 8;
  2165.    if (pK->your.maxPacketSize > 9024)
  2166.       pK->my.capabilities[0] |= 16;
  2167.    pK->my.capabilities[0] |= 32;
  2168.    {
  2169.       BYTE   *source = pK->my.capabilities;
  2170.  
  2171.       pMyExtended = myInit + 9;
  2172.       do {
  2173.          *pMyExtended++ = *source + 32;
  2174.       } while (*source++ & 1);
  2175.       if (pK->my.capabilities[0] & 4)
  2176.          *pMyExtended++ = pK->windowSize + 32;
  2177.       else
  2178.          *pMyExtended++ = 1 + 32;
  2179.       {
  2180.          long    extendedPacketSize = pK->your.maxPacketSize;
  2181.  
  2182.          if (pK->my.capabilities[0] & 16)
  2183.             extendedPacketSize /= 95;
  2184.          if (extendedPacketSize > 9024)
  2185.             extendedPacketSize = 9024;
  2186.          *pMyExtended++ = (extendedPacketSize / 95) + 32;
  2187.          *pMyExtended++ = (extendedPacketSize % 95) + 32;
  2188.       }
  2189.       myInitLength = pMyExtended - myInit;
  2190.    }
  2191.    *pMyInitLength = myInitLength;
  2192. }
  2193. STATIC int KSendInitiate
  2194.         (KERMIT_PRIVATE *pK) {
  2195.    BYTE   *myInit = pK->txPacket;
  2196.    unsigned myInitLength;
  2197.  
  2198.    KBuildMyInit (pK, myInit, &myInitLength);
  2199.    if (pK->debug)
  2200.       KDumpInitString (pK, myInit, myInitLength);
  2201.    StsRet (KSendPacketReliable (pK, 'S', myInit, myInitLength));
  2202.    if (pK->debug)
  2203.       KDumpInitString (pK, pK->rxPacket, pK->rxPacketLength);
  2204.    KParseYourInit (pK, pK->rxPacket, pK->rxPacketLength);
  2205.    StsRet (KInitWindow (pK));
  2206.    if (pK->my.preferredPacketCheck == pK->your.preferredPacketCheck)
  2207.       pK->packetCheck = pK->my.preferredPacketCheck;
  2208.    else
  2209.       pK->packetCheck = '1';
  2210.    pK->lockingShift = pK->your.capabilities[0] & pK->my.capabilities[0] & 32;
  2211.    if (!pK->my.prefix8bit)
  2212.       pK->lockingShift = 0;
  2213.    KInitEncoding (pK);
  2214.    return kOK;
  2215. }
  2216. STATIC int KReceiveNegotiate
  2217.         (KERMIT_PRIVATE *pK, BYTE *yourInit,
  2218.          unsigned yourInitLength) {
  2219.    BYTE    myInit[100];
  2220.    unsigned myInitLength;
  2221.  
  2222.    if (pK->debug)
  2223.       KDumpInitString (pK, yourInit, yourInitLength);
  2224.    KParseYourInit (pK, yourInit, yourInitLength);
  2225.    StsRet (KInitWindow (pK));
  2226.    if (pK->your.timeout < pK->my.timeout + 5)
  2227.       pK->your.timeout = pK->my.timeout + 5;
  2228.    if (pK->your.timeout < 2 * pK->my.timeout)
  2229.       pK->your.timeout = 2 * pK->my.timeout;
  2230.    pK->my.preferredPacketCheck = pK->your.preferredPacketCheck;
  2231.    pK->my.prefixRepeat = pK->your.prefixRepeat;
  2232.    {
  2233.       int     i = 0;
  2234.  
  2235.       for (i = 0; i < sizeof (pK->my.capabilities); i++)
  2236.          pK->my.capabilities[i] &= pK->your.capabilities[i];
  2237.    }
  2238.    KBuildMyInit (pK, myInit, &myInitLength);
  2239.    if (pK->debug)
  2240.       KDumpInitString (pK, myInit, myInitLength);
  2241.    StsRet (KSendResponse (pK, 'Y', myInit, myInitLength));
  2242.    pK->packetCheck = pK->my.preferredPacketCheck;
  2243.    pK->lockingShift = pK->your.capabilities[0] & pK->my.capabilities[0] & 32;
  2244.    if (!pK->my.prefix8bit)
  2245.       pK->lockingShift = 0;
  2246.    KInitEncoding (pK);
  2247.    return kOK;
  2248. }
  2249. STATIC int KServer
  2250.         (KERMIT_PRIVATE *pK) {
  2251.    int     defaultTimeout = pK->my.timeout;
  2252.  
  2253.    KProgress (pK, stsNegotiating);
  2254.    while (TRUE) {
  2255.       KResetSequence (pK);
  2256.       if (pK->serverMode) {
  2257.          defaultTimeout = pK->my.timeout;
  2258.          pK->my.timeout = -1;
  2259.       }
  2260.       StsRet (KReceivePacketReliable (pK));
  2261.       pK->my.timeout = defaultTimeout;
  2262.       switch (pK->rxPacketType) {
  2263.       case 'S':
  2264.          KReceiveNegotiate (pK, pK->rxPacket, pK->rxPacketLength);
  2265.          StsRet (KReceiveFiles (pK));
  2266.          if (!pK->serverMode)
  2267.             return kOK;
  2268.          break;
  2269.       case 'G':
  2270.          switch (pK->rxPacket[0]) {
  2271.          case 'F':
  2272.             StsRet (KSendResponse (pK, 'Y', NULL, 0));
  2273.             return kOK;
  2274.          case 'L':
  2275.             StsRet (KSendResponse (pK, 'Y', NULL, 0));
  2276.             return kOK;
  2277.          default:
  2278.             StsRet (KSendResponse (pK, 'E', (const BYTE *) "Command not implemented", 23));
  2279.          }
  2280.          pK->serverMode = TRUE;
  2281.          break;
  2282.       case 'R':
  2283.       case 'I':
  2284.       case 'X':
  2285.       case 'C':
  2286.       case 'K':
  2287.          pK->serverMode = TRUE;
  2288.       default:
  2289.          StsRet (KSendResponse (pK, 'E', (const BYTE *) "Command not implemented", 23));
  2290.          break;
  2291.       }
  2292.    }
  2293. }
  2294. int     KermitInit
  2295.         (KERMIT *pKPublic, SERIAL_PORT port) {
  2296.    KERMIT_PRIVATE *pK;
  2297.  
  2298.    pK = malloc (sizeof (*pK));
  2299.    if (pK == NULL)
  2300.       return 1;
  2301.    memset (pK, 0, sizeof (*pK));
  2302.    pK->sending = TRUE;
  2303.    pK->userCancel = 0;
  2304.    pK->debug = NULL;
  2305.    KInitCrc ();
  2306.    pK->port = NULL;
  2307.    pK->f = NULL;
  2308.    pK->fileSize = -1;
  2309.    pK->filenames = NULL;
  2310.    pK->currentFileName = 0;
  2311.    pK->numFileNames = 0;
  2312.    pK->fileType = diskFileUnknown;
  2313.    pK->progress = NULL;
  2314.    pK->filePosition = 0;
  2315.    {
  2316.       pK->pFileBuffer = (BYTE *) malloc (FILE_BUFFER_SIZE);
  2317.       if (pK->pFileBuffer == NULL)
  2318.          return 1;
  2319.       pK->fileBufferSize = FILE_BUFFER_SIZE;
  2320.       pK->pFileThisChar = pK->pFileBuffer;
  2321.       pK->pFileBufferLimit = pK->pFileBuffer;
  2322.       pK->eofFlag = 0;
  2323.    }
  2324.    pK->your.prefixControl = '#';
  2325.    pK->my.prefixControl = '#';
  2326.    pK->your.prefix8bit = 'N';
  2327.    pK->my.prefix8bit = 'Y';
  2328.    pK->your.prefixRepeat = '~';
  2329.    pK->my.prefixRepeat = '~';
  2330.    pK->lockingShift = FALSE;
  2331.    pK->lockingFlip = 0;
  2332.    pK->quoteNext = 0;
  2333.    pK->your.preferredPacketCheck = '1';
  2334.    pK->my.preferredPacketCheck = '1';
  2335.    pK->packetCheck = '1';
  2336.    pK->your.sopCharacter = 0xff;
  2337.    pK->my.sopCharacter = 0xff;
  2338.    pK->your.maxPacketSize = 90;
  2339.    pK->my.maxPacketSize = 80;
  2340.    pK->my.timeout = 30;
  2341.    pK->your.timeout = 10;
  2342.    pK->your.padCount = 0;
  2343.    pK->my.padCount = 0;
  2344.    pK->your.padByte = 0;
  2345.    pK->my.padByte = 0;
  2346.    pK->your.packetTerminator = 0x0d;
  2347.    pK->my.packetTerminator = 0x0d;
  2348.    {
  2349.       int     i;
  2350.  
  2351.       pK->exchange[0].sequence = 0;
  2352.       pK->exchange[0].packetCheck = '1';
  2353.       pK->exchange[0].myPacket = NULL;
  2354.       pK->exchange[0].myPacketLength = 0;
  2355.       pK->exchange[0].myPacketType = 0;
  2356.       pK->exchange[0].yourPacket = NULL;
  2357.       pK->exchange[0].yourPacketLength = 0;
  2358.       pK->exchange[0].yourPacketType = 0;
  2359.       for (i = 1; i < 64; i++) {
  2360.          pK->exchange[i] = pK->exchange[0];
  2361.          pK->exchange[i].sequence = i;
  2362.       }
  2363.    }
  2364.    pK->rxPacket = NULL;
  2365.    pK->rxPacketLength = 0;
  2366.    pK->rxPacketType = 0;
  2367.    pK->txPacket = NULL;
  2368.    pK->txPacketLength = 0;
  2369.    pK->currentWindowSize = 1;
  2370.    pK->windowSize = 1;
  2371.    pK->minCache = 0;
  2372.    pK->maxUsed = 0;
  2373.    pK->minUsed = 0;
  2374.    pK->sequence = 0;
  2375.    pK->retries = 10;
  2376.    pK->rawBufferLength = 0;
  2377.    pK->rawBuffer = NULL;
  2378.    pK->rawBufferPacketSize = 0;
  2379.    pK->spareExchange = pK->exchange[0];
  2380.    {
  2381.       int     i;
  2382.  
  2383.       for (i = 0; i < 5; i++) {
  2384.          pK->your.capabilities[i] = 0;
  2385.          pK->my.capabilities[i] = 0;
  2386.       }
  2387.    }
  2388.    pK->serverMode = FALSE;
  2389.    KInitWindow (pK);
  2390.    pK->port = port;
  2391.    *pKPublic = pK;
  2392.    return 0;
  2393. }
  2394. int     KermitDestroy
  2395.         (KERMIT kPublic) {
  2396.    KERMIT_PRIVATE *pK = (KERMIT_PRIVATE *) kPublic;
  2397.  
  2398.    free (pK->pFileBuffer);
  2399.    return 0;
  2400. }
  2401. int     KermitSetFast
  2402.         (KERMIT kPublic, int speed) {
  2403.    KERMIT_PRIVATE *pK = (KERMIT_PRIVATE *) kPublic;
  2404.    int     packetSize = 90, windowSize = 1;
  2405.  
  2406.    if (speed <= 0)
  2407.       return 1;
  2408.    switch (speed) {
  2409.    default:
  2410.    case 8:
  2411.       packetSize = 9024;
  2412.       windowSize = 32;
  2413.       break;
  2414.    case 7:
  2415.       packetSize = 4096;
  2416.       windowSize = 31;
  2417.       break;
  2418.    case 6:
  2419.       packetSize = 2048;
  2420.       windowSize = 31;
  2421.       break;
  2422.    case 5:
  2423.       packetSize = 1024;
  2424.       windowSize = 16;
  2425.       break;
  2426.    case 4:
  2427.       packetSize = 256;
  2428.       windowSize = 16;
  2429.       break;
  2430.    case 3:
  2431.       packetSize = 128;
  2432.       windowSize = 16;
  2433.       break;
  2434.    case 2:
  2435.       packetSize = 90;
  2436.       windowSize = 11;
  2437.       break;
  2438.    case 1:
  2439.       packetSize = 1024;
  2440.       windowSize = 1;
  2441.       break;
  2442.    }
  2443.    pK->your.maxPacketSize = packetSize;
  2444.    pK->my.maxPacketSize = packetSize;
  2445.    pK->windowSize = windowSize;
  2446.    if (packetSize > 500)
  2447.       pK->my.preferredPacketCheck = '3';
  2448.    else if (packetSize > 90)
  2449.       pK->my.preferredPacketCheck = '2';
  2450.    return 0;
  2451. }
  2452. int     KermitSetDebug
  2453.         (KERMIT kPublic, DEBUG debug) {
  2454.    KERMIT_PRIVATE *pK = (KERMIT_PRIVATE *) kPublic;
  2455.  
  2456.    pK->debug = debug;
  2457.    return 0;
  2458. }
  2459. int     KermitSetProgress
  2460.         (KERMIT kPublic, PROGRESS progress) {
  2461.    KERMIT_PRIVATE *pK = (KERMIT_PRIVATE *) kPublic;
  2462.  
  2463.    pK->progress = progress;
  2464.    return 0;
  2465. }
  2466. int     KermitSetFileType
  2467.         (KERMIT kPublic, int fileType) {
  2468.    KERMIT_PRIVATE *pK = (KERMIT_PRIVATE *) kPublic;
  2469.  
  2470.    pK->fileType = fileType;
  2471.    return 0;
  2472. }
  2473. int     KermitSend
  2474.         (KERMIT kPublic, const char *filenames[], int numFiles) {
  2475.    KERMIT_PRIVATE *pK = (KERMIT_PRIVATE *) kPublic;
  2476.    int     returnVal = 0;
  2477.  
  2478.    pK->filenames = filenames;
  2479.    pK->numFileNames = numFiles;
  2480.    pK->currentFileName = 0;
  2481.    pK->sending = TRUE;
  2482.    ProgressSending (pK->progress);
  2483.    if (KSendFiles (pK) != kOK)
  2484.       returnVal = 1;
  2485.    return returnVal;
  2486. }
  2487. int     KermitReceive
  2488.         (KERMIT kPublic) {
  2489.    KERMIT_PRIVATE *pK = (KERMIT_PRIVATE *) kPublic;
  2490.    int     returnVal = 0;
  2491.  
  2492.    pK->sending = FALSE;
  2493.    ProgressReceiving (pK->progress);
  2494.    if (KServer (pK) != kOK)
  2495.       returnVal = 1;
  2496.    return returnVal;
  2497. }
  2498. int     KermitServer
  2499.         (KERMIT kPublic) {
  2500.    KERMIT_PRIVATE *pK = (KERMIT_PRIVATE *) kPublic;
  2501.    int     returnVal = 0;
  2502.  
  2503.    pK->serverMode = TRUE;
  2504.    pK->sending = FALSE;
  2505.    ProgressReceiving (pK->progress);
  2506.    if (KServer (pK) != kOK)
  2507.       returnVal = 1;
  2508.    return returnVal;
  2509. }
  2510. int     KermitCancel
  2511.         (KERMIT kPublic) {
  2512.    KERMIT_PRIVATE *pK = (KERMIT_PRIVATE *) kPublic;
  2513.  
  2514.    pK->userCancel = TRUE;
  2515.    return 0;
  2516. }
  2517.