home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************************************
- ** **
- ** Kermit for Microsoft Windows **
- ** ---------------------------- **
- ** KERMPROT.C **
- ** **
- ** This module contains Kermit protocol implementation. The routines used **
- ** are derived from the book by Frank daCruz and are modified for **
- ** compatibility with MS Windows. **
- ** **
- *******************************************************************************/
-
- // INCLUDES -------------------------------------------------------------------
-
- #include "kermit.h"
- #include "kermprot.h"
-
- //-----------------------------------------------------------------------------
- void error(char *s)
-
- // Description of what function does.
-
- // Param(s): x...............Description.
-
- // Returns: Result description.
-
- {
- spack('E',seq,strlen(s),s);
-
- if (local) {
- message("Kermit - Fatal Error", s);
- }
- }
-
- //-----------------------------------------------------------------------------
- int NEAR spack(char type, int n, int len, char *d)
- {
- int i=0, j, k;
-
- for (i = 0; i < spadn; i++)
- sndpkt[i] = spadc;
-
- sndpkt[i++] = smark;
- k = i++;
- sndpkt[i++] = (char)tochar(n);
- sndpkt[i++] = (char)type;
- j = len + bctu;
- if (j > 95) {
- sndpkt[k] = tochar(0);
- sndpkt[i++] = (char)tochar(j / 95);
- sndpkt[i++] = (char)tochar(j % 95);
- sndpkt[i] = '\0';
- sndpkt[i++] = (char)tochar(chk1(sndpkt + k));
- }
- else
- sndpkt[k] = (char)tochar(j + 2);
-
- for (j = len; j > 0; j--)
- sndpkt[i++] = *d++;
-
- sndpkt[i] = '\0';
- switch (bctu) {
- case 1:
- sndpkt[i++] = tochar((char)(chk1(sndpkt+k)));
- break;
- case 2:
- j = (int)chksum(sndpkt+k);
- sndpkt[i++] = (char)tochar((j >> 6) & 077);
- sndpkt[i++] = (char)tochar(j & 077);
- break;
- case 3:
- j = chk3(sndpkt+k);
- sndpkt[i++] = (char)tochar((j >> 12) & 017);
- sndpkt[i++] = (char)tochar((j >> 6) & 077);
- sndpkt[i++] = (char)tochar(j & 077);
- break;
- }
- sndpkt[i++] = (char)seol;
- sndpkt[i] = '\0';
- sndpkl = i;
-
- i = ttol(sndpkt,sndpkl);
- if (local && !xflag)
- tmsg(".");
- ShowTypeOut((char)type);
- ShowPackets(++Stats.Packets);
- return(i);
- }
-
- //-----------------------------------------------------------------------------
- char NEAR rpack (void)
- {
- int i, j, x, type, rlnpos;
- char pbc[4];
-
- if (!(j = ttinl(rcvpkt, MAXRP, reol, timint)))
- return(0);
-
- rsn = rln = -1;
-
- if (j < 0) {
- ShowTypeIn('T');
- return('T');
- }
-
- if (ProtSet.DebugPacket) {
- tmsg("\n\rReceived: ");
- traw(rcvpkt, j);
- }
-
- for (i = 0; rcvpkt[i] != rmark && (i < j); i++);
-
- if (i == j) {
- ShowTypeIn('Q');
- return('Q');
- }
-
- rlnpos = ++i;
- if ((j = unchar(rcvpkt[i++])) == 0) {
- j = rlnpos + 5;
- if (j > MAXRP) {
- ShowTypeIn('Q');
- return('Q');
- }
- x = rcvpkt[j];
- rcvpkt[j] = '\0';
- if (unchar(x) != chk1(rcvpkt+rlnpos)) {
- ShowTypeIn('Q');
- return('Q');
- }
- rcvpkt[j] = (char)x;
- rln = unchar(rcvpkt[j - 2]) * 95 + unchar(rcvpkt[j - 1]) - bctu;
- j = 3;
- }
- else {
- rln = j - bctu - 2;
- j = 0;
- }
- rsn = unchar(rcvpkt[i++]);
- type = rcvpkt[i++];
- i += j;
- rdatap = rcvpkt + i;
- j = rln + i;
-
- if (j > MAXRP) {
- ShowTypeIn('Q');
- return('Q');
- }
- for (x = 0; x < bctu; x++)
- pbc[x] = rcvpkt[j+x];
- rcvpkt[j] = '\0';
-
- switch (bctu) {
- case 1:
- if (unchar(*pbc) != (char)chk1(rcvpkt+rlnpos)) {
- ShowTypeIn('Q');
- return('Q');
- }
- break;
- case 2:
- x = unchar(*pbc) << 6 | unchar(pbc[1]);
- if (x != (int)chksum(rcvpkt+rlnpos)) {
- ShowTypeIn('Q');
- return('Q');
- }
- break;
- case 3:
- x = unchar(*pbc) << 12 | unchar(pbc[1]) << 6 | unchar(pbc[2]);
- if (x != chk3(rcvpkt+rlnpos)) {
- ShowTypeIn('Q');
- return('Q');
- }
- break;
- default:
- error("Impossible Block Check Type");
- }
-
- ShowTypeIn((char)type);
- return((char)type);
- }
-
- //-----------------------------------------------------------------------------
- int NEAR input(void)
- {
- static int try;
- int type;
-
- if (start != 0) {
- type = start;
- start = 0;
- try = 0;
- return(type);
- }
-
- if (!(type = rpack()))
- return(0);
-
- if (ProtSet.DebugOther)
- tmsg("\n\rPacket: Type %c, Sequence %i for %i, Length %i",
- type, rsn, seq, rln);
-
- if (cc) {
- message("Kermit Done", "Kermit Aborted by User");
- EndKermit(-1);
- return(0);
- }
-
- if (type == 'E')
- return(type);
-
- if (rsn != seq || strchr("TQN",type)) {
- if (type == 'N' && rsn == (seq+1) & 63)
- type = 'Y';
- else if (try > limit)
- type = 'T';
- else {
- try++;
- resend();
- return(0);
- }
- }
-
- try = 0;
- ttflui();
- return(type);
- }
-
- //-----------------------------------------------------------------------------
- void NEAR nxtpkt (void)
- {
- seq = (seq + 1) & 63;
- }
-
- //-----------------------------------------------------------------------------
- int NEAR resend(void)
- {
- int x;
- if (*sndpkt)
- x = ttol(sndpkt, sndpkl);
- else
- x = nak();
- if (local && !xflag)
- tmsg("%%");
- ShowRetries(++Stats.Retries);
- cr = FALSE;
- return(x);
- }
-
- //-----------------------------------------------------------------------------
- int NEAR chk3(char *s)
- {
- unsigned int c, q;
- long crc = 0;
-
- while ((c = *s++) != '\0') {
- if (parity) c &= 0177;
- q = (int)(crc ^ c) & 017;
- crc = (crc >> 4) ^ (q * 010201);
- q = (int)(crc ^ (c >> 4)) & 017;
- crc = (crc >> 4) ^ (q * 010201);
- }
- return((int)crc);
- }
-
-
- //-----------------------------------------------------------------------------
- int NEAR chk1(char *packet)
- {
- int s, t;
-
- s = (int)chksum(packet);
- t = (((s & 192) >> 6) + s) & 63;
- return(t);
- }
-
- //-----------------------------------------------------------------------------
- long NEAR chksum(char *p)
- {
- unsigned int m;
- long s;
-
- m = (parity) ? 0177 : 0377;
- for (s = 0; *p != '\0'; *p++)
- s += *p & m;
- return(s & 07777);
- }
-
- //-----------------------------------------------------------------------------
- void NEAR tinit(void)
- {
- spsiz = ProtSet.SendPktSize;
- rpsiz = ProtSet.RecvPktSize;
- timint = ProtSet.SendTimeout;
- rtimo = ProtSet.RecvTimeout;
- bctr = ProtSet.BlockCheck;
- limit = ProtSet.RetryLimit;
-
- spadc = (char)PktSet.Send.PadChar;
- rpadc = (char)PktSet.Recv.PadChar;
- rpadn = PktSet.Recv.PadCount;
- spadn = PktSet.Send.PadCount;
- smark = (char)PktSet.Send.StartChar;
- rmark = (char)PktSet.Recv.StartChar;
- seol = (char)PktSet.Send.EndChar;
- reol = (char)PktSet.Recv.EndChar;
- sctlq = (char)PktSet.Send.CtlPrefix;
- rctlq = (char)PktSet.Recv.CtlPrefix;
-
- bctu = 1;
- ebq = '&';
- ebqflg = 0;
- rqf = -1;
- rq = 0;
- sq = 'Y';
- rpt = 0;
- rptq = '~';
- rptflg = 0;
- start = 0;
- clrinl = 0;
-
- capas = 10;
- atcapb = 8; atcapr = ProtSet.Attributes; atcapu = 0;
- swcapb = 4; swcapr = ProtSet.Windowing; swcapu = 0;
- lpcapb = 2; lpcapr = ProtSet.LongPackets; lpcapu = 0;
-
- seq = 0;
- sndpkl = 0;
-
- sndpkt[0] = '\0';
- rcvpkt[0] = '\0';
- isp = NULL;
- osp = NULL;
- ssc = 0;
-
- filsiz = 0;
-
- cx = 0;
- cz = 0;
- cr = 0;
- ce = 0;
- cc = 0;
- xflag = 0;
- xpkt = 0;
-
- parity = !(CommSet.Parity == NOPARITY);
- delay = 5;
- local = 1;
-
- server = 0;
- first = 0;
- keep = 0;
-
- Stats.Packets = 0;
- Stats.Bytes = 0;
- Stats.Retries = 0;
-
- ttflui();
- }
-
- //-----------------------------------------------------------------------------
- int NEAR ack(void)
- {
- int x;
- x = spack('Y', seq, 0, "");
- nxtpkt();
- return(x);
- }
-
- //-----------------------------------------------------------------------------
- int NEAR ackl(char *s)
- {
- int x;
- x = spack('Y', seq, strlen(s), s);
- nxtpkt();
- return(x);
- }
-
- //-----------------------------------------------------------------------------
- int NEAR nak(void)
- {
- int x;
- x = spack('N', seq, 0, "");
- return(x);
- }
-
- //-----------------------------------------------------------------------------
- int NEAR sinit(char c)
- {
- char *s;
-
- s = rpar();
- tmsg("\n\rInitializing to send");
- if (local == 0 && c == 'S' && server == 0) {
- tmsg("\n\rEscape back to local system, give RECEIVE command...");
- /* sleep(delay); */
- }
- return(spack(c, seq, strlen(s), s));
- }
-
- //-----------------------------------------------------------------------------
- void NEAR rinit(void)
- {
- tmsg("\n\rInitializing to receive");
- }
-
- //-----------------------------------------------------------------------------
- int NEAR gnfile(void)
- {
- if (cz)
- return(0);
-
- if (hSendList)
- return(SendMessage(hSendList, LB_GETTEXT, nfils++,
- (LONG)(LPSTR)filnam) != LB_ERR);
-
- if (nfils-- > 0)
- return(1);
- else
- return(0);
- }
-
- //-----------------------------------------------------------------------------
- int NEAR sfile(void)
- {
- int x;
- char pktnam[80];
- char MsgBuf[100];
-
- if (zopeni(filnam) < 0) return(-1);
- zltor(filnam, pktnam);
- x = encstr(pktnam);
- sprintf(MsgBuf, "Sending %s", pktnam);
- SetDlgItemText(hXfrWnd, IDD_ACTION, MsgBuf);
- if (local)
- tmsg("\n\rSending %s as %s", filnam, pktnam);
- first = 1;
- maxsiz = spsiz - (bctr + 3);
- nxtpkt();
- return(spack((char)(xpkt ? 'X' : 'F'), seq, x, data));
- }
-
- //-----------------------------------------------------------------------------
- int NEAR rcvfil(void)
- {
- char myname[80];
- char MsgBuf[100];
-
- if (xflag) {
- SetDlgItemText(hXfrWnd, IDD_ACTION, "Receiving Screen Data");
- tmsg("\n\rReceiving Screen Data\n\r");
- return(0);
- }
-
- zrtol(filnam,myname,TRUE);
- if (zopeno(myname) < 0)
- return(-1);
- else {
- sprintf(MsgBuf, "Receiving %s", myname);
- SetDlgItemText(hXfrWnd, IDD_ACTION, MsgBuf);
- if (local)
- tmsg("\n\rReceiving %s as %s", filnam, myname);
- strcpy(filnam, myname);
- return(0);
- }
- }
-
- //-----------------------------------------------------------------------------
- int NEAR closof(void)
- {
- if (xflag)
- return(0);
- if (zcloso((rln >= 1) && (rdatap[0] == 'D')) < 0)
- return(-1);
- tmsg("\n\rOK");
- return(0);
- }
-
- //-----------------------------------------------------------------------------
- int NEAR seot(void)
- {
- nxtpkt();
- tmsg("\n\rDone");
- return(spack('B',seq,0,""));
- }
-
- //-----------------------------------------------------------------------------
- int NEAR sdata(void)
- {
- int x;
-
- if (rln >= 1)
- switch (rdatap[0]) {
- case 'Z':
- cz = TRUE;
- break;
- case 'X':
- cx = TRUE;
- break;
- }
-
- if (cx || cz)
- return(0);
-
- if ((x = getpkt(maxsiz)) == 0)
- return(0);
- nxtpkt();
- ShowBytes(Stats.Bytes);
- return(spack('D', seq, x, data));
- }
-
- //-----------------------------------------------------------------------------
- int NEAR seof(char *s)
- {
- if (zclosi() < 0)
- return(-1);
- else {
- if (local)
- tmsg("\n\rOK");
- nxtpkt();
- return(spack('Z', seq, strlen(s), s));
- }
- }
-
- //-----------------------------------------------------------------------------
- int NEAR getpkt(int maxlen)
- {
- int i, next;
- static int c;
- static char remain[6] = "\0\0\0\0\0\0";
-
- if (first == 1) {
- first = 0;
- *remain = '\0';
- c = gnchar();
- if (c < 0) {
- first = -1;
- return(size = 0);
- }
- }
- else if (first == -1) {
- return(size = 0);
- }
- for (size = 0; (data[size] = remain [size]) != '\0'; size++);
- *remain = '\0';
-
- rpt = 0;
- while (first > -1) {
- next = gnchar();
- if (next < 0)
- first = -1;
- osize = size;
- encode(c, next);
- c = next;
-
- if (size == maxlen)
- return(size);
-
- if (size > maxlen) {
- for (i = 0; (remain[i] = data[osize+i]) != '\0'; i++);
- size = osize;
- data[size] = '\0';
- return(size);
- }
- }
- return(size);
- }
-
- //-----------------------------------------------------------------------------
- int NEAR gnchar (void)
- {
- char c;
-
- if (isp)
- return((c = *isp++) > 0 ? c : -1);
- else
- return(zgetc());
- }
-
- //-----------------------------------------------------------------------------
- void NEAR encode(int a, int next)
- {
- int a7, b8;
-
- if (rptflg) {
- if (a == next) {
- if (++rpt < 94) {
- return;
- }
- else if (rpt == 94) {
- data[size++] = (char)rptq;
- data[size++] = (char)tochar(rpt);
- rpt = 0;
- }
- }
- else if (rpt == 1) {
- rpt = 0;
- encode(a,-1);
- if (size <= maxsiz)
- osize = size;
- rpt = 0;
- encode(a,-1);
- return;
- }
- else if (rpt > 1) {
- data[size++] = (char)rptq;
- data[size++] = (char)tochar(++rpt);
- rpt = 0;
- }
- }
- a7 = a & 127;
- b8 = a & 128;
-
- if (ebqflg && b8) {
- data[size++] = (char)ebq;
- a = a7;
- }
-
- if (a7 < 32 || a7 == 127) {
- data[size++] = sctlq;
- a = ctl(a);
- }
- else if (a7 == sctlq)
- data[size++] = sctlq;
- else if (ebqflg && a7 == ebq)
- data[size++] = sctlq;
- else if (rptflg && a7 == rptq)
- data[size++] = sctlq;
-
- data[size++] = (char)a;
- data[size] = '\0';
- }
-
- //-----------------------------------------------------------------------------
- int NEAR decode(void)
- {
- char a, a7, b8;
-
- while ((a = *rdatap++) != '\0') {
- rpt = 1;
- if (rptflg) {
- if (a == (char)rptq) {
- rpt = unchar(*rdatap++);
- a = *rdatap++;
- }
- }
- b8 = 0;
- if (ebqflg) {
- if (a == (char)ebq) {
- b8 = 128;
- a = *rdatap++;
- }
- }
- if (a == rctlq) {
- a = *rdatap++;
- a7 = a & 127;
- if (a7 > 62 && a7 < 96)
- a = ctl(a);
- }
- a |= b8;
- for (; rpt > 0; rpt--)
- if (pnchar(a) < 0)
- return(-1);
- }
- ShowBytes(Stats.Bytes);
- return(0);
- }
-
- //-----------------------------------------------------------------------------
- int NEAR pnchar (int c)
- {
- if (xflag) {
- tchar((char)c);
- Stats.Bytes++;
- return(1);
- }
- else if (osp) {
- *osp++ = (char)c;
- return(1);
- }
- else
- return(zputc(c));
- }
-
- //-----------------------------------------------------------------------------
- int NEAR encstr(char *s)
- {
- first = 1;
- isp = s;
- getpkt(spsiz);
- isp = NULL;
- return(size);
- }
-
- //-----------------------------------------------------------------------------
- void NEAR decstr(char *s)
- {
- osp = s;
- decode();
- *osp = '\0';
- osp = NULL;
- }
-
- //-----------------------------------------------------------------------------
- void NEAR spar(char *s)
- {
- int x;
-
- s--;
-
- x = (rln >= 1) ? unchar(s[1]) : 80;
- spsiz = (x < 10) ? 80 : x;
-
- x = (rln >= 2) ? unchar(s[2]) : 5;
- timint = (x < 0) ? 5 : x;
-
- spadn = 0;
- spadc = '\0';
- if (rln >= 3) {
- spadn = unchar(s[3]);
- if (rln >= 4)
- spadc = ctl(s[4]);
- else
- spadc = 0;
- }
-
- seol = (rln >= 5) ? unchar(s[5]) : '\r';
- if ((seol < 2) || (seol > 31))
- seol = '\r';
-
- x = (rln >= 6) ? s[6] : '#';
- rctlq = ((x > 32 && x < 63) || (x > 95 && x < 127)) ? (char)x : '#';
-
- rq = (rln >= 7) ? s[7] : 0;
- if (rq == 'Y')
- rqf = 1;
- else if ((rq > 32 && rq < 63) || (rq > 95 && rq < 127))
- rqf = 2;
- else
- rqf = 0;
- switch (rqf) {
- case 0:
- ebqflg = 0;
- break;
- case 1:
- if (parity) {
- ebqflg = 1;
- ebq = '&';
- }
- break;
- case 2:
- if (ebqflg = (ebq == sq || sq == 'Y'))
- ebq = rq;
- }
-
- x = 1;
- if (rln >= 8) {
- x = s[8] - '0';
- if ((x < 1) || (x > 3))
- x = 1;
- }
- bctr = x;
-
- if (rln >= 9) {
- rptq = s[9];
- rptflg = ((rptq > 32 && rptq < 63) || (rptq > 95 && rptq < 127));
- }
- else
- rptflg = 0;
-
- atcapu = lpcapu = swcapu = 0;
- if (rln >= 10) {
- x = unchar(s[10]);
- atcapu = (x & atcapb) && atcapr;
- lpcapu = (x & lpcapb) && lpcapr;
- swcapu = (x & swcapb) && swcapr;
- for (capas = 10; (unchar(s[capas]) & 1) && (rln >= capas); capas++);
- }
-
- if (lpcapu) {
- if (rln > capas + 2) {
- x = unchar(s[capas + 2]) * 95 + unchar(s[capas + 3]);
- spsiz = x > MAXSP ? MAXSP : x;
- }
- }
- }
-
- //-----------------------------------------------------------------------------
- char NEAR *rpar(void)
- {
- data[1] = tochar(94);
- data[2] = tochar((char)rtimo);
- data[3] = tochar((char)rpadn);
- data[4] = ctl(rpadc);
- data[5] = tochar(reol);
- data[6] = '#';
- switch (rqf) {
- case -1:
- case 1:
- if (parity) ebq = sq = '&';
- break;
- case 0:
- case 2:
- break;
- }
- data[7] = (char)sq;
- data[8] = (char)bctr + '0';
- if (rptflg)
- data[9] = (char)rptq;
- else
- data[9] = '~';
-
- data[10] = (char)tochar((atcapr?atcapb:0) |
- (lpcapr?lpcapb:0) |
- (swcapr?swcapb:0));
- data[11] = tochar(0);
- data[12] = (char)tochar(rpsiz / 95);
- data[13] = (char)tochar(rpsiz % 95);
- data[14] = '\0';
-
- return(data+1);
- }
-
- int sadone;
-
- //-----------------------------------------------------------------------------
- int NEAR sattr(void)
- {
- int fh;
- char sizestr[20];
- char attrstr[20];
-
- if (sadone)
- return(0);
-
- fh = open(filnam, O_RDONLY);
- ltoa((filsiz = filelength(fh))/1024, sizestr, 10);
- close(fh);
-
- sadone = 1;
- nxtpkt();
- sprintf(attrstr, "!%c%s", tochar(strlen(sizestr)), sizestr);
- return(spack('A',seq,strlen(attrstr),attrstr));
- }
-
- //-----------------------------------------------------------------------------
- int NEAR rdattr(char *s)
- {
- return(0);
- }
-
- //-----------------------------------------------------------------------------
- char *NEAR setatt(char *s)
- {
- int i;
- char attrtype;
- int attrlen;
- char attrstr[20];
-
- i = 0;
- while (i < rln) {
- attrtype = s[i++];
- attrlen = unchar(s[i++]);
- memset(attrstr, 0, sizeof(attrstr));
- memcpy(attrstr, s+i, attrlen);
- i += attrlen;
- switch (attrtype) {
- case '!':
- if (filsiz == 0)
- filsiz = atol(attrstr) * 1024;
- break;
- case '1':
- filsiz = atol(attrstr);
- break;
- }
- }
-
- return("");
- }
-
- //-----------------------------------------------------------------------------
- int NEAR scmd(char t, char *s)
- {
- encstr(s);
- return(spack(t, seq, size, data));
- }
-
- //-----------------------------------------------------------------------------
- void DoKermit(void)
- {
- static char state;
- char type;
- static int filcnt;
-
- if (!(type = (char)input()))
- return;
-
- if (ProtSet.DebugState)
- tmsg("\n\rProtocol: State %i, Type: %c", state, type);
-
- if (ce) {
- ERR("User Intervention");
- }
-
- /******************************************************
- * Kermit Send state transitions... *
- ******************************************************/
-
- else if (type == 's') {
- tinit();
- if (sinit('S') < 0) {
- ERR("sinit");
- }
- else {
- filcnt = 0;
- BEGIN(ssfil);
- }
- }
-
- else if (state == ssfil && type == 'Y') {
- if (filcnt++ == 0)
- spar(rdatap);
- cx = 0;
- Stats.Bytes = 0;
- sadone = 0;
- bctu = bctr;
- if (gnfile() > 0) {
- if (sfile() < 0) {
- ERR("sfile");
- }
- else if (atcapu) {
- BEGIN(ssatr);
- }
- else {
- BEGIN(ssdat);
- }
- }
- else {
- if (seot() < 0) {
- ERR("seot");
- }
- else {
- BEGIN(sseot);
- }
- }
- }
-
- else if (state == ssatr && type == 'Y') {
- int x;
- if ((x = sattr()) < 0) {
- ERR("sattr");
- }
- else if (x > 0)
- BEGIN(ssatx);
- else {
- start = 'Y';
- BEGIN(ssdat);
- }
- }
-
- else if (state == ssatx && type == 'Y') {
- int x;
- if (rdattr(rdatap) < 0) {
- if (seof("D") < 0) {
- ERR("seof");
- }
- else
- BEGIN(sseot);
- }
- else if ((x = sattr()) < 0) {
- ERR("sattr");
- }
- else if (x == 0) {
- start = 'Y';
- BEGIN(ssdat);
- }
- }
-
- else if (state == ssdat && type == 'Y') {
- int x;
- if ((x = sdata()) == 0) {
- if (seof((cx | cz) ? "D" : "") < 0) {
- ERR("seof");
- }
- else {
- BEGIN(ssfil);
- }
- }
- else if (x < 0) {
- ERR("sdata");
- }
- }
- else if (state == sseot && type == 'Y') {
- message("Kermit Done","Transfer Completed");
- RESUME(0);
- }
-
- /******************************************************
- * Kermit Receive state transitions. *
- ******************************************************/
-
- else if (type == 'v') {
- tinit();
- rinit();
- BEGIN(srini);
- }
-
- else if (state == srini && type == 'S') {
- spar(rdatap);
- ackl(rpar());
- bctu = bctr;
- BEGIN(srfil);
- }
-
- else if (state == srfil && type == 'B') {
- tmsg("\n\rDone");
- ack();
- message("Kermit Done","Transfer Completed");
- RESUME(0);
- }
-
- else if (state == srfil && type == 'F') {
- decstr(filnam);
- ack();
- BEGIN(sratt);
- }
-
- else if (state == sratt && type == 'A') {
- ackl(setatt(rdatap));
- }
-
- else if (state == sratt && type == 'D') {
- if (rcvfil() < 0) {
- ERR("rcvfil");
- }
- else {
- cx = 0;
- Stats.Bytes = 0;
- start = type;
- BEGIN(srdat);
- }
- }
-
- else if (state == srdat && type == 'D') {
- if (decode() < 0) {
- ERR("decode");
- }
- else {
- if (cx)
- ackl("X");
- else if (cz)
- ackl("Z");
- else
- ack();
- }
- }
-
- else if (state == srdat && type == 'Z') {
- if (closof() < 0) {
- ERR("closof");
- }
- else {
- ack();
- BEGIN(srfil);
- }
- }
-
- /******************************************************
- * Kermit Client state transitions. *
- ******************************************************/
-
- else if (type == 'r') {
- tinit();
- ssc = 0;
- sinit('I');
- BEGIN(sipkt);
- }
-
- else if (type == 'c') {
- tinit();
- ssc = 'C';
- sinit('I');
- BEGIN(sipkt);
- }
-
- else if (type == 'g') {
- tinit();
- ssc = 'G';
- sinit('I');
- BEGIN(sipkt);
- }
-
- else if (state == sipkt && type == 'Y') {
- spar(rdatap);
- start = 'E';
- }
-
- else if (state == sipkt && type == 'E') {
- if (ssc) {
- if (scmd(ssc, cmarg) < 0) {
- ERR("scmd");
- }
- else
- BEGIN(srgen);
- }
- else {
- if (scmd('R', cmarg) < 0) {
- ERR("scmd");
- }
- else
- BEGIN(srini);
- }
- }
-
- else if (state == srgen && type == 'Y') {
- xflag = 1;
- decode();
- RESUME(0);
- }
-
- else if (state == srgen && type == 'S') {
- spar(rdatap);
- ackl(rpar());
- bctu = bctr;
- BEGIN(srfil);
- }
-
- else if ((state == srgen || state == srfil) && type == 'X') {
- xflag = 1;
- ack();
- BEGIN(sratt);
- }
-
- /******************************************************
- * Kermit Server state transitions. *
- ******************************************************/
-
- else if (type == 'x') {
- SERVE;
- }
-
- else if (state == sserv && type == 'T') {
- SERVE;
- }
-
- else if (state == sserv && type == 'I') {
- spar(rdatap);
- ackl(rpar());
- seq = 0;
- }
-
- else if (state == sserv && type == 'R') {
- decstr(strbuf);
- nfils = 1;
- strcpy(filnam, strbuf);
- if (sinit('S') < 0) {
- ERR("sinit");
- }
- else {
- filcnt = 0;
- BEGIN(ssfil);
- }
- }
-
- else if (state == sserv && type == 'S') {
- spar(rdatap);
- ackl(rpar());
- bctu = bctr;
- BEGIN(srfil);
- }
-
- else if (state == sserv && type == 'G') {
- decstr(strbuf);
- start = *strbuf;
- xpkt = 1;
- BEGIN(ssgen);
- }
-
- else if (state == sserv && type == 'E') {
- SERVE;
- }
-
- else if (state == sserv) {
- ERR("Unknown Server Command");
- SERVE;
- }
-
- else if (state == ssgen && type == 'F') {
- ack();
- server = 0;
- RESUME(0);
- }
-
- else if (state == ssgen && type == 'T') {
- decstr(strbuf);
- nfils = 1;
- strcpy(filnam, strbuf + 2);
- if (sinit('S') < 0) {
- ERR("sinit");
- }
- else {
- filcnt = 0;
- BEGIN(ssfil);
- }
- }
-
- else if (state == ssgen) {
- ERR("Unknown Generic Command");
- SERVE;
- }
-
- /******************************************************
- * Error state transitions... *
- ******************************************************/
-
- else if (type == 'E') {
- message("Kermit - Remote Error",rdatap);
- RESUME(-1);
- }
-
- else if (type == 'T') {
- ERR("Remote Kermit Not Responding");
- }
-
- else {
- ERR("Unexpected Packet Type");
- }
- }
-