home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
atarist.tar.gz
/
atarist.tar
/
astrec.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-06-19
|
14KB
|
361 lines
/*
* astrec.c receive file routines for ATARI ST kermit
*/
#include <osbind.h>
#include <stdio.h>
#include "astobj.h"
#include "astinc.h"
extern FILE *fopen(),*fopenb();
/*
* r e c s w
*
* This is the state table switcher for receiving files.
*/
recsw()
{
char rinit(), rfile(), rdata(); /* Use these procedures */
start_timer(&starttrans);
state = 'R';
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, NIL);
*/
for (;;) {
msgdeb(MSGDSTAT,state,n);
bps = ((timer(starttrans) != 0) ?
(bytecnt/timer(starttrans)) : 0);
dt_packets(TRUE);
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':
spack('E', n, 5, "Abort");
return (FALSE); /* "Abort" */
case 'E':
return(FALSE); /* "Error Abort" */
default:
msgdeb(MSGSTATE);
return (FALSE); /* Unknown, fail */
}
}
}
/*
* r i n i t
*
* Receive Initialization
*/
char rinit()
{
int i, len, num; /* Packet length, number */
char sfile(); /* routine used for get command */
if (numtry++ > maxtry)
{msgall(KRTRAERR,MSGTRAER); return('A');};
ebq = TRUE; /* assume 7-bit transfer for init */
switch(rpack(&len, &num, packet)) { /* Get a packet */
case 'S': /* Send-Init */
for (i=len;i<10;i++) packet[i] = '\0';
rpar(packet); /* Get the other side's init data */
spar(packet); /* Fill up packet with my init info */
spack('Y', n, 7, 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 */
n_total++;
return('F'); /* Enter File-Receive state */
case 'E': /* Error packet received */
prerrpkt(packet); /* Print it out and */
return('E'); /* abort */
case FALSE: /* Didn't get packet */
case 'N': /* or got a NAK */
nakcnt++;
if (!getfile)
spack('N', n, 0, NIL); /* Return a NAK */
else
spack('R',n,strlen(filnam1),filnam1);
return(state); /* Keep trying */
case 'Y':
return(state); /* Ignore leftover ACK */
/* (or incorrect ACK of 'R' packet) */
case 'A':
return('A'); /* user abort */
default:
msgall(KRPROERR,MSGPROER);
return('A'); /* Some other packet type, "abort" */
}
}
/*
* r f i l e
*
* Receive File Header
*/
char rfile()
{
int num, len; /* Packet number, length */
int f1x, fx; /* index to filnam1 and filnam */
int extx; /* start of extension */
int tryix; /* trying numbers for extension */
char convc; /* converted char in filename */
if (numtry++ > maxtry)
{msgall(KRTRAERR,MSGTRAER); return('A');};
switch (rpack(&len, &num, packet)) { /* Get a packet */
case 'S': /* Send-Init, maybe our ACK lost */
nakcnt++;
if (oldtry++ > maxtry)
{msgall(KRTRAERR,MSGTRAER); return('A');};
if (num != ((n == 0) ? 63 : n - 1))
{msgall(KRPROERR,MSGPROER);
return('A'); /* Not previous packet, "abort" */
};
/* Previous packet, mod 64; ack with our */
/* Send-Init parameters */
spar(packet);
spack('Y', num, 7, packet);
numtry = 0; /* Reset try counter */
return(state); /* Stay in this state */
case 'Z': /* End-Of-File */
nakcnt++;
if (oldtry++ > maxtry)
{msgall(KRTRAERR,MSGTRAER); return('A');};
if (num != ((n==0) ? 63:n-1))
{msgall(KRPROERR,MSGPROER);
return('A'); /* Not previous packet, "abort" */
};
spack('Y',num,0,NIL);
numtry = 0;
return(state); /* Stay in this state */
case 'F': /* File Header (just what we want) */
if (num != n)
{msgall(KRPROERR,MSGPROER);
return('A'); /* The packet number must be right */
};
strcpy(filnam1, packet); /* Copy the file name */
/* convert filename to valid TOS file name*/
fx = 0;
extx = -1;
if (filnam[0] == '\0')
{for (f1x = 0; filnam1[f1x] != '\0'; f1x++)
{convc = filnam1[f1x];
if ((convc >= 'a') && (convc <= 'z'))
convc ^= 040;
if (convc == ' ')
convc = '.';
if (!((convc == '.') ||
((convc >= 'A') && (convc <= 'Z')) ||
((convc >= '0') && (convc <= '9'))))
convc = ']';
if (convc == '.')
if (extx >= 0)
convc = ']';
else
extx = fx;
if ((fx < 8) ||
((extx >= 0) &&
((fx - extx) < 4)))
filnam[fx++] = convc;
};
filnam[fx] = '\0';
if (filnamwarn)
{tryix = 0;
while ((!access(filnam,4)) && (tryix < 50))
{msgdeb(MSGERSNA,filnam1,filnam);
if (extx < 0)
{extx = fx;
filnam[fx++] = '.';
filnam[fx] = '\0';
};
sprintf(&filnam[extx+1],"K%02d",tryix++);
};
};
};
/* Try to open a new file */
if (image)
fp = fopenb(filnam,"w");
else
fp = fopen(filnam,"w");
if (fp == NULL) {
msgall(KRWOPERR,MSGWOPER, filnam);
return('A'); /* Give up */
}
/* OK, give message */
msgall(-1,MSGFRASF, filnam1, filnam);
dt_files(TRUE);
spack('Y', n, 0, NIL); /* Acknowledge the file header */
n_total++;
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)
{msgall(KRPROERR,MSGPROER);
return ('A'); /* Need right packet number here */
};
spack('Y', n, 0, NIL); /* Say OK */
n_total++;
return('C'); /* Go to complete state */
case 'E': /* Error packet received */
prerrpkt(packet); /* Print it out and */
return('E'); /* abort */
case FALSE: /* Didn't get packet */
spack('N', n, 0, NIL); /* Return a NAK */
nakcnt++;
return(state); /* Keep trying */
case 'A':
return('A'); /* user abort */
default:
msgall(KRPROERR,MSGPROER);
return ('A'); /* Some other packet, "abort" */
}
}
/*
* r d a t a
*
* Receive Data
*/
char rdata()
{
int num, len; /* Packet number, length */
if (numtry++ > maxtry)
{msgall(KRTRAERR,MSGTRAER); return('A');};
switch (rpack(&len, &num, packet)) { /* Get packet */
case 'D': /* Got Data packet */
if (num != n) { /* Right packet? */
/* No! */
if (num != ((n==0) ? 63:n-1)) /* not prev. packet */
{msgall(KRPROERR,MSGPROER);
return('A');
};
if (oldtry++ > maxtry)
{msgall(KRTRAERR,MSGTRAER);
return('A');
};
spack('Y', num, 0, NIL); /* Yes, re-ACK it */
nakcnt++;
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, NIL); /* Acknowledge the packet */
#else
/* ACK before file write to overlap disk and serial i/o */
spack('Y', n, 0, NIL); /* 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 */
n_total++;
if (ferror(fp))
{msgall(KRFATFER,MSGFATFE);
return('A');
};
return('D'); /* Remain in data state */
case 'F': /* Got a File Header */
if (num != ((n==0) ? 63:n-1)) /* not prev. packet */
{msgall(KRPROERR,MSGPROER);
return('A');
};
if (oldtry++ > maxtry)
{msgall(KRTRAERR,MSGTRAER);
return('A');
};
spack('Y', num, 0, NIL); /* ACK it again */
nakcnt++;
numtry = 0; /* Reset try counter */
return(state); /* Stay in Data state */
case 'Z': /* End-Of-File */
if (num != n)
{msgall(KRPROERR,MSGPROER);
return('A'); /* Must have right packet number */
};
if (ferror(fp))
{msgall(KRFATFER,MSGFATFE);
return('A');
};
#ifdef nooverlap
/* can't handle disk and serial i/o at the same time */
fclose(fp); /* close the file */
spack('Y', n, 0, NIL); /* Ack the 'Z' packet */
#else
/* ACK before close to allow i/o overlap */
spack('Y', n, 0, NIL); /* OK, ACK it. */
fclose(fp); /* Close the file */
#endif
n = (n + 1) % 64; /* Bump packet number */
msgall(-1,MSGTREOF,filnam);
n_total++;
filecnt++;
dt_files(TRUE);
filnam[0] = '\0';
return('F'); /* Go back to Receive File state */
case 'E': /* Error packet received */
prerrpkt(packet); /* Print it out and */
return('E'); /* abort */
case FALSE: /* Didn't get packet */
spack('N', n, 0, NIL); /* Return a NAK */
nakcnt++;
return(state); /* Keep trying */
case 'A':
return('A'); /* user abort */
default:
msgall(KRPROERR,MSGPROER);
return('A'); /* Some other packet, "abort" */
}
}