Article View: comp.sys.atari.st
Article #24793Uemail source (4 of 12)
From: RDROYA01
Date: Thu, 05 Feb 1987 11:24
Date: Thu, 05 Feb 1987 11:24
1587 lines
58159 bytes
58159 bytes
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# kermit.c
# kertrans.c
# kerrec.c
# kertty.c
# This archive created: Tue Feb 3 17:54:14 1987
cat << \SHAR_EOF > kermit.c
/* kermit.c support routines and main entry point for Uemail file transfer
* functions. Kermit send, receive, get, put, finish, and bye supported.
* Buffer logging and direct ASCII transfer also available. All actions are
* ASCII 7 bit files. Transfers are made into and out of Uemail buffers.
*/
#include <stdio.h>
#include <osbind.h>
#include <ctype.h>
#include "ed.h"
#include "kermit.h"
int emacsfile; /* if TRUE then \r become \n on ASCII transfers */
char getfiln[NFILEN]; /* name for remote file get or put */
char deflow[] = "XON/XOFF";
static unsigned char *tsr_ptr = (char *)0x00fffa2d; /* See St internals */
static long *hz_200 = (long *)0x000004ba;
int *aaddress(); /* thanks Jwahar R. Bammi for this line A code */
int *aline_addr; /* Ptr to base of Aline variables */
int sav_row, sav_col;
int flow = DEFLO; /* default flow control */
int defbaud = 7;
int bps = DEFBPS;
unsigned long *hpterm; /* HOST */
/* KERMIT CTRL command prompt for action and switch to appropriate state.
* Returns TRUE on success. !TRUE on failures. Bound to ^_ and HELP on ST.
*/
kermit(flg, _n)
register int flg, _n;
{
static char command[9]; /* command */
register char key;
register int owf;
owf = curwp->w_flag; /* save for redraw */
if ((_n=mlreply("Kermit-ST> ",command,8)) != TRUE)
return(_n==FALSE ? FALSE : ABORT);
/* Initialize these values */
/* Hope the first packet will get across OK */
eol = CR; /* EOL for outgoing packets */
quotech = '#'; /* Standard control-quote char "#" */
pad = 0; /* No padding */
padchar = '\0'; /* Use null if any padding wanted */
timint = DEFTIME; /* Default timeout */
parity = DEFPAR; /* Default to no parity */
logfile = 0; /* Capture flag */
emacsfile = 0; /* Trans to emacs (no EOF) */
en8quote(FALSE);
key = tolower(command[0]);
switch (key)
{
case 'b': /* B = Bye */
if(mlyesno("Logout remote")==TRUE)
if(gencmdsw('L')==FALSE)
{
mlwrite("Remote does not ACK BYE");
(*term.t_beep)();
return(FALSE);
}
return(TRUE); /* No update */
case 'c': /* C = Connect command */
connect();
break;
case 'e': /* E = transmit to GNU_EMACS command */
if(usebuffer(NULL,NULL) != TRUE)
return(FALSE);
gotobob(NULL, 1);
update();
mlwrite("[Transmitting %s to remote EMACS]",curbp->b_bna
me);
emacsfile = 1;
trans();
emacsfile = 0;
connect();
break;
case 'f': /* F = Finish */
if(gencmdsw('F')==FALSE)
{
mlwrite("Remote does not ACK FINISH");
(*term.t_beep)();
return(FALSE);
}
return(TRUE); /* No update */
case 'g': /* G = Get command */
if((_n=mlreply("Remote filename: ",getfiln,NFILEN))!=TRU
E)
return(_n);
if(usebuffer(NULL,NULL) != TRUE)
return(FALSE);
gotoeob(NULL, 1);
update();
if((_n=getsw()) == FALSE)
{
(*term.t_beep)();
mlreply("Get failed. Type <CR>",command,2);
}
break;
case 'l': /* L = Log session */
if(usebuffer(NULL,NULL) != TRUE)
return(FALSE);
gotoeob(NULL, 1);
logfile = TRUE;
connect();
break;
case 'r': /* R = Receive command */
if(usebuffer(NULL,NULL) != TRUE)
return(FALSE);
gotoeob(NULL, 1);
update();
if((_n=recsw()) == FALSE)
{
(*term.t_beep)();
mlreply("Receive failed. Type <CR>",command,2);
}
break;
case 'p': /* P = Put command */
if((_n=mlreply("Remote filename: ",getfiln,NFILEN))!=TRU
E)
return(_n);
case 's': /* S = Send command */
if(usebuffer(NULL,NULL) != TRUE)
return(FALSE);
if (key == 's')
strcpy(getfiln,curbp->b_bname);
gotobob(NULL, 1);
update();
if((_n=sendsw()) == FALSE)
{
if (key == 's')
mlwrite("Send failed");
else
mlwrite("Put failed");
(*term.t_beep)();
}
if (key == 's')
connect();
break;
case 't': /* T = transmit command */
if(usebuffer(NULL,NULL) != TRUE)
return(FALSE);
gotobob(NULL, 1);
update();
mlwrite("[Transmitting: %s]",curbp->b_bname);
trans();
connect();
break;
default:
mlwrite("Connect, Send, Receive, Get, Put, Finish, Bye\
, Log, Transfer");
return(FALSE);
}
/* Restore controlling tty's modes */
owf |= WFHARD; owf |= WFMODE;
curwp->w_flag |= owf;
sgarbf = TRUE; /* we know screen is garbage after connect */
update();
return(TRUE);
}
/*
* c o n n e c t
*
* Establish a virtual terminal connection with the remote host, over an
* assigned tty line.
*/
connect()
{
register int c;
setterm(REMOTE);
while (1)
{
if (Bconstat(2))
if(readcon() == FALSE)
break;
if (Bconstat(1))
{
c=readaux();
ttputc(c);
if (logfile)
{
if (c=='\n')
{
lnewline();
continue;
}
if (c=='\r')
continue;
linsert(1,c);
}
}
}
setterm(HOST);
return(FALSE);
}
/* set up terminal's screen and allow it to be saved for later.
*/
setterm(f)
int f;
{
static char scrbase[0x7d10];
static unsigned char firsttime = TRUE;
extern int deskcol;
if (hpterm == NULL)
hpterm = Physbase(); /* init TERM screen address */
if (f == REMOTE)
{
Bconout(2,0x1b); /* disable cursor */
Bconout(2,'f');
copy(scrbase,hpterm,0x7d00);
if (firsttime)
{
aline_addr = aaddress();
Bconout(2,0x1b); /* clear screen */
Bconout(2,'E');
showhelp();
sav_row = aline_addr[-13];/* save cursor position */
sav_col = aline_addr[-14];
Rsconf(defbaud,flow,-1,-1,-1,-1);
mtwrite("[%s active at %dbps]",deflow,bps);
firsttime = FALSE;
}
(*term.t_move)(sav_row,sav_col);
Bconout(2,0x1b); /* enable cursor */
Bconout(2,'e');
return(TRUE);
}
else if (f == HOST)
{
sav_row = aline_addr[-13]; /* save cursor position */
sav_col = aline_addr[-14];
Bconout(2,0x1b); /* disable cursor */
Bconout(2,'f');
copy(hpterm,scrbase,0x7d00);
ttopen(); /* restore uemail screen */
Bconout(2,0x1b); /* enable cursor */
Bconout(2,'e');
return(TRUE);
}
else if (f == SHOWHELP)
{
sav_row = aline_addr[-13]; /* save cursor position */
sav_col = aline_addr[-14];
Bconout(2,0x1b); /* disable cursor */
Bconout(2,'f');
copy(hpterm,scrbase,0x7d00); /* save current screen */
showhelp(); /* write help message */
while(ttgetc()) /* wait for */
if (scancode == 0x62) /* HELP key */
break;
copy(scrbase,hpterm,0x7d00); /* restore old screen */
(*term.t_move)(sav_row,sav_col);
Bconout(2,0x1b); /* enable cursor */
Bconout(2,'e');
return(TRUE);
}
}
/*
* return the base address of the line A variables
* Bammi @ Case
*/
int *
aaddress()
{
asm("dc.w $A000");/* Line A trap - 0000 is init line-A */
/* d0 and a0 now contain the address
* so we can just return and the result
* will be valid
*/
}
/* a mini-mlwrite for the terminal mode */
/* VARARGS */
mtwrite(fmt,arg1,arg2,arg3,arg4)
register char *fmt;
register long arg1,arg2,arg3,arg4;
{
static char buf[128];
sprintf(buf,fmt,arg1,arg2,arg3,arg4);
ttputc(0x1b);ttputc('j'); /* save cursor */
(*term.t_move)(term.t_nrow,0);
ttputc(0x1b);ttputc('l'); /* delete line */
Cconws(buf);
ttputc(0x1b);ttputc('k'); /* restore cursor */
return(TRUE);
}
/* A modicum of help for the RS232 connection module */
int
showhelp()
{
register int i;
i = 5;
Crawio(0x1b);
Crawio('p'); /* rev video on */
(*term.t_move)(i++,17);
Cconws(" ");
(*term.t_move)(i++,17);
Cconws(" ALT-UNDO return to Uemail ");
(*term.t_move)(i++,17);
Cconws(" ALT-B set the baud rate ");
(*term.t_move)(i++,17);
Cconws(" ALT-C change color ");
(*term.t_move)(i++,17);
Cconws(" ALT-E load an alias file ");
(*term.t_move)(i++,17);
Cconws(" ALT-L load a macro file ");
(*term.t_move)(i++,17);
Cconws(" ALT-O turn off flow control ");
(*term.t_move)(i++,17);
Cconws(" ALT-R turn on RTS/CTS ");
(*term.t_move)(i++,17);
Cconws(" ALT-X turn on XON/XOFF ");
(*term.t_move)(i++,17);
Cconws(" ALT-T show the current time ");
(*term.t_move)(i++,17);
Cconws(" ALT-CTRL-B send a break ");
(*term.t_move)(i++,17);
Cconws(" ALT-CTRL-C run a program ");
(*term.t_move)(i++,17);
Cconws(" ALT-? this help message ");
(*term.t_move)(i++,17);
Cconws(" HELP this help message ");
(*term.t_move)(i++,17);
Cconws(" \r\n");
Crawio(0x1b);
Crawio('q'); /* rev video off */
return(TRUE);
}
/* setbaud for RS232 (default is 1200) */
int
setbaud()
{
register int c;
mtwrite("Baud rate [a/b/c/d/e] a = 300, \
b = 1200, c = 2400, d = 9600, e = 19,200");
c = ttgetc();
switch(c)
{
case 'a':
case 'A':
defbaud = 9;
bps = 300;
Rsconf(defbaud,flow,-1,-1,-1,-1);
mtwrite("[Baud = %dbps]",bps);
return(TRUE);
case 'b':
case 'B':
defbaud = 7;
bps = 1200;
Rsconf(defbaud,flow,-1,-1,-1,-1);
mtwrite("[Baud = %dbps]",bps);
return(TRUE);
case 'c':
case 'C':
defbaud = 4;
bps = 2400;
Rsconf(defbaud,flow,-1,-1,-1,-1);
mtwrite("[Baud = %dbps]",bps);
return(TRUE);
case 'd':
case 'D':
defbaud = 1;
bps = 9600;
Rsconf(defbaud,flow,-1,-1,-1,-1);
mtwrite("[Baud = %dbps]",bps);
return(TRUE);
case 'e':
case 'E':
defbaud = 0;
bps = 19200;
Rsconf(defbaud,flow,-1,-1,-1,-1);
mtwrite("[Baud = %dbps]",bps);
return(TRUE);
default:
Rsconf(defbaud,flow,-1,-1,-1,-1);
mtwrite("[Baud = %dbps]",bps);
return(TRUE);
}
}
/*
* KERMIT utilities.
*/
/* generic command for BYE and FINish */
gencmdsw(cmd)
char cmd;
{
int num, len; /* Packet number, length */
packet[0] = cmd; /* Generic command */
spack('G', 0, 1, packet); /* Send Generic command */
switch(rpack(&len,&num,packet)) /* Get packet */
{
case 'Y':
return(TRUE);
case 'E':
prerrpkt(packet);
return(FALSE);
default:
return(FALSE);
}
}
/*
* b u f i l l
*
* Get a bufferful of data from the buffer that's being sent.
* Only control-quoting and 8-bit quoting is done;
* repeat count prefixes are not handled.
*/
bufill(buffer)
char buffer[]; /* Buffer */
{
register char t; /* Char read from file */
register char *buffend; /* End of buffer pointer */
register char *buffp; /* Pointer into buffer */
register int unprintable; /* Is a character printable ?*/
short eolflag = FALSE; /* kludge for VAX */
buffend = &buffer[spsiz-9]; /* set up end of buffer pointer */
buffp=buffer; /* and the current position */
while(curwp->w_dotp != curbp->b_linep)
{
t = lgetc(curwp->w_dotp, curwp->w_doto);
if (curwp->w_doto == llength(curwp->w_dotp))
{
t = eol;
eolflag = TRUE; /* kludge for VAX */
}
unprintable = ((t<SP)||(t==DEL));
/* Does this char require special handling? */
if ((unprintable) || t==quotech)
{
*buffp++ = quotech; /* Quote the character */
if (unprintable)
t = ctl(t); /* and uncontrolify */
}
*buffp++ = t;
if (eolflag)
{
eolflag = FALSE; /* be sure it gets \r\n pair */
*buffp++ = quotech; /* this is for VAX/VMS */
*buffp++ = ctl(LF);
}
forwchar(FALSE,1);
/* Check length */
if (buffp>=buffend) /* this is how you avoid pointer */
return((int)buffp-(int)buffer); /* subtraction */
} /* not (int)(buffp-buffer) */
if (buffp == buffer)
return(EOF);
return((int)buffp-(int)buffer); /* Handle partial buffer */
}
/*
* b u f e m p
*
* Put data from an incoming packet into the default buffer.
*/
bufemp(buffer,len)
char buffer[]; /* Buffer */
int len; /* Length */
{
register int i; /* Counter */
register char t; /* Character holder */
register int highbit; /* place to hold quoted highbit */
highbit = 0;
for (i=0; i<len; i++) /* Loop thru the data field */
{
t = buffer[i]; /* Get a character */
if (t == MYQUOTE) /* Control quote? */
{ /* Yes */
t = buffer[++i]; /* Get the quoted character */
/* Low order bits match quote char? */
if (((t & 0177) != MYQUOTE) &&
(!qflag || ((t & 0x7F)!=qbin)))
t = ctl(t); /* No, uncontrollify it */
}
t |= highbit; /* set top bit if needed */
highbit=0;
if (t==eol)
{
lnewline();
continue;
}
if (t=='\n')
continue;
linsert(1,t);
}
}
int
readaux()
{
int i;
while(!Bconstat(1)) /* loop until line is ready or */
if (i++ >= 32000) /* time is up */
return(FALSE);
return ((int)Bconin(1)); /* char not masked when read */
}
sauxstr(buf,len)
char *buf;
int len;
{
for(;len>0;len--)
sendaux(*buf++);
}
sendaux(c)
int c;
{
while(!Bcostat(1))
{
if (Bconstat(2))
if (ttgetc()==0x07)
return(FALSE);
}
Bconout(1,c); /* Send character */
}
/*
* p r e r r p k t
*
* Print contents of error packet received from remote host.
*/
prerrpkt(msg)
char *msg;
{
mlwrite("ABORT: %s",msg);
return;
}
en8quote(t)
int t;
{
qflag = t;
/* no binary files allowed */
}
/* tsr_ptr points to the 8 bit TSR register of the 68901
* From Jwahar R. Bammi
* send a break
* Modifies Bit 3 in the TSR (reg 23) of the Mfp
*/
sendbrk()
{
register long save_ssp;
register long time;
save_ssp = Super(0L); /* Super Mode */
/* set bit 3 of the TSR */
*tsr_ptr |= (unsigned char)8;
/* wait for 250 ms -- you can adjust the duration
* 250 ms seems to be almost a universal figure for break
* duration.
*/
time = *hz_200 + 50;
while(*hz_200 < time)
/* wait */ ;
/* reset bit 3 of the tsr */
*tsr_ptr &= (unsigned char)~8;
Super(save_ssp); /* Back to user Mode */
}
/*
* f l u s h i n p u t
*
* Dump all pending input to clear stacked up NACK's.
*/
flushinput()
{
/* TOS Clear AUX receive buffer */
while (Cauxis())
Cauxin();
}
SHAR_EOF
cat << \SHAR_EOF > kertrans.c
/* kertrans.c transfer and send functions to support file sends through
* ueMail. All functions available only through kermit().
*/
#include <stdio.h>
#include <osbind.h>
#include "ed.h"
#include "kermit.h"
/* ASCII transmit. Some delay ability. Use for short files only or over
* a direct link.
*/
extern int emacsfile;
extern char getfiln[NFILEN];
int
trans()
{
register int c;
register int ln = 0;
while (curwp->w_dotp != curbp->b_linep)
{
c = lgetc(curwp->w_dotp, curwp->w_doto);
if (curwp->w_doto == llength(curwp->w_dotp))
{
mlwrite("[Transmitting line: %d]",++ln);
if (!emacsfile)
c = '\r';
else
c = '\n';
}
while (!(int)Bcostat(1)) /* check for line ready */
{
if (Bconstat(2))
if (ttgetc()==0x07)
return(FALSE);
}
sendaux(c);
if (!forwchar(FALSE, 1))
return(FALSE);
}
if(!emacsfile)
{
while (!(int)Bcostat(1))
{
if (Bconstat(2))
if (ttgetc()==0x07)
return(FALSE);
}
sendaux(CLEAR);
}
return(ln);
}
/*
* s e n d s w
*
* Sendsw is the state table switcher for sending files. It loops until
* either it finishes, or an error is encountered. The routines called
* by sendsw are responsible for changing the state.
*
*/
int
sendsw()
{
state = 'S'; /* Send initiate is the start state */
n = np = 0; /* Initialize message number */
numtry = 0; /* Say no tries yet */
while(TRUE) /* Do this as long as necessary */
{
switch(state)
{
case 'S':
mlwrite("[Sending init packet]");
state = sinit();
break; /* Send-Init */
case 'F':
state = sfile();
break; /* Send-File */
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':
return (TRUE); /* Complete */
case 'A':
return (FALSE); /* "Abort" */
default:
return (FALSE); /* Unknown, fail */
}
}
}
/*
* s i n i t
*
* Send Initiate: send this host's parameters and get other side's back.
*/
char sinit()
{
int num, len; /* Packet number, length */
/* If too many tries, give up */
if (numtry++ > MAXTRY) return('A');
len = spar(packet); /* Fill up init info packet */
spack('S',n,len,packet); /* Send an S packet */
switch(rpack(&len,&num,recpkt)) /* What was the reply? */
{
case 'N':
return(state); /* NAK, try it again */
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 */
numtry = 0; /* Reset try counter */
n = (n+1)%64; /* Bump packet count */
return('F'); /* OK, switch state to F */
case 'E': /* Error packet received */
prerrpkt(recpkt); /* Print it out and */
return('A'); /* abort */
case FALSE:
return(state); /* Receive failure, try again */
default:
return('A'); /* Anything else, just "abort" */
}
}
/*
* s f i l e
*
* Send File Header.
*/
char sfile()
{
int num, len; /* Packet number, length */
/* If too many tries, give up */
if (numtry++ > MAXTRY) return('A');
len = strlen(getfiln);
mlwrite("[Sending %s as %s]",curbp->b_bname,getfiln);
spack('F',n,len,getfiln); /* Send an F packet */
switch(rpack(&len,&num,recpkt)) /* What was the reply? */
{
case 'N': /* NAK, just stay in this state, */
/* unless it's NAK for next packet */
num = (--num<0 ? 63:num);
if (n != num) /* which is just like an ACK for */
return(state); /* this packet so fall thru to... */
case 'Y': /* ACK */
if (n != num) return(state); /* If wrong ACK, stay in F state */
numtry = 0; /* Reset try counter */
n = (n+1)%64; /* Bump packet count */
size = bufill(packet); /* Get first data from file */
return('D'); /* Switch state to D */
case 'E': /* Error packet received */
prerrpkt(recpkt); /* Print it out and */
return('A'); /* abort */
case FALSE:
return(state); /* Receive failure, stay in F state */
default:
return('A'); /* Something else, just "abort" */
}
}
/*
* s d a t a
*
* Send File Data
*/
char sdata()
{
int num, len; /* Packet number, length */
if (numtry++ > MAXTRY) return('A'); /* If too many tries, give up */
spack('D',n,(int)size,packet); /* Send a D packet */
switch(rpack(&len,&num,recpkt)) /* What was the reply? */
{
case 'N': /* NAK, just stay in this state, */
/* unless it's NAK for next packet */
num = (--num<0 ? 63:num);
if (n != num) /* which is just like an ACK for */
return(state); /* this packet so fall thru to... */
case 'Y': /* ACK */
if (n != num) return(state); /* If wrong ACK, fail */
numtry = 0; /* Reset try counter */
n = (n+1)%64; /* Bump packet count */
mlwrite("[Sending packet: %d]",++np);
if ((size=bufill(packet))==EOF) /* Get data from file */
return('Z'); /* If EOF set state to that */
return('D'); /* Got data, stay in state D */
case 'E': /* Error packet received */
prerrpkt(recpkt); /* Print it out and */
return('A'); /* abort */
case FALSE:
return(state); /* Receive failure, stay in D */
default:
return('A'); /* Anything else, "abort" */
}
}
/*
* s e o f
*
* Send End-Of-File.
*/
char seof()
{
int num, len; /* Packet number, length */
if (numtry++ > MAXTRY) return('A'); /* If too many tries, "abort" */
spack('Z',n,0,packet); /* Send a 'Z' packet */
switch(rpack(&len,&num,recpkt)) /* What was the reply? */
{
case 'N': /* NAK, just stay in this state, */
/* unless it's NAK for next packet, */
num = (--num<0 ? 63:num);
if (n != num) /* which is just like an ACK for */
return(state); /* this packet so fall thru to... */
case 'Y': /* ACK */
if (n != num) return(state); /* If wrong ACK, hold out */
numtry = 0; /* Reset try counter */
n = (n+1)%64; /* and bump packet count */
return('B'); /* if not, break, EOT, all done */
case 'E': /* Error packet received */
prerrpkt(recpkt); /* Print it out and */
return('A'); /* abort */
case FALSE:
return(state); /* Receive failure, stay in Z */
default:
return('A'); /* Something else, "abort" */
}
}
/*
* s b r e a k
*
* Send Break (EOT)
*/
char sbreak()
{
int num, len; /* Packet number, length */
if (numtry++ > MAXTRY) return('A'); /* If too many tries "abort" */
spack('B',n,0,packet); /* Send a B packet */
switch (rpack(&len,&num,recpkt)) /* What was the reply? */
{
case 'N': /* NAK, just stay in this state, */
/* unless NAK for previous packet, */
num = (--num<0 ? 63:num);
if (n != num) /* which is just like an ACK for */
return(state); /* this packet so fall thru to... */
case 'Y': /* ACK */
if (n != num) return(state); /* If wrong ACK, fail */
numtry = 0; /* Reset try counter */
n = (n+1)%64; /* and bump packet count */
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:
return ('A'); /* Other, "abort" */
}
}
SHAR_EOF
cat << \SHAR_EOF > kerrec.c
/* 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 */
}
SHAR_EOF
cat << \SHAR_EOF > kertty.c
#include <stdio.h>
#include <ctype.h>
#include <osbind.h>
#include "ed.h"
#include "kermit.h"
#ifndef ESC
#define ESC 0x1b
#endif
#ifndef DEL
#define DEL 0x7f
#endif
extern int *aline_addr; /* Ptr to base of Aline variables */
extern int sav_row, sav_col;
typedef struct MACTAB {
struct MACTAB *m_fmac; /* next MACTAB */
short *keymac; /* pointer to the macro */
char key; /* the key */
} MACTAB;
/* Do a direct read of the console. The present scheme does not always
* work with a minimal NULL modem (i.e. only lines 1,2,&3 connected).
*/
readcon()
{
register int c,i;
extern MACTAB *mheadp, *mcralloc();
register MACTAB *mt;
char fname[16];
extern char *getfname();
extern short getktpcode();
c=getkkey(); /* Read the keyboard and get mask */
if (c == '`') /* keyboard macro */
{
c = (*term.t_getchar)();
if (c == '`')
{
sendaux('`');
return(TRUE);
}
if (mheadp==NULL || mheadp->m_fmac == NULL)
{
mtwrite("No defineable macros assigned");
return(TRUE);
}
if((mt=mcralloc(FALSE,c))!= (MACTAB *)NULL)
sendmacro(mt->keymac);
}
else if (shiftstatus == 12 && scancode == 0x30) /* CTRL-ALT-B */
sendbrk();
else if (shiftstatus == 12 && scancode == 0x2e) /* CTRL-ALT-C */
{
setterm(HOST);
shell(FALSE,HUGE);
setterm(REMOTE);
}
else if (shiftstatus == 17 || shiftstatus == 18) /* C-Lock + Shift */
{
i=tolower(c);
sendaux(i);
}
else if (shiftstatus == 0 && scancode == 0x62) /* HELP Key */
setterm(SHOWHELP);
else if (shiftstatus == 8) /* ALT key pressed */
{
switch(scancode)
{
case 0x12: /* E */
/* save cursor position */
sav_row = aline_addr[-13];
sav_col = aline_addr[-14];
commfil(TRUE,TRUE);
ttopen(); /* update color */
(*term.t_move)(sav_row,sav_col);
return(TRUE);
case 0x61: /* UNDO */
return(FALSE);
case 0x2e: /* C */
/* save cursor position */
sav_row = aline_addr[-13];
sav_col = aline_addr[-14];
paintbuffer(TRUE,TRUE);
(*term.t_move)(sav_row,sav_col);
return(TRUE);
case 0x30: /* B */
return(setbaud());
case 0x26: /* L */
sav_row = aline_addr[-13];
sav_col = aline_addr[-14];
loadmac(TRUE);
(*term.t_move)(sav_row,sav_col);
return(TRUE);
case 0x18: /* O */
/* Turn off flow control */
flow = NOFLO;
Rsconf(-1,flow,-1,-1,-1,-1);
mtwrite("[Handshaking disabled]");
return(TRUE);
case 0x13: /* R */
flow = RTS;
Rsconf(-1,flow,-1,-1,-1,-1);
mtwrite("[RTS/CTS active]");
return(TRUE);
case 0x14:
showtime(TRUE,HUGE);
return(TRUE);
case 0x2d: /* X */
flow = XON;
Rsconf(-1,flow,-1,-1,-1,-1);
mtwrite("[XON/XOFF active]");
return(TRUE);
case 0x35: /* / ? */
setterm(SHOWHELP);
return(TRUE);
default:
sendaux(c);
return(TRUE);
}
}
else
{
if (c & SPEC)
if (getfname(c,fname)!=(char *)NULL)
c = (int)getktpcode(fname);
if (c & META)
{
i = c & ~META;
sendaux(ESC);
c = i;
}
if (c & CTLX)
{
i = c & ~CTLX;
sendaux(0x18);
c = i;
}
if (c & CTRL)
{
i = c & ~CTRL;
c = i - '@';
}
sendaux(c);
}
return(TRUE);
}
/* pratically identical to getkey in main.c but that one uses mlwrite
* which would damage the terminal screen when it tried to update.
*/
getkkey()
{
register int c;
extern char keyscan[];
c = (*term.t_getchar)();
#if ST
if (scancode == 0x70 && shiftstatus != 16)
return (CTRL|'X');
#endif
if (c == DEL)
return(c);
if (c == METACH) { /* Apply M- prefix */
mtwrite("Meta: ");
c = (*term.t_getchar)();
return (META | c);
}
#if ST
/* use special keys or number pad (code >= 0x63) ?
* 0x03 = scancode for ^@ (setmark).
*/
if ((c == NULL && scancode != 0x03) || scancode >= 0x4a)
if (scancode > 0x32)
{
/* if CapsLock and number pad, use real numbers */
if (shiftstatus == 16 && (scancode > 0x62 ||
scancode == 0x4a || scancode == 0x4e))
return(c);
else
return (SPEC | scancode);
}
else {
c = keyscan[scancode];
return (META | c);
}
#endif
if (c>=0x00 && c<=0x1F) /* C0 control -> C- */
c = CTRL | (c+'@');
return (c);
}
/* Allows keyboard macros to go through completely on a slow and noisy line */
sendmacro(buf)
register short *buf;
{
register int c;
char fname[16];
while(*buf != (CTLX|')'))
{
while(!(int)Cauxos()) /* wait for line to clear */
;
if (*buf & SPEC)
if (getfname(*buf,fname)!=(char *)NULL)
*buf = (int)getktpcode(fname);
if (*buf & META)
{
c = *buf & ~META;
sendaux(ESC);
*buf = c;
}
if (*buf & CTLX)
{
c = *buf & ~CTLX;
sendaux(0x18);
*buf = c;
}
if (*buf & CTRL)
{
c = *buf & ~CTRL;
*buf = c - '@';
}
sendaux(*buf++);
}
}
SHAR_EOF
# End of shell archive
exit 0
%NONAME-W-NOMSG, Message number 00000000
Technical Details
Message-ID:
<8702052241.AA16292@ucbvax.Berkeley.EDU>Path:
arc1-ca.pugleaf.net!utzoo!watmath!clyde!rutgers!mit-eddie!genrad!decvax!ucbvax!ULKYVX.BITNET!RDROYA01Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!rutgers!mit-eddie!genrad!decvax!ucbvax!ULKYVX.BITNET!RDROYA01 From: RDROYA01@ULKYVX.BITNET.UUCP Newsgroups: comp.sys.atari.st Subject: Uemail source (4 of 12) Message-ID: <8702052241.AA16292@ucbvax.Berkeley.EDU> Date: Thu, 5-Feb-87 06:24:00 EST Article-I.D.: ucbvax.8702052241.AA16292 Posted: Thu Feb 5 06:24:00 1987 Date-Received: Sat, 7-Feb-87 16:36:38 EST Sender: daemon@ucbvax.BERKELEY.EDU Organization: University of Louisville Lines: 1587