home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
researchmachines.zip
/
rmllin.c
< prev
next >
Wrap
Text File
|
1985-07-11
|
11KB
|
452 lines
/***********************************************************************/
/* File KLINE.C - Comms-line handling procedures for RML Kermit;
Chris Kennington RML. 9th July 1985. */
#define DEFS1 1
#define DEFS2 1
#include "stdio.h"
#include "b:kext.h"
/* local globals for nextin/nextout */
static int fuzzy = 20000; /* arbitry value */
static int ret;
static char dummy, typout;
static char comerr[] = "Comms err %x";
static char enter[] = " Enter %s for mainframe:\r> ";
connect() /* keyboard/screen to comms line relay */
/* Reads keyboard and transmits to line; reads line and outputs to
screen; checks comms line for error conditions. */
{
char c, cn, conn;
static char pager = 0, *data[5];
int in;
printmsg("Connecting you to remote mainframe ... ");
keyconn(); /* make arrows valid */
outc(NL);
kmode = CONN;
while (kmode == CONN) { /* until stopped */
if (keyget(&c) != 0) {
if (echo != 0)
outc(c);
cn = 100;
while (cn-- > 0)
if (s4put(1,&c) > 0)
break;
if (cn == 0)
bell();
}
if ( (in = s4get7(1,&data)) == 1 ) {
#ifndef MPUZ80
if (*data != LF)
#endif
outfc(*data);
}
else if (in != 0) {
outc(NL);
printmsg("Comms error code %x; ", in);
while (s4test() == in)
;
}
} /* end switch */
/* broken out by changing kmode */
return;
} /* End of connect() */
flushinput()
/* Dump all pending input to clear stacked up NAK's. */
{
char rubbish[11];
while (s4get(10,rubbish) > 0)
;
} /* end of flushinput */
inctry() /* increment tries & pkt-# */
/* used by both recieve & send routines */
{
oldtry = numtry;
numtry = 0;
n = (n+1)%64;
return;
} /* end of inctry() */
/* Line-I/O Routines for sending/receiving files */
static nextab() /* set abort-flag if CTLC */
{
if (dummy == CTLC) { /* treat ctlc as abort */
printmsg("Abort transfer");
if (confirm() == TRUE)
abtflag = 1;
dummy = 0;
}
return;
} /* end of nextab() */
nextin(ic) /* next char from line */
/* strips parity bit if !image; handles fuzzy timeout;
returns 0, but 1 if either abtflag or nakflag has been set */
char *ic;
{
int r;
abtflag = nakflag = 0;
One:
while ( (ret = (image) ? s4get(1,ic) : s4get7(1,ic)) == 0 ) {
keyget(&dummy);
nextab();
if ( (abtflag+nakflag) != 0 )
return(1);
if (--fuzzy == 0) { /* timer expired */
nakflag = 1;
++timouts;
if (list == 1)
outc('T');
if (list > 2)
txtout("\rDbg: Timeout.");
return(1);
} }
while (ret < 0) { /* error */
printmsg(comerr,ret);
while ( (r = (image) ? s4get(1,ic) : s4get7(1,ic)) == ret) {
keyget(&dummy);
if ( (abtflag+nakflag) != 0 )
return(1);
}
if (r == 0)
goto One;
ret = r;
}
if (list > 4)
outc(*ic);
if (*ic == SOH)
fuzzy = fuzz[env]; /* fuzzy timer re-set on SOH only */
return(abtflag+nakflag);
} /* end of nextin() */
nextout(c) /* next char to line */
/* returns 0, but 1 if either abtflag or nakflag has been set */
char c;
{
int r;
abtflag = nakflag = 0;
One:
while ( (ret = s4put(1,&c)) == 0 ) {
keyget(&dummy);
nextab();
if ( (abtflag+nakflag) != 0 )
return(1);
}
while (ret < 0) { /* error */
printmsg(comerr,ret);
while ( (r = s4put(1,&c)) == ret) {
keyget(&dummy);
if ( (abtflag+nakflag) != 0 )
return(1);
}
if (r == 0)
goto One;
ret = r;
}
if (list > 4)
outc(c);
keyget(&dummy);
return(abtflag+nakflag);
} /* end of nextout() */
char rpack(len,num,data) /* Read a Packet */
/* If !image, nextin() has stripped the parity bit. */
int *len, *num; /* Packet length, number */
char *data; /* Packet data */
{
int i, done; /* Data character number, loop exit */
char t, /* Current input character */
cchksum, /* Our (computed) checksum */
rchksum; /* Checksum received from other host */
static int oldnum = 63;
Top:
fuzzy = fuzz[env]; /* set timer */
t = type = 0; /* could be garbage */
*len = 0; /* in case timeout */
while (t != SOH) if (nextin(&t) != 0) {
type = 'T';
goto Flag;
}
done = FALSE; /* Got SOH, init loop */
while (!done) { /* Loop to get a packet */
if (nextin(&t) != 0) /* Get length character */
break;
cchksum = t; /* Start the checksum */
if (t == SOH)
continue; /* Resynchronize if SOH */
t &= 0x7f; /* 7-bit protocol char */
if ( (*len = unchar(t)-3) < 0 ) /* Character count */
return(FALSE); /* protect against bad length */
if (nextin(&t) != 0) /* Get packet-number character */
break;
cchksum = cchksum + t; /* Update checksum */
t &= 0x7f; /* 7-bit protocol char */
if (t == SOH)
continue; /* Resynchronize if SOH */
*num = unchar(t); /* Packet number */
if (*num == oldnum)
++dupes; /* its a duplicate */
else
oldnum = *num;
vtout(LOCSEQ,t|0x80);
if (nextin(&t) != 0) /* Get packet-type character */
break;
cchksum = cchksum + t; /* Update checksum */
t &= 0x7f; /* 7-bit protocol char */
if (t == SOH)
continue; /* Resynchronize if SOH */
if ( (type = t) == 'N' ) {
++naxin; /* its a NAK */
if (list == 1)
outc('N');
}
if (type == typout)
goto Top; /* its an echo */
vtout(LOCIN,type);
for (i=0; i<*len; i++) { /* The data itself, if any */
if (nextin(&t) != 0) /* Get data character */
break;
cchksum = cchksum + t; /* Update checksum */
data[i] = t; /* Put it in the data buffer */
t &= 0x7f; /* 7-bit char */
if (t == SOH) break; /* stop if SOH */
}
if (t == SOH)
continue; /* Resynchronize if SOH */
if ( (nakflag+abtflag) != 0 )
break;
data[*len] = 0; /* Mark the end of the data */
if (nextin(&t) != 0) /* Get checksum character */
break;
rchksum = unchar(t); /* Convert to numeric */
done = TRUE; /* Got checksum, done */
}
flushinput(); /* discard anything stacked */
if ( (list > 3) && ( (nakflag+abtflag) == 0 ) ) { /* Display */
outc(CR);
printf(" Packet in: type %c, num %d, len%d;",type,*num,*len);
outc(CR);
if (*len != 0) {
data[*len] = 0;
printf(" data: \"%s\";",data);
outc(CR);
} }
Flag: /* check for user abort or nak */
vtout(LOCIN,type|0x80); /* inverse of type */
if (nakflag != 0)
return(FALSE); /* cause NAK to be sent */
if (abtflag != 0) {
abtflag = 0;
return('A'); /* cause ABORT */
}
/* Fold in bits 7,8 to compute */
cchksum = (((cchksum&0300) >> 6)+cchksum)&077; /* final checksum */
if (cchksum == rchksum) {
if (type == 'D')
blockmv(oldpkt,data,*len); /* copy for reference */
return(type); /* OK return */
}
++badcrcs; /* count bad checksum */
if (list == 1)
outc('C');
else if (list > 2)
txtout(" Bad checksum ");
return(FALSE);
} /* end of rpack() */
servsend(type) /* send command to server-Kermit etc. */
char type;
{
int *len, *num;
char pkt;
switch(type) {
case RMSV: /* Server Commands */
pkt = 'K'; /* packet-type */
goto Rmcont;
case RMH: /* OS Commands */
pkt = 'C'; /* packet-type */
Rmcont:
txtout(" Calling mainframe ... ");
if (parex() == 0) { /* exchange parameters */
printmsg("Mainframe Kermit seems dead ");
kmode = KERM;
break;
}
else forever {
printmsg(enter,"message");
if (keyline(packet) == 0) {
kmode = CMND;
break;
}
printmsg("Telling mainframe ... ");
recsw(type,pkt);
}
break;
case GET: /* fetch files */
printf(inform);
printmsg(enter,"filenames");
if (keyline(packet) == 0)
kmode = KERM;
else {
vtline(LOCMODE,rcvng);
state = kmode = GET;
}
break;
case SEND: /* send files */
vtline(LOCMODE,sendf);
kmode = SEND;
break;
case BYE: /* logout from mainframe */
spack('G',n,1,"L"); /* generic logout */
kmode = KERM;
outc(SP);
txtout(trying);
rpack(&len,&num,recpkt);
if (len != 0) {
recpkt[*len] = 0;
printmsg("%s %s",mainsays,recpkt);
}
break;
case LOGO: /* cancel mainframe Kermit */
spack('G',n,1,"F"); /* try "Finish" */
txtout(dots);
if (rpack(&len,&num,recpkt) != 'Y') /* synchronize */
spack('E',0,strlen(errmsg),errmsg);
vtline(LOCMODE,connto);
kmode = CONN;
break;
case QUIT: /* cancel (local) Kermit */
kermkill(1);
case MAIN: /* back to top level */
kmode = KERM;
break;
} /* end switch */
return;
} /* end of servsend() */
setbaud() /* set line-speed from spdcode */
{
vtline(LOCSPEED+3," ");
vtline(LOCSPEED,spval[spdcode]);
s4speed(spdcode);
return;
} /* end of setbaud() */
setpar() /* set parity from parity */
{
commode &= 0xfcff; /* remove parity bits */
commode |= (int)parity * 256; /* substitute new */
s4set(commode,comctrl);
return;
} /* end of setpar() */
spack(type,num,len,data) /* Send a Packet */
char type, *data;
int num, len;
{
int i; /* Character loop counter */
char c, chksum;
register char *bufp; /* Buffer pointer */
static int cumnum = 0;
if (list > 3) { /* Display outgoing packet */
outc(CR);
printf(" Packet out: type %c, num %d, len %d:",type,num,len);
outc(CR);
if (len != 0) {
data[len] = 0;
printf(" data: \"%s\";",data);
outc(CR);
} }
vtout(LOCOUT,type);
vtout(LOCSEQ,tochar(n));
sprintf(work,"%d =",cumnum++);
vtline(LOCPKTS,work);
for (i=1; i<=pad; i++)
if (nextout(&padchar) != 0) /* padding */
return;
bufp = work; /* buffer pointer */
*bufp++ = SOH;
*bufp++ = tochar(len+3);
chksum = tochar(len+3);
*bufp++ = tochar(num);
chksum += tochar(num);
typout = *bufp++ = type;
chksum += type;
for (i=0; i<len; i++) { /* for all data characters */
*bufp++ = c = data[i];
chksum += c;
}
chksum = (((chksum&0300) >> 6)+chksum)&077; /* Compute final checksum */
*bufp++ = tochar(chksum);
*bufp++ = eol; /* Extra-packet line terminator */
*bufp = CR; /* & CR for safety */
len = bufp-work+1;
bufp = work;
while (len-- > 0)
if (nextout(*bufp++) != 0)
break;
vtout(LOCOUT,type|0x80); /* inverse of type */
if (netslow) /* discard any buffered dupes */
flushinput();
return;
} /* end of spack() */
/********************** End of KLINE.C **************************/