home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / panix / ek17.tar.gz / ek17.tar / kermit.c < prev    next >
C/C++ Source or Header  |  2011-06-06  |  53KB  |  1,620 lines

  1. #define KERMIT_C
  2. /*
  3.   Embedded Kermit protocol module
  4.   Version: 1.7
  5.   Most Recent Update: Mon Jun  6 15:36:26 2011
  6.  
  7.   No stdio or other runtime library calls, no system calls, no system 
  8.   includes, no static data, and no global variables in this module.
  9.  
  10.   Warning: you can't use debug() in any routine whose argument list
  11.   does not include "struct k_data * k".  Thus most routines in this
  12.   module include this arg, even if they don't use it.
  13.  
  14.   Author: Frank da Cruz.
  15.   As of version 1.6 of 30 March 2011, E-Kermit is Open Source software under
  16.   the Revised 3-Clause BSD license which follows.  E-Kermit 1.6 is identical
  17.   to version 1.51 except for the new license.
  18.  
  19.   Author: Frank da Cruz.
  20.  
  21.   Copyright (C) 1995, 2011, 
  22.   Trustees of Columbia University in the City of New York.
  23.   All rights reserved.
  24.  
  25.   Redistribution and use in source and binary forms, with or without
  26.   modification, are permitted provided that the following conditions are met:
  27.  
  28.   * Redistributions of source code must retain the above copyright notice,
  29.     this list of conditions and the following disclaimer.
  30.  
  31.   * Redistributions in binary form must reproduce the above copyright notice,
  32.     this list of conditions and the following disclaimer in the documentation
  33.     and/or other materials provided with the distribution.
  34.  
  35.   * Neither the name of Columbia University nor the names of its contributors
  36.     may be used to endorse or promote products derived from this software
  37.     without specific prior written permission.
  38.   
  39.   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  40.   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  41.   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  42.   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  43.   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  44.   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  45.   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  46.   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  47.   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  48.   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  49.   POSSIBILITY OF SUCH DAMAGE.
  50. */
  51. #include "cdefs.h"            /* C language defs for all modules */
  52. #include "debug.h"            /* Debugging */
  53. #include "kermit.h"            /* Kermit protocol definitions */
  54.  
  55. #define zgetc() \
  56. ((--(k->zincnt))>=0)?((int)(*(k->zinptr)++)&0xff):(*(k->readf))(k)
  57.  
  58. /* See cdefs.h for meaning of STATIC, ULONG, and UCHAR */
  59.  
  60. STATIC ULONG stringnum(UCHAR *, struct k_data *);
  61. STATIC UCHAR * numstring(ULONG, UCHAR *, int, struct k_data *);
  62. int STATIC spkt(char, short, int, UCHAR *, struct k_data *);
  63. int STATIC ack(struct k_data *, short, UCHAR * text);
  64. int STATIC nak(struct k_data *, short, short);
  65. int STATIC chk1(UCHAR *, struct k_data *);
  66. STATIC USHORT chk2(UCHAR *, struct k_data *);
  67. #ifdef F_CRC
  68. STATIC USHORT chk3(UCHAR *, struct k_data *);
  69. #endif /* F_CRC */
  70. void STATIC spar(struct k_data *, UCHAR *, int);
  71. int STATIC rpar(struct k_data *, char);
  72. int STATIC decode(struct k_data *, struct k_response *, short, UCHAR *);
  73. #ifdef F_AT
  74. int STATIC gattr(struct k_data *, UCHAR *, struct k_response *);
  75. int STATIC sattr(struct k_data *, struct k_response *);
  76. #endif /* F_AT */
  77. #ifndef RECVONLY
  78. int STATIC sdata(struct k_data *, struct k_response *);
  79. #endif /* RECVONLY */
  80. void STATIC epkt(char *, struct k_data *);
  81. int STATIC getpkt(struct k_data *, struct k_response *);
  82. int STATIC encstr(UCHAR *, struct k_data *, struct k_response *);
  83. void STATIC decstr(UCHAR *, struct k_data *, struct k_response *);
  84. void STATIC encode(int, int, struct k_data *);
  85. int STATIC nxtpkt(struct k_data *);
  86. int STATIC resend(struct k_data *);
  87. #ifdef DEBUG
  88. int xerror(void);
  89. #endif /* DEBUG */
  90.  
  91. int                    /* The kermit() function */
  92. kermit(short f,                /* Function code */
  93.        struct k_data *k,        /* The control struct */
  94.        short r_slot,            /* Received packet slot number */
  95.        int len,                /* Length of packet in slot */
  96.        char *msg,            /* Message for error packet */
  97.        struct k_response *r) {        /* Response struct */
  98.  
  99.     int i, j, rc;            /* Workers */
  100.     int datalen;                        /* Length of packet data field */
  101.     UCHAR *p;                           /* Pointer to packet data field */
  102.     UCHAR *q;                           /* Pointer to data to be checked */
  103.     UCHAR *s;                /* Worker string pointer */
  104.     UCHAR c, t;                         /* Worker chars */
  105.     UCHAR pbc[4];                       /* Copy of packet block check */
  106.     short seq, prev;            /* Copies of sequence numbers */
  107.     short chklen;                       /* Length of packet block check */
  108. #ifdef F_CRC
  109.     unsigned int crc;                   /* 16-bit CRC */
  110. #endif /* F_CRC */
  111.     int ok;
  112.  
  113.     debug(DB_MSG,"----------",0,0);    /* Marks each entry */
  114.     debug(DB_LOG,"f",0,f);
  115.     debug(DB_LOG,"state",0,k->state);
  116.     debug(DB_LOG,"zincnt",0,(k->zincnt));
  117.  
  118.     if (f == K_INIT) {            /* Initialize packet buffers etc */
  119.  
  120.     k->version = (UCHAR *)VERSION;    /* Version of this module */
  121.         r->filename[0] = '\0';        /* No filename yet. */
  122.         r->filedate[0] = '\0';        /* No filedate yet. */
  123.         r->filesize = 0L;               /* No filesize yet. */
  124.     r->sofar = 0L;            /* No bytes transferred yet */
  125.  
  126.         for (i = 0; i < P_WSLOTS; i++) { /* Packet info for each window slot */
  127.         freerslot(k,i);
  128.         freesslot(k,i);
  129.     }
  130. #ifdef F_TSW
  131.         for (i = 0; i < 64; i++) {    /* Packet finder array */
  132.         k->r_pw[i] = -1;        /* initialized to "no packets yet" */
  133.         k->s_pw[i] = -1;        /* initialized to "no packets yet" */
  134.     }
  135. #endif /* F_TSW */
  136.  
  137. /* Initialize the k_data structure */    
  138.  
  139.     for (i = 0; i < 6; i++)
  140.       k->s_remain[i] = '\0';
  141.  
  142.         k->state    = R_WAIT;        /* Beginning protocol state */
  143.     r->status   = R_WAIT;
  144.     k->what     = W_RECV;        /* Default action */
  145.     k->s_first  = 1;        /* Beginning of file */
  146.         k->r_soh    = k->s_soh = SOH;    /* Packet start */
  147.         k->r_eom    = k->s_eom = CR;    /* Packet end */
  148.         k->s_seq    = k->r_seq =  0;    /* Packet sequence number */
  149.         k->s_type   = k->r_type = 0;    /* Packet type */
  150.         k->r_timo   = P_R_TIMO;        /* Timeout interval for me to use */
  151.         k->s_timo   = P_S_TIMO;        /* Timeout for other Kermit to use */
  152.         k->r_maxlen = P_PKTLEN;         /* Maximum packet length */
  153.         k->s_maxlen = P_PKTLEN;         /* Maximum packet length */
  154.         k->window   = P_WSLOTS;        /* Maximum window slots */
  155.         k->wslots   = 1;        /* Current window slots */
  156.     k->zincnt   = 0;
  157.     k->dummy    = 0;
  158.     k->filename = (UCHAR *)0;
  159.  
  160.         /* Parity must be filled in by the caller */
  161.  
  162.         k->retry  = P_RETRY;            /* Retransmission limit */
  163.         k->s_ctlq = k->r_ctlq = '#';    /* Control prefix */
  164.         k->ebq    = 'Y';        /* 8th-bit prefix negotiation */
  165.     k->ebqflg = 0;            /* 8th-bit prefixing flag */
  166.         k->rptq   = '~';        /* Send repeat prefix */
  167.         k->rptflg = 0;                  /* Repeat counts negotiated */
  168.     k->s_rpt  = 0;            /* Current repeat count */
  169.         k->capas  = 0                   /* Capabilities */
  170. #ifdef F_LP
  171.           | CAP_LP                      /* Long packets */
  172. #endif /* F_LP */
  173. #ifdef F_SW
  174.             | CAP_SW                    /* Sliding windows */
  175. #endif /* F_SW */
  176. #ifdef F_AT
  177.               | CAP_AT                  /* Attribute packets */
  178. #endif /* F_AT */
  179.                 ;
  180.  
  181.     k->opktbuf[0] = '\0';        /* No packets sent yet. */
  182.     k->opktlen = 0;
  183.  
  184. #ifdef F_CRC
  185. /* This is the only way to initialize these tables -- no static data. */
  186.  
  187.         k->crcta[ 0] =       0;        /* CRC generation table A */
  188.         k->crcta[ 1] =  010201;
  189.         k->crcta[ 2] =  020402;
  190.         k->crcta[ 3] =  030603;
  191.         k->crcta[ 4] =  041004;
  192.         k->crcta[ 5] =  051205;
  193.         k->crcta[ 6] =  061406;
  194.         k->crcta[ 7] =  071607;
  195.         k->crcta[ 8] = 0102010;
  196.         k->crcta[ 9] = 0112211;
  197.         k->crcta[10] = 0122412;
  198.         k->crcta[11] = 0132613;
  199.         k->crcta[12] = 0143014,
  200.         k->crcta[13] = 0153215;
  201.         k->crcta[14] = 0163416;
  202.         k->crcta[15] = 0173617;
  203.  
  204.         k->crctb[ 0] =       0;        /* CRC table B */
  205.         k->crctb[ 1] =  010611;
  206.         k->crctb[ 2] =  021422;
  207.         k->crctb[ 3] =  031233;
  208.         k->crctb[ 4] =  043044;
  209.         k->crctb[ 5] =  053655;
  210.         k->crctb[ 6] =  062466;
  211.         k->crctb[ 7] =  072277;
  212.         k->crctb[ 8] = 0106110;
  213.         k->crctb[ 9] = 0116701;
  214.         k->crctb[10] = 0127532;
  215.         k->crctb[11] = 0137323;
  216.         k->crctb[12] = 0145154;
  217.         k->crctb[13] = 0155745;
  218.         k->crctb[14] = 0164576;
  219.         k->crctb[15] = 0174367;
  220. #endif /* F_CRC */
  221.  
  222.     return(X_OK);
  223.  
  224. #ifndef RECVONLY
  225.     } else if (f == K_SEND) {
  226.     if (rpar(k,'S') != X_OK)    /* Send S packet with my parameters */
  227.       return(X_ERROR);        /* I/O error, quit. */
  228.     k->state = S_INIT;        /* All OK, switch states */
  229.     r->status = S_INIT;
  230.     k->what = W_SEND;        /* Act like a sender */
  231.         return(X_OK);
  232. #endif /* RECVONLY */
  233.  
  234.     } else if (f == K_STATUS) {         /* Status report requested. */
  235.         return(X_STATUS);               /* File name, date, size, if any. */
  236.  
  237.     } else if (f == K_QUIT) {           /* You told me to quit */
  238.         return(X_DONE);                 /* so I quit. */
  239.  
  240.     } else if (f == K_ERROR) {          /* Send an error packet... */
  241.         epkt(msg,k);
  242.     k->closef(k,0,(k->state == S_DATA) ? 1 : 2); /* Close file */
  243.         return(X_DONE);                 /* and quit. */
  244.  
  245.     } else if (f != K_RUN) {            /* Anything else is an error. */
  246.         return(X_ERROR);
  247.     }
  248.     if (k->state == R_NONE)             /* (probably unnecessary) */
  249.       return(X_OK);
  250.  
  251. /* If we're in the protocol, check to make sure we got a new packet */
  252.  
  253.     debug(DB_LOG,"r_slot",0,r_slot);
  254.     debug(DB_LOG,"len",0,len);
  255.  
  256.     if (r_slot < 0)            /* We should have a slot here */
  257.       return(K_ERROR);
  258.     else
  259.       k->ipktinfo[r_slot].len = len;    /* Copy packet length to ipktinfo. */
  260.     
  261.     if (len < 4) {            /* Packet obviously no good? */
  262. #ifdef RECVONLY
  263.     return(nak(k,k->r_seq,r_slot)); /* Send NAK for the packet we want */
  264. #else
  265.     if (k->what == W_RECV)        /* If receiving */
  266.       return(nak(k,k->r_seq,r_slot)); /* Send NAK for the packet we want */
  267.     else                /* If sending */
  268.       return(resend(k));        /* retransmit last packet. */
  269. #endif /* RECVONLY */
  270.     }
  271.  
  272. /* Parse the packet */    
  273.  
  274.     if (k->what == W_RECV) {        /* If we're sending ACKs */
  275.     switch(k->cancel) {        /* Get cancellation code if any */
  276.       case 0: s = (UCHAR *)0;   break;
  277.       case 1: s = (UCHAR *)"X"; break;
  278.       case 2: s = (UCHAR *)"Z"; break;
  279.     }
  280.     }
  281.     p = &(k->ipktbuf[0][r_slot]);    /* Point to it */
  282.  
  283.     q = p;                              /* Pointer to data to be checked */
  284.     k->ipktinfo[r_slot].len = xunchar(*p++); /* Length field */
  285.     seq = k->ipktinfo[r_slot].seq = xunchar(*p++); /* Sequence number */
  286.     t = k->ipktinfo[r_slot].typ = *p++;    /* Type */
  287.  
  288.     if (
  289. #ifndef RECVONLY
  290.     (k->what == W_RECV) &&        /* Echo (it happens), ignore */
  291. #endif /* RECVONLY */
  292.     (t == 'N' || t  == 'Y')) {
  293.         freerslot(k,r_slot);
  294.         return(X_OK);
  295.     }
  296.     k->ipktinfo[r_slot].dat = p;    /* Data field, maybe */
  297. #ifdef F_LP
  298.     if (k->ipktinfo[r_slot].len == 0) {    /* Length 0 means long packet */
  299.         c = p[2];                       /* Get header checksum */
  300.         p[2] = '\0';
  301.         if (xunchar(c) != chk1(p-3,k)) {  /* Check it */
  302.             freerslot(k,r_slot);    /* Bad */
  303.         debug(DB_MSG,"HDR CHKSUM BAD",0,0);
  304. #ifdef RECVONLY
  305.         return(nak(k,k->r_seq,r_slot)); /* Send NAK */
  306. #else
  307.         if (k->what == W_RECV)
  308.           return(nak(k,k->r_seq,r_slot)); /* Send NAK */
  309.         else
  310.           return(resend(k));
  311. #endif /* RECVONLY */
  312.         }
  313.     debug(DB_MSG,"HDR CHKSUM OK",0,0);
  314.         p[2] = c;                       /* Put checksum back */
  315.     /* Data length */
  316.         datalen = xunchar(p[0])*95 + xunchar(p[1]) - ((k->bctf) ? 3 : k->bct);
  317.         p += 3;                         /* Fix data pointer */
  318.         k->ipktinfo[r_slot].dat = p;    /* Permanent record of data pointer */
  319.     } else {                            /* Regular packet */
  320. #endif /* F_LP */
  321.         datalen = k->ipktinfo[r_slot].len - k->bct - 2; /* Data length */
  322. #ifdef F_LP
  323.     }
  324. #endif /* F_LP */
  325. #ifdef F_CRC
  326.     if (k->bctf) {            /* FORCE 3 */
  327.     chklen = 3;
  328.     } else {
  329.     if (t == 'S' || k->state == S_INIT) { /* S-packet was retransmitted? */
  330.         if (q[10] == '5') {        /* Block check type requested is 5 */
  331.         k->bctf = 1;        /* FORCE 3 */
  332.         chklen = 3;
  333.         }
  334.         chklen = 1;            /* Block check is always type 1 */
  335.         datalen = k->ipktinfo[r_slot].len - 3; /* Data length */
  336.     } else {
  337.         chklen = k->bct;
  338.     }
  339.     }
  340. #else
  341.     chklen = 1;                /* Block check is always type 1 */
  342.     datalen = k->ipktinfo[r_slot].len - 3; /* Data length */
  343. #endif /* F_CRC */
  344.     debug(DB_LOG,"bct",0,(k->bct));
  345.     debug(DB_LOG,"datalen",0,datalen);
  346.     debug(DB_LOG,"chkalen",0,chklen);
  347.  
  348. #ifdef F_CRC
  349.     for (i = 0; i < chklen; i++)        /* Copy the block check */
  350.       pbc[i] = p[datalen+i];
  351.     pbc[i] = '\0';            /* Null-terminate block check string */
  352. #else
  353.     pbc[0] = p[datalen];
  354.     pbc[1] = '\0';
  355. #endif /* F_CRC */
  356.     p[datalen] = '\0';            /* and the packet DATA field. */
  357. #ifdef F_CRC
  358.     switch (chklen) {                   /* Check the block check  */
  359.       case 1:                /* Type 1, 6-bit checksum */
  360. #endif /* F_CRC */
  361.     ok = (xunchar(*pbc) == chk1(q,k));
  362. #ifdef DEBUG
  363.     if (ok && xerror()) ok = 0;
  364. #endif /* DEBUG */
  365.     if (!ok) {
  366.         freerslot(k,r_slot);
  367. #ifdef RECVONLY
  368.         nak(k,k->r_seq,r_slot);
  369. #else
  370.         if (k->what == W_RECV)
  371.           nak(k,k->r_seq,r_slot);
  372.         else
  373.           resend(k);
  374. #endif /* RECVONLY */
  375.         return(X_OK);
  376.     }
  377. #ifdef F_CRC
  378.     break;
  379.  
  380.       case 2:                         /* Type 2, 12-bit checksum */
  381.     i = xunchar(*pbc) << 6 | xunchar(pbc[1]);
  382.     ok = (i == chk2(q,k));
  383. #ifdef DEBUG
  384.     if (ok && xerror()) ok = 0;
  385. #endif /* DEBUG */
  386.     if (!ok) {            /* No match */
  387.         if (t == 'E') {        /* Allow E packets to have type 1 */
  388.         int j;
  389.         j = datalen;
  390.         p[j++] = pbc[0];    
  391.         p[j] = '\0';
  392.         if (xunchar(pbc[1]) == chk1(q,k))
  393.           break;
  394.         else
  395.           p[--j] = '\0';
  396.         }
  397.         freerslot(k,r_slot);
  398. #ifdef RECVONLY
  399.         nak(k,k->r_seq,r_slot);
  400. #else
  401.         if (k->what == W_RECV)
  402.           nak(k,k->r_seq,r_slot);
  403.         else
  404.           resend(k);
  405. #endif /* RECVONLY */
  406.         return(X_OK);
  407.     }
  408.     break;
  409.  
  410.       case 3:                /* Type 3, 16-bit CRC */
  411.     crc = (xunchar(pbc[0]) << 12)
  412.       | (xunchar(pbc[1]) << 6)
  413.         | (xunchar(pbc[2]));
  414.     ok = (crc == chk3(q,k));
  415. #ifdef DEBUG
  416.     if (ok && xerror()) {
  417.         ok = 0;
  418.         debug(DB_MSG,"CRC ERROR INJECTED",0,0);
  419.     } 
  420. #endif /* DEBUG */
  421.     if (!ok) {
  422.         debug(DB_LOG,"CRC ERROR t",0,t);
  423.         if (t == 'E') {        /* Allow E packets to have type 1 */
  424.         int j;
  425.         j = datalen;
  426.         p[j++] = pbc[0];    
  427.         p[j++] = pbc[1];
  428.         p[j] = '\0';
  429.         if (xunchar(pbc[2]) == chk1(q,k))
  430.           break;
  431.         else { j -=2; p[j] = '\0'; }
  432.         }
  433.         freerslot(k,r_slot);
  434. #ifdef RECVONLY
  435.         nak(k,k->r_seq,r_slot);
  436. #else
  437.         if (k->what == W_RECV)
  438.           nak(k,k->r_seq,r_slot);
  439.         else
  440.           resend(k);
  441. #endif /* RECVONLY */
  442.         return(X_OK);
  443.     }
  444.     }
  445. #endif /* F_CRC */
  446.     if (t == 'E')            /* (AND CLOSE FILES?) */
  447.       return(X_ERROR);
  448.  
  449.     prev = k->r_seq - 1;        /* Get sequence of previous packet */
  450.     if (prev < 0)
  451.       prev = 63;
  452.  
  453.     debug(DB_LOG,"Seq",0,seq);
  454.     debug(DB_LOG,"Prev",0,prev);
  455.  
  456.     if (seq == k->r_seq) {        /* Is this the packet we want? */
  457.     k->ipktinfo[r_slot].rtr = 0;    /* Yes */
  458.     } else {
  459.         freerslot(k,r_slot);        /* No, discard it. */
  460.  
  461.         if (seq == prev) {              /* If it's the previous packet again */
  462.         debug(DB_LOG,"PREVIOUS PKT RETRIES",0,
  463.           (long)(k->ipktinfo[r_slot].rtr));
  464.             if (k->ipktinfo[r_slot].rtr++ > k->retry) { /* Count retries */
  465.                 epkt("Too many retries", k); /* Too may */
  466.                 return(X_ERROR);    /* Give up */
  467.             } else {            /* Otherwise */
  468.         return(resend(k));    /* Send old outbound packet buffer */
  469.             }
  470. #ifdef RECVONLY
  471.     } else {
  472.         return(nak(k,k->r_seq,r_slot));
  473. #else
  474.         } else if (k->what == W_RECV) {    /* Otherwise NAK the one we want */
  475.         return(nak(k,k->r_seq,r_slot));
  476.     } else {            /* or whatever... */
  477.         return(resend(k));
  478. #endif /* RECVONLY */
  479.     } 
  480.     }
  481. #ifndef RECVONLY
  482.     if (k->what == W_SEND) {        /* Sending, check for ACK */
  483.     if (t != 'Y') {            /* Not an ACK */
  484.         debug(DB_LOG,"t!=Y t",0,t);
  485.         freerslot(k,r_slot);    /* added 2004-06-30 -- JHD */
  486.         return(resend(k));
  487.     }
  488.     if (k->state == S_DATA) {    /* ACK to Data packet?*/
  489.         if (k->cancel ||        /* Cancellation requested by caller? */
  490.         *p == 'X' || *p == 'Z') { /* Or by receiver? */
  491.         k->closef(k,*p,1);      /* Close input file*/
  492.         nxtpkt(k);          /* Next packet sequence number */
  493.         if ((rc = spkt('Z',k->s_seq,0,(UCHAR *)0,k)) != X_OK)
  494.           return(rc);
  495.         if (*p == 'Z' || k->cancel == I_GROUP) { /* Cancel Group? */
  496.             debug(DB_MSG,"Group Cancel (Send)",0,0);
  497.             while (*(k->filelist)) { /* Go to end of file list */
  498.             debug(DB_LOG,"Skip",*(k->filelist),0);
  499.             (k->filelist)++;
  500.             }
  501.         }
  502.         k->state = S_EOF;    /* Wait for ACK to EOF */
  503.         r->status = S_EOF;
  504.         k->r_seq = k->s_seq;    /* Sequence number of packet we want */
  505.         return(X_OK);
  506.         }
  507.     }
  508.     freerslot(k,r_slot);        /* It is, free the ACK. */
  509.     }
  510. #endif /* RECVONLY */
  511.  
  512. /* Now we have an incoming packet with the expected sequence number. */
  513.  
  514.     debug(DB_CHR,"Packet OK",0,t);
  515.     debug(DB_LOG,"State",0,k->state);
  516.  
  517.     switch (k->state) {                 /* Kermit protocol state switcher */ 
  518.  
  519. #ifndef RECVONLY
  520.       case S_INIT:            /* Got other Kermit's parameters */
  521.       case S_EOF:            /* Got ACK to EOF packet */
  522.     nxtpkt(k);            /* Get next packet number etc */
  523.     if (k->state == S_INIT) {    /* Got ACK to S packet? */
  524.         spar(k,p,datalen);        /* Set negotiated parameters */
  525.         debug(DB_CHR,"Parity",0,k->parity);
  526.         debug(DB_LOG,"Ebqflg",0,(k->ebqflg));
  527.         debug(DB_CHR,"Ebq",0,(k->ebq));
  528.     }
  529.     k->filename = *(k->filelist);    /* Get next filename */
  530.     if (k->filename) {        /* If there is one */
  531.         int i;
  532.         for (i = 0; i < FN_MAX; i++) { /* Copy name to result struct */
  533.         r->filename[i] = k->filename[i];
  534.         if (!(r->filename[i]))
  535.             break;
  536.         }
  537.         (k->filelist)++;
  538.         debug(DB_LOG,"Filename",k->filename,0);
  539.         if ((rc = (k->openf)(k,k->filename,1)) != X_OK) /* Try to open */
  540.           return(rc);
  541.         encstr(k->filename,k,r);    /* Encode the name for transmission */
  542.         if ((rc = spkt('F',k->s_seq,-1,k->xdata,k)) != X_OK)
  543.           return(rc);        /* Send F packet */
  544.         r->sofar = 0L;
  545.         k->state = S_FILE;        /* Wait for ACK */
  546.         r->status = S_FILE;
  547.     } else {            /* No more files - we're done */
  548.         if ((rc = spkt('B',k->s_seq,0,(UCHAR *)0,k)) != X_OK)
  549.           return(rc);        /* Send EOT packet */
  550.         k->state = S_EOT;        /* Wait for ACK */
  551.         r->status = S_EOT;
  552.     }
  553.     k->r_seq = k->s_seq;        /* Sequence number of packet we want */
  554.     return(X_OK);            /* Return to control program */
  555.  
  556.       case S_FILE:            /* Got ACK to F packet */
  557.     nxtpkt(k);            /* Get next packet number etc */
  558. #ifdef F_AT
  559.     if (k->capas & CAP_AT) {    /* A-packets negotiated? */
  560.         if ((rc = sattr(k,r)) != X_OK) /* Yes, send Attribute packet */
  561.           return(rc);
  562.         k->state = S_ATTR;        /* And wait for its ACK */
  563.         r->status = S_ATTR;
  564.     } else
  565. #endif /* F_AT */
  566.       if (sdata(k,r) == 0) {    /* No A packets - send first data */
  567.         /* File is empty so send EOF packet */
  568.         if ((rc = spkt('Z',k->s_seq,0,(UCHAR *)0,k)) != X_OK)
  569.           return(rc);
  570.         k->closef(k,*p,1);        /* Close input file*/
  571.         k->state = S_EOF;        /* Wait for ACK to EOF */
  572.         r->status = S_EOF;
  573.     } else {            /* Sent some data */
  574.         k->state = S_DATA;        /* Wait for ACK to first data */
  575.         r->status = S_DATA;
  576.     }
  577.     k->r_seq = k->s_seq;        /* Sequence number to wait for */
  578.     return(X_OK);
  579.  
  580.       case S_ATTR:            /* Got ACK to A packet */
  581.       case S_DATA:            /* Got ACK to D packet */
  582.     nxtpkt(k);            /* Get next packet number */
  583.     if (k->state == S_ATTR) {
  584.         /* CHECK ATTRIBUTE RESPONSE */
  585.         /* IF REJECTED do the right thing... */
  586.         k->state = S_DATA;
  587.         r->status = S_DATA;
  588.     }
  589.     rc = sdata(k,r);        /* Send first or next data packet */
  590.  
  591.     debug(DB_LOG,"Seq",0,(k->s_seq));
  592.     debug(DB_LOG,"sdata()",0,rc);
  593.  
  594.     if (rc == 0) {            /* If there was no data to send */
  595.         if ((rc = spkt('Z',k->s_seq,0,(UCHAR *)0,k)) != X_OK)
  596.           return(rc);        /* Send EOF */
  597.         k->closef(k,*p,1);        /* Close input file*/
  598.         k->state = S_EOF;        /* And wait for ACK */
  599.         r->status = S_EOF;
  600.     }                /* Otherwise stay in data state */
  601.     k->r_seq = k->s_seq;        /* Sequence number to wait for */
  602.     return(X_OK);
  603.  
  604.       case S_EOT:            /* Get ACK to EOT packet */
  605.         return(X_DONE);            /* (or X_ERROR) */
  606. #endif /* RECVONLY */
  607.  
  608.       case R_WAIT:                      /* Waiting for the S packet */
  609.         if (t == 'S') {                 /* Got it */
  610.             spar(k,p,datalen);          /* Set parameters from it */
  611.             rc = rpar(k,'Y');        /* ACK with my parameters */
  612.         debug(DB_LOG,"rpar rc",0,rc);
  613.             if (rc != X_OK)
  614.               return(X_ERROR);          /* I/O error, quit. */
  615.             k->state = R_FILE;          /* All OK, switch states */
  616.             r->status = R_FILE;
  617.         } else {                        /* Wrong kind of packet, send NAK */
  618.             epkt("Unexpected packet type",k);
  619.             rc = X_ERROR;
  620.         }
  621.         freerslot(k,r_slot);        /* Free packet slot */
  622.         return(rc);
  623.  
  624.       case R_FILE:                      /* Want an F or B packet */
  625.         if (t == 'F') {                 /* File name */
  626.             if ((rc = decode(k, r, 0, p)) == X_OK) /* Decode and save */
  627.               k->state = R_ATTR;        /* Switch to next state */
  628.         r->status = k->state;
  629.         debug(DB_LOG,"R_FILE decode rc",0,rc);
  630.         debug(DB_LOG,"R_FILE FILENAME",r->filename,0);
  631.             if (rc == X_OK) {        /* All OK so far */
  632.         r->filedate[0] = '\0';    /* No file date yet */
  633.         r->filesize = 0L;    /* Or file size */
  634.         r->sofar = 0L;        /* Or bytes transferred yet */
  635.         rc = ack(k, k->r_seq, r->filename); /* so ACK the F packet */
  636.         } else {
  637.         epkt("Filename error",k); /* Error decoding filename */
  638.         }
  639.         } else if (t == 'B') {          /* Break, end of transaction */
  640.             freerslot(k,r_slot);
  641.             rc = (ack(k, k->r_seq, (UCHAR *)0) == X_OK) ? X_DONE : X_ERROR;
  642.  
  643.         } else {
  644.             epkt("Unexpected packet type",k);
  645.             rc = X_ERROR;
  646.         }
  647.         freerslot(k,r_slot);
  648.         return(rc);
  649.  
  650.       case R_ATTR:                      /* Want A, D, or Z packet */
  651. #ifdef F_AT
  652.         if (t == 'A') {                 /* Attribute packet */
  653.         int x;
  654.             x = gattr(k, p, r);        /* Read the attributes */
  655.         if (x > -1)
  656.           k->binary = x;
  657.             freerslot(k,r_slot);
  658.             ack(k, k->r_seq, (UCHAR *) "Y"); /* Always accept the file */
  659.             return(X_OK);
  660.         } else
  661. #endif /* F_AT */
  662.       if (t == 'D') {        /* First data packet */
  663.             k->obufpos = 0;             /* Initialize output buffer */
  664.         k->filename = r->filename;
  665.         r->sofar = 0L;
  666.             if ((rc = (*(k->openf))(k,r->filename, 2)) == X_OK) {
  667.                 k->state = R_DATA;      /* Switch to Data state */
  668.         r->status = k->state;
  669.                 rc = decode(k, r, 1, p); /* Write out first data packet */
  670.                 freerslot(k,r_slot);
  671.             } else {
  672.                 epkt("File refused or can't be opened", k);
  673.                 freerslot(k,r_slot);
  674.                 return(rc);
  675.             }
  676.             if (rc == X_OK)
  677.               rc = ack(k, k->r_seq, s);
  678.             else
  679.               epkt("Error writing data", k);
  680.             return(rc);
  681.     } else if (t == 'Z') {        /* Empty file */
  682.         debug(DB_LOG,"R_ATTR empty file",r->filename,0);
  683.             k->obufpos = 0;             /* Initialize output buffer */
  684.         k->filename = r->filename;
  685.         r->sofar = 0L;        /* Open and close the file */
  686.             if ((rc = (*(k->openf))(k,r->filename, 2)) == X_OK) {
  687.         if (((rc = (*(k->closef))(k,*p,2)) == X_OK)) {
  688.             k->state = R_FILE;
  689.             rc = ack(k, k->r_seq, s);
  690.         } else {
  691.             epkt("Error closing empty file", k);
  692.             freerslot(k,r_slot);
  693.             return(rc);
  694.         }
  695.             } else {
  696.                 epkt("File refused or can't be opened", k);
  697.                 freerslot(k,r_slot);
  698.                 return(rc);
  699.             }
  700.         r->status = k->state;
  701.             freerslot(k,r_slot);
  702.  
  703.         } else {
  704.             epkt("Unexpected packet type",k);
  705.             return(X_ERROR);
  706.         }
  707.         break;
  708.  
  709.       case R_DATA:                      /* Want a D or Z packet */
  710.     debug(DB_CHR,"R_DATA t",0,t);
  711.         if (t == 'D') {                 /* Data */
  712.             rc = decode(k, r, 1, p);    /* Decode it */
  713.             freerslot(k,r_slot);
  714.         } else if (t == 'Z') {          /* End of file */
  715.         debug(DB_CHR,"R_DATA",0,t);
  716.             if (k->obufpos > 0) {       /* Flush output buffer */
  717.                 rc = (*(k->writef))(k,k->obuf,k->obufpos);
  718.         debug(DB_LOG,"R_DATA writef rc",0,rc);
  719.         r->sofar += k->obufpos;
  720.                 k->obufpos = 0;
  721.             }
  722.             if (((rc = (*(k->closef))(k,*p,2)) == X_OK) && (rc == X_OK))
  723.               k->state = R_FILE;
  724.         debug(DB_LOG,"R_DATA closef rc",0,rc);
  725.         r->status = k->state;
  726.             freerslot(k,r_slot);
  727.         } else {
  728.             epkt("Unexpected packet type",k);
  729.             return(X_ERROR);
  730.         }
  731.         if (rc == X_OK)
  732.           rc = ack(k, k->r_seq, s);
  733.         else
  734.           epkt(t == 'Z' ? "Can't close file" : "Error writing data",k);
  735.         return(rc);
  736.  
  737.       case R_ERROR:                     /* Canceled from above */
  738.       default:
  739.         epkt(msg,k);
  740.         return(X_ERROR);
  741.     }
  742.     return(X_ERROR);
  743. }
  744.  
  745. /* Utility routines */
  746.  
  747. UCHAR *
  748. getrslot(struct k_data *k, short *n) {   /* Find a free packet buffer */
  749.     register int i;
  750. /*
  751.   Note: We don't clear the retry count here.
  752.   It is cleared only after the NEXT packet arrives, which
  753.   indicates that the other Kermit got our ACK for THIS packet.
  754. */
  755.     for (i = 0; i < P_WSLOTS; i++) {    /* Search */
  756.         if (k->ipktinfo[i].len < 1) {
  757.             *n = i;                     /* Slot number */
  758.             k->ipktinfo[i].len = -1;    /* Mark it as allocated but not used */
  759.             k->ipktinfo[i].seq = -1;
  760.             k->ipktinfo[i].typ = SP;
  761.             /* k->ipktinfo[i].rtr =  0; */  /* (see comment above) */
  762.             k->ipktinfo[i].dat = (UCHAR *)0;
  763.             return(&(k->ipktbuf[0][i]));
  764.         }
  765.     }   
  766.     *n = -1;
  767.     return((UCHAR *)0);
  768. }
  769.  
  770. void                    /* Initialize a window slot */
  771. freerslot(struct k_data *k, short n) {
  772.     k->ipktinfo[n].len = 0;        /* Packet length */
  773. #ifdef COMMENT
  774.     k->ipktinfo[n].seq = 0;        /* Sequence number */
  775.     k->ipktinfo[n].typ = (char)0;    /* Type */
  776.     k->ipktinfo[n].rtr = 0;        /* Retry count */
  777.     k->ipktinfo[n].flg = 0;        /* Flags */
  778. #endif /* COMMENT */
  779. }
  780.  
  781. UCHAR *
  782. getsslot(struct k_data *k, short *n) {   /* Find a free packet buffer */
  783. #ifdef COMMENT
  784.     register int i;
  785.     for (i = 0; i < P_WSLOTS; i++) {    /* Search */
  786.         if (k->opktinfo[i].len < 1) {
  787.             *n = i;                     /* Slot number */
  788.             k->opktinfo[i].len = -1;    /* Mark it as allocated but not used */
  789.             k->opktinfo[i].seq = -1;
  790.             k->opktinfo[i].typ = SP;
  791.             k->opktinfo[i].rtr =  0;
  792.             k->opktinfo[i].dat = (UCHAR *)0;
  793.             return(&(k->opktbuf[0][i]));
  794.         }
  795.     }   
  796.     *n = -1;
  797.     return((UCHAR *)0);
  798. #else
  799.     *n = 0;
  800.     return(k->opktbuf);
  801. #endif /* COMMENT */
  802. }
  803.  
  804. void                                    /* Initialize a window slot */
  805. freesslot(struct k_data * k, short n) {
  806.     k->opktinfo[n].len = 0;        /* Packet length */
  807.     k->opktinfo[n].seq = 0;        /* Sequence number */
  808.     k->opktinfo[n].typ = (char)0;    /* Type */
  809.     k->opktinfo[n].rtr = 0;        /* Retry count */
  810.     k->opktinfo[n].flg = 0;        /* Flags */
  811. }
  812.  
  813. /*  C H K 1  --  Compute a type-1 Kermit 6-bit checksum.  */
  814.  
  815. STATIC int
  816. chk1(UCHAR *pkt, struct k_data * k) {
  817.     register unsigned int chk;
  818.     chk = chk2(pkt,k);
  819.     chk = (((chk & 0300) >> 6) + chk) & 077;
  820.     return((int) chk);
  821. }
  822.  
  823. /*  C H K 2  --  Numeric sum of all the bytes in the packet, 12 bits.  */
  824.  
  825. STATIC USHORT
  826. chk2(UCHAR *pkt,struct k_data * k) {
  827.     register USHORT chk;
  828.     for (chk = 0; *pkt != '\0'; pkt++)
  829.       chk += *pkt;
  830.     return(chk);
  831. }
  832.  
  833. #ifdef F_CRC
  834.  
  835. /*  C H K 3  --  Compute a type-3 Kermit block check.  */
  836. /*
  837.  Calculate the 16-bit CRC-CCITT of a null-terminated string using a lookup 
  838.  table.  Assumes the argument string contains no embedded nulls.
  839. */
  840. STATIC USHORT
  841. chk3(UCHAR *pkt, struct k_data * k) {
  842.     register USHORT c, crc;
  843.     for (crc = 0; *pkt != '\0'; pkt++) {
  844. #ifdef COMMENT
  845.         c = crc ^ (long)(*pkt);
  846.         crc = (crc >> 8) ^ (k->crcta[(c & 0xF0) >> 4] ^ k->crctb[c & 0x0F]);
  847. #else
  848.     c = crc ^ (*pkt);
  849.        crc = (crc >> 8) ^ ((k->crcta[(c & 0xF0) >> 4]) ^ (k->crctb[c & 0x0F]));
  850. #endif    /*  COMMENT */
  851.     }
  852.     return(crc);
  853. }
  854. #endif /* F_CRC */
  855.  
  856. /*   S P K T  --  Send a packet.  */
  857. /*
  858.   Call with packet type, sequence number, data length, data, Kermit struct.
  859.   Returns:
  860.     X_OK on success
  861.     X_ERROR on i/o error
  862. */
  863. STATIC int
  864. spkt(char typ, short seq, int len, UCHAR * data, struct k_data * k) {
  865.  
  866.     unsigned int crc;                   /* For building CRC */
  867.     int i, j, lenpos, m, n, x;        /* Workers */
  868.     UCHAR * s, * buf;
  869.  
  870.     debug(DB_LOG,"spkt len 1",0,len);
  871.     if (len < 0) {            /* Calculate data length ourselves? */
  872.     len = 0;
  873.     s = data;
  874.     while (*s++) len++;
  875.     }
  876.     debug(DB_LOG,"spkt len 2",0,len);
  877.     buf = k->opktbuf;            /* Where to put packet (FOR NOW) */
  878.  
  879.     i = 0;                              /* Packet buffer position */
  880.     buf[i++] = k->s_soh;        /* SOH */
  881.     lenpos = i++;            /* Remember this place */
  882.     buf[i++] = tochar(seq);        /* Sequence number */
  883.     buf[i++] = typ;            /* Packet type */
  884.     j = len + k->bct;
  885. #ifdef F_LP
  886.     if ((len + k->bct + 2) > 94) {    /* If long packet */
  887.     buf[lenpos] = tochar(0);    /* Put blank in LEN field */
  888.     buf[i++] = tochar(j / 95);    /* Make extended header: Big part */
  889.     buf[i++] = tochar(j % 95);    /* and small part of length. */
  890.         buf[i] = NUL;            /* Terminate for header checksum */
  891.         buf[i++] = tochar(chk1(&buf[lenpos],k)); /* Insert header checksum */
  892.     } else {                /* Short packet */
  893. #endif /* F_LP */
  894.     buf[lenpos] = tochar(j+2);    /* Single-byte length in LEN field */
  895. #ifdef F_LP
  896.     }
  897. #endif /* F_LP */
  898.     if (data)                           /* Copy data, if any */
  899.       for ( ; len--; i++)
  900.         buf[i] = *data++;
  901.     buf[i] = '\0';
  902.  
  903. #ifdef F_CRC
  904.     switch (k->bct) {                   /* Add block check */
  905.       case 1:                           /* 1 = 6-bit chksum */
  906.     buf[i++] = tochar(chk1(&buf[lenpos],k));
  907.         break;
  908.       case 2:                           /* 2 = 12-bit chksum */
  909.         j = chk2(&buf[lenpos],k);
  910. #ifdef XAC
  911.     /* HiTech's XAC compiler silently ruins the regular code. */
  912.     /* An intermediate variable provides a work-around. */
  913.     /* 2004-06-29 -- JHD */
  914.     {
  915.         USHORT jj;
  916.         jj = (j >> 6) & 077; buf[i++] = tochar(jj);
  917.         jj = j & 077;        buf[i++] = tochar(jj);
  918.     }
  919. #else
  920.         buf[i++] = (unsigned)tochar((j >> 6) & 077);
  921.         buf[i++] = (unsigned)tochar(j & 077);
  922. #endif /* XAC */
  923.         break;
  924.       case 3:                           /* 3 = 16-bit CRC */
  925.         crc = chk3(&buf[lenpos],k);
  926. #ifdef XAC
  927.     /* HiTech's XAC compiler silently ruins the above code. */
  928.     /* An intermediate variable provides a work-around. */
  929.     /* 2004-06-29 -- JHD */
  930.     {
  931.         USHORT jj;
  932.         jj = (crc >> 12) & 0x0f; buf[i++] = tochar(jj);
  933.         jj = (crc >>  6) & 0x3f; buf[i++] = tochar(jj);
  934.         jj =  crc        & 0x3f; buf[i++] = tochar(jj);
  935.     }
  936. #else
  937.         buf[i++] = (unsigned)tochar(((crc & 0170000)) >> 12);
  938.         buf[i++] = (unsigned)tochar((crc >> 6) & 077);
  939.         buf[i++] = (unsigned)tochar(crc & 077);
  940. #endif /* XAC */
  941.         break;
  942.     }
  943. #else
  944.     buf[i++] = tochar(chk1(&buf[lenpos],k));
  945. #endif /* F_CRC */
  946.  
  947.     buf[i++] = k->s_eom;        /* Packet terminator */
  948.     buf[i] = '\0';            /* String terminator */
  949.     k->s_seq = seq;                     /* Remember sequence number */
  950.  
  951.     k->opktlen = i;            /* Remember length for retransmit */
  952.  
  953. #ifdef DEBUG
  954. /* CORRUPT THE PACKET SENT BUT NOT THE ONE WE SAVE */
  955.     if (xerror()) {
  956.     UCHAR p[P_PKTLEN+8];
  957.     int i;
  958.     for (i = 0; i < P_PKTLEN; i++)
  959.       if (!(p[i] = buf[i]))
  960.         break;
  961.     p[i-2] = 'X';
  962.     debug(DB_PKT,"XPKT",(char *)&p[1],0);
  963.     return((*(k->txd))(k,p,k->opktlen)); /* Send it. */
  964.     }
  965.     debug(DB_PKT,"SPKT",(char *)&buf[1],0);
  966. #endif /* DEBUG */
  967.  
  968.     return((*(k->txd))(k,buf,k->opktlen)); /* Send it. */
  969. }
  970.  
  971. /*  N A K  --  Send a NAK (negative acknowledgement)  */
  972.  
  973. STATIC int
  974. nak(struct k_data * k, short seq, short slot) {
  975.     int rc;
  976.     rc = spkt('N', seq, 0, (UCHAR *)0, k);
  977.     if (k->ipktinfo[slot].rtr++ > k->retry)
  978.       rc = X_ERROR;
  979.     return(rc);
  980. }
  981.  
  982. /*  A C K  --  Send an ACK (positive acknowledgement)  */
  983.  
  984. STATIC int
  985. ack(struct k_data * k, short seq, UCHAR * text) {
  986.     int len, rc;
  987.     len = 0;
  988.     if (text) {                         /* Get length of data */
  989.         UCHAR *p;
  990.         p = text;
  991.         for ( ; *p++; len++) ;
  992.     }
  993.     rc = spkt('Y', seq, len, text, k);  /* Send the packet */
  994.     debug(DB_LOG,"ack spkt rc",0,rc);
  995.     if (rc == X_OK)                     /* If OK */
  996.       k->r_seq = (k->r_seq + 1) % 64;   /* bump the packet number */
  997.     return(rc);
  998. }
  999.  
  1000. /*  S P A R  --  Set parameters requested by other Kermit  */
  1001.  
  1002. STATIC void
  1003. spar(struct k_data * k, UCHAR *s, int datalen) {
  1004.     int x, y;
  1005.     UCHAR c;
  1006.  
  1007.     s--;                                /* Line up with field numbers. */
  1008.  
  1009.     if (datalen >= 1)                   /* Max packet length to send */
  1010.       k->s_maxlen = xunchar(s[1]);
  1011.  
  1012.     if (datalen >= 2)                   /* Timeout on inbound packets */
  1013.       k->r_timo = xunchar(s[2]);
  1014.  
  1015.     /* No padding */
  1016.  
  1017.     if (datalen >= 5)                   /* Outbound Packet Terminator */
  1018.       k->s_eom = xunchar(s[5]);
  1019.  
  1020.     if (datalen >= 6)                   /* Incoming control prefix */
  1021.       k->r_ctlq = s[6];
  1022.  
  1023.     if (datalen >= 7) {                 /* 8th bit prefix */
  1024.         k->ebq = s[7];
  1025.         if ((s[7] > 32 && s[7] < 63) || (s[7] > 95 && s[7] < 127)) {
  1026.         if (!k->parity)        /* They want it */
  1027.           k->parity = 1;        /* Set parity to something nonzero */
  1028.         k->ebqflg = 1;
  1029.     } else if (s[7] == 'Y' && k->parity) {
  1030.         k->ebqflg = 1;
  1031.         k->ebq = '&';
  1032.     } else if (s[7] == 'N') {
  1033.         /* WHAT? */
  1034.     }
  1035.     }
  1036.     if (datalen >= 8) {                 /* Block check */
  1037.         k->bct = s[8] - '0';
  1038. #ifdef F_CRC
  1039.         if ((k->bct < 1) || (k->bct > 3))
  1040. #endif /* F_CRC */
  1041.       k->bct = 1;
  1042.     if (k->bctf) k->bct = 3;
  1043.     }
  1044.     if (datalen >= 9) {                 /* Repeat counts */
  1045.         if ((s[9] > 32 && s[9] < 63) || (s[9] > 95 && s[9] < 127)) {
  1046.             k->rptq = s[9];
  1047.             k->rptflg = 1;
  1048.         }
  1049.     }
  1050.     if (datalen >= 10) {                /* Capability bits */
  1051.         x = xunchar(s[10]);
  1052.  
  1053. #ifdef F_LP                             /* Long packets */
  1054.         if (!(x & CAP_LP))
  1055. #endif /* F_LP */
  1056.           k->capas &= ~CAP_LP;
  1057.  
  1058. #ifdef F_SW                             /* Sliding Windows */
  1059.         if (!(x & CAP_SW))
  1060. #endif /* F_SW */
  1061.           k->capas &= ~CAP_SW;
  1062.  
  1063. #ifdef F_AT                             /* Attributes */
  1064.         if (!(x & CAP_AT))
  1065. #endif /* F_AT */
  1066.           k->capas &= ~CAP_AT;
  1067.  
  1068. #ifdef F_RS                             /* Recovery */
  1069.         if (!(x & CAP_RS))
  1070. #endif /* F_RS */
  1071.           k->capas &= ~CAP_RS;
  1072.  
  1073. #ifdef F_LS                             /* Locking shifts */
  1074.         if (!(x & CAP_LS))
  1075. #endif /* F_LS */
  1076.           k->capas &= ~CAP_LS;
  1077.  
  1078.         /* In case other Kermit sends addt'l capas fields ... */
  1079.  
  1080.         for (y = 10; (xunchar(s[y]) & 1) && (datalen >= y); y++) ;
  1081.     }
  1082.  
  1083. #ifdef F_LP                             /* Long Packets */
  1084.     if (k->capas & CAP_LP) {
  1085.         if (datalen > y+1) {
  1086.             x = xunchar(s[y+2]) * 95 + xunchar(s[y+3]);
  1087.             k->s_maxlen = (x > P_PKTLEN) ? P_PKTLEN : x;
  1088.             if (k->s_maxlen < 10)
  1089.               k->s_maxlen = 60;
  1090.         }
  1091.     }
  1092. #endif /* F_LP */
  1093.     
  1094.     debug(DB_LOG,"S_MAXLEN",0,k->s_maxlen);
  1095.  
  1096. #ifdef F_SW
  1097.     if (k->capas & CAP_SW) {
  1098.         if (datalen > y) {
  1099.             x = xunchar(s[y+1]);
  1100.             k->window = (x > P_WSLOTS) ? P_WSLOTS : x;
  1101.             if (k->window < 1)          /* Watch out for bad negotiation */
  1102.               k->window = 1;
  1103.             if (k->window > 1)
  1104.               if (k->window > k->retry)   /* Retry limit must be greater */
  1105.                 k->retry = k->window + 1; /* than window size. */
  1106.         }
  1107.     }
  1108. #endif /* F_SW */
  1109. }
  1110.  
  1111. /*  R P A R  --  Send my parameters to other Kermit  */
  1112.  
  1113. STATIC int
  1114. rpar(struct k_data * k, char type) {
  1115.     UCHAR *d;
  1116.     int rc, len;
  1117. #ifdef F_CRC
  1118.     short b;
  1119. #endif /* F_CRC */
  1120.  
  1121.     d = k->ack_s;                       /* Where to put it */
  1122.     d[ 0] = tochar(94);                 /* Maximum short-packet length */
  1123.     d[ 1] = tochar(k->s_timo);          /* When I want to be timed out */
  1124.     d[ 2] = tochar(0);                  /* How much padding I need */
  1125.     d[ 3] = ctl(0);                     /* Padding character I want */
  1126.     d[ 4] = tochar(k->r_eom);           /* End-of message character I want */
  1127.     d[ 5] = k->s_ctlq;                  /* Control prefix I send */
  1128.     if ((k->ebq == 'Y') && (k->parity)) /* 8th-bit prefix */
  1129.       d[ 6] = k->ebq = '&';           /* I need to request it */
  1130.     else                                /* else just agree with other Kermit */
  1131.       d[ 6] = k->ebq;
  1132.     if (k->bctf)            /* Block check type */
  1133.       d[7] = '5';            /* FORCE 3 */
  1134.     else
  1135.       d[7] = k->bct + '0';        /* Normal */
  1136.     d[ 8] = k->rptq;            /* Repeat prefix */
  1137.     d[ 9] = tochar(k->capas);           /* Capability bits */
  1138.     d[10] = tochar(k->window);          /* Window size */
  1139.  
  1140. #ifdef F_LP
  1141.     d[11] = tochar(k->r_maxlen / 95);   /* Long packet size, big part */
  1142.     d[12] = tochar(k->r_maxlen % 95);   /* Long packet size, little part */
  1143.     d[13] = '\0';            /* Terminate the init string */
  1144.     len = 13;
  1145. #else
  1146.     d[11] = '\0';
  1147.     len = 11;
  1148. #endif /* F_LP */
  1149.  
  1150. #ifdef F_CRC
  1151.     if (!(k->bctf)) {            /* Unless FORCE 3 */
  1152.     b = k->bct;
  1153.     k->bct = 1;            /* Always use block check type 1 */
  1154.     }
  1155. #endif /* F_CRC */
  1156.     switch (type) {
  1157.       case 'Y':                /* This is an ACK for packet 0 */
  1158.     rc = ack(k,0,d);
  1159.     break;
  1160.       case 'S':                /* It's an S packet */
  1161.     rc = spkt('S', 0, len, d, k);
  1162.     break;
  1163.       default:
  1164.     rc = -1;
  1165.     }
  1166. #ifdef F_CRC
  1167.     if (!(k->bctf)) {            /* Unless FORCE 3 */
  1168.     k->bct = b;
  1169.     }
  1170. #endif /* F_CRC */
  1171.     return(rc);                         /* Pass along return code. */
  1172. }
  1173.  
  1174. /*  D E C O D E  --  Decode data field of Kermit packet - binary mode only */
  1175. /*
  1176.   Call with:
  1177.     k = kermit data structure
  1178.     r = kermit response structure
  1179.     f = function code
  1180.       0 = decode filename
  1181.       1 = decode file data    
  1182.     inbuf = pointer to packet data to be decoded
  1183.   Returns:
  1184.     X_OK on success
  1185.     X_ERROR if output function fails
  1186. */
  1187. STATIC int
  1188. decode(struct k_data * k, struct k_response * r, short f, UCHAR *inbuf) {
  1189.  
  1190.     register unsigned int a, a7;        /* Current character */
  1191.     unsigned int b8;                    /* 8th bit */
  1192.     int rpt;                            /* Repeat count */
  1193.     int rc;                /* Return code */
  1194.     UCHAR *p;
  1195.  
  1196.     rc = X_OK;
  1197.     rpt = 0;                            /* Initialize repeat count. */
  1198.     if (f == 0)                         /* Output function... */
  1199.       p = r->filename;
  1200.  
  1201.     while ((a = *inbuf++ & 0xFF) != '\0') { /* Character loop */
  1202.         if (k->rptflg && a == k->rptq) { /* Got a repeat prefix? */
  1203.             rpt = xunchar(*inbuf++ & 0xFF); /* Yes, get the repeat count, */
  1204.             a = *inbuf++ & 0xFF;        /* and get the prefixed character. */
  1205.         }
  1206.         b8 = 0;                         /* 8th-bit value */
  1207.         if (k->parity && (a == k->ebq)) { /* Have 8th-bit prefix? */
  1208.             b8 = 0200;                  /* Yes, flag the 8th bit */
  1209.             a = *inbuf++ & 0x7F;        /* and get the prefixed character. */
  1210.         }
  1211.         if (a == k->r_ctlq) {           /* If control prefix, */
  1212.             a  = *inbuf++ & 0xFF;       /* get its operand */
  1213.             a7 = a & 0x7F;              /* and its low 7 bits. */
  1214.             if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') /* Controllify */
  1215.               a = ctl(a);               /* if in control range. */
  1216.         }
  1217.         a |= b8;                        /* OR in the 8th bit */
  1218.  
  1219.         if (rpt == 0) rpt = 1;          /* If no repeats, then one */
  1220.  
  1221.         for (; rpt > 0; rpt--) {        /* Output the char 'rpt' times */
  1222.             if (f == 0) {
  1223.                 *p++ = (UCHAR) a;       /* to memory */
  1224.             } else {                    /* or to file */
  1225.                 k->obuf[k->obufpos++] = (UCHAR) a; /* Deposit the byte */
  1226.                 if (k->obufpos == k->obuflen) { /* Buffer full? */
  1227.                     rc = (*(k->writef))(k,k->obuf,k->obuflen); /* Dump it. */
  1228.             r->sofar += k->obuflen;
  1229.             if (rc != X_OK) break;
  1230.                     k->obufpos = 0;
  1231.                 }
  1232.             }
  1233.         }
  1234.     }
  1235.     if (f == 0)                         /* If writing to memory */
  1236.       *p = '\0';            /* terminate the string */
  1237.     return(rc);
  1238. }
  1239.  
  1240. STATIC ULONG                /* Convert decimal string to number  */
  1241. stringnum(UCHAR *s, struct k_data * k) {
  1242.     long n;
  1243.     n = 0L;
  1244.     while (*s == SP)
  1245.       s++;
  1246.     while(*s >= '0' && *s <= '9')
  1247.       n = n * 10 + (*s++ - '0');
  1248.     return(n);
  1249. }
  1250.  
  1251. STATIC UCHAR *                /* Convert number to string */
  1252. numstring(ULONG n, UCHAR * buf, int buflen, struct k_data * k) {
  1253.     int i, x;
  1254.     buf[buflen - 1] = '\0';
  1255.     for (i = buflen - 2; i > 0; i--) {
  1256.     x = n % 10L;
  1257.     buf[i] = x + '0';
  1258.     n /= 10L;
  1259.     if (!n)
  1260.       break;
  1261.     }
  1262.     if (n) {
  1263.     return((UCHAR *)0);
  1264.     }
  1265.     if (i > 0) {
  1266.     UCHAR * p, * s;
  1267.     s = &buf[i];
  1268.     p = buf;
  1269.     while ((*p++ = *s++)) ;
  1270.     *(p-1) = '\0';
  1271.     }
  1272.     return((UCHAR *)buf);
  1273. }
  1274.  
  1275. #ifdef F_AT
  1276.  
  1277. /*
  1278.   G A T T R  --  Read incoming attributes.
  1279.  
  1280.   Returns:
  1281.    -1 if no transfer mode (text/binary) was announced.
  1282.     0 if text was announced.
  1283.     1 if binary was announced.
  1284. */
  1285.  
  1286. #define SIZEBUFL 32                     /* For number conversions */
  1287.  
  1288. STATIC int
  1289. gattr(struct k_data * k, UCHAR * s, struct k_response * r) {
  1290.     long fsize, fsizek;                 /* File size */
  1291.     UCHAR c;                            /* Workers */
  1292.     int aln, i, rc;
  1293.  
  1294.     UCHAR sizebuf[SIZEBUFL];
  1295.  
  1296.     rc = -1;
  1297.     while ((c = *s++)) {        /* Get attribute tag */
  1298.         aln = xunchar(*s++);            /* Length of attribute string */
  1299.         switch (c) {
  1300.           case '!':                     /* File length in K */
  1301.       case '"':            /* File type */
  1302.             for (i = 0; (i < aln) && (i < SIZEBUFL); i++) /* Copy it */
  1303.               sizebuf[i] = *s++;
  1304.             sizebuf[i] = '\0';           /* Terminate with null */
  1305.             if (i < aln) s += (aln - i); /* If field was too long for buffer */
  1306.         if (c == '!') {             /* Length */
  1307.         fsizek = stringnum(sizebuf,k); /* Convert to number */
  1308.         } else {                 /* Type */
  1309.         if (sizebuf[0] == 'A')         /* Text */
  1310.           rc = 0;
  1311.         else if (sizebuf[0] == 'B')  /* Binary */
  1312.           rc = 1;
  1313.         debug(DB_LOG,"gattr rc",0,rc);
  1314.         debug(DB_LOG,"gattr size",sizebuf,0);
  1315.         }
  1316.             break;
  1317.  
  1318.           case '#':                     /* File creation date */
  1319.             for (i = 0; (i < aln) && (i < DATE_MAX); i++)
  1320.               r->filedate[i] = *s++;    /* Copy it into a static string */
  1321.             if (i < aln) s += (aln - i);
  1322.             r->filedate[i] = '\0';
  1323.             break;
  1324.  
  1325.           case '1':                     /* File length in bytes */
  1326.             for (i = 0; (i < aln) && (i < SIZEBUFL); i++) /* Copy it */
  1327.               sizebuf[i] = *s++;
  1328.             sizebuf[i] = '\0';           /* Terminate with null */
  1329.             if (i < aln) s += (aln - i);
  1330.             fsize = stringnum(sizebuf,k); /* Convert to number */
  1331.             break;
  1332.  
  1333.       default:            /* Unknown attribute */
  1334.         s += aln;            /* Just skip past it */
  1335.         break;
  1336.         }
  1337.     }
  1338.     if (fsize > -1L) {            /* Remember the file size */
  1339.         r->filesize = fsize;            
  1340.     } else if (fsizek > -1L) {
  1341.         r->filesize = fsizek * 1024L;
  1342.     }
  1343.     debug(DB_LOG,"gattr r->filesize",0,(r->filesize));
  1344.     debug(DB_LOG,"gattr r->filedate=",r->filedate,0);
  1345.     return(rc);
  1346. }
  1347.  
  1348. #define ATTRLEN 48
  1349.  
  1350. STATIC int
  1351. sattr(struct k_data *k, struct k_response *r) {    /* Build and send A packet */
  1352.     int i, x, aln;
  1353.     short tmp;
  1354.     long filelength;
  1355.     UCHAR datebuf[DATE_MAX], * p;
  1356.  
  1357.     debug(DB_LOG,"sattr k->zincnt 0",0,(k->zincnt));
  1358.  
  1359.     tmp = k->binary;
  1360.     filelength = (*(k->finfo))
  1361.     (k,k->filename,datebuf,DATE_MAX,&tmp,k->xfermode);
  1362.     k->binary = tmp;
  1363.  
  1364.     debug(DB_LOG,"sattr filename: ",k->filename,0);
  1365.     debug(DB_LOG,"sattr filedate: ",datebuf,0);
  1366.     debug(DB_LOG,"sattr filelength",0,filelength);
  1367.     debug(DB_LOG,"sattr binary",0,(k->binary));
  1368.  
  1369.     i = 0;
  1370.  
  1371.     k->xdata[i++] = '"';
  1372.     if (k->binary) {            /* Binary */
  1373.     k->xdata[i++] = tochar(2);    /*  Two characters */
  1374.     k->xdata[i++] = 'B';        /*  B for Binary */
  1375.     k->xdata[i++] = '8';        /*  8-bit bytes (note assumption...) */
  1376.     } else {                /* Text */
  1377.     k->xdata[i++] = tochar(3);    /*  Three characters */
  1378.     k->xdata[i++] = 'A';        /*  A = (extended) ASCII with CRLFs */
  1379.     k->xdata[i++] = 'M';        /*  M for carriage return */
  1380.     k->xdata[i++] = 'J';        /*  J for linefeed */
  1381.     k->xdata[i++] = '*';        /* Encoding */
  1382.     k->xdata[i++] = tochar(1);    /* Length of value is 1 */
  1383.     k->xdata[i++] = 'A';        /* A for ASCII */
  1384.     }
  1385.     if (filelength > -1L) {        /* File length in bytes */
  1386.     UCHAR lenbuf[16];
  1387.     r->filesize = filelength;
  1388.     p = numstring(filelength,lenbuf,16,k);
  1389.     if (p) {
  1390.         for (x = 0; p[x]; x++) ;    /* Get length of length string */
  1391.         if (i + x < ATTRLEN - 3) {    /* Don't overflow buffer */
  1392.         k->xdata[i++] = '1';    /* Length-in-Bytes attribute */
  1393.         k->xdata[i++] = tochar(x);
  1394.         while (*p)
  1395.           k->xdata[i++] = *p++;
  1396.         }
  1397.     }
  1398.     }
  1399.     debug(DB_LOG,"sattr DATEBUF: ",datebuf,0);
  1400.  
  1401.     if (datebuf[0]) {            /* File modtime */
  1402.     p = datebuf;
  1403.     for (x = 0; p[x]; x++) ;    /* Length of modtime */
  1404.     if (i + x < ATTRLEN - 3) {    /* If it will fit */
  1405.         k->xdata[i++] = '#';    /* Add modtime attribute */
  1406.         k->xdata[i++] = tochar(x);    /* Its length */
  1407.         while (*p)            /* And itself */
  1408.           k->xdata[i++] = *p++;
  1409.         /* Also copy modtime to result struct */
  1410.         for (x = 0; x < DATE_MAX-1 && datebuf[x]; x++)
  1411.           r->filedate[x] = datebuf[x];
  1412.         r->filedate[x] = '\0';
  1413.     }    
  1414.     }
  1415.     k->xdata[i++] = '@';        /* End of Attributes */
  1416.     k->xdata[i++] = ' ';
  1417.     k->xdata[i] = '\0';            /* Terminate attribute string */
  1418.     debug(DB_LOG,"sattr k->xdata: ",k->xdata,0);
  1419.     return(spkt('A',k->s_seq,-1,k->xdata,k));
  1420. }
  1421. #endif /* F_AT */
  1422.  
  1423. STATIC int
  1424. getpkt(struct k_data *k, struct k_response *r) { /* Fill a packet from file */
  1425.     int i, next, rpt, maxlen;
  1426.     static int c;            /* PUT THIS IN STRUCT */
  1427.  
  1428.     debug(DB_LOG,"getpkt k->s_first",0,(k->s_first));
  1429.     debug(DB_LOG,"getpkt k->s_remain=",k->s_remain,0);
  1430.  
  1431.     maxlen = k->s_maxlen - k->bct - 3;    /* Maximum data length */
  1432.     if (k->s_first == 1) {        /* If first time thru...  */
  1433.     k->s_first = 0;            /* don't do this next time, */
  1434.     k->s_remain[0] = '\0';        /* discard any old leftovers. */
  1435.     if (k->istring) {        /* Get first byte. */
  1436.         c = *(k->istring)++;    /* Of memory string... */
  1437.         if (!c) c = -1;
  1438.     } else {            /* or file... */
  1439. #ifdef DEBUG
  1440.         k->zincnt = -1234;
  1441.         k->dummy = 0;
  1442. #endif /* DEBUG */
  1443.         c = zgetc();
  1444.  
  1445. #ifdef DEBUG
  1446.         if (k->dummy) debug(DB_LOG,"DUMMY CLOBBERED (A)",0,0);
  1447. #endif /* DEBUG */
  1448.     }
  1449.     if (c < 0) {            /* Watch out for empty file. */
  1450.         debug(DB_CHR,"getpkt first c",0,c);
  1451.         k->s_first = -1;
  1452.         return(k->size = 0);
  1453.     }
  1454.     r->sofar++;
  1455.     debug(DB_LOG,"getpkt first c",0,c);
  1456.     } else if (k->s_first == -1 && !k->s_remain[0]) { /* EOF from last time? */
  1457.         return(k->size = 0);
  1458.     }
  1459.     for (k->size = 0;
  1460.      (k->xdata[k->size] = k->s_remain[k->size]) != '\0';
  1461.      (k->size)++)
  1462.       ;
  1463.     k->s_remain[0] = '\0';
  1464.     if (k->s_first == -1)
  1465.       return(k->size);
  1466.  
  1467.     rpt = 0;                /* Initialize repeat counter. */
  1468.     while (k->s_first > -1) {        /* Until end of file or string... */
  1469.     if (k->istring) {
  1470.         next = *(k->istring)++;
  1471.         if (!next) next = -1;
  1472.     } else {
  1473. #ifdef DEBUG
  1474.         k->dummy = 0;
  1475. #endif /* DEBUG */
  1476.         next = zgetc();
  1477. #ifdef DEBUG
  1478.         if (k->dummy) debug(DB_LOG,"DUMMY CLOBBERED B",0,k->dummy);
  1479. #endif /* DEBUG */
  1480.     }
  1481.     if (next < 0) {            /* If none, we're at EOF. */
  1482.         k->s_first = -1;
  1483.     } else {            /* Otherwise */
  1484.         r->sofar++;            /* count this byte */
  1485.     }
  1486.         k->osize = k->size;        /* Remember current size. */
  1487.         encode(c,next,k);        /* Encode the character. */
  1488.     /* k->xdata[k->size] = '\0'; */
  1489.     c = next;            /* Old next char is now current. */
  1490.  
  1491.         if (k->size == maxlen)        /* Just at end, done. */
  1492.       return(k->size);
  1493.  
  1494.         if (k->size > maxlen) {        /* Past end, must save some. */
  1495.             for (i = 0;
  1496.          (k->s_remain[i] = k->xdata[(k->osize)+i]) != '\0';
  1497.          i++)
  1498.           ;
  1499.             k->size = k->osize;
  1500.             k->xdata[k->size] = '\0';
  1501.             return(k->size);        /* Return size. */
  1502.         }
  1503.     }
  1504.     return(k->size);            /* EOF, return size. */
  1505. }
  1506.  
  1507. #ifndef RECVONLY
  1508. STATIC int
  1509. sdata(struct k_data *k,struct k_response *r) { /* Send a data packet */
  1510.     int len, rc;
  1511.     if (k->cancel) {            /* Interrupted */
  1512.     debug(DB_LOG,"sdata interrupted k->cancel",0,(k->cancel));
  1513.     return(0);
  1514.     }
  1515.     len = getpkt(k,r);            /* Fill data field from input file */
  1516.     debug(DB_LOG,"sdata getpkt",0,len);
  1517.     if (len < 1)
  1518.       return(0);
  1519.     rc = spkt('D',k->s_seq,len,k->xdata,k); /* Send the packet */
  1520.     debug(DB_LOG,"sdata spkt",0,rc);
  1521.     return((rc == X_ERROR) ? rc : len);
  1522. }
  1523. #endif /* RECVONLY */
  1524.  
  1525. /*  E P K T  --  Send a (fatal) Error packet with the given message  */
  1526.  
  1527. STATIC void
  1528. epkt(char * msg, struct k_data * k) {
  1529.     if (!(k->bctf)) {            /* Unless FORCE 3 */
  1530.     k->bct = 1;
  1531.     }
  1532.     (void) spkt('E', 0, -1, (UCHAR *) msg, k);
  1533. }
  1534.  
  1535. STATIC int                /* Fill a packet from string s. */
  1536. encstr(UCHAR * s, struct k_data * k, struct k_response *r) {
  1537.     k->s_first = 1;            /* Start lookahead. */
  1538.     k->istring = s;            /* Set input string pointer */
  1539.     getpkt(k,r);            /* Fill a packet */
  1540.     k->istring = (UCHAR *)0;        /* Reset input string pointer */
  1541.     k->s_first = 1;            /* "Rewind" */
  1542.     return(k->size);            /* Return data field length */
  1543. }
  1544.  
  1545. /* Decode packet data into a string */
  1546.  
  1547. STATIC void
  1548. decstr(UCHAR * s, struct k_data * k, struct k_response * r) {
  1549.     k->ostring = s;            /* Set output string pointer  */
  1550.     (void) decode(k, r, 0, s);
  1551.     *(k->ostring) = '\0';        /* Terminate with null */
  1552.     k->ostring = (UCHAR *)0;        /* Reset output string pointer */
  1553. }
  1554.  
  1555. STATIC void
  1556. encode(int a, int next, struct k_data * k) { /* Encode character into packet */
  1557.     int a7, b8, maxlen;
  1558.  
  1559.     maxlen = k->s_maxlen - 4;
  1560.     if (k->rptflg) {            /* Doing run-length encoding? */
  1561.     if (a == next) {        /* Yes, got a run? */
  1562.         if (++(k->s_rpt) < 94) {    /* Yes, count. */
  1563.         return;
  1564.         } else if (k->s_rpt == 94) { /* If at maximum */
  1565.             k->xdata[(k->size)++] = k->rptq; /* Emit prefix, */
  1566.         k->xdata[(k->size)++] = tochar(k->s_rpt); /* and count, */
  1567.         k->s_rpt = 0;        /* and reset counter. */
  1568.         }
  1569.     } else if (k->s_rpt == 1) {    /* Run broken, only two? */
  1570.         k->s_rpt = 0;        /* Yes, do the character twice */
  1571.         encode(a,-1,k);        /* by calling self recursively. */
  1572.         if (k->size <= maxlen)    /* Watch boundary. */
  1573.           k->osize = k->size;
  1574.         k->s_rpt = 0;        /* Call self second time. */
  1575.         encode(a,-1,k);
  1576.         return;
  1577.     } else if (k->s_rpt > 1) {    /* Run broken, more than two? */
  1578.         k->xdata[(k->size)++] = k->rptq; /* Yes, emit prefix and count */
  1579.         k->xdata[(k->size)++] = tochar(++(k->s_rpt));
  1580.         k->s_rpt = 0;        /* and reset counter. */
  1581.     }
  1582.     }
  1583.     a7 = a & 127;            /* Get low 7 bits of character */
  1584.     b8 = a & 128;            /* And "parity" bit */
  1585.  
  1586.     if (k->ebqflg && b8) {        /* If doing 8th bit prefixing */
  1587.     k->xdata[(k->size)++] = k->ebq; /* and 8th bit on, insert prefix */
  1588.     a = a7;                /* and clear the 8th bit. */
  1589.     }
  1590.     if (a7 < 32 || a7 == 127) {           /* If in control range */
  1591.         k->xdata[(k->size)++] = k->s_ctlq; /* insert control prefix */
  1592.         a = ctl(a);             /* and make character printable. */
  1593.     } else if (a7 == k->s_ctlq)         /* If data is control prefix, */
  1594.       k->xdata[(k->size)++] = k->s_ctlq; /* prefix it. */
  1595.     else if (k->ebqflg && a7 == k->ebq)  /* If doing 8th-bit prefixing, */
  1596.       k->xdata[(k->size)++] = k->s_ctlq; /* ditto for 8th-bit prefix. */
  1597.     else if (k->rptflg && a7 == k->rptq) /* If doing run-length encoding, */
  1598.       k->xdata[(k->size)++] = k->s_ctlq; /* ditto for repeat prefix. */
  1599.  
  1600.     k->xdata[(k->size)++] = a;        /* Finally, emit the character. */
  1601.     k->xdata[(k->size)] = '\0';        /* Terminate string with null. */
  1602. }
  1603.  
  1604. STATIC int
  1605. nxtpkt(struct k_data * k) {        /* Get next packet to send */
  1606.     k->s_seq = (k->s_seq + 1) & 63;    /* Next sequence number */
  1607.     k->xdata = k->xdatabuf;
  1608.     return(0);
  1609. }
  1610.  
  1611. STATIC int
  1612. resend(struct k_data * k) {
  1613.     UCHAR * buf;
  1614.     if (!k->opktlen)            /* Nothing to resend */
  1615.       return(X_OK);
  1616.     buf = k->opktbuf;
  1617.     debug(DB_PKT,">PKT",&buf[1],k->opktlen);
  1618.     return((*(k->txd))(k,buf,k->opktlen));
  1619. }
  1620.