ng@s.cc.purdue.edu.UUCP (10/02/87)
# 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 # Xshar: Extended Shell Archiver. # This is part 2 out of 3. # This archive created: Fri Oct 2 13:14:34 1987 # By: Craig Norborg (Purdue University Computing Center) # Run the following text with /bin/sh to create: # init.c # kermit.c # remote.c # vt100.h cat << \SHAR_EOF > init.c /*************************************************************** * vt100 - terminal emulator - initialization * * v2.65 NG - added tek4014 emulation * v2.6 870227 DBW - bug fixes for all the stuff in v2.5 * v2.5 870214 DBW - more additions (see readme file) * v2.4 861214 DBW - lots of fixes/additions (see readme file) * v2.3 861101 DBW - minor bug fixes * 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 * ***************************************************************/ #include "vt100.h" char line[256]; static char cmds[] = "<>GRSBLHX+-I7.DWKCZ"; /* changed a bit for tek */ char *InitDefaults(argc,argv) int argc; char **argv; { FILE *fd; char *p; int l; doing_init = 1; /* make sure we only allow INIT script commands */ 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) { line[strlen(line)-1] = '\000'; p = next_wrd(&line[0],&l); if (*p) { *p |= ' '; if (p[1]) p[1] |= ' '; if (*p == '#') continue; if (*p == 'e' && p[1] == 'x') break; exe_cmd(p,l); } } fclose(fd); } doing_init = 0; /* 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 = 0L; 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)+16); if (p_interlace == 1) NewScreen.TopEdge = (long)(400 - NewScreen.Height); else NewScreen.TopEdge = (long)(208 - NewScreen.Height); } else { p_depth = 2L; NewWindow.TopEdge = 0L; NewWindow.Screen = NULL; NewWindow.Type = WBENCHSCREEN; } /* see if we exit with a startup script */ if (*p == 'e') { p = next_wrd(p+l+1,&l); if (*p) return(p); } 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); if ((myfont = (struct TextFont *)OpenFont(&myattr)) == NULL) cleanup("can't open font",4); myviewport = (struct ViewPort *)ViewPortAddress(mywindow); myrastport = (struct RastPort *)mywindow->RPort; SetFont(myrastport,myfont); if (p_depth > 1) myrequest.BackFill = 2; if (p_screen != 0 && p_wbcolors == 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(0L,0L); 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(0L,0L); 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",0L); Script_Timer_Port = CreatePort("Timer Port",0L); 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",0L); 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,nplus1; /* initialize each menu item and IntuiText with loop */ for( n=0; n<FILEMAX; n++ ) { nplus1 = n + 1; FileItem[n].NextItem = &FileItem[nplus1]; FileItem[n].LeftEdge = 0; FileItem[n].TopEdge = 10 * n; FileItem[n].Width = 120+40; FileItem[n].Height = 10; FileItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP; FileItem[n].MutualExclude = 0; FileItem[n].ItemFill = (APTR)&FileText[n]; FileItem[n].SelectFill = NULL; if (n >= 2 && n <= 7) { FileItem[n].Command = cmds[n-2]; FileItem[n].Flags |= COMMSEQ; } else 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,nplus1; /* initialize each menu item and IntuiText with loop */ for( n=0; n<COMMAX; n++ ) { nplus1 = n + 1; CommItem[n].NextItem = &CommItem[nplus1]; 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++ ) { nplus1 = n + 1; RSItem[n].NextItem = &RSItem[nplus1]; RSItem[n].LeftEdge = 75; RSItem[n].TopEdge = 10 * n; RSItem[n].Width = 56+40; 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; if (n >= 1 && n <= 2) { RSItem[n].Command = cmds[n+5]; RSItem[n].Flags |= COMMSEQ; } else 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++ ) { nplus1 = n + 1; ParItem[n].NextItem = &ParItem[nplus1]; ParItem[n].LeftEdge = 75; ParItem[n].TopEdge = 10 * n; ParItem[n].Width = 56+40; 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; if (n == 0 || n == 3 || n == 4) { ParItem[n].Command = cmds[(n==0)?8:n+6]; ParItem[n].Flags |= COMMSEQ; } else 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++ ) { nplus1 = n + 1; XFItem[n].NextItem = &XFItem[nplus1]; XFItem[n].LeftEdge = 75; XFItem[n].TopEdge = 10 * n; XFItem[n].Width = 80+40; XFItem[n].Height = 10; XFItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT; if (n < 2) XFItem[n].MutualExclude = 2 - n; else XFItem[n].MutualExclude = 0; XFItem[n].ItemFill = (APTR)&XFText[n]; XFItem[n].SelectFill = NULL; if (n < 2) { XFItem[n].Command = cmds[n+11]; XFItem[n].Flags |= COMMSEQ; } else 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; if (p_convert) XFItem[2].Flags |= CHECKED; /* initialize text for specific menu items */ XFText[0].IText = (UBYTE *)" Image "; XFText[1].IText = (UBYTE *)" Text "; XFText[2].IText = (UBYTE *)" Convert"; } /* end of InitCommItems() */ /*****************************************************************/ /* The following function initializes the structure arrays */ /* needed to provide the Script menu topic. */ /*****************************************************************/ void InitScriptItems() { int n,nplus1; /* initialize each menu item and IntuiText with loop */ for( n=0; n<SCRIPTMAX; n++ ) { nplus1 = n + 1; ScriptItem[n].NextItem = &ScriptItem[nplus1]; 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,nplus1; /* initialize each menu item and IntuiText with loop */ for( n=0; n<UTILMAX; n++ ) { nplus1 = n + 1; UtilItem[n].NextItem = &UtilItem[nplus1]; UtilItem[n].LeftEdge = 0; UtilItem[n].TopEdge = 10 * n; UtilItem[n].Width = 88+40; UtilItem[n].Height = 10; UtilItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP; if (n > 3) UtilItem[n].Flags |= CHECKIT; UtilItem[n].MutualExclude = 0; UtilItem[n].ItemFill = (APTR)&UtilText[n]; UtilItem[n].SelectFill = NULL; if (n == 0 || n == 2) { UtilItem[n].Command = cmds[(n==0)?13:14]; UtilItem[n].Flags |= COMMSEQ; } else if (n >= 5) { UtilItem[n].Command = cmds[n+10]; UtilItem[n].Flags |= COMMSEQ; } else 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; } UtilItem[UTILMAX-1].NextItem = NULL; if (p_echo) UtilItem[4].Flags |= CHECKED; if (p_wrap) UtilItem[5].Flags |= CHECKED; if (p_keyapp == 0) UtilItem[6].Flags |= CHECKED; if (p_curapp) UtilItem[7].Flags |= CHECKED; if (p_bs_del) UtilItem[8].Flags |= CHECKED; /* initialize text for specific menu items */ UtilText[0].IText = (UBYTE *)"Send Break"; UtilText[1].IText = (UBYTE *)"Hang Up"; UtilText[2].IText = (UBYTE *)"Change Dir"; UtilText[3].IText = (UBYTE *)"Clear Scrn"; UtilText[4].IText = (UBYTE *)" Echo"; UtilText[5].IText = (UBYTE *)" Wrap"; UtilText[6].IText = (UBYTE *)" Num Key"; UtilText[7].IText = (UBYTE *)" App Cur"; UtilText[8].IText = (UBYTE *)" BS<->DEL"; } /****************************************************************/ /* The following function inits the Menu structure array with */ /* appropriate values for our simple menu. 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 = &menu[4]; /* link to tek menu items */ 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.6 870227 DBW - bug fixes for all the stuff in v2.5 * v2.5 870214 DBW - more additions (see readme file) * v2.4 861214 DBW - lots of fixes/additions (see readme file) * v2.3 861101 DBW - minor bug fixes * 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, err recovry,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 * *************************************************************/ #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 MYEBQ '&' /* 8th bit prefix character */ #define MYPAD 0 /* Number of padding charss 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], sl1[] = "FILE PKT NUM RETR BYTES", sl2[] = "%-15s %c %4d %2d %6ld %5s", sl3[50], mainmode[10]; FILE *fp; /* file for send/receive */ char * getfname(name) /* returns ptr to start of file name from 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); } p = file; while(*p && *p != '*' && *p != '?') p++; if (*p) { wild = TRUE; list = expand(file, &amount); if (list == NULL) req("KERMIT","No wild card match",0); } 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; if ((fp = fopen(p,"r")) == NULL) { req("KERMIT: can't open send file:",p,0); continue; } strcpy(mainmode,"SEND"); ClearBuffer(); if (sendsw()) dostats(' ',"DONE"); fclose(fp); } 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); if (server) strcpy(mainmode,"GET"); else strcpy(mainmode,"RECV"); tp = retry = n = numtry = notfirst = 0; totbytes = 0L; ClearBuffer(); retval = recsw(); 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': dostats('E',"ERROR"); /* so print the err and abort */ print_host_err(ackpkt); return(FALSE); case 'A': if (timeout == USERABORT) { timeout = GOODREAD; n = (n+1)%64; sendabort = 1; dostats('A',"ABORT"); strcpy(msgpkt, "D"); state = 'Z'; break; } if (timeout == TIMEOUT) dostats('A',"TMOUT"); else { /* protocol error dectected by us */ dostats('A',"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() { dostats(' ',"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': /* 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. */ if (timeout == USERABORT){ /* send an error packet back */ dostats('A',"ABORT"); spack('E',n,12,"User aborted"); } else if (timeout == TIMEOUT) { /* we timed out waiting */ /* will we need to spack here ?*/ dostats('A',"TMOUT"); } /* must be 'E' from host or we detected a protocol error */ else dostats('A',"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 (p_convert) { char *p; p = &filnam[0]; while (*p) { *p = tolower(*p); p++; } } if (notfirst) { totbytes = 0L; dostats('F',"RECV"); } /* is the first file so emit actual file name from host */ else { notfirst++; } if ((fp = fopen(filnam,"w")) == NULL) { req("KERMIT: Unable to create file:",filnam,0); strcpy(msgpkt,"VT100 - Kermit - cannot create file: "); strcat(msgpkt,filnam); spack('E',n,strlen(msgpkt),msgpkt); /* let host know */ dostats('E',"ERROR"); return ('\0'); /* abort everything */ } spack('Y',n,0,0); oldtry = numtry; numtry = 0; retry--; n = (n+1)%64; return('D'); /* totaly done server sending no more */ case 'B': 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--; dostats('Z',"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,mainmode); 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,mainmode); 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) { req("KERMIT:","Too may retries for packet",0); strcpy(msgpkt,"VT100 KERMIT: Too many retries for packet"); } else { req("KERMIT:","Protocol Error",0); strcpy(msgpkt,"VT100 KERMIT: Protocol Error"); } spack('E',n,strlen(msgpkt)); } print_host_err(msg) char *msg; { req("KERMIT Host Error:",msg,0); } dostats(type,stat) char type,*stat; { if (type == 'Y' || type == 'N' || type == 'G') return; sprintf(sl3,sl2,filnam,type,n+(tp*64),retry-1,(long)totbytes,stat); if (n==63) tp++; req(sl1,sl3,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 cat << \SHAR_EOF > remote.c /**************************************************** * vt100 emulator - remote character interpretation * * v2.65 NG - added tek4014 emulation * v2.6 870227 DBW - bug fixes for all the stuff in v2.5 * v2.5 870214 DBW - more additions (see readme file) * v2.4 861214 DBW - lots of fixes/additions (see readme file) * v2.3 861101 DBW - minor bug fixes * v2.2 861012 DBW - more of the same * v2.1 860915 DBW - new features (see README) * 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 * ****************************************************/ #include "vt100.h" static int p[10]; static int numpar; static char escseq[40]; /************************************************ * function to handle remote characters *************************************************/ void doremote(c) char c; { if (Tek(c)) /* added for tek emulation */ return; if (c == 24) { inesc = 0; inctrl = 0; return; } if (c == 27 || (inesc >= 0 && c >= ' ')) { doesc(c); return; } if (inctrl >= 0 && c >= ' ') { 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 */ /* Collect intermediates */ if (c < '0') {escseq[inesc++] = c; return; } /* 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; curmode = FS_NORMAL; p_keyapp = 0; p_curapp = 0; inesc = -1; a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0; redoutil(); emit(12); 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; case '=': /* set keypad application mode */ p_keyapp = 1; redoutil(); return; case '>': /* reset application mode */ p_keyapp = 0; redoutil(); return; case 'Z': sendchar(27); sendstring("[?1;7c"); 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 */ /* Only allowed BEFORE parameters */ if (inctrl == 0) private = c; 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 most private sequences right now, so just punt them */ if ((private != 0 && private != '?') || badseq != 0) return; if (private == '?' && escseq[0] != 'h' && escseq[0] != 'l') 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 'L': /* ANSI insert line */ case 'M': /* ANSI delete line */ if (p[0] <= 0) p[0] = 1; ScrollRaster(mywindow->RPort,0L, (long)((escseq[0] == 'M' ? 8L : -8L) * p[0]), (long)MINX,(long)y-6,(long)(MAXX+7),(long)bot+1); 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 = FS_NORMAL; break; case 1: curmode |= FSF_BOLD; break; case 4: curmode |= FSF_UNDERLINED; break; case 5: curmode |= FSF_ITALIC; break; default: curmode |= FSF_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 (private == 0 && p[0] == 20) nlmode = 1; else if (private == '?') { if (p[0] == 7) p_wrap = 1; else if (p[0] == 1) p_curapp = 1; redoutil(); } return; case 'l': /* Reset parameter */ if (private == 0 && p[0] == 20) nlmode = 0; else if (private == '?') { if (p[0] == 7) p_wrap = 0; else if (p[0] == 1) p_curapp = 0; redoutil(); } 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;7c"); 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 'a': doline(0,-6,8,1); break; case 'j': case 'm': case 'v': doline(4,-6,4,-2); if (c=='j') doline(0,-2,4,-2); else if (c=='m') doline(4,-2,8,-2); else doline(0,-2,8,-2); break; case 'k': case 'l': case 'w': doline(4,-2,4,1); if (c=='k') doline(0,-2,4,-2); else if (c=='l') doline(4,-2,8,-2); else doline(0,-2,8,-2); break; case 'n': case 'q': doline(0,-2,8,-2); if (c=='n') doline(4,-6,4,2); break; case 't': case 'u': case 'x': doline(4,-6,4,1); if (c=='t') doline(4,-2,8,-2); else if (c=='u') doline(0,-2,4,-2); 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 > vt100.h /********************************************************************* * a terminal program that has ascii and xmodem transfer capability * * v2.65 NG - added tek4014 emulation * v2.6 870227 DBW - bug fixes for all the stuff in v2.5 * v2.5 870214 DBW - more additions (see readme file) * v2.4 861214 DBW - lots of fixes/additions (see readme file) * v2.3 861101 DBW - minor bug fixes * v2.2 861012 DBW - more of the same * v2.1 860915 DBW - new features (see README) * 860823 DBW - Integrated and rewrote lots of code * v2.0 860809 DBW - Major release.. LOTS of changes * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes * v1.0 860712 DBW - First version released * * use esc to abort xmodem transfer * * written by Michael Mounier * new version by Dave Wecker 860621 ********************************************************************/ /********* major version (used for title of terminal window) *********/ #define VERSION "VT100/TEK4014 (V2.65)" /*********** ######## define the compiler type here ######## ********/ #define LATTICE 0 #define MANX 1 #include "tek.h" /* added for tek emulation */ /* compiler directives to fetch the necessary header files */ #include <exec/types.h> #include <exec/exec.h> #include <intuition/intuition.h> #include <intuition/intuitionbase.h> #include <graphics/gfxbase.h> #include <graphics/gfx.h> #include <graphics/text.h> #include <graphics/regions.h> #include <graphics/copper.h> #include <graphics/gels.h> #include <devices/serial.h> #include <devices/keymap.h> #include <devices/inputevent.h> #include <devices/audio.h> #include <hardware/blit.h> /* for Lattice you may have to change these with: */ #include <stdio.h> /* #include <lattice/stdio.h> and */ #include <ctype.h> /* #include <lattice/ctype.h> */ #include <libraries/dos.h> #include <libraries/dosextens.h> #include <devices/timer.h> #if MANX #include <functions.h> #undef NULL #define NULL ((void *)0) #endif #define INTUITION_REV 1L #define GRAPHICS_REV 1L /* things for xmodem send and recieve */ #define GOODREAD 0 #define TIMEOUT 1 #define USERABORT 2 #define SECSIZ 0x80 #define TTIME_SHORT 5 /* number of seconds for short timeout */ #define TTIME_LONG 50 /* number of seconds for long timeout */ #define TTIME_KERMIT 10 /* number of seconds for KERMIT timeout*/ #define BufSize 0x200 /* Text buffer for XMODEM */ #define ERRORMAX 10 /* Max errors before abort */ #define RETRYMAX 10 /* Maximum retrys before abort */ #define SOH 1 /* Start of sector char */ #define EOT 4 /* end of transmission char */ #define ACK 6 /* acknowledge sector transmission */ #define NAK 21 /* error in transmission detected */ #define FILEMAX 8 /* number of file menu items */ #define COMMAX 3 /* number of communication sub menus */ #define RSMAX 5 /* speed menu items */ #define PARMAX 5 /* parity items */ #define XFMAX 3 /* transfer mode items */ #define SCRIPTMAX 2 /* script menu items */ #define UTILMAX 9 /* utility menu */ #define MAXMENU 6 /* total number of menu entries */ /* change to 6 (add two more entries for tek) */ #define FSF_REVERSE 256 /* fake font style to flag INVERSVID mode */ /* things for script support */ #define GOTOLABEL 1 #define NEXTCOMMAND 0 #define ONCOMMAND 2 #define WAIT_TIMER 2 #define WAIT_STRING 1 /* things for 'beep' support */ #define BEEPSIZE 10L #define BEEPFREQ 1000L #define COLORCLOCK 3579545L extern struct MsgPort *CreatePort(); extern char *malloc(),*strcpy(),*fgets(); extern long ftell(); extern int multi; /* flags multi file transfers */ extern int server; extern char bufr[BufSize]; extern int fd, timeout, ttime; extern long bytes_xferred; extern char MyDir[60]; extern struct FileLock *MyDirLock; extern struct FileLock *StartLock; extern struct IntuitionBase *IntuitionBase; extern struct GfxBase *GfxBase; extern struct TextAttr myattr; extern struct TextFont *myfont; extern struct NewScreen NewScreen; extern struct NewWindow NewWindow; extern struct Screen *myscreen; extern struct Window *mywindow; extern struct ViewPort *myviewport; extern struct RastPort *myrastport; extern struct IntuiMessage *NewMessage; extern struct Preferences *Prefs; extern char InpBuf[80],UndoBuf[80],Prompt[80]; extern struct StringInfo mystrinfo; extern struct Gadget mystrgad; extern struct IntuiText donetxt; extern struct Gadget mydonegad; extern struct IntuiText mystrtxt; extern struct Requester myrequest; extern int numreqs; extern struct MenuItem FileItem[FILEMAX]; extern struct IntuiText FileText[FILEMAX]; extern struct MenuItem CommItem[COMMAX]; extern struct IntuiText CommText[COMMAX]; extern struct MenuItem RSItem[RSMAX]; extern struct IntuiText RSText[RSMAX]; extern struct MenuItem ParItem[PARMAX]; extern struct IntuiText ParText[PARMAX]; extern struct MenuItem XFItem[XFMAX]; extern struct IntuiText XFText[XFMAX]; extern struct MenuItem ScriptItem[SCRIPTMAX]; extern struct IntuiText ScriptText[SCRIPTMAX]; extern struct MenuItem UtilItem[UTILMAX]; extern struct IntuiText UtilText[UTILMAX]; extern struct Menu menu[MAXMENU]; extern struct timerequest Timer, Script_Timer; extern struct MsgPort *Timer_Port, *Script_Timer_Port; extern struct IOExtSer *Read_Request; extern char *rs_in; extern struct IOExtSer *Write_Request; extern char rs_out[2]; extern int x,y,curmode; extern int MINX,MAXX,MINY,MAXY,top,bot,savx,savy; extern int savmode,nlmode,alt,savalt,a[2],sa[2]; extern int inesc,inctrl,private,badseq,maxcol; extern struct IOAudio Audio_Request; extern struct MsgPort *Audio_Port; extern UBYTE *BeepWave; extern UBYTE Audio_AllocMap[4]; extern int p_baud,p_screen,p_interlace,p_depth,p_buffer,p_wbcolors; extern int p_foreground,p_background,p_bold,p_cursor,p_lines,p_mode; extern int p_parity,p_volume,p_wrap,p_echo,p_keyapp,p_curapp,p_bs_del; extern int p_convert; extern char p_keyscript; extern long p_break; extern char *p_f[10],*p_F[10]; extern int script_on; extern int script_wait; extern int doing_init; /* vt100.c */ extern int do_send(),do_capture(),cleanup(); extern void setserpar(), setserbaud(), setparams(), redoutil(), redocomm(), handle_menupick(); /* init.c */ extern void InitDevs(),InitFileItems(),InitCommItems(), InitScriptItems(),InitUtilItems(),InitMenu(); extern char *InitDefaults(); /* window.c */ extern void swap_bs_del(),req(),emits(),emit(),emitbatch(),cursorflip(); extern int toasc(); /* xmodem.c */ extern void sendchar(),sendstring(),sendbreak(),multi_xfer(), No_XON(),Do_XON(); extern int readchar(),XMODEM_Read_File(),XMODEM_Send_File(); /* remote.c */ extern void doremote(),doindex(),doctrl(),doesc(),doerase(); /* kermit.c */ extern int doksend(), dokreceive(), saybye(); extern void encode(), decode(), rpar(), spar(); /* script.c */ extern int script_start(), chk_script(), exit_script(), do_script_cmd(); extern char *next_wrd(), *tostring(); /* init commands */ extern void cmd_bkg(), cmd_bold(), cmd_buf(), cmd_cursor(), cmd_depth(), cmd_fore(), cmd_inter(), cmd_lines(), cmd_screen(), cmd_volume(), cmd_wb(), cmd_null(), /* script commands */ cmd_as(), cmd_beep(), cmd_cap(), cmd_cd(), cmd_delay(), cmd_goto(), cmd_goto(), cmd_kb(), cmd_kg(), cmd_kr(), cmd_ks(), cmd_on(), cmd_sb(), cmd_send(), cmd_wait(), cmd_xr(), cmd_xs(), /* init and script commands */ cmd_appcur(), cmd_baud(), cmd_bt(), cmd_conv(), cmd_echo(), cmd_exit(), cmd_fnc(), cmd_key(), cmd_mode(), cmd_numkey(), cmd_parity(), cmd_swap(), cmd_wrap(); /* expand.c */ extern char **expand(); extern int set_dir(), free_expand(); SHAR_EOF