Thread View: mod.amiga.sources
1 messages
1 total messages
Started by doc
Wed, 03 Sep 1986 06:53
New VT100 (part 2 of 2)
Author: doc
Date: Wed, 03 Sep 1986 06:53
Date: Wed, 03 Sep 1986 06:53
2095 lines
57019 bytes
57019 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:
# init.c
# kermit.c
# remote.c
# script.c
# This archive created: Wed Sep 3 01:51:08 1986
# By: Craig Norborg (Purdue University Computing Center)
cat << \SHAR_EOF > init.c
/***************************************************************
* vt100 - terminal emulator - initialization
*
* 860823 DBW - Integrated and rewrote lots of code
* v2.0 860809 DBW - Major rewrite
* v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
* v1.0 860712 DBW - First version released
*
***************************************************************/
#define MODULE_INIT 1
#include "vt100.h"
extern char *malloc();
void InitDefaults(argc,argv)
int argc;
char **argv;
{
FILE *fd;
char line[256],scr[32],delim,macro[256],c0,*ptr;
int i,j,k;
if (((argc > 1) && (fd=fopen(argv[1],"r")) != 0) ||
(fd=fopen("vt100.init","r")) != 0 ||
(fd=fopen("c:vt100.init","r")) != 0) {
while (fgets(line,256,fd) != 0) {
if ((c0 = line[0]) == '#') continue;
if ((c0|' ') == 'e') break;
switch (c0|' ') {
case 'b':
if ((line[1]|' ') == 'o') {
/* bold color */
if (sscanf(line,"%s %x",scr,&i) == 2) p_bold = i;
break;
}
if ((line[1]|' ') != 'a') break;
switch(line[2]|' ') {
/* baud rate */
case 'u':
if (sscanf(line,"%s %d",scr,&i) == 2) p_baud = i;
break;
/* background */
case 'c':
if (sscanf(line,"%s %x",scr,&i) == 2) p_background = i;
break;
}
break;
/* screen type */
case 's':
if (sscanf(line,"%s %s",scr,scr) == 2) {
if ((scr[0]|' ') == 'w') p_screen = 0;
else p_screen = 1;
}
break;
/* number of lines */
case 'l':
if (sscanf(line,"%s %d",scr,&i) == 2) p_lines = i;
break;
/* screen depth */
case 'd':
if (sscanf(line,"%s %d",scr,&i) == 2) p_depth = i;
break;
/* cursor color */
case 'c':
if (sscanf(line,"%s %d",scr,&i) == 2) p_cursor = i;
break;
/* interlace type */
case 'i':
if (sscanf(line,"%s %s",scr,scr) == 2) {
if ((scr[1]|' ') == 'n') p_interlace = 1;
else p_interlace = 0;
}
break;
case 'f':
switch (line[1]|' ') {
/* foreground color */
case 'o':
if (sscanf(line,"%s %x",scr,&i) == 2) p_foreground = i;
break;
/* function key */
default:
if (sscanf(&line[1],"%d",&i) != 1) break;
if (i < 1 || i > 10) break;
delim = 0;
for (j=2; line[j] != 0 &&
(line[j] == ' ' || line[j] == '\t'); j++) ;
if (line[j] == 0) {
if (c0 == 'f') p_f[i-1] = NULL;
else p_F[i-1] = NULL;
break;
}
delim = line[j];
k = 0;
macro[0] = 0;
while (line[++j] != delim) {
if (line[j] == 0) {
if (fgets(line,256,fd) == 0) {
line[0] = delim;
line[1] = 0;
}
j = -1;
continue;
}
if (line[j] == '^' && line[++j] != '^')
macro[k++] = (line[j]|' ') - 0x60;
else if (line[j] != '\n') macro[k++] = line[j];
macro[k] = 0;
}
ptr = malloc(k+1);
if (c0 == 'f') p_f[i-1] = ptr;
else p_F[i-1] = ptr;
strcpy(ptr,macro);
break;
}
break;
case 'm':
if (sscanf(line,"%s %s",scr,scr) == 2) {
if ((scr[0]|' ') == 'i') p_mode = 0;
else p_mode = 1;
}
break;
case 'x':
if (sscanf(line,"%s %s",scr,scr) == 2) {
if ((scr[0]|' ') == 'd') p_xon = 0;
else p_xon = 1;
}
break;
}
}
fclose(fd);
}
/* Now set up all the screen info as necessary */
if (p_interlace == 0) {
if (p_lines > 24) p_lines = 24;
MINY = 14;
NewWindow.Height = (long)((p_lines*8)+8);
}
else {
if (p_lines > 48) p_lines = 48;
MINY = 16;
NewScreen.ViewModes |= LACE;
NewWindow.Height = (long)((p_lines*8)+10);
}
NewWindow.MinHeight = NewWindow.Height;
NewWindow.MaxHeight = NewWindow.Height;
NewWindow.TopEdge = 3L;
MAXY = ((p_lines-1)*8) + MINY;
top = MINY;
bot = MAXY;
savx = MINX;
savy = MINY;
if (p_screen == 1) {
if (p_depth > 2) p_depth = 2;
if (p_depth < 1) p_depth = 1;
NewScreen.Depth = (long)p_depth;
NewScreen.Height = (long)((p_lines*8)+15);
if (p_interlace == 1)
NewScreen.TopEdge = (long)(402 - NewScreen.Height);
else
NewScreen.TopEdge = 0L;
}
else {
p_depth = 2L;
NewWindow.TopEdge = 0L;
NewWindow.Screen = NULL;
NewWindow.Type = WBENCHSCREEN;
}
}
void InitDevs()
{
USHORT colors[4];
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", INTUITION_REV);
if( IntuitionBase == NULL )
{
puts("can't open intuition\n");
exit(TRUE);
}
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",GRAPHICS_REV);
if( GfxBase == NULL )
{
puts("can't open graphics library\n");
exit(TRUE);
}
if (p_screen == 1) {
if ((myscreen = (struct Screen *)OpenScreen(&NewScreen)) == NULL) {
puts("can't open screen!!\n");
exit(TRUE);
}
NewWindow.Screen = myscreen;
}
if(( mywindow = (struct Window *)OpenWindow(&NewWindow) ) == NULL)
{
puts("cant open window\n");
if (p_screen != 0) CloseScreen( myscreen );
exit(TRUE);
}
myviewport = (struct ViewPort *)ViewPortAddress(mywindow);
if (p_screen != 0) {
colors[0] = p_background;
colors[1] = p_foreground;
colors[2] = p_bold;
colors[3] = p_cursor;
if (p_depth == 1)
LoadRGB4(myviewport,(struct ColorMap *)colors,2L);
else
LoadRGB4(myviewport,(struct ColorMap *)colors,4L);
}
Read_Request = (struct IOExtSer *)
AllocMem((long)sizeof(*Read_Request),MEMF_PUBLIC|MEMF_CLEAR);
Read_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
Read_Request->IOSer.io_Message.mn_ReplyPort = CreatePort("Read_RS",0);
if(OpenDevice(SERIALNAME,NULL,Read_Request,NULL))
{
puts("Cant open Read device\n");
CloseWindow( mywindow );
if (p_screen != 0) CloseScreen( myscreen );
DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
FreeMem(Read_Request,(long)sizeof(*Read_Request));
exit(TRUE);
}
Read_Request->IOSer.io_Command = CMD_READ;
Read_Request->IOSer.io_Length = 1;
Read_Request->IOSer.io_Data = (APTR) &rs_in[0];
Write_Request = (struct IOExtSer *)
AllocMem((long)sizeof(*Write_Request),MEMF_PUBLIC|MEMF_CLEAR);
Write_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
Write_Request->IOSer.io_Message.mn_ReplyPort = CreatePort("Write_RS",0);
if(OpenDevice(SERIALNAME,NULL,Write_Request,NULL))
{
puts("Cant open Write device\n");
CloseDevice(Read_Request);
DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
FreeMem(Read_Request,(long)sizeof(*Read_Request));
DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
FreeMem(Write_Request,(long)sizeof(*Write_Request));
CloseWindow( mywindow );
if (p_screen != 0) CloseScreen( myscreen );
exit(TRUE);
}
Write_Request->IOSer.io_Command = CMD_WRITE;
Write_Request->IOSer.io_Length = 1;
Write_Request->IOSer.io_Data = (APTR) &rs_out[0];
Read_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
Read_Request->io_Baud = p_baud;
Read_Request->io_ReadLen = 8;
Read_Request->io_WriteLen = 8;
Read_Request->io_CtlChar = 1L;
Read_Request->io_RBufLen = 2048;
Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
DoIO(Read_Request);
Read_Request->IOSer.io_Command = CMD_READ;
Timer_Port = CreatePort("Timer Port",0);
Script_Timer_Port = CreatePort("Timer Port",0);
if (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Timer, 0) ||
OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Script_Timer, 0)) {
puts("can't open timer device");
DeletePort(Timer_Port);
DeletePort(Script_Timer_Port);
CloseDevice(Read_Request);
DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
FreeMem(Read_Request,(long)sizeof(*Read_Request));
CloseDevice(Write_Request);
DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
FreeMem(Write_Request,(long)sizeof(*Write_Request));
CloseWindow( mywindow );
if (p_screen != 0) CloseScreen( myscreen );
exit(TRUE);
}
Timer.tr_node.io_Message.mn_ReplyPort = Timer_Port;
Timer.tr_node.io_Command = TR_ADDREQUEST;
Timer.tr_node.io_Flags = 0;
Timer.tr_node.io_Error = 0;
Script_Timer.tr_node.io_Message.mn_ReplyPort = Script_Timer_Port;
Script_Timer.tr_node.io_Command = TR_ADDREQUEST;
Script_Timer.tr_node.io_Flags = 0;
Script_Timer.tr_node.io_Error = 0;
}
/*****************************************************************/
/* The following function initializes the structure arrays */
/* needed to provide the File menu topic. */
/*****************************************************************/
void InitFileItems()
{
int n;
/* initialize each menu item and IntuiText with loop */
for( n=0; n<FILEMAX; n++ )
{
FileItem[n].NextItem = &FileItem[n+1];
FileItem[n].LeftEdge = 0;
FileItem[n].TopEdge = 11 * n;
FileItem[n].Width = 135;
FileItem[n].Height = 11;
FileItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX;
FileItem[n].MutualExclude = 0;
FileItem[n].ItemFill = (APTR)&FileText[n];
FileItem[n].SelectFill = NULL;
FileItem[n].Command = 0;
FileItem[n].SubItem = NULL;
FileItem[n].NextSelect = 0;
FileText[n].FrontPen = 0;
FileText[n].BackPen = 1;
FileText[n].DrawMode = JAM2; /* render in fore and background */
FileText[n].LeftEdge = 0;
FileText[n].TopEdge = 1;
FileText[n].ITextFont = NULL;
FileText[n].NextText = NULL;
}
FileItem[FILEMAX-1].NextItem = NULL;
/* initialize text for specific menu items */
FileText[0].IText = (UBYTE *)"Ascii Capture";
FileText[1].IText = (UBYTE *)"Ascii Send";
FileText[2].IText = (UBYTE *)"Xmodem Receive";
FileText[3].IText = (UBYTE *)"Xmodem Send";
FileText[4].IText = (UBYTE *)"Kermit Get";
FileText[5].IText = (UBYTE *)"Kermit Receive";
FileText[6].IText = (UBYTE *)"Kermit Send";
FileText[7].IText = (UBYTE *)"Kermit BYE";
}
/*****************************************************************/
/* The following function initializes the structure arrays */
/* needed to provide the BaudRate menu topic. */
/*****************************************************************/
void InitRSItems()
{
int n;
/* initialize each menu item and IntuiText with loop */
for( n=0; n<RSMAX; n++ )
{
RSItem[n].NextItem = &RSItem[n+1];
RSItem[n].LeftEdge = 0;
RSItem[n].TopEdge = 11 * n;
RSItem[n].Width = 85;
RSItem[n].Height = 11;
RSItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX | CHECKIT;
RSItem[n].MutualExclude = (~(1 << n));
RSItem[n].ItemFill = (APTR)&RSText[n];
RSItem[n].SelectFill = NULL;
RSItem[n].Command = 0;
RSItem[n].SubItem = NULL;
RSItem[n].NextSelect = 0;
RSText[n].FrontPen = 0;
RSText[n].BackPen = 1;
RSText[n].DrawMode = JAM2; /* render in fore and background */
RSText[n].LeftEdge = 0;
RSText[n].TopEdge = 1;
RSText[n].ITextFont = NULL;
RSText[n].NextText = NULL;
}
RSItem[RSMAX-1].NextItem = NULL;
/* select baud item chekced */
switch (p_baud) {
case 300: n = 0; break;
case 1200: n = 1; break;
case 2400: n = 2; break;
case 4800: n = 3; break;
case 9600: n = 4; break;
default: n = 2; p_baud = 2400;
}
RSItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX | CHECKIT | CHECKED;
/* initialize text for specific menu items */
RSText[0].IText = (UBYTE *)" 300";
RSText[1].IText = (UBYTE *)" 1200";
RSText[2].IText = (UBYTE *)" 2400";
RSText[3].IText = (UBYTE *)" 4800";
RSText[4].IText = (UBYTE *)" 9600";
}
/*****************************************************************/
/* The following function initializes the structure arrays */
/* needed to provide the Transfer Mode menu topic. */
/*****************************************************************/
void InitXFItems()
{
int n;
/* initialize each menu item and IntuiText with loop */
for( n=0; n<XFMAX; n++ )
{
XFItem[n].NextItem = &XFItem[n+1];
XFItem[n].LeftEdge = 0;
XFItem[n].TopEdge = 11 * n;
XFItem[n].Width = 85;
XFItem[n].Height = 11;
XFItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX | CHECKIT;
XFItem[n].MutualExclude = (~(1 << n));
XFItem[n].ItemFill = (APTR)&XFText[n];
XFItem[n].SelectFill = NULL;
XFItem[n].Command = 0;
XFItem[n].SubItem = NULL;
XFItem[n].NextSelect = 0;
XFText[n].FrontPen = 0;
XFText[n].BackPen = 1;
XFText[n].DrawMode = JAM2; /* render in fore and background */
XFText[n].LeftEdge = 0;
XFText[n].TopEdge = 1;
XFText[n].ITextFont = NULL;
XFText[n].NextText = NULL;
}
XFItem[XFMAX-1].NextItem = NULL;
/* mode checked */
XFItem[p_mode].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX | CHECKIT | CHECKED;
/* initialize text for specific menu items */
XFText[0].IText = (UBYTE *)" image";
XFText[1].IText = (UBYTE *)" CR LF";
}
/*****************************************************************/
/* The following function initializes the structure arrays */
/* needed to provide the Script menu topic. */
/*****************************************************************/
void InitScriptItems()
{
int n;
/* initialize each menu item and IntuiText with loop */
for( n=0; n<SCRIPTMAX; n++ )
{
ScriptItem[n].NextItem = &ScriptItem[n+1];
ScriptItem[n].LeftEdge = 0;
ScriptItem[n].TopEdge = 11 * n;
ScriptItem[n].Width = 155;
ScriptItem[n].Height = 11;
ScriptItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX;
ScriptItem[n].MutualExclude = 0;
ScriptItem[n].ItemFill = (APTR)&ScriptText[n];
ScriptItem[n].SelectFill = NULL;
ScriptItem[n].Command = 0;
ScriptItem[n].SubItem = NULL;
ScriptItem[n].NextSelect = 0;
ScriptText[n].FrontPen = 0;
ScriptText[n].BackPen = 1;
ScriptText[n].DrawMode = JAM2; /* render in fore and background */
ScriptText[n].LeftEdge = 0;
ScriptText[n].TopEdge = 1;
ScriptText[n].ITextFont = NULL;
ScriptText[n].NextText = NULL;
}
ScriptItem[SCRIPTMAX-1].NextItem = NULL;
/* initialize text for specific menu items */
ScriptText[0].IText = (UBYTE *)"Execute file";
ScriptText[1].IText = (UBYTE *)"Abort Execution";
}
/**********************************************************************/
/* The following function initializes the Menu structure array with */
/* appropriate values for our simple menu strip. Review the manual */
/* if you need to know what each value means. */
/**********************************************************************/
void InitMenu()
{
menu[0].NextMenu = &menu[1];
menu[0].LeftEdge = 5;
menu[0].TopEdge = 0;
menu[0].Width = 50;
menu[0].Height = 10;
menu[0].Flags = MENUENABLED;
menu[0].MenuName = "File"; /* text for menu-bar display */
menu[0].FirstItem = &FileItem[0]; /* pointer to first item in list */
menu[1].NextMenu = &menu[2];
menu[1].LeftEdge = 65;
menu[1].TopEdge = 0;
menu[1].Width = 85;
menu[1].Height = 10;
menu[1].Flags = MENUENABLED;
menu[1].MenuName = "BaudRate"; /* text for menu-bar display */
menu[1].FirstItem = &RSItem[0]; /* pointer to first item in list */
menu[2].NextMenu = &menu[3];
menu[2].LeftEdge = 160;
menu[2].TopEdge = 0;
menu[2].Width = 85;
menu[2].Height = 10;
menu[2].Flags = MENUENABLED;
menu[2].MenuName = "Xfer Mode"; /* text for menu-bar display */
menu[2].FirstItem = &XFItem[0]; /* pointer to first item in list */
menu[3].NextMenu = NULL;
menu[3].LeftEdge = 255;
menu[3].TopEdge = 0;
menu[3].Width = 85;
menu[3].Height = 10;
menu[3].Flags = MENUENABLED;
menu[3].MenuName = "Script"; /* text for menu-bar display */
menu[3].FirstItem = &ScriptItem[0]; /* pointer to first item in list */
}
SHAR_EOF
cat << \SHAR_EOF > kermit.c
/*************************************************************
* vt100 terminal emulator - KERMIT protocol support
*
* 860823 DBW - Integrated and rewrote lots of code
* 860811 Steve Drew multi filexfer, bugs, status line ect..
* v2.0 860809 DBW - Major rewrite
* v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
* v1.0 860712 DBW - First version released
*
*************************************************************/
#define MODULE_KERMIT 1
#include "vt100.h"
#define MAXPACKSIZ 94 /* Maximum msgpkt size */
#define CR 13 /* ASCII Carriage Return */
#define LF 10 /* ASCII line feed */
#define SP 32 /* ASCII space */
#define DEL 127 /* Delete (rubout) */
#define MAXTRY 5 /* Times to retry a msgpkt */
#define MYQUOTE '#' /* Quote character I will use */
#define MYRPTQ '~' /* Repeat quote character */
#define MYPAD 0 /* Number of padding characters I will need */
#define MYPCHAR 0 /* Padding character I need (NULL) */
#define MYEOL '\n' /* End-Of-Line character I need */
#define tochar(ch) ((ch) + ' ')
#define unchar(ch) ((ch) - ' ')
#define ctl(ch) ((ch) ^ 64 )
/* Global Variables */
int
size, /* Size of present data */
osize, /* Size of last data entry */
rpsiz, /* Maximum receive msgpkt size */
spsiz, /* Maximum send msgpkt size */
timint, /* Time interval to wait */
pad, /* How much padding to send */
n, /* Packet number */
tp, /* total packets */
numtry, /* Times this msgpkt retried */
retry, /* total retries */
oldtry, /* Times previous msgpkt retried */
rptflg, /* are we doing repeat quoting */
first, /* is this the first time in a file */
rpt, /* current repeat count */
next, /* what is the next character */
t; /* current character */
long
totbytes; /* total bytes xfered on this file */
char
state, /* Present state of the automaton */
padchar, /* Padding character to send */
eol, /* End-Of-Line character to send */
quote, /* Quote character in incoming data */
rptq, /* Quote character for repeats */
ackpkt[MAXPACKSIZ+20], /* ACK/NAK packet buffer */
msgpkt[MAXPACKSIZ+20], /* Message Packet buffer */
filnam[40]; /* remote file name */
snum[10];
void encode(), decode(), rpar(), spar();
FILE *fp; /* file for send/receive */
int shutdown = 0; /* shut down server after all xfers complete */
char *
getfname(name) /* returns pointer to start of file name from file spec */
char *name;
{
int l;
l = strlen(name);
while(l && name[l] != '/' && name[l] != ':') l--;
if (name[l] == '/' || name[l] == ':') l++;
return(name += l);
}
doksend(file,more)
char *file;
int more;
{
int retval;
ttime = TTIME_LONG;
if (!strcmp(file,"$")) { saybye(); return(2); }
if (file[strlen(file)-1] == '$') {
shutdown = 1;
file[strlen(file)-1] = '\0';
}
if ((fp = fopen(file,"r")) == NULL) {
emits("Cannot open send file\n");
return FALSE;
}
getready(file,more);
emits("SEND");
retval = sendsw();
if (retval) { x = 600; emits("DONE"); }
curmode = 0;
if (shutdown) saybye();
emits("\n");
fclose(fp);
return(retval);
}
dokreceive(file,more)
char *file;
int more;
{
int retval;
ttime = TTIME_LONG;
if (!strcmp(file,"$")) { saybye(); return(2); }
if (file[strlen(file)-1] == '$') {
shutdown = 1;
file[strlen(file)-1] = '\0';
}
if ((fp = fopen(file,"w")) == NULL) {
emits("Cannot open file\n");
return FALSE;
}
getready(file,more);
emits("RECV");
retval = recsw();
if (retval) { x = 600; emits("DONE"); }
curmode = 0;
if (shutdown) saybye();
emits("\n");
fclose(fp);
return(retval);
}
getready(file,more)
char *file;
int more;
{
if (!more) {
emits("Remote file name [");
emits(getfname(file));
emits("]: ");
filename(filnam);
if (filnam[0] == 0) strcpy(filnam,getfname(file));
emits("Type <ESC> to abort transfer\n");
}
else strcpy(filnam,getfname(file));
eatup();
tp = retry = 0; totbytes = 0L; n = numtry = 0;
want_message = FALSE; /* tell readchar no error msgs status bar instead */
statusline();
x = 600;
}
sendsw()
{
char sinit(), sfile(), sdata(), seof(), sbreak();
state = 'S';
while(TRUE) {
switch(state) {
case 'S': state = sinit(); break;
case 'F': state = sfile(); break;
case 'D': state = sdata(); break;
case 'Z': state = seof(); break;
case 'B': state = sbreak(); break;
case 'C': return(TRUE);
case 'A': x = 600;
if (timeout == USERABORT) { sabort(); return(FALSE); }
if (timeout == TIMEOUT) emits("TMOUT");
else emits("ERROR");
return(FALSE);
default: return(FALSE);
}
}
}
char sinit()
{
int num, len;
retry++;
if (numtry++ > MAXTRY) return('A');
spar(msgpkt);
spack('S',n,9,msgpkt);
switch(rpack(&len,&num,ackpkt)) {
case 'N': return(state);
case 'Y': if (n != num) return(state);
rpar(ackpkt);
if (eol == 0) eol = '\n';
if (quote == 0) quote = '#';
numtry = 0;
retry--;
n = (n+1)%64;
return('F');
case 'E': return('A');
case FALSE:if (timeout == USERABORT) state = 'A';
return(state);
default: return('A');
}
}
char sfile()
{
int num, len;
retry++;
if (numtry++ > MAXTRY) return('A');
spack('F',n,strlen(filnam),filnam);
switch(rpack(&len,&num,ackpkt)) {
case 'N':
num = (--num<0 ? 63:num);
if (n != num) return(state);
case 'Y':
if (n != num) return(state);
numtry = 0;
retry--;
n = (n+1)%64;
first = 1;
size = getpkt();
return('D');
case 'E':
return('A');
case FALSE: if (timeout == USERABORT) state = 'A';
return(state);
default: return('A');
}
}
char sdata()
{
int num, len;
retry++;
if (numtry++ > MAXTRY) return('A');
spack('D',n,size,msgpkt);
switch(rpack(&len,&num,ackpkt)) {
case 'N':
num = (--num<0 ? 63:num);
if (n != num) return(state);
case 'Y':
if (n != num) return(state);
numtry = 0;
retry--;
n = (n+1)%64;
if ((size = getpkt()) == 0) return('Z');
return('D');
case 'E':
return('A');
case FALSE: if (timeout == USERABORT) state = 'A';
return(state);
default: return('A');
}
}
char seof()
{
int num, len;
retry++;
if (numtry++ > MAXTRY) return('A');
if (timeout == USERABORT) {
timeout = GOODREAD;
spack('Z',n,1,"D"); /* tell host to discard file */
}
else spack('Z',n,0,msgpkt);
switch(rpack(&len,&num,ackpkt)) {
case 'N':
num = (--num<0 ? 63:num);
if (n != num) return(state);
case 'Y':
if (n != num) return(state);
numtry = 0;
retry--;
n = (n+1)%64;
return('B');
case 'E':
return('A');
case FALSE: return(state);
default: return('A');
}
}
char sbreak()
{
int num, len;
retry++;
if (numtry++ > MAXTRY) return('A');
spack('B',n,0,msgpkt);
switch (rpack(&len,&num,ackpkt)) {
case 'N':
num = (--num<0 ? 63:num);
if (n != num) return(state);
case 'Y':
if (n != num) return(state);
numtry = 0;
retry--;
n = (n+1)%64;
return('C');
case 'E':
return('A');
case FALSE: return(state);
default: return ('A');
}
}
/* timeout equals USERABORT so lets end the file and quit */
/* when host receives 'Z' packet with "D" in data field he */
/* should discard the file. */
sabort()
{
emits("ABORT");
n = (n+1)%64;
retry--;
state = 'Z';
while (state == 'Z') state = seof();
while (state == 'B') state = sbreak();
return(FALSE);
}
recsw()
{
char rinit(), rfile(), rdata(), rbreak();
state = 'R';
while(TRUE) {
switch(state) {
case 'R': state = rinit(); break;
case 'F': state = rfile(); break;
case 'D': state = rdata(); break;
case 'Z': state = rbreak(); break;
case 'C': return(TRUE);
case 'A': x = 600;
if (timeout == USERABORT){/* easy way to cleanly abort
should really send and ACK
with "X" in data field and
wait for host to abort but
not all kermits support
this feature. */
emits("ABORT");
spack('E',n,0,0); /* send an error packet back */
}
else if (timeout == TIMEOUT) emits("TMOUT");
else emits("ERROR");
return(FALSE);
}
}
}
char rinit()
{
int len, num;
retry++;
if (numtry++ > MAXTRY) return('A');
if (server) spack('R',n,strlen(filnam),filnam);
else spack('N',n,0,0);
switch(rpack(&len,&num,msgpkt)) {
case 'S':
rpar(msgpkt);
spar(msgpkt);
spack('Y',n,9,msgpkt);
oldtry = numtry;
numtry = 0;
retry--;
n = (n+1)%64;
return('F');
case 'E':
return('A');
case FALSE:
if (timeout == USERABORT) return('A');
spack('N',n,0,0);
return(state);
default:
return('A');
}
}
char rfile()
{
int num, len;
retry++;
if (numtry++ > MAXTRY) return('A');
switch(rpack(&len,&num,msgpkt)) {
case 'S':
if (oldtry++ > MAXTRY) return('A');
if (num == ((n==0) ? 63:n-1)) {
spar(msgpkt);
spack('Y',num,9,msgpkt);
retry--;
numtry = 0;
return(state);
}
else return('A');
case 'Z':
if (oldtry++ > MAXTRY) return('A');
if (num == ((n==0) ? 63:n-1)) {
spack('Y',num,0,0);
numtry = 0;
retry--;
return(state);
}
else return('A');
case 'F':
if (num != n) return('A');
spack('Y',n,0,0);
oldtry = numtry;
numtry = 0;
retry--;
n = (n+1)%64;
return('D');
case 'B':
if (num != n) return ('A');
spack('Y',n,0,0);
retry--;
return('C');
case 'E':
return('A');
case FALSE:
if (timeout == USERABORT) return('A');
spack('N',n,0,0);
return(state);
default:
return ('A');
}
}
char rdata()
{
int num, len;
retry++;
if (numtry++ > MAXTRY) return('A');
switch(rpack(&len,&num,msgpkt)) {
case 'D':
if (num != n) {
if (oldtry++ > MAXTRY) return('A');
if (num == ((n==0) ? 63:n-1)) {
spack('Y',num,6,msgpkt);
retry--;
numtry = 0;
return(state);
}
else return('A');
}
decode();
spack('Y',n,0,0);
oldtry = numtry;
numtry = 0;
retry--;
n = (n+1)%64;
return('D');
case 'F':
if (oldtry++ > MAXTRY) return('A');
if (num == ((n==0) ? 63:n-1)) {
spack('Y',num,0,0);
numtry = 0;
retry--;
return(state);
}
else return('A');
case 'Z':
if (num != n) return('A');
spack('Y',n,0,0);
n = (n+1)%64;
retry--;
return('Z');
case 'E':
return('A');
case FALSE:
if (timeout == USERABORT) return('A');
spack('N',n,0,0);
return(state);
default:
return('A');
}
}
char rbreak()
{
int num, len;
retry++;
if (numtry++ > MAXTRY) return('A');
switch(rpack(&len,&num,msgpkt)) {
case 'B':
spack('Y',n,0,0);
return('C');
case 'Z':
spack('Y',n,0,0);
return('Z');
case 'E':
return('A');
case FALSE:
spack('N',n,0,0);
return(state);
default:
return('A');
}
}
spack(type,num,len,data)
char type, *data;
int num, len;
{
int i;
char chksum, buffer[100];
register char *bufp;
dostats(type);
bufp = buffer;
for (i=1; i<=pad; i++) sendchar(padchar);
*bufp++ = SOH;
*bufp++ = tochar(len+3);
chksum = tochar(len+3);
*bufp++ = tochar(num);
chksum += tochar(num);
*bufp++ = type;
chksum += type;
for (i=0; i<len; i++) {
*bufp++ = data[i];
chksum += data[i];
}
chksum = (((chksum&0300) >> 6)+chksum)&077;
*bufp++ = tochar(chksum);
*bufp++ = '\r';
*bufp++ = '\n';
*bufp = 0;
sendstring(buffer);
}
rpack(len,num,data)
int *len, *num;
char *data;
{
int i, done;
char type, cchksum, rchksum;
char t = '\0';
do {
t = readchar();
if (timeout != GOODREAD) return(FALSE);
} while (t != SOH);
done = FALSE;
while (!done) {
t = readchar();
if (timeout != GOODREAD) return(FALSE);
if (t == SOH) continue;
cchksum = t;
*len = unchar(t)-3;
t = readchar();
if (timeout != GOODREAD) return(FALSE);
if (t == SOH) continue;
cchksum = cchksum + t;
*num = unchar(t);
t = readchar();
if (timeout != GOODREAD) return(FALSE);
if (t == SOH) continue;
cchksum = cchksum + t;
type = t;
for (i=0; i<*len; i++) {
t = readchar();
if (timeout != GOODREAD) return(FALSE);
if (t == SOH) continue;
cchksum = cchksum + t;
data[i] = t;
}
data[*len] = 0;
t = readchar();
if (timeout != GOODREAD) return(FALSE);
rchksum = unchar(t);
t = readchar();
if (timeout != GOODREAD) return(FALSE);
if (t == SOH) continue;
done = TRUE;
}
dostats(type);
cchksum = (((cchksum&0300) >> 6)+cchksum)&077;
if (cchksum != rchksum) return(FALSE);
return((int)type);
}
getpkt() {
int i,eof;
static char leftover[10] = { '\0', '\0', '\0', '\0', '\0',
'\0', '\0', '\0', '\0', '\0' };
if (first == 1) {
first = 0;
*leftover = '\0';
t = getc(fp);
if (t == EOF) {
first = 1;
return(size = 0);
}
totbytes++;
}
else if (first == -1) {
first = 1;
return(size = 0);
}
for (size = 0; (msgpkt[size] = leftover[size]) != '\0'; size++) ;
*leftover = '\0';
rpt = 0;
eof = 0;
while (!eof) {
next = getc(fp);
if (next == EOF) {
first = -1;
eof = 1;
}
else totbytes++;
osize = size;
encode(t);
t = next;
if (size == spsiz-3) return(size);
if (size > spsiz-3) {
for (i = 0; (leftover[i] = msgpkt[osize+i]) != '\0'; i++) ;
size = osize;
msgpkt[size] = '\0';
return(size);
}
}
return(size);
}
void encode(a)
char a;
{
int a7,b8;
if (p_mode == 1 && a == '\n') {
rpt = 0;
msgpkt[size++] = quote;
msgpkt[size++] = ctl('\r');
if (size <= spsiz-3) osize = size;
msgpkt[size++] = quote;
msgpkt[size++] = ctl('\n');
msgpkt[size] = '\0';
return;
}
if (rptflg) {
if (a == next && (first == 0)) {
if (++rpt < 94) return;
else if (rpt == 94) {
msgpkt[size++] = rptq;
msgpkt[size++] = tochar(rpt);
rpt = 0;
}
}
else if (rpt == 1) {
rpt = 0;
encode(a);
if (size <= spsiz-3) osize = size;
rpt = 0;
encode(a);
return;
}
else if (rpt > 1) {
msgpkt[size++] = rptq;
msgpkt[size++] = tochar(++rpt);
rpt = 0;
}
}
a7 = a & 0177;
b8 = a & 0200;
if ((a7 < SP) || (a7==DEL)) {
msgpkt[size++] = quote;
a = ctl(a);
}
if (a7 == quote) msgpkt[size++] = quote;
if ((rptflg) && (a7 == rptq)) msgpkt[size++] = quote;
msgpkt[size++] = a;
msgpkt[size] = '\0';
}
void decode()
{
USHORT a, a7;
char *buf;
buf = msgpkt;
rpt = 0;
while ((a = *buf++) != '\0') {
if (rptflg) {
if (a == rptq) {
rpt = unchar(*buf++);
a = *buf++;
}
}
if (a == quote) {
a = *buf++;
a7 = a & 0177;
if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') a = ctl(a);
}
if (rpt == 0) rpt = 1;
if (p_mode == 1 && a == '\r') continue;
totbytes += rpt;
for (; rpt > 0; rpt--) putc(a, fp);
}
return;
}
void spar(data)
char data[];
{
data[0] = tochar(MAXPACKSIZ);
data[1] = tochar(TTIME_LONG);
data[2] = tochar(MYPAD);
data[3] = ctl(MYPCHAR);
data[4] = tochar(MYEOL);
data[5] = MYQUOTE;
data[6] = 'N';
data[7] = '1';
data[8] = MYRPTQ;
data[9] = '\0';
}
void rpar(data)
char data[];
{
spsiz = unchar(data[0]);
timint = unchar(data[1]);
pad = unchar(data[2]);
padchar = ctl(data[3]);
eol = unchar(data[4]);
quote = data[5];
rptflg = 0;
if (data[6] == 0) return;
if (data[7] == 0) return;
if (data[8] == 0) return;
rptq = data[8];
rptflg = ((rptq > 040 && rptq < 0100) || (rptq > 0140 && rptq < 0177));
}
saybye()
{
int len,num;
shutdown = 0;
spack('G',n,1,"F"); /* shut down server no more files */
rpack(&len,&num,ackpkt);
}
statusline()
{
emits ("\nFile: Pckt: Pckt No: Retrn: Bytes: Stat: ");
x = 48;
curmode = 1;
emits (filnam);
return(0);
}
dostats(type)
char type;
{
if (type != 'Y' && type != 'N' && type != 'G') {
x = 224;
emit(type);
x = 312;
sprintf(snum,"%4d",n+(tp * 64));
emits(snum);
if (n==63) tp++;
x = 408;
sprintf(snum,"%2d",retry-1);
emits(snum);
x = 488;
sprintf(snum,"%6ld",(long)totbytes);
emits(snum);
}
}
/* allow for multi file xfers separated by commas under kermit and XMODEM */
multi_xfer(name,mode,do_send)
char *name;
int (*mode)();
int do_send;
{
int done = 0;
int status;
char *p;
p = name;
while(*p && *p != ',') p++;
if (*p == '\0') {
done = TRUE;
if (multi == 1) multi++;
}
else multi = 1;
*p = '\0';
status = ((*mode)(name, multi));
if (status == TRUE) {
if (do_send) emits("Sent File: ");
else emits("Received File: ");
emits(name);
emits("\n");
emit(8);
}
else if (status == FALSE)
{
close(fd);
if (do_send) emits("Send Failed: ");
else emits("Receive Failed: ");
emits(name);
emits("\n");
emit(8);
}
if (!done) multi_xfer(++p, mode, do_send);
server = 0;
multi = 0;
}
/* gobble up all garb that we received while getting file name strings */
eatup()
{
while(CheckIO(Read_Request)) {
WaitIO(Read_Request);
BeginIO(Read_Request);
}
}
SHAR_EOF
cat << \SHAR_EOF > remote.c
/****************************************************
* vt100 emulator - remote character interpretation
*
* 860823 DBW - Integrated and rewrote lots of code
* v2.0 860803 DRB - Rewrote the control sequence parser
* v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
* v1.0 860712 DBW - First version released
*
****************************************************/
#define MODULE_REMOTE 1
#include "vt100.h"
static int p[10];
static int numpar;
static char escseq[40];
void doctrl();
void doesc(); /* force correct denomination */
void doerase();
void doindex();
/************************************************
* function to handle remote characters
*************************************************/
void doremote(c)
char c;
{
if (c == 27 || inesc >= 0) { doesc(c); return; }
if (inctrl >= 0) { doctrl(c); return; }
if (c == 10 || c == 11 || c == 12) {
if (nlmode) doindex('E'); else doindex('D');
return;
}
if (c == 13) {
if (!nlmode) emit(c);
return;
}
if (c == 15) { alt = 0; return; }
if (c == 14) { alt = 1; return; }
if (a[alt] && c > 94 && c < 127) { doalt(c); return; }
emit(c);
}
void doesc(c)
char c;
{
if (inesc < 0) { inesc = 0; return; }
if (c == 27 || c == 24) { inesc = -1; return; }
if (c < ' ' || c == 127) return; /* Ignore control chars */
if (c < '0') {escseq[inesc++] = c; return; } /* Collect intermediates */
/* by process of elimination, we have a final character. Put it in
the buffer, and dispatch on the first character in the buffer */
escseq[inesc] = c;
inesc = -1; /* No longer collecting a sequence */
switch (escseq[0]) /* Dispatch on the first received */
{
case '[': /* Control sequence introducer */
numpar = 0; /* No parameters yet */
private = 0; /* Not a private sequence (yet?) */
badseq = 0; /* Good until proven bad */
p[0] = p[1] = 0; /* But default the first parameter */
inctrl = 0; /* We are in a control sequence */
return; /* All done for now ... */
case 'D': case 'E': case 'M': /* Some kind of index */
doindex (c); /* Do the index */
return; /* Return */
case '7': /* Save cursor position */
savx = x; savy = y; savmode = curmode; savalt = alt;
sa[0] = a[0]; sa[1] = a[1];
return;
case '8': /* Restore cursor position */
x = savx; y = savy; alt = savalt; curmode = savmode;
a[0] = sa[0]; a[1] = sa[1];
return;
case 'c': /* Reset */
top = MINY; bot = MAXY; savx = MINX; savy = MINY;
a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
emit(12); return;
inesc = -1;
return;
case '(': /* Change character set */
if (c == '0' || c == '2') a[0] = 1; else a[0] = 0;
return;
case ')': /* Change the other character set */
if (c == '0' || c == '2') a[1] = 1; else a[1] = 0;
return;
/* If we didn't match anything, we can just return, happy in the
knowledge that we've at least eaten the whole sequence */
} /* End of switch */
return;
}
void doctrl(c)
char c;
{
int i;
if (c == 27 || c == 24) { inctrl = -1; return; }
if (c < ' ' || c == 127) return; /* Ignore control chars */
/* First, look for some parameter characters. If the very first
parameter character isn't a digit, then we have a private sequence */
if (c >= '0' && c < '@')
{
/* can't have parameters after intermediates */
if (inctrl > 0) {badseq++ ; return; }
switch (c)
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
p[numpar] = p[numpar] * 10 + (c - '0');
return;
case ';':
p[++numpar] = 0; /* Start a new parameter */
return;
case '<': case '=': case '>': case '?': /* Can only mean private */
if (inctrl = 0) private = c; /* Only allowed BEFORE parameters */
return;
/* if we come here, it's a bad sequence */
}
badseq++; /* Flag the bad sequence */
}
if (c < '0') /* Intermediate character */
{
escseq[inctrl++] = c; /* Save the intermediate character */
return;
}
/* if we get here, we have the final character. Put it in the
escape sequence buffer, then dispatch the control sequence */
numpar++; /* Reflect the real number of parameters */
escseq[inctrl++] = c; /* Store the final character */
escseq[inctrl] = '\000'; /* Tie off the buffer */
inctrl = -1; /* End of the control sequence scan */
/* Don't know how to do any private sequences right now, so just punt
them */
if (private != 0 || badseq != 0) return;
switch (escseq[0]) /* Dispatch on first intermediate or final */
{
case 'A': if (p[0]<=0) p[0] = 1;
y -= 8*p[0]; if (y<top) y = top; return;
case 'B': if (p[0]<=0) p[0] = 1;
y += 8*p[0]; if (y>bot) y = bot; return;
case 'C': if (p[0]<=0) p[0] = 1;
x += 8*p[0]; if (x>MAXX) x = MAXX; return;
case 'D': if (p[0]<=0) p[0] = 1;
x -= 8*p[0]; if (x<MINX) x = MINX; return;
case 'H': case 'f': /* Cursor position */
if (p[0] <= 0) p[0] = 1;
if (p[1] <= 0) p[1] = 1;
y = (--p[0]*8)+MINY; x = (--p[1]*8)+MINX;
if (y > MAXY) y = MAXY;
if (x > MAXX) x = MAXX;
if (y < MINY) y = MINY;
if (x < MINX) x = MINX;
return;
case 'r': /* Set scroll region */
if (p[0] <= 0) p[0] = 1;
if (p[1] <= 0) p[1] = p_lines;
top = (--p[0]*8)+MINY; bot = (--p[1]*8)+MINY;
if (top < MINY) top = MINY;
if (bot > MAXY) bot = MAXY;
if (top > bot) { top = MINY; bot = MAXY; }
x = MINX; y = MINY;
return;
case 'm': /* Set graphic rendition */
for (i=0;i<numpar;i++) {
if (p[i] < 0) p[i] = 0;
switch (p[i]) {
case 0:
curmode = 0;
break;
case 1:
case 5:
if (p_depth > 1) curmode |= BOLD;
else curmode |= REVERSE;
break;
case 4:
curmode |= UNDERLINE;
break;
default:
curmode |= REVERSE;
break;
}
}
return;
case 'K': /* Erase in line */
doerase();
return;
case 'J': /* Erase in display */
if (p[0] < 0) p[0] = 0;
SetAPen(mywindow->RPort,0L);
if (p[0] == 0) {
if (y < MAXY) RectFill(mywindow->RPort,
(long)MINX,(long)(y+2),(long)(MAXX+7),(long)(MAXY+1));
}
else if (p[0] == 1) {
if (y > MINY) RectFill(mywindow->RPort,
(long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(y-7));
}
else RectFill(mywindow->RPort,
(long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
SetAPen(mywindow->RPort,1L);
doerase(); return;
case 'h': /* Set parameter */
if (p[0] == 20) nlmode = 1;
return;
case 'l': /* Reset parameter */
if (p[0] == 20) nlmode = 0;
return;
case 'x':
sendchar(27); sendstring("[3;1;8;64;64;1;0x"); return;
case 'n':
if (p[0] == 6) {
sendchar(27);
sprintf(escseq,"[%d;%dR",((y-MINY)/8)+1,((x-MINX)/8)+1);
sendstring(escseq); return;
}
sendchar(27); sendstring("[0n"); return;
case 'c':
sendchar(27); sendstring("[?1;0c"); return;
}
/* Don't know how to do this one, so punt it */
}
void doindex(c)
char c;
{
if (c != 'M') {
if (c == 'E') x = MINX;
if (y > bot) if (y < MAXY) y += 8;
if (y == bot)
ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,(long)(top-6),
(long)(MAXX+7),(long)(bot+1));
if (y < bot) y += 8;
}
else {
if (y < top) if (y > MINY) y -= 8;
if (y == top)
ScrollRaster(mywindow->RPort,0L,-8L,(long)MINX,(long)(top-6),
(long)(MAXX+7),(long)(bot+1));
if (y > top) y -= 8;
}
return;
}
doalt(c)
char c;
{
int oldx,newx;
inesc = -1;
oldx = x; emit(' '); newx = x;
x = oldx;
SetAPen(mywindow->RPort,1L);
switch (c) {
case 'j':
case 'm':
case 'v': doline(4,-8,4,-4);
if (c=='j') doline(0,-4,4,-4);
else if (c=='m') doline(4,-4,8,-4);
else doline(0,-4,8,-4);
break;
case 'k':
case 'l':
case 'w': doline(4,-4,4,0);
if (c=='k') doline(0,-4,4,-4);
else if (c=='l') doline(4,-4,8,-4);
else doline(0,-4,8,-4);
break;
case 'n':
case 'q': doline(0,-4,8,-4);
if (c=='n') doline(4,-8,4,0);
break;
case 't':
case 'u':
case 'x': doline(4,-8,4,0);
if (c=='t') doline(4,-4,8,-4);
else if (c=='u') doline(0,-4,4,-4);
break;
}
x = newx;
}
doline(x1,y1,x2,y2) {
RectFill(mywindow->RPort,(long)(x+x1),(long)(y+y1),
(long)(x+x2),(long)(y+y2));
}
void doerase()
{
if (p[0] < 0) p[0] = 0;
SetAPen(mywindow->RPort,0L);
if (p[0] == 0) RectFill(mywindow->RPort,(long)x,(long)(y-6),
(long)(MAXX+7),(long)(y+1));
else if (p[0] == 1) RectFill(mywindow->RPort,
(long)MINX,(long)(y-6),(long)(x+7),(long)(y+1));
else RectFill(mywindow->RPort,
(long)MINX,(long)(y-6),(long)(MAXX+7),(long)(y+1));
SetAPen(mywindow->RPort,1L);
return;
}
SHAR_EOF
cat << \SHAR_EOF > script.c
/*************************************************************
* vt100 terminal emulator - Script file support
*
* 860823 DBW - Integrated and rewrote lots of code
* 860815 Steve Drew: Initial version written of SCRIPT.C
* v2.0 860809 DBW - Major rewrite
* v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
* v1.0 860712 DBW - First version released
*
*************************************************************/
#define MODULE_SCRIPT 1
#include "vt100.h"
extern char *fgets(),*malloc();
extern long ftell();
struct COMMAND {
int (*func)();
char *cname;
};
struct LABEL {
struct LABEL *next;
char *name;
long pos;
};
/**************** globals needed ******************/
char on_string[20]; /* string to match on for on cmd */
char wait_string[20]; /* string to match of for wait cmd */
char golabel[20]; /* label we are looking for in goto */
char on_cmd[255]; /* command to execute when on matchs*/
int onsize; /* size of on_string */
int waitsize; /* size of wait_string */
int onpos; /* position in on string for search */
int waitpos; /* pos in wait_string for search */
int on_match; /* flag set while doing on_cmd */
FILE *sf; /* file pointer for script file */
struct LABEL *lbase = NULL; /* will point to first label */
struct LABEL *labels; /* current label pointer */
int cmd_send(), cmd_wait(), cmd_on(), cmd_goto(), cmd_delay(), cmd_done(),
cmd_ks(), cmd_kg(), cmd_kr(), cmd_xs(), cmd_xr(), cmd_cap(), cmd_as(),
cmd_null(), cmd_kb();
char *next_wrd(), *tostring();
/********************** command table **********************************/
static struct COMMAND commands[]= {
cmd_send, "SEND", /* send string to host */
cmd_wait, "WAIT", /* wait for a string from host */
cmd_on, "ON", /* on a 'string' do a cmd */
cmd_goto, "GOTO", /* goto label */
cmd_delay, "DELAY", /* delay amount of seconds */
cmd_done, "EXIT", /* exit script file */
cmd_ks, "KS", /* kermit send file */
cmd_kr, "KR", /* kermit receive file */
cmd_kg, "KG", /* kermit get file */
cmd_kb, "KB", /* kermit bye (for server) */
cmd_xs, "XS", /* xmodem send file */
cmd_xr, "XR", /* xmodem receive file */
cmd_cap, "CAPTURE", /* ascii capture on/off */
cmd_as, "ASCII_SEND", /* ascii send */
cmd_null, NULL
};
/********************************************************************/
/* checks char to see if match with on string or wait_string */
/* if on string match oncmd gets executed imediately, */
/* if wait_string match script_wait is set. */
/********************************************************************/
chk_script(c)
char c;
{
if (on_string[0] != '\0') {
if (on_string[onpos] == c) {
onpos++;
if (onpos == onsize) {
on_match = TRUE;
do_script_cmd(ONCOMMAND);
on_match = FALSE;
return(0);
}
}
else onpos = 0;
}
if (wait_string[0] != '\0') {
if (wait_string[waitpos] != c) {
waitpos = 0;
return(0);
}
waitpos++;
if (waitpos != waitsize) return(0);
wait_string[0] = '\0';
script_wait = FALSE;
}
}
script_start(file)
char *file;
{
if ((sf = fopen(file, "r")) == NULL) {
emits("Can't open script file\n");
return(0);
}
script_on = TRUE;
script_wait = FALSE;
wait_string[0] = '\0';
on_string[0] = '\0';
on_match = FALSE;
lbase = NULL;
}
/* return pointer to next word. set l to size of the word */
char *next_wrd(s,l)
char *s;
int *l;
{
char *p;
while(*s && (*s == ' ' || *s == 9)) s++;
p = s;
while(*s && (*s != ' ' && *s != 9)) s++;
*l = s-p;
return(p);
}
exe_cmd(p,l)
char *p;
int l;
{
int i;
for (i=0; commands[i].func != cmd_null; ++i)
if (strncmp(p, commands[i].cname, l) == 0) {
(*commands[i].func)(next_wrd(p+l, &l));
return(TRUE);
}
emits ("\nScript - unknown command: ");
emits (p);
emits ("\n");
}
struct LABEL *find_label(lname)
char *lname;
{
struct LABEL *label;
label = lbase;
while(label != NULL) {
if (strcmp(label->name, lname) == 0) return (label);
label = label->next;
}
return(NULL);
}
do_script_cmd(stat)
int stat;
{
int len,l;
char line[256];
char *p;
if (stat == ONCOMMAND) { /* if ON command is matched and we were */
strcpy(line,on_cmd); /* doing a DELAY then abort the delay timer,*/
p = next_wrd(line,&l); /* except if on_cmd was just a SEND. */
if (*p != 'S' && script_wait == WAIT_TIMER) {
AbortIO((char *) &Script_Timer);
Wait (1L << Script_Timer_Port->mp_SigBit);
script_wait = FALSE; /* script will proceed after on command */
}
exe_cmd(p,l);
return(0);
}
script_wait = FALSE;
while(fgets(line,256,sf) != NULL) {
len = strlen(line);
line[--len] = '\0';
p = next_wrd(&line[0], &l);
if (*(p + l - 1) == ':') { /* its a label */
*(p + l - 1) = '\0';
if (find_label(p) == NULL) { /* it's a new label */
if (lbase == NULL) { /* it's the first label */
labels = lbase = (struct LABEL *) malloc (sizeof (struct LABEL));
}
else {
labels->next =
(struct LABEL *) malloc (sizeof (struct LABEL));
labels = labels->next;
}
labels->pos = ftell(sf);
labels->name = malloc(l);
labels->next = NULL;
strcpy(labels->name, p);
if (stat == GOTOLABEL && strcmp(p, golabel) == 0)
stat = NEXTCOMMAND;
}
if (l < len) p = next_wrd(p+l+1, &l);
else return(0);
} /* end of it's a label */
if (stat == GOTOLABEL || *p == '#') continue;
if (*p) exe_cmd(p,l);
return(0);
} /* end of while */
if (stat == GOTOLABEL) {
emits("\nScript - label not found: ");
emits(golabel);
emits("\n");
}
exit_script();
}
exit_script()
{
if (script_wait == WAIT_TIMER) /* timer not done yet */
AbortIO((char *) &Script_Timer); /* so abort it */
emits("\nScript - terminated\n");
script_on = FALSE;
script_wait = TRUE;
fclose(sf);
}
/* remove quotes terminate string & return pointer to start */
char *tostring(ptr)
char *ptr;
{
char *s;
s = ptr;
if (*ptr == '"') {
while(*ptr++ && *ptr !='"');
if (*ptr == '"') {
*ptr = '\0';
ptr = s+1;
while(*s++) if (*s == '|') *s = '\r';
return(ptr);
}
}
if (*s == '^') {
*s = *(s+1)-64;
*(s+1) = '\0';
return(s);
}
*(s+1) = '\0';
return(s);
}
cmd_goto(lname)
char *lname;
{
struct LABEL *label;
/* if on_cmd was a goto kill wait state */
if (on_match) { wait_string[0] = '\0'; script_wait = FALSE; }
if ((label = find_label(lname)) == NULL) { /* is it forward */
strcpy(golabel,lname);
do_script_cmd(GOTOLABEL);
}
else {
fseek(sf,(long)(label->pos),0);
}
}
cmd_send(str)
char *str;
{
sendstring(tostring(str));
}
cmd_wait(str)
char *str;
{
str = tostring(str);
*(str+20) = '\0'; /* 20 characters max */
strcpy(wait_string, str);
waitsize = strlen(str);
script_wait = WAIT_STRING;
}
cmd_on(str)
char *str;
{
char *p;
p = tostring(str);
strcpy(on_string, p);
onsize = strlen(p);
*(p+onsize+2+20) = '\0'; /* 20 characters max */
strcpy(on_cmd,p+onsize+2);
}
cmd_delay(seconds)
char *seconds;
{
script_wait = WAIT_TIMER;
Script_Timer.tr_time.tv_secs = atoi(seconds);
Script_Timer.tr_time.tv_micro = 0;
SendIO((char *) &Script_Timer.tr_node);
}
cmd_done()
{
exit_script();
}
cmd_ks(file)
char *file;
{
multi_xfer(file, doksend, 1);
}
cmd_kr(file)
char *file;
{
multi_xfer(file, dokreceive, 0);
}
cmd_kg(file)
char *file;
{
server = TRUE;
multi_xfer(file, dokreceive, 0);
}
cmd_kb()
{
saybye();
}
cmd_xs(file)
char *file;
{
multi_xfer(file, XMODEM_Send_File, 1);
}
cmd_xr(file)
char *file;
{
multi_xfer(file, XMODEM_Read_File, 1);
}
cmd_cap(file)
char *file;
{
do_capture(file);
}
cmd_as(file)
char *file;
{
do_send(file);
}
cmd_null(file)
char *file;
{
}
SHAR_EOF
# End of shell archive
exit 0
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads