home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
archives
/
os9.zip
/
os9rec.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-08-16
|
10KB
|
250 lines
/*
* os9rec.c receive file routines for os9 kermit
*/
#include "os9inc.h"
/*
* r e c s w
*
* This is the state table switcher for receiving files.
*/
recsw()
{
char rinit(), rfile(), rdata(); /* Use these procedures */
state = 'R'; /* Receive-Init is the start state */
n = 0; /* Initialize message number */
numtry = 0; /* Say no tries yet */
/*
* We are commenting out code that automatically NAKed
* in case the sender started first; this may be the reason
* that this Kermit gets out of whack. The original code
* said
* if (gflg == FALSE)
* spack('N', n, 0, 0);
*/
for (;;) {
if (debug)
printf(" recsw state: %c\n",state);
switch(state) { /* Do until done */
case 'R':
state = rinit(); 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 */
}
}
}
/*
* r i n i t
*
* Receive Initialization
*/
char rinit()
{
int len, num; /* Packet length, number */
char sfile(); /* routine used for get command */
if (numtry++ > MAXTRY)
return('A'); /* If too many tries, "abort" */
switch(rpack(&len, &num, packet)) { /* Get a packet */
case 'S': /* Send-Init */
rpar(packet); /* Get the other side's init data */
spar(packet); /* Fill up packet with my init info */
spack('Y', n, 6, 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(packet); /* Print it out and */
return('A'); /* abort */
case FALSE: /* Didn't get packet */
case 'N': /* or got a NAK */
if (gflg)
sfile(); /* request file again */
else
spack('N', n, 0, 0); /* Return a NAK */
return(state); /* Keep trying */
case 'Y':
return(state); /* Ignore leftover ACK */
/* (or incorrect ACK of 'R' packet) */
default:
return('A'); /* Some other packet type, "abort" */
}
}
/*
* r f i l e
*
* Receive File Header
*/
char rfile()
{
int num, len; /* Packet number, length */
char filnam1[50]; /* Holds the converted file name */
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 (oldtry++ > MAXTRY)
return('A'); /* If too many tries "abort" */
if (num != ((n == 0) ? 63 : n - 1))
return('A'); /* Not previous packet, "abort" */
/* Previous packet, mod 64; ack with our */
/* Send-Init parameters */
spar(packet);
spack('Y', num, 6, packet);
numtry = 0; /* Reset try counter */
return(state); /* Stay in this state */
case 'Z': /* End-Of-File */
if (oldtry++ > MAXTRY)
return('A');
if (num != ((n==0) ? 63:n-1))
return('A'); /* Not previous packet, "abort" */
spack('Y',num,0,0);
numtry = 0;
return(state); /* Stay in this state */
case 'F': /* File Header (just what we want) */
if (num != n)
return('A'); /* The packet number must be right */
strcpy(filnam1, packet); /* Copy the file name */
if (filnamcnv) { /* Convert upper case to lower */
for (filnam = filnam1; *filnam != '\0'; filnam++)
if (*filnam >= 'A' && *filnam <= 'Z')
*filnam |= 040;
}
/* Try to open a new file */
if ((fp = fopen(filnam1, "w")) == NULL) {
error("Cannot create %s", filnam1);
return('A'); /* Give up */
}
/* OK, give message */
printmsg("Receiving %s as %s", packet, filnam1);
spack('Y', n, 0, 0); /* 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, 0); /* Say OK */
return('C'); /* Go to complete state */
case 'E': /* Error packet received */
prerrpkt(packet); /* Print it out and */
return('A'); /* abort */
case FALSE: /* Didn't get packet */
spack('N', n, 0, 0); /* 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 || /* too many tries */
(num != ((n==0) ? 63:n-1))) /* not prev. packet */
return('A');
spack('Y', num, 6, packet); /* Yes, re-ACK it */
numtry = 0; /* Reset try counter */
return(state); /* Don't write data! */
}
/* Got data with right packet number */
#ifdef nooverlap
/* Cannot handle concurrent disk and serial i/o, so delay ACK */
/* until file written */
bufemp(packet, len); /* Write the data to the file */
spack('Y', n, 0, 0); /* Acknowledge the packet */
#else
/* ACK before file write to overlap disk and serial i/o */
spack('Y', n, 0, 0); /* Acknowledge the packet */
bufemp(packet, len); /* Write the data to the file */
#endif
oldtry = numtry; /* Reset the try counters */
numtry = 0; /* ... */
n = (n + 1) % 64; /* Bump packet number, mod 64 */
return('D'); /* Remain in data state */
case 'F': /* Got a File Header */
if (oldtry++ > MAXTRY || /* too many tries */
(num != ((n==0) ? 63:n-1))) /* not prev. packet */
return('A');
spack('Y', num, 0, 0); /* ACK it again */
numtry = 0; /* Reset try counter */
return(state); /* Stay in Data state */
case 'Z': /* End-Of-File */
if (num != n)
return('A'); /* Must have right packet number */
#ifdef nooverlap
/* can't handle disk and serial i/o at the same time */
fclose(fp); /* close the file */
spack('Y', n, 0, 0); /* Ack the 'Z' packet */
#else
/* ACK before close to allow i/o overlap */
spack('Y', n, 0, 0); /* OK, ACK it. */
fclose(fp); /* Close the file */
#endif
n = (n + 1) % 64; /* Bump packet number */
return('F'); /* Go back to Receive File state */
case 'E': /* Error packet received */
prerrpkt(packet); /* Print it out and */
return('A'); /* abort */
case FALSE: /* Didn't get packet */
spack('N', n, 0, 0); /* Return a NAK */
return(state); /* Keep trying */
default:
return('A'); /* Some other packet, "abort" */
}
}