home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
files
/
telecomm
/
uemlsrc
/
kerrec.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-08-24
|
16KB
|
424 lines
/* kerrec.c kermit protocol file receive support.
*/
#include <stdio.h>
#include <osbind.h>
#include "ed.h"
#include "kermit.h"
extern char getfiln[NFILEN];
/*
* r e c s w
*
* This is the state table switcher for receiving files.
*/
recsw()
{
state = 'R'; /* Receive-Init is the start state */
n = np = 0; /* Initialize message number */
numtry = 0; /* Say no tries yet */
while(TRUE)
{
switch(state) /* Do until done */
{
case 'R':
state = rinit();
mlwrite("[Awaiting remote init]");
break; /* Receive-Init */
case 'F':
state = rfile();
break; /* Receive-File */
case 'D':
state = rdata();
break; /* Receive-Data */
case 'C':
return(TRUE); /* Complete state */
case 'A':
return(FALSE); /* "Abort" state */
}
}
}
/*
* astget.c server function GET
* implemented by B. Nebel
*/
getsw()
{
int result;
flushinput();
spack('R',0,strlen(getfiln),getfiln);
result = recsw();
return (result);
}
/*
* r i n i t
*
* Receive Initialization
*/
char rinit()
{
int len, num; /* Packet length, number */
if (numtry++ > MAXTRY) return('A'); /* If too many tries, "abort" */
switch(rpack(&len,&num,packet)) /* Get a packet */
{
case 'S': /* Send-Init */
rpar(packet,len); /* Get the other side's init data */
len = spar(packet); /* Fill up packet with my init info */
spack('Y',n,len,packet); /* ACK with my parameters */
oldtry = numtry; /* Save old try count */
numtry = 0; /* Start a new counter */
n = (n+1)%64; /* Bump packet number, mod 64 */
return('F'); /* Enter File-Receive state */
case 'E': /* Error packet received */
prerrpkt(recpkt); /* Print it out and */
return('A'); /* abort */
case FALSE: /* Didn't get packet */
spack('N',n,0,NULLPTR); /* Return a NAK */
return(state); /* Keep trying */
default:
return('A'); /* Some other packet type, "abort" */
}
}
/*
* r f i l e
*
* Receive File Header
*/
char rfile()
{
int num, len; /* Packet number, length */
if (numtry++ > MAXTRY) return('A'); /* "abort" if too many tries */
switch(rpack(&len,&num,packet)) /* Get a packet */
{
case 'S': /* Send-Init, maybe our ACK lost */
/* If too many tries "abort" */
if (oldtry++ > MAXTRY) return('A');
if (num == ((n==0) ? 63:n-1)) /* Previous packet, mod 64? */
{ /* Yes, ACK it again with */
len = spar(packet); /* our Send-Init parameters */
spack('Y',num,len,packet);
numtry = 0; /* Reset try counter */
return(state); /* Stay in this state */
}
else return('A'); /* Not previous packet, "abort" */
case 'Z': /* End-Of-File */
if (oldtry++ > MAXTRY) return('A');
if (num == ((n==0) ? 63:n-1)) /* Previous packet, mod 64? */
{ /* Yes, ACK it again. */
spack('Y',num,0,NULLPTR);
numtry = 0;
return(state); /* Stay in this state */
}
else return('A'); /* Not previous packet, "abort" */
case 'F': /* File Header (just what we want) */
/* The packet number must be right */
if (num != n) return('A');
mlwrite("[Receiving %s as %s]",packet,curbp->b_bname);
spack('Y',n,0,NULLPTR); /* Acknowledge the file header */
oldtry = numtry; /* Reset try counters */
numtry = 0;
n = (n+1)%64; /* Bump packet number, mod 64 */
return('D'); /* Switch to Data state */
case 'B': /* Break transmission (EOT) */
if (num != n) return ('A'); /* Need right packet number here */
spack('Y',n,0,NULLPTR); /* Say OK */
return('C'); /* Go to complete state */
case 'E': /* Error packet received */
prerrpkt(recpkt); /* Print it out and */
return('A'); /* abort */
case FALSE: /* Didn't get packet */
spack('N',n,0,NULLPTR); /* Return a NAK */
return(state); /* Keep trying */
default:
return ('A'); /* Some other packet, "abort" */
}
}
/*
* r d a t a
*
* Receive Data
*/
char rdata()
{
int num, len; /* Packet number, length */
if (numtry++ > MAXTRY) return('A'); /* "abort" if too many tries */
switch(rpack(&len,&num,packet)) /* Get packet */
{
case 'D': /* Got Data packet */
if (num != n) /* Right packet? */
{ /* No */
if (oldtry++ > MAXTRY)
return('A'); /* If too many tries, abort */
if (num == ((n==0) ? 63:n-1))
{ /* Else check previous packet again? */
spack('Y',num,0,NULLPTR); /* Yes, re-ACK it */
numtry = 0; /* Reset try counter */
return(state); /* Don't write out data! */
}
else return('A'); /* sorry, wrong number */
}
/* Got data with right packet number */
bufemp(packet,len); /* Write the data to the file */
spack('Y',n,0,NULLPTR); /* Acknowledge the packet */
oldtry = numtry; /* Reset the try counters */
numtry = 0; /* ... */
mlwrite("[Receiving packet: %d]", ++np);
n = (n+1)%64; /* Bump packet number, mod 64 */
return('D'); /* Remain in data state */
case 'F': /* Got a File Header */
if (oldtry++ > MAXTRY)
return('A'); /* If too many tries, "abort" */
if (num == ((n==0) ? 63:n-1)) /* Else check packet number */
{ /* It was the previous one */
spack('Y',num,0,NULLPTR); /* ACK it again */
numtry = 0; /* Reset try counter */
return(state); /* Stay in Data state */
}
else return('A'); /* Not previous packet, "abort" */
case 'Z': /* End-Of-File */
/* Must have right packet number */
if (num != n) return('A');
spack('Y',n,0,NULLPTR); /* OK, ACK it. */
n = (n+1)%64; /* Bump packet number */
return('F'); /* Go back to Receive File state */
case 'E': /* Error packet received */
prerrpkt(recpkt); /* Print it out and */
return('A'); /* abort */
case FALSE: /* Didn't get packet */
spack('N',n,0,NULLPTR); /* Return a NAK */
return(state); /* Keep trying */
default:
return('A'); /* Some other packet, "abort" */
}
}
/*
* r p a c k
*
* Read a Packet
*/
char
rpack(len,num,data)
int *len, *num; /* Packet length, number */
char *data; /* Packet data */
{
register int i, done; /* Data character number, loop exit */
register char t, /* Current input character */
cchksum, /* Our (computed) checksum */
rchksum, /* Checksum received from other host */
type; /* Packet type */
do
{
if (Bconstat(2))
if (ttgetc() == 0x07) /* ^G abort */
{
mlwrite("User ABORT");
(*term.t_beep)();
return('A');
}
if (!Cauxis())
continue;
else
t = (char)readaux()& 0x7f;
}while (t != SOH); /* Wait for packet header */
done = FALSE; /* Got SOH, init loop */
while (!done) /* Loop to get a packet */
{
if (Bconstat(2))
if (ttgetc() == 0x07) /* ^G abort */
{
mlwrite("User ABORT");
(*term.t_beep)();
return('A');
}
t = (char)readaux(); /* Get character */
if (t == SOH) continue; /* Resynchronize if SOH */
cchksum = t; /* Start the checksum */
*len = unchar(t)-3; /* Character count */
t = (char)readaux(); /* Get character */
if (t == SOH) continue; /* Resynchronize if SOH */
cchksum += t; /* Update checksum */
*num = unchar(t); /* Packet number */
t = (char)readaux(); /* Get character */
if (t == SOH) continue; /* Resynchronize if SOH */
cchksum += t; /* Update checksum */
type = t; /* Packet type */
for (i=0; i<*len; i++) /* The data itself, if any */
{ /* Loop for character count */
if (Bconstat(2))
if (ttgetc() == 0x07) /* ^G abort */
{
mlwrite("User ABORT");
(*term.t_beep)();
return('A');
}
t = (char)readaux(); /* Get character */
if (t == SOH) continue; /* Resynch if SOH */
cchksum += t; /* Update checksum */
data[i] = t; /* Put it in the data buffer */
}
data[*len] = 0; /* Mark the end of the data */
t = (char)readaux(); /* Get last character (checksum) */
rchksum = unchar(t); /* Convert to numeric */
t = (char)readaux(); /* get EOL character and toss it */
if (t == SOH) continue; /* Resynchronize if SOH */
done = TRUE; /* Got checksum, done */
}
/* Fold in bits 7,8 to compute */
cchksum = (((cchksum&0300) >> 6)+cchksum)&077; /* final checksum */
if (cchksum != rchksum) return((char)FALSE);
return(type); /* All OK, return packet type */
}
/* r p a r
*
* Get the other host's send-init parameters
*
*/
void
rpar(data,len)
char data[];
int len;
{
spsiz = DEFMAXL; /* default packet size */
timint = DEFTIME;
pad = DEFPAD;
padchar = DEFPADC;
eol = DEFEOL;
quotech = DEFQUOTE;
qbin = DEFQBIN;
switch (len){
default:
case 10: /* attributes */
case 9: /* repeat count */
case 8: /* Check type */
case 7: /* 8 bit quoting */
qbin = data[6];
if (((qbin >='!') && (qbin <= '>'))
|| ((qbin >= '`')&&(qbin <= '~')))
/* qflag = TRUE; */ en8quote(TRUE); /* jgc dec 25th.
1985 */
case 6: /* Incoming data quote character */
quotech = data[5];
case 5: /* EOL character I must send */
eol = unchar(data[4]);
case 4: /* Padding character I must send */
padchar = ctl(data[3]);
case 3: /* Number of pads to send */
pad = unchar(data[2]);
case 2: /* When I should time out */
timint = unchar(data[1]);
if ((timint > MAXTIM) || (timint < MINTIM)) timint = MYTIME;
case 1: /* Maximum send packet size */
spsiz = unchar(data[0]);
case 0:
break;
}
if (qflag) {
if (qbin == 'N') mlwrite("Can't do 8 bit quoting");
else if (qbin == 'Y') qbin = QBIN;
}
}
/*
* s p a r
*
* Fill the data array with my send-init parameters
*
*/
int
spar(data)
char data[];
{
data[0] = tochar(MYPACKSIZ); /* Biggest packet I can receive */
data[1] = tochar(MYTIME); /* When I want to be timed out */
data[2] = tochar(MYPAD); /* How much padding I need */
data[3] = ctl(MYPCHAR); /* Padding character I want */
data[4] = tochar(MYEOL); /* End-Of-Line character I want */
data[5] = MYQUOTE; /* Control-Quote character I send */
data[6] = qflag?QBIN:'Y'; /* Request 8 bit quoting */
return (7); /* return number of parameters */
}
/*
* s p a c k
*
* Send a Packet
*/
void
spack(type,num,len,data)
char type, *data;
int num, len;
{
register int i; /* Character loop counter */
char chksum, buffer[100]; /* Checksum, packet buffer */
register char *bufp; /* Buffer pointer */
bufp = buffer; /* Set up buffer pointer */
for (i=1; i<=pad; i++) sendaux(padchar); /* Issue any padding */
*bufp++ = SOH; /* Packet marker, ASCII 1 (SOH) */
*bufp++ = tochar(len+3); /* Send the character count */
chksum = tochar(len+3); /* Initialize the checksum */
*bufp++ = tochar(num); /* Packet number */
chksum += tochar(num); /* Update checksum */
*bufp++ = type; /* Packet type */
chksum += type; /* Update checksum */
for (i=0; i<len; i++) /* Loop for all data characters */
{
*bufp++ = data[i]; /* Get a character */
chksum += data[i]; /* Update checksum */
}
chksum = (((chksum&0300) >> 6)+chksum)&077; /* Compute final checksum */
*bufp++ = tochar(chksum); /* Put it in the packet */
*bufp = eol; /* Extra-packet line terminator */
sauxstr( buffer,((int)bufp-(int)buffer+1)); /* Send the packet */
}