Article View: mod.amiga.sources
Article #49VT100 (V2.2 861012 DBW) Part 3 of 3
From: doc
Date: Tue, 14 Oct 1986 18:03
Date: Tue, 14 Oct 1986 18:03
1632 lines
46873 bytes
46873 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
# This archive created: Tue Oct 14 12:58:51 1986
# By: Craig Norborg (Purdue University Computing Center)
cat << \SHAR_EOF > init.c
/***************************************************************
* vt100 - terminal emulator - initialization
*
* v2.2 861012 DBW - more of the same
* v2.1 860915 DBW - new features (see README)
* 860901 ACS - Added Parity and Word Length and support code
* 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"
char line[256];
char *InitDefaults(argc,argv)
int argc;
char **argv;
{
FILE *fd;
char scr[32],delim,macro[256],c0,*ptr,*ptr2;
int i,j,k;
long li;
if (((argc > 1) && (fd=fopen(argv[1],"r")) != 0) ||
(fd=fopen("vt100.init","r")) != 0 ||
(fd=fopen("s: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]|' ') == 'u') {
/* buffer size */
if (sscanf(line,"%s %d",scr,&i) == 2) p_buffer = i;
if (p_buffer < 512) p_buffer = 512;
break;
}
if ((line[1]|' ') == 'r') {
/* break time */
if (sscanf(line,"%s %ld",scr,&li) == 2) p_break = li;
break;
}
if ((line[1]|' ') != 'a') break;
switch(line[2]|' ') {
/* baud rate */
case 'u':
if (sscanf(line,"%s %d",scr,&i) == 2)
switch (i) {
case 300:
case 1200:
case 2400:
case 4800:
case 9600: p_baud = i; break;
}
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 %x",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=(i==10?3: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 'k':
/*keyscript*/
if (sscanf(line,"%s %x",scr,&i) == 2)
p_keyscript = i & 0x7F;
break;
case 'm':
if (sscanf(line,"%s %s",scr,scr) == 2) {
if ((scr[0]|' ') == 'i') p_mode = 0;
else p_mode = 1;
}
break;
case 'p': /*parity*/
if (sscanf(line,"%s %s",scr,scr) == 2)
switch(*scr|' ') {
case 'n': p_parity = 0; break;
case 'm': p_parity = 1; break;
case 's': p_parity = 2; break;
case 'e': p_parity = 3; break;
case 'o': p_parity = 4; break;
}
break;
case 'v': /*volume*/
if (sscanf(line,"%s %d",scr,&i) == 2)
if (i > 0) p_volume = i;
break;
case 'w':
/*wrap*/
if (sscanf(line,"%s %s",scr,scr) == 2) {
if ((scr[1]|' ') == 'n') p_wrap = 1;
else p_wrap = 0;
}
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;
}
/* see if we exit with a startup script */
if ((c0|' ') == 'e') {
ptr = &line[0];
while (*ptr != '\000' && *ptr != ' ' && *ptr != '\t') ptr++;
if (*ptr == '\000') return(NULL);
while (*ptr != '\000' && (*ptr == ' ' || *ptr == '\t')) ptr++;
if (*ptr == '\000') return(NULL);
ptr2 = ptr;
while (*ptr2 != '\000' && *ptr2 != ' ' &&
*ptr2 != '\t' && *ptr2 != '\n') ptr2++;
*ptr2 = '\000';
return(ptr);
}
else return(NULL);
}
void InitDevs()
{
USHORT colors[4];
int i;
BYTE *b,*c;
IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", INTUITION_REV);
if( IntuitionBase == NULL )
cleanup("can't open intuition",1);
GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",GRAPHICS_REV);
if( GfxBase == NULL )
cleanup("can't open graphics library",2);
if (p_screen == 1) {
if ((myscreen = (struct Screen *)OpenScreen(&NewScreen)) == NULL)
cleanup("can't open screen",3);
NewWindow.Screen = myscreen;
}
if(( mywindow = (struct Window *)OpenWindow(&NewWindow) ) == NULL)
cleanup("can't open window",4);
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 = 0L;
Read_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0,0);
if(OpenDevice(SERIALNAME,NULL,Read_Request,NULL))
cleanup("Cant open Read device",5);
rs_in = malloc(p_buffer+1);
Read_Request->io_SerFlags = 0L;
Read_Request->io_Baud = p_baud;
Read_Request->io_ReadLen = 8L;
Read_Request->io_WriteLen = 8L;
Read_Request->io_CtlChar = 0x11130000L;
Read_Request->io_RBufLen = p_buffer;
Read_Request->io_BrkTime = p_break;
Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
DoIO(Read_Request);
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);
b = (BYTE *)Read_Request;
c = (BYTE *)Write_Request;
for (i=0;i<sizeof(struct IOExtSer);i++) *c++ = *b++;
Write_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0,0);
Write_Request->IOSer.io_Command = CMD_WRITE;
Write_Request->IOSer.io_Length = 1;
Write_Request->IOSer.io_Data = (APTR) &rs_out[0];
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))
cleanup("can't open timer device",7);
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;
BeepWave = (UBYTE *)AllocMem(BEEPSIZE,(long)(MEMF_CHIP|MEMF_CLEAR));
if (BeepWave != 0) BeepWave[0] = 100;
Audio_Port = CreatePort("Audio Port",0);
Audio_Request.ioa_Request.io_Message.mn_ReplyPort = Audio_Port;
Audio_Request.ioa_Request.io_Message.mn_Node.ln_Pri = 85;
Audio_Request.ioa_Data = Audio_AllocMap;
Audio_Request.ioa_Length = (ULONG) sizeof(Audio_AllocMap);
if (OpenDevice(AUDIONAME, NULL, (char *) &Audio_Request, NULL))
cleanup("can't open audio device",8);
Audio_Request.ioa_Request.io_Command = CMD_WRITE;
Audio_Request.ioa_Request.io_Flags = ADIOF_PERVOL;
Audio_Request.ioa_Data = BeepWave;
Audio_Request.ioa_Length = BEEPSIZE;
Audio_Request.ioa_Period = COLORCLOCK / (BEEPSIZE * BEEPFREQ);
Audio_Request.ioa_Volume = p_volume;
Audio_Request.ioa_Cycles = 100;
}
/*****************************************************************/
/* 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 = 10 * n;
FileItem[n].Width = 120;
FileItem[n].Height = 10;
FileItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
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";
}
/*************************************************************************
/* Main Comm menu
/* set up for Baud & Parity submenus
/************************************************************************/
void InitCommItems()
{
int n;
/* initialize each menu item and IntuiText with loop */
for( n=0; n<COMMAX; n++ )
{
CommItem[n].NextItem = &CommItem[n+1];
CommItem[n].LeftEdge = 0;
CommItem[n].TopEdge = 10 * n;
CommItem[n].Width = 88;
CommItem[n].Height = 10;
CommItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP ;
CommItem[n].MutualExclude = 0;
CommItem[n].ItemFill = (APTR)&CommText[n];
CommItem[n].SelectFill = NULL;
CommItem[n].Command = 0;
CommItem[n].NextSelect = 0;
CommText[n].FrontPen = 0;
CommText[n].BackPen = 1;
CommText[n].DrawMode = JAM2;
CommText[n].LeftEdge = 0;
CommText[n].TopEdge = 1;
CommText[n].ITextFont = NULL;
CommText[n].NextText = NULL;
}
CommItem[COMMAX-1].NextItem = NULL;
CommText[0].IText = (UBYTE *)"Baud Rate";
CommText[1].IText = (UBYTE *)"Parity ";
CommText[2].IText = (UBYTE *)"Xfer Mode";
CommItem[0].SubItem = RSItem;
CommItem[1].SubItem = ParItem;
CommItem[2].SubItem = XFItem;
/*****************************************************************/
/* The following initializes the structure arrays */
/* needed to provide the BaudRate Submenu topic. */
/*****************************************************************/
for( n=0; n<RSMAX; n++ )
{
RSItem[n].NextItem = &RSItem[n+1];
RSItem[n].LeftEdge = 75;
RSItem[n].TopEdge = 10 * n;
RSItem[n].Width = 56;
RSItem[n].Height = 10;
RSItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | 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 |= 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 initializes the structure arrays */
/* needed to provide the Parity Submenu topic. */
/*****************************************************************/
for( n=0; n<PARMAX; n++ )
{
ParItem[n].NextItem = &ParItem[n+1];
ParItem[n].LeftEdge = 75;
ParItem[n].TopEdge = 10 * n;
ParItem[n].Width = 56;
ParItem[n].Height = 10;
ParItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
ParItem[n].MutualExclude = (~(1 << n));
ParItem[n].ItemFill = (APTR)&ParText[n];
ParItem[n].SelectFill = NULL;
ParItem[n].Command = 0;
ParItem[n].SubItem = NULL;
ParItem[n].NextSelect = 0;
ParText[n].FrontPen = 0;
ParText[n].BackPen = 1;
ParText[n].DrawMode = JAM2; /* render in fore and background */
ParText[n].LeftEdge = 0;
ParText[n].TopEdge = 1;
ParText[n].ITextFont = NULL;
ParText[n].NextText = NULL;
}
ParItem[PARMAX-1].NextItem = NULL;
/* select parity item chekced */
ParItem[p_parity].Flags |= CHECKED;
/* initialize text for specific menu items */
ParText[0].IText = (UBYTE *)" None ";
ParText[1].IText = (UBYTE *)" Mark ";
ParText[2].IText = (UBYTE *)" Space";
ParText[3].IText = (UBYTE *)" Even ";
ParText[4].IText = (UBYTE *)" Odd ";
/*****************************************************************/
/* The following initializes the structure arrays */
/* needed to provide the Transfer Mode menu topic. */
/*****************************************************************/
/* initialize each menu item and IntuiText with loop */
for( n=0; n<XFMAX; n++ )
{
XFItem[n].NextItem = &XFItem[n+1];
XFItem[n].LeftEdge = 75;
XFItem[n].TopEdge = 10 * n;
XFItem[n].Width = 80;
XFItem[n].Height = 10;
XFItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | 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;
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 |= CHECKED;
/* initialize text for specific menu items */
XFText[0].IText = (UBYTE *)" image";
XFText[1].IText = (UBYTE *)" CR LF";
} /* end of InitCommItems() */
/*****************************************************************/
/* 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 = 10 * n;
ScriptItem[n].Width = 128;
ScriptItem[n].Height = 10;
ScriptItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
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 structure arrays */
/* needed to provide the Util menu topic. */
/*****************************************************************/
void InitUtilItems()
{
int n;
/* initialize each menu item and IntuiText with loop */
for( n=0; n<UTILMAX; n++ )
{
UtilItem[n].NextItem = &UtilItem[n+1];
UtilItem[n].LeftEdge = 0;
UtilItem[n].TopEdge = 10 * n;
UtilItem[n].Width = 88;
UtilItem[n].Height = 10;
UtilItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
UtilItem[n].MutualExclude = 0;
UtilItem[n].ItemFill = (APTR)&UtilText[n];
UtilItem[n].SelectFill = NULL;
UtilItem[n].Command = 0;
UtilItem[n].SubItem = NULL;
UtilItem[n].NextSelect = 0;
UtilText[n].FrontPen = 0;
UtilText[n].BackPen = 1;
UtilText[n].DrawMode = JAM2; /* render in fore and background */
UtilText[n].LeftEdge = 0;
UtilText[n].TopEdge = 1;
UtilText[n].ITextFont = NULL;
UtilText[n].NextText = NULL;
}
/* until we know how to toggle DTR */
/* UtilItem[1].Flags ^= ITEMENABLED; */
UtilItem[UTILMAX-1].NextItem = NULL;
/* initialize text for specific menu items */
UtilText[0].IText = (UBYTE *)"Send Break";
UtilText[1].IText = (UBYTE *)"Hang Up";
UtilText[2].IText = (UBYTE *)"Change Dir";
}
/**********************************************************************/
/* 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 = 40;
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 = 55;
menu[1].TopEdge = 0;
menu[1].Width = 88;
menu[1].Height = 10;
menu[1].Flags = MENUENABLED;
menu[1].MenuName = "Comm Setup"; /* text for menu-bar display */
menu[1].FirstItem = &CommItem[0]; /* pointer to first item in list */
menu[2].NextMenu = &menu[3];
menu[2].LeftEdge = 153;
menu[2].TopEdge = 0;
menu[2].Width = 56;
menu[2].Height = 10;
menu[2].Flags = MENUENABLED;
menu[2].MenuName = "Script"; /* text for menu-bar display */
menu[2].FirstItem = &ScriptItem[0]; /* pointer to first item in list */
menu[3].NextMenu = NULL;
menu[3].LeftEdge = 225;
menu[3].TopEdge = 0;
menu[3].Width = 64;
menu[3].Height = 10;
menu[3].Flags = MENUENABLED;
menu[3].MenuName = "Utility"; /* text for menu-bar display */
menu[3].FirstItem = &UtilItem[0]; /* pointer to first item in list */
}
SHAR_EOF
cat << \SHAR_EOF > kermit.c
/*************************************************************
* vt100 terminal emulator - KERMIT protocol support
*
* v2.2 861012 DBW - more of the same
* v2.1 860915 DBW - new features (see README)
* 860901 ACS - Added eight bit quoting
* 860830 Steve Drew Wild card support, error recovery, bugs.
* 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 CONVERTNAME TRUE /* convert file name to lower case for receive */
#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 MYEBQ '&' /* 8th bit prefix 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 */
sendabort, /* flag for aborting send file */
rptflg, /* are we doing repeat quoting */
ebqflg, /* are we doing 8th bit quoting */
notfirst, /* is this the first file received */
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 */
ebq, /* Quote character for 8th bit quoting */
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 */
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 amount, c, wild;
char *p, **list = NULL;
if (!strcmp(file,"$")) { saybye(); return(2); }
want_message = FALSE; /* tell readchar no error msgs */
p = file;
while(*p && *p != '*' && *p != '?') p++;
if (*p) {
wild = TRUE;
list = expand(file, &amount);
if (list == NULL) emits("No wild card match\n");
}
else {
wild = FALSE;
amount = 1;
}
for (c = 0; c < amount; c++) {
if (wild == TRUE) p = list[c];
else p = file;
strcpy(filnam,getfname(p));
ttime = TTIME_KERMIT;
tp = retry = n = numtry = 0; totbytes = 0L;
statusline();
if ((fp = fopen(p,"r")) == NULL) {
emits("ERROR");
emits("\nVT100 - Kermit - Cannot open send file: ");
emits(p);
curmode = FS_NORMAL;
continue;
}
emits("SEND");
ClearBuffer();
if (sendsw()) { x = 600; emits("DONE"); }
fclose(fp);
curmode = FS_NORMAL;
}
free_expand(list);
return TRUE;
}
dokreceive(file,more)
char *file;
int more;
{
int retval;
ttime = TTIME_KERMIT;
if (!strcmp(file,"$")) { saybye(); return(2); }
strcpy(filnam, file);
statusline();
if (server) emits("GET ");
else emits("RECV");
tp = retry = n = numtry = notfirst = 0; totbytes = 0L;
want_message = FALSE; /* tell readchar no error msgs status bar instead */
ClearBuffer();
retval = recsw();
curmode = FS_NORMAL;
return(retval);
}
sendsw()
{
char sinit(), sfile(), sdata(), seof(), sbreak();
sendabort = 0;
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': if (sendabort) return FALSE;
else return TRUE;
case 'E': x = 600; /* host sent us error packet */
emits("ERROR"); /* so print the error and abort */
print_host_err(ackpkt);
return(FALSE);
case 'A': x = 600;
if (timeout == USERABORT) {
timeout = GOODREAD;
n = (n+1)%64;
sendabort = 1;
emits("ABORT");
strcpy(msgpkt, "D");
state = 'Z';
break;
}
if (timeout == TIMEOUT) emits("TMOUT");
else { /* protocol error dectected by us */
emits("ERROR");
print_our_err();
}
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 = MYQUOTE;
numtry = 0;
retry--;
n = (n+1)%64;
return('F');
case 'E': return('E');
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('E');
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('E');
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) { /* tell host to discard file */
/* timeout = GOODREAD;
spack('Z',n,1,"D");
}
else */ spack('Z',n,sendabort,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('E');
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('E');
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();
state = 'R';
while(TRUE) {
switch(state) {
case 'R': state = rinit(); break;
case 'Z':
case 'F': state = rfile(); break;
case 'D': state = rdata(); break;
case 'C': return(TRUE);
case 'E':
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"); /* send an error packet back */
spack('E',n,12,"User aborted");
}
else if (timeout == TIMEOUT) { /* we timed out waiting */
/* will we need to spack here ?*/
emits("TMOUT");
}
else emits("ERROR"); /* must be 'E' from host or we
detected a protocol error */
if (state == 'E') print_host_err(msgpkt);
else if (timeout == GOODREAD) /* tell host why */
print_our_err();
/* will this kill all files ?*/
do {
ttime = 2;
readchar();
} while (timeout == GOODREAD);
fclose(fp);
sendstring("\r");
return(FALSE);
default: 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('E');
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);
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;
return(state);
}
else return('A');
case 'F':
if (num != n) return('A');
strcpy(filnam,msgpkt);
if (CONVERTNAME) {
char *p;
p = &filnam[0];
while (*p) { *p = tolower(*p); p++; }
}
if (notfirst) {
curmode = FS_NORMAL;
totbytes = 0L;
statusline();
emits("RECV");
}
else { /* is the first file so emit actual file name from host */
x = 48; emits(" ");
x = 48; emits(filnam);
notfirst++;
}
if ((fp = fopen(filnam,"w")) == NULL) {
strcpy(msgpkt,"VT100 - Kermit - Unable to create file: ");
strcat(msgpkt,filnam);
spack('E',n,strlen(msgpkt),msgpkt); /* let host know */
x = 600; emits("ERROR");
emits("\n");
emits(msgpkt); /* let user know */
return ('\0'); /* abort everything */
}
spack('Y',n,0,0);
oldtry = numtry;
numtry = 0;
retry--;
n = (n+1)%64;
return('D');
case 'B': /* totaly done server sending no more */
if (num != n) return ('A');
spack('Y',n,0,0);
retry--;
return('C');
case 'E':
return('E');
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);
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 'Z':
if (num != n) return('A');
spack('Y',n,0,0);
n = (n+1)%64;
retry--;
x = 600;
emits("DONE");
fclose(fp);
return('Z');
case 'F':
if (oldtry++ > MAXTRY) return('A');
if (num == ((n==0) ? 63:n-1)) {
spack('Y',num,0,0);
numtry = 0;
return(state);
}
case 'E':
return('E');
case FALSE:
if (timeout == USERABORT) return('A');
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;
ClearBuffer();
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 (ebqflg && b8) { /* Do 8th bit prefix if necessary. */
msgpkt[size++] = ebq;
a = a7;
}
if ((a7 < SP) || (a7==DEL)) {
msgpkt[size++] = quote;
a = ctl(a);
}
if (a7 == quote) msgpkt[size++] = quote;
if ((rptflg) && (a7 == rptq)) msgpkt[size++] = quote;
if ((ebqflg) && (a7 == ebq)) /* Prefix the 8th bit prefix */
msgpkt[size++] = quote; /* if doing 8th-bit prefixes */
msgpkt[size++] = a;
msgpkt[size] = '\0';
}
void decode()
{
USHORT a, a7, b8;
char *buf;
buf = msgpkt;
rpt = 0;
while ((a = *buf++) != '\0') {
if (rptflg) {
if (a == rptq) {
rpt = unchar(*buf++);
a = *buf++;
}
}
b8 = 0;
if (ebqflg) { /* 8th-bit prefixing? */
if (a == ebq) { /* Yes, got an 8th-bit prefix? */
b8 = 0200; /* Yes, remember this, */
a = *buf++; /* and get the prefixed character. */
}
}
if (a == quote) {
a = *buf++;
a7 = a & 0177;
if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') a = ctl(a);
}
a |= b8;
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_KERMIT);
data[2] = tochar(MYPAD);
data[3] = ctl(MYPCHAR);
data[4] = tochar(MYEOL);
data[5] = MYQUOTE;
if ((p_parity >= 0) || ebqflg) { /* 8-bit quoting... */
data[6] = MYEBQ; /* If parity or flag on, send &. */
if ((ebq > 0040 && ebq < 0100) || /* If flag off, then turn it on */
(ebq > 0140 && ebq < 0177) || /* if other side has asked us to */
(ebq == 'Y')) ebqflg = 1;
}
else /* Normally, */
data[6] = 'Y'; /* just say we're willing. */
data[7] = '1';
data[8] = MYRPTQ;
data[9] = '\0';
}
void rpar(data)
char data[];
{
spsiz = unchar(data[0]);
ttime = unchar(data[1]);
pad = unchar(data[2]);
padchar = ctl(data[3]);
eol = unchar(data[4]);
quote = data[5];
rptflg = 0;
ebqflg = 0;
if (data[6] == 0) return;
ebq = data[6];
if ((ebq > 040 && ebq < 0100) || (ebq > 0140 && ebq < 0177)) ebqflg = 1;
else if (((p_parity >= 0) || ebqflg) && (ebq == 'Y')) {
ebqflg = 1;
ebq = '&';
}
else ebqflg = 0;
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;
spack('G',n,1,"F"); /* shut down server no more files */
rpack(&len,&num,ackpkt);
}
print_our_err()
{
if (retry > MAXTRY || oldtry > MAXTRY)
strcpy(msgpkt,"VT100 - Kermit - Too many retries for packet");
else
strcpy(msgpkt,"VT100 - Kermit - Protocol Error");
spack('E',n,strlen(msgpkt));
emits("\n");
emits(msgpkt);
}
print_host_err(msg)
char *msg;
{
curmode = FS_NORMAL;
emits("\n");
emits("Host Error: ");
curmode = FSF_BOLD;
emits(msg);
}
statusline()
{
emits ("\nFile: Pckt: Pckt No: Retrn: Bytes: Stat: ");
x = 48;
curmode = FSF_BOLD;
emits (filnam);
x = 600;
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++;
while(*p && *p != ',' && *p != ' ') p++;
if (*p == '\0') done = TRUE;
else multi = 1;
*p = '\0';
status = ((*mode)(name, multi));
if (status == TRUE && want_message) {
if (do_send) emits("Sent File: ");
else emits("Received File: ");
emits(name);
emits("\n");
}
else if (status == FALSE && want_message)
{
close(fd);
if (do_send) emits("Send Failed: ");
else emits("Receive Failed: ");
emits(name);
emits("\n");
}
if (!done && timeout != USERABORT) multi_xfer(++p, mode, do_send);
else emits("\n");
server = 0;
multi = 0;
}
ClearBuffer()
{
AbortIO(Read_Request);
Read_Request->IOSer.io_Command = CMD_CLEAR;
DoIO(Read_Request);
Read_Request->IOSer.io_Command = CMD_READ;
SendIO(Read_Request);
}
SHAR_EOF
# End of shell archive
exit 0
Technical Details
Message-ID:
<2293@j.cc.purdue.edu>Path:
arc1-ca.pugleaf.net!utzoo!decvax!ucbvax!ucbcad!nike!lll-crg!lll-lcc!qantel!ihnp4!inuxc!pur-ee!j.cc.purdue.edu!docShow Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: arc1-ca.pugleaf.net!utzoo!decvax!ucbvax!ucbcad!nike!lll-crg!lll-lcc!qantel!ihnp4!inuxc!pur-ee!j.cc.purdue.edu!doc From: doc@j.cc.purdue.edu Newsgroups: mod.amiga.sources Subject: VT100 (V2.2 861012 DBW) Part 3 of 3 Message-ID: <2293@j.cc.purdue.edu> Date: Tue, 14-Oct-86 14:03:00 EDT Article-I.D.: j.2293 Posted: Tue Oct 14 14:03:00 1986 Date-Received: Thu, 16-Oct-86 08:42:17 EDT Sender: doc@j.cc.purdue.edu Organization: Purdue University Computing Center Lines: 1632 Approved: doc@j.cc.purdue.edu