home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
kermit.columbia.edu
/
kermit.columbia.edu.tar
/
kermit.columbia.edu
/
archives
/
researchmachines.zip
/
rmlsen.c
< prev
next >
Wrap
Text File
|
1985-07-11
|
11KB
|
404 lines
/***********************************************************************/
/* File KSEND.C - Send procedures for RML Kermit;
Chris Kennington, RML. 1st July 1985 */
#define DEFS2 1
#define DEFS4 1
#include "stdio.h"
#include "b:kext.h"
/* static externals for this file only */
static char cannot[] = "Cannot open <%s>; ";
static char mainhas[] = "Mainframe has ";
static char unable[] = "Nothing from mainframe. ";
static int num, len; /* Packet number & length */
gnxtfl()
/* Get next file in a file group; if wildcard, expand it into
cmdline. Return TRUE or FALSE. */
{
char ret;
if (filecount-- == 0) {
filnam = 0;
return(FALSE); /* If no more, fail */
}
else {
vtline(LOCFILE,filblank);
vtline(LOCFILE,(filnam = *(filelist++)));
printmsg(null);
if ( ( (ret = fileok(filnam))&(char)0x07 ) != 0 ) {
txtout("not sent."); /* no file */
return(gnxtfl()); /* recursive call */
}
else if ( (ret&(char)0x40) != 0 ) { /* wildcards */
printf("Expanding wildcards ...");
ret = wildex(filnam,cmdline);
printmsg("Will send: %s",cmdline);
if (ret > (char)8)
txtout(" (more on disk)");
filecount = decol8(cmdline,cmdparm,8);
filelist = cmdparm;
return(gnxtfl()); /* recursive call */
}
else {
return(TRUE);
} } } /* end of gnxtfl() */
char sbreak() /* Send Break (EOT) */
{
if (numtry++ > MAXTRY) return('A'); /* If too many tries "abort" */
spack('B',n,0,0); /* Send a B packet */
switch (rpack(&len,&num,recpkt)) /* What was the reply? */
{
case 'N': /* NAK, just stay in this state, */
num = (--num<0 ? 63:num); /* unless NAK for previous packet, */
case 'Y': /* ACK */
if (n != num) return(state); /* If wrong ACK, fail */
inctry(); /* ++n%64 & ++tries */
printmsg("** All files sent OK. ");
return('C'); /* Switch state to Complete */
case 'E': /* Error packet received */
prerrpkt(recpkt); /* Print it out and */
return('A'); /* abort */
case FALSE: return(state); /* Receive failure, stay in B */
default: /* Other, "abort" */
printmsg(badmsg,'Y',type);
return('A');
}
} /* end of sbreak() */
char sdata() /* Send File Data */
{
if (numtry++ > MAXTRY) return('A'); /* If too many tries, give up */
spack('D',n,size,packet); /* Send a D packet */
if (abtflag != 0) {
sendfail();
return('A');
}
switch(rpack(&len,&num,recpkt)) /* What was the reply? */
{
case 'N': /* NAK, just stay in this state, */
if (list > 2)
printf("\rDbg: NAK for packet %c.", tochar(num));
num = (--num<0 ? 63:num); /* unless it's NAK for next packet, */
/* which is just like an ACK for this packet so fall thru to... */
case 'Y': /* ACK */
if (n != num)
return(state); /* If wrong ACK, repeat */
inctry(); /* ++n%64 & ++tries */
if (len != 0) switch (*recpkt) { /* truncation */
case 'X': /* single file */
printmsg("%struncated file",mainhas);
return('Z');
case 'Z': /* file group */
printmsg("%scancelled transfer",mainhas);
seclose();
return('B');
default:
if (list > 2)
printf("\rDbg: Bad ACK <%s>",recpkt);
break;
}
if ((size = bufill(packet)) == EOF) /* Get data from file */
if (errno == 0)
return('Z'); /* If EOF set state to that */
else { /* error */
error(diskfail,errno);
return('A');
}
else
return('D'); /* Got data, stay in state D */
case 'E': /* Error packet received */
prerrpkt(recpkt); /* Print it out and */
seclose();
return('A'); /* abort */
case FALSE:
return(state); /* Receive failure, stay in D */
case 'A': /* User abort */
sendfail();
return('A');
default: /* Anything else, just "abort" */
printmsg(badmsg,'Y',type);
return('A');
}
} /* end of sdata() */
seclose() /* close send-file */
{
if (fp != 0) {
kclose(fp);
fp = 0;
filnam = 0;
}
return;
} /* end of seclose() */
sendfail() /* process user abort */
{
abtflag = 0;
rpack(&len,&num,recpkt); /* ignore next packet */
error(errmsg); /* then abort */
seclose();
return;
} /* end of sendfail() */
sendsw(ist) /* Send files */
int ist; /* initial state */
{
state = ist;
n = 0;
numtry = 0;
while(TRUE) {
if (list > 2) {
outc(CR);
printf("Dbg: sendsw() state: %c, ",state);
}
errdisp(); /* update error display */
switch(state) {
case 'S':
txtout(dots);
state = sinit();
break; /* Send-Init */
case 'F': state = sfile();
break; /* Send file-init */
case 'D': state = sdata();
break; /* Send-Data */
case 'Z': state = seof();
break; /* Send-End-of-File */
case 'B': state = sbreak();
break; /* Send-Break */
case 'C':
seclose();
return (TRUE); /* Complete */
case 'A': /* "Abort" */
default: /* Unknown, fail */
seclose();
return (FALSE);
} }
} /* end sendsw() */
char seof() /* Send End-Of-File. */
{
if (numtry++ > MAXTRY) return('A'); /* If too many tries, "abort" */
spack('Z',n,0,0); /* Send a 'Z' packet */
if (fp != 0)
printmsg("** File %s sent OK. ",filnam);
seclose(); /* close file */
switch(rpack(&len,&num,recpkt)) {
case 'N': /* NAK, just stay in this state, */
num = (--num<0 ? 63:num); /* unless it's NAK for next packet, */
case 'Y': /* ACK */
if (n != num) return(state); /* If wrong ACK, hold out */
inctry(); /* ++n%64 & ++tries */
fp = NULL; /* Set flag indicating no file open */
if (gnxtfl() == FALSE) /* No more files go? */
return('B'); /* if not, break, EOT, all done */
return('F'); /* More files, switch state to F */
case 'E': /* Error packet received */
prerrpkt(recpkt); /* Print it out and */
return('A'); /* abort */
case FALSE:
return(state); /* Receive failure, stay in Z */
case 'A': /* User abort */
sendfail();
return('A');
default: /* Anything else, just "abort" */
printmsg(badmsg,'Y',type);
return('A');
}
} /* End of seof() */
char sfile() /* Send File Header. */
{
char wk[14], *newfilnam, /* Pointer to file name to send */
c, *cp; /* char, pointer */
if (numtry++ > MAXTRY) {
txtout(unable);
return('A');
}
if ( (fp == NULL) && ( (fp = kropen(filnam)) == NULL) ) {
/* trouble opening file */
if (filecount != 0) { /* if more to go */
printf(cannot,filnam);
gnxtfl();
numtry = 0; /* permit name message */
return('F'); /* send next one */
}
else {
error(cannot,filnam);
return('A');
} }
strcpy(wk, filnam); /* Copy file name */
newfilnam = &wk;
if (newfilnam[1] == ':')
newfilnam += 2; /* strip CP/M disk-letter */
/* Filenames are always u.c. under CP/M */
len = strlen(newfilnam);
if (numtry == 1) /* once per file only */
printf("Sending <%s> as <%s>\r",filnam,newfilnam);
if (abtflag != 0) {
sendfail();
return('A');
}
spack('F',n,len,newfilnam); /* Send an F packet */
switch(rpack(&len,&num,recpkt)) {
case 'N': /* NAK, just stay in this state, */
num = (--num<0 ? 63:num);
printmsg("Trouble exchanging params");
/* unless it's NAK for next packet which is just like an ACK for this packet so fall thru to... */
case 'Y': /* ACK */
if (n != num) return(state); /* If wrong ACK, stay in F state */
inctry(); /* ++n%64 & ++tries */
softeof = FALSE;
if ( (size = bufill(packet)) == EOF ) { /* null file */
if (errno == 0) {
printmsg("File empty.");
return('Z'); /* on to next */
}
else { /* error */
error(diskfail,errno);
return('A');
} }
else
return('D'); /* Switch state to D */
case 'E': /* Error packet received */
prerrpkt(recpkt); /* Print it out and */
seclose();
return('A'); /* abort */
case FALSE:
if (list != 1)
txtout(trying);
return(state); /* Receive failure, stay in F state */
case 'A': /* User abort */
sendfail();
return('A');
default: /* Anything else, just "abort" */
printmsg(badmsg,'Y',type);
return('A');
}
} /* end of sfile() */
char sinit() /* Send Initiate */
/* send this host's parameters and get other side's back.*/
{
if (numtry++ > MAXTRY) { /* If too many tries, give up */
txtout(unable);
return('A');
}
len = spar(packet); /* Fill up init info packet */
flushinput(); /* Flush pending input */
spack('S',n,len,packet); /* Send an S packet */
if (abtflag != 0) {
sendfail();
return('A');
}
switch(rpack(&len,&num,recpkt)) /* What was the reply? */
{
case 'Y': /* ACK */
if (n != num) /* If wrong ACK, stay in S state */
return(state); /* and try again */
rpar(recpkt,len); /* Get other side's init info */
compmode(); /* tell user */
if (eol == 0) eol = '\n'; /* Check and set defaults */
if (quote == 0) quote = '#';
inctry(); /* ++n%64 & ++tries */
return('F'); /* OK, switch state to F */
case 'I': /* Info-exchange */
rpar(recpkt,len);
len = spar(packet);
compmode();
spack('Y',n,len,packet);
rpack(&len,&num,recpkt); /* ignore response */
return('S');
case 'R': /* Get-packet */
txtout("R-packet from remote Kermit ");
rpar(recpkt,len);
return(state); /* causes retransmission of 'S' */
case 'E': /* Error packet received */
prerrpkt(recpkt); /* Print it out and */
return('A'); /* abort */
case FALSE: /* Receive failure */
if (list != 1)
txtout(trying);
case 'N': /* NAK, try it again */
return(state);
case 'A': /* User abort */
sendfail();
return('A');
default: /* Anything else, just "abort" */
printmsg(badmsg,'Y',type);
return('A');
}
} /* end of sinit() */
/********************* END of KSEND.C ****************************/