home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Transactor
/
Transactor_26_1988_Transactor_Publishing.d64
/
xmodem.c
< prev
next >
Wrap
Text File
|
2023-02-26
|
8KB
|
493 lines
/* xmodem.c - xmodem protocol */
/* W Mat Waites - Sept 1988 */
#include <stdio.h>
/* number of retries, timeouts */
#define RETRY 5
#define TOUT 2
#define BTOUT 10
/* protocol characters */
#define SOH 0x01
#define EOT 0x04
#define ACK 0x06
#define NAK 0x15
#define CAN 0x18
#define RECSIZE 128
char *diskerr();
int rec;
int tries;
int timeout;
/* buffer for data in/out */
char buffer[132];
/* sendfile() - send file via xmodem */
sendfile(fname, disk)
char *fname;
int disk;
{SHIFT-+}
int st;
int ch;
char errbuf[41];
char locname[21];
char *status = 0x0090;
FILE dfile;
rec = 1;
strcpy(locname, fname);
strcat(locname, ",r");
/* attempt to open file for read */
device(disk);
dfile = fopen(locname);
/* check for disk error */
strcpy(errbuf, diskerr(disk));
st = atoi(errbuf);
if(st >= 20)
{SHIFT-+}
close(dfile);
showerr(fname, errbuf);
return(0);
{SHIFT--}
printf("%s opened\n", fname);
/* clear input buffer */
while(getserial() >= 0)
{SHIFT-+}
{SHIFT--}
tries = RETRY;
for(;;)
{SHIFT-+}
printf("Synching...\n");
if(chkstop())
{SHIFT-+}
close(dfile);
return(0);
{SHIFT--}
ch = getchtmo(BTOUT);
if(timeout)
{SHIFT-+}
printf("Timeout\n");
tries--;
if(tries > 0)
{SHIFT-+}
continue;
{SHIFT--}
close(dfile);
return(0);
{SHIFT--}
if(ch == NAK)
{SHIFT-+}
break;
{SHIFT--}
printf("Strange char [%02x]\n", ch);
{SHIFT--}
printf("Synched\n");
/* send the file */
while(fillbuf(dfile, buffer))
{SHIFT-+}
if(chkstop())
{SHIFT-+}
close(dfile);
return(0);
{SHIFT--}
if(!txrec(buffer))
{SHIFT-+}
close(dfile);
return(0);
{SHIFT--}
{SHIFT--}
/* tell 'em we're done */
putserial(EOT);
for(;;)
{SHIFT-+}
ch = getchtmo(TOUT);
if(timeout)
{SHIFT-+}
putserial(EOT);
{SHIFT--}
else
{SHIFT-+}
if(ch == ACK)
{SHIFT-+}
printf("sent EOT\n\n");
break;
{SHIFT--}
{SHIFT--}
{SHIFT--}
close(dfile);
printf("%s transferred\n\n", fname);
return(1);
{SHIFT--}
/* recvfile() - recv file via xmodem */
recvfile(fname, disk)
char *fname;
int disk;
{SHIFT-+}
int st;
int ch;
int i;
char r1, r2, dt;
int response;
char rchk;
char locname[21];
char errbuf[41];
unsigned chksum;
FILE dfile;
rec = 1;
strcpy(locname, fname);
strcat(locname, ",w");
/* attempt to open file for write */
device(disk);
dfile = fopen(locname);
/* check for disk error */
strcpy(errbuf, diskerr(disk));
st = atoi(errbuf);
if(st >= 20)
{SHIFT-+}
close(dfile);
showerr(fname, errbuf);
return(0);
{SHIFT--}
printf("%s opened\n", fname);
/* clear input queue */
while(getserial() >= 0)
{SHIFT-+}
{SHIFT--}
/* transfer file */
response = NAK;
for(;;)
{SHIFT-+}
/* get a record */
printf("Record %3d ", rec);
tries = RETRY;
for(;;)
{SHIFT-+}
if(chkstop())
{SHIFT-+}
close(dfile);
return(0);
{SHIFT--}
/* shake hands */
putserial(response);
/* get 1st char */
ch = getchtmo(TOUT);
if(timeout)
{SHIFT-+}
tries--;
if(tries > 0)
{SHIFT-+}
continue; /* try again */
{SHIFT--}
printf("Can't sync w/sender\n");
close(dfile);
return(0);
{SHIFT--}
if(ch == SOH) /* beg of data */
{SHIFT-+}
break;
{SHIFT--}
else if(ch == EOT) /* done */
{SHIFT-+}
printf("got EOT\n\n");
close(dfile);
putserial(ACK);
printf("%s transferred\n\n",
fname);
return(1);
{SHIFT--}
else if(ch == CAN) /* cancelled */
{SHIFT-+}
close(dfile);
printf("Transfer cancelled!\n");
return(0);
{SHIFT--}
else
{SHIFT-+}
printf("Strange char [%02x]\n", ch);
gobble(); /* clear any weirdness */
response = NAK; /* and try again */
{SHIFT--}
{SHIFT--}
response = NAK;
r1 = getchtmo(TOUT); /* record number */
if(timeout)
{SHIFT-+}
printf("TMO on recnum\n");
continue;
{SHIFT--}
/* get 1's comp record number */
r2 = getchtmo(TOUT);
if(timeout)
{SHIFT-+}
printf("TMO on comp recnum\n");
continue;
{SHIFT--}
/* get data */
chksum = 0;
for(i=0; i<RECSIZE; i++)
{SHIFT-+}
dt = getchtmo(TOUT);
if(timeout)
{SHIFT-+}
break;
{SHIFT--}
buffer[i] = dt;
chksum += dt;
chksum &= 0xff;
{SHIFT--}
/* check for data timeout */
if(timeout)
{SHIFT-+}
printf("TMO on data\n");
continue;
{SHIFT--}
/* get checksum */
rchk = getchtmo(TOUT);
if(timeout)
{SHIFT-+}
printf("TMO on checksum\n");
continue;
{SHIFT--}
/* compare rec num and 1's comp */
if(({CBM-P}r1 & 0xff) != (r2 & 0xff))
{SHIFT-+}
printf("Bad recnum's\n");
continue;
{SHIFT--}
/* compare checksum and local one */
if(rchk != chksum)
{SHIFT-+}
printf("Bad checksum\n");
response = NAK;
continue;
{SHIFT--}
if((r1 ==(rec-1) & 0xff)) /* dupe */
{SHIFT-+}
printf("Duplicate record\n");
response = ACK;
continue;
{SHIFT--}
if(r1 != (rec & 0xff))
{SHIFT-+}
printf("Record numbering error\n");
close(dfile);
return(0);
{SHIFT--}
rec++;
/* write data to file */
for(i=0; i<RECSIZE; i++)
{SHIFT-+}
putc(buffer[i], dfile);
{SHIFT--}
printf("OK\n");
response = ACK;
{SHIFT--}
{SHIFT--}
/* showerr() - display disk error */
showerr(fname, errmsg)
char *fname;
char *errmsg;
{SHIFT-+}
erase();
move(11, 5);
printf("Error accessing %s", fname);
move(13, 5);
printf("[%s]", errmsg);
move(20, 5);
{SHIFT--}
/* getchtmo() - get char w/timeout */
getchtmo(timlen)
int timlen;
{SHIFT-+}
int serchar;
timeout = 0;
setclock((unsigned)0); /* start timer */
for(;;)
{SHIFT-+}
serchar = getserial();
if(serchar >= 0)
{SHIFT-+}
return(serchar);
{SHIFT--}
if(getclock() >= timlen)
{SHIFT-+}
timeout = 1;
return 0;
{SHIFT--}
{SHIFT--}
{SHIFT--}
/* fillbuf() - get buffer of data */
fillbuf(filnum, buf)
int filnum;
char buf[];
{SHIFT-+}
int i;
int echk;
char *status = 0x0090;
for(i=0; i<RECSIZE; i++)
{SHIFT-+}
/* get a char from file */
if((echk=fgetc(filnum)) == EOF)
{SHIFT-+}
break;
{SHIFT--}
buf[i] = echk;
{SHIFT--}
if(i == 0) return 0;
/* set rest of buffer to CTRL-Z */
for(; i<RECSIZE; i++)
{SHIFT-+}
buf[i] = (char)26;
{SHIFT--}
return(1);
{SHIFT--}
/* txrec() - send rec, get response */
txrec(buf)
char buf[];
{SHIFT-+}
int i;
int ch;
unsigned chksum;
tries = RETRY;
for(;;)
{SHIFT-+}
/* send record */
printf("Record %3d ", rec);
putserial(SOH);
putserial(rec);
putserial({CBM-P}rec);
chksum = 0;
for(i=0; i<RECSIZE; i++)
{SHIFT-+}
putserial(buf[i]);
chksum += buf[i];
chksum &= 0xff;
{SHIFT--}
putserial(chksum);
/* get response */
ch = getchtmo(BTOUT);
if(timeout)
{SHIFT-+}
tries--;
if(tries > 0)
{SHIFT-+}
printf("Retrying...\n");
continue;
{SHIFT--}
printf("Timeout\n");
return(0);
{SHIFT--}
/* analyze response */
if(ch == CAN)
{SHIFT-+}
printf("Cancelled\n");
return(0);
{SHIFT--}
else if(ch == ACK)
{SHIFT-+}
printf("ACKed\n", rec);
break;
{SHIFT--}
else
{SHIFT-+}
if(ch == NAK)
{SHIFT-+}
printf("NAKed\n", rec);
{SHIFT--}
else
{SHIFT-+}
printf("Strange response\n");
{SHIFT--}
tries--;
if(tries > 0)
{SHIFT-+}
continue;
{SHIFT--}
printf("No more retries!\n");
return(0);
{SHIFT--}
{SHIFT--}
rec++;
return(1);
{SHIFT--}
/* gobble() - gobble up stray chars */
gobble()
{SHIFT-+}
unsigned gotone;
printf("\ngobbling\n");
sleep(2);
for(;;)
{SHIFT-+}
gotone = 0;
/* clear input queue */
while(getserial() >= 0)
{SHIFT-+}
gotone = 1;
{SHIFT--}
if(gotone)
{SHIFT-+}
sleep(1);
{SHIFT--}
else
{SHIFT-+}
return;
{SHIFT--}
{SHIFT--}
{SHIFT--}
/* end of file */