/******************************************************************** * vt100 terminal emulator with xmodem transfer capability * * 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 * * use to abort xmodem or kermit transfers * * written by Michael Mounier * new version by Dave Wecker *******************************************************************/ /* all includes defines and globals */ #include "vt100.h" /**************************************************************/ /* here are all the global definitions that appear in vt100.h */ /**************************************************************/ char bufr[BufSize]; int fd, timeout = FALSE, ttime; int multi = FALSE, server; long bytes_xferred; char MyDir[60]; struct FileLock *MyDirLock = NULL; struct FileLock *StartLock = NULL; struct IntuitionBase *IntuitionBase; struct GfxBase *GfxBase; struct TextAttr myattr = { (STRPTR) "topaz.font", 8, 0, 0}; struct TextFont *myfont = NULL; struct NewScreen NewScreen = { 0L,0L,640L,200L,1L, /* left, top, width, height, depth */ 0,1,HIRES, /* DetailPen, BlockPen, ViewModes */ CUSTOMSCREEN,&myattr, /* Type, Font */ (UBYTE *)"VT100", /* Title */ NULL,NULL }; /* Gadgets, Bitmap */ struct NewWindow NewWindow = { 0,0L,640L,200L, /* left, top, width, height */ 0,1, /* detailpen, blockpen */ MENUPICK|CLOSEWINDOW|RAWKEY|REQCLEAR|REQSET|ACTIVEWINDOW|INACTIVEWINDOW, SMART_REFRESH|ACTIVATE|BORDERLESS|WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG, NULL,NULL, /* FirstGadget, CheckMark */ (UBYTE *)NULL, NULL, /* set screen after open screen */ NULL, /* bitmap */ 640L, 200L, 640L, 200L,/* minw, minh, maxw, maxh */ CUSTOMSCREEN /* Type */ }; struct IntuiText MyTitle = { 0,1,JAM2,26,0, /* front pen, back pen, mode, left, top */ &myattr, /* font */ (UBYTE *)VERSION, /* title */ NULL}; /* next text */ struct Screen *myscreen = NULL; /* ptr to applications screen */ struct Window *mywindow = NULL; /* ptr to applications window */ struct ViewPort *myviewport; struct RastPort *myrastport; struct IntuiMessage *NewMessage; /* msg structure for GetMsg() */ struct Preferences *Prefs; /* preferences from GetPrefs() */ /**** String requester support ******/ char InpBuf[80],UndoBuf[80],Prompt[80]; struct IntuiText donetxt = { 1,0,JAM2,0,0, /* front pen, back pen, mode, left, top */ &myattr, /* font */ (UBYTE *)"DONE", /* question to ask */ NULL}; /* next text */ struct Gadget mydonegad = { NULL,290,2,40,10,/* next,left,top,width,height */ GADGHCOMP|REQGADGET,/* flags */ RELVERIFY|ENDGADGET,/* activation */ BOOLGADGET, /* gadget type */ NULL,NULL,&donetxt, /* gad render, sel render, gad text */ 0L,NULL,2,NULL}; /* mutual exclude, special, ID, user data */ struct StringInfo mystrinfo = { (UBYTE *)InpBuf, (UBYTE *)UndoBuf, 0,80,0,0,0,0, /* initial, max, disp, undo, #chrs, dsp chrs */ 0,0,NULL,0L,NULL}; /* left,top,layer,longint,keymap */ struct Gadget mystrgad = { &mydonegad,10,12,320,10, /* next,left,top,width,height */ GADGHCOMP|REQGADGET,/* flags */ ENDGADGET,STRGADGET,/* activation, type */ NULL,NULL,NULL, /* gad render, sel render, gad text */ 0L, /* mutual exclude */ (APTR)&mystrinfo, /* special info */ 1,NULL}; /* gadget ID, user data */ struct IntuiText mystrtxt = { 0,1,JAM2,10,2, /* front pen, back pen, mode, left, top */ &myattr, /* font */ (UBYTE *)Prompt, /* question to ask */ NULL}; /* next text */ struct Requester myrequest = { NULL,200,40,340,22, /* older requester, left, top, width, height */ 0,0,&mystrgad, /* relleft reltop, gadgets */ NULL, /* border */ &mystrtxt, /* text */ NULL,1,NULL, /* flags, back fill pen, layer */ {0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0}, /* pad1 */ NULL,NULL, /* image bit map, rquest window */ {0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0} /* pad2 */ }; int numreqs = 0; /* number of outstanding requestors */ /***** menu structures *****/ struct MenuItem FileItem[FILEMAX]; struct IntuiText FileText[FILEMAX]; struct MenuItem CommItem[COMMAX]; struct IntuiText CommText[COMMAX]; struct MenuItem RSItem[RSMAX]; struct IntuiText RSText[RSMAX]; struct MenuItem ParItem[PARMAX]; struct IntuiText ParText[PARMAX]; struct MenuItem XFItem[XFMAX]; struct IntuiText XFText[XFMAX]; struct MenuItem ScriptItem[SCRIPTMAX]; struct IntuiText ScriptText[SCRIPTMAX]; struct MenuItem UtilItem[UTILMAX]; struct IntuiText UtilText[UTILMAX]; struct Menu menu[MAXMENU]; struct IOExtSer *Read_Request; char *rs_in; struct IOExtSer *Write_Request; char rs_out[2]; struct timerequest Timer; struct MsgPort *Timer_Port = NULL; struct timerequest Script_Timer; struct MsgPort *Script_Timer_Port = NULL; struct IOAudio Audio_Request; struct MsgPort *Audio_Port = NULL; UBYTE *BeepWave; UBYTE Audio_AllocMap[4] = { 1, 8, 2, 4 }; int x,y,curmode; int MINX = 0; int MAXX = 632; int MINY = 14; int MAXY = 198; int top = 14; int bot = 198; int savx = 0; int savy = 14; int savmode = 0; int nlmode = 0; int alt = 0; int savalt = 0; int a[2] = { 0, 0 }; int sa[2] = { 0, 0 }; int inesc = -1; int inctrl = -1; int private = 0; int badseq = 0; int maxcol = 79; /*************************** defaults *******************************/ int p_baud = 2400; /* baud rate */ int p_screen = 1; /* 0 = WORKBENCH, 1 = CUSTOM */ int p_wbcolors = 1; /* 0 = Custom, 1 = Workbench colors */ int p_interlace = 1; /* 0 = no interlace, 1 = interlace */ int p_depth = 1; /* number of bit planes (1 or 2) */ int p_foreground = 0x950; /* default foreground RGB color */ int p_background = 0x000; /* default background RGB color */ int p_bold = 0x900; /* default BOLD RGB color */ int p_cursor = 0x009; /* default Cursor RGB color */ int p_lines = 48; /* number of lines on the screen */ int p_mode = 1; /* 0 = image, 1 = CRLF (for kermit) */ int p_buffer = 512; /* read buffer size (>= 512 bytes) */ int p_parity = 0; /* 0=none,1=mark,2=space,3=even,4=odd */ long p_break = 750000; /* break time (in micro seconds) */ int p_volume = 64; /* beep volume (0 = DisplayBeep) */ int p_wrap = 0; /* 0 = truncate, 1 = wrap long lines */ int p_keyapp = 0; /* 0 = numeric, 1 = application keypad */ int p_curapp = 0; /* 0 = cursor, 1 = application cursor */ int p_echo = 0; /* 0 = full duplex, 1 = half duplex */ int p_bs_del = 0; /* 0 = normal, 1 = swap bs and delete */ int p_convert = 1; /* 1 = convert filenames to lower case */ char p_keyscript = 0x7E; /* function key script introducer = ~ */ char *p_f[10] = { /* function key defaults */ "\033OP","\033OQ","\033OR","\033OS", "f5","f6","f7","f8","f9","f10" }; char *p_F[10] = { /* shifted function key defaults */ "F1","F2","F3","F4","F5", "F6","F7","F8","F9","F10"}; /* for script file */ int script_on; int script_wait; int doing_init = 0; /******************************************************/ /* Main Program */ /* */ /* This is the main body of the program. */ /******************************************************/ char lookahead[80]; FILE *tranr = NULL; FILE *trans = NULL; int capture,send; char name[80]; struct MsgPort *mySerPort; main(argc,argv) int argc; char **argv; { ULONG class; unsigned int code, qual; int KeepGoing,i,la,dola,actual; char c,*ptr; ptr = InitDefaults(argc,argv); InitDevs(); InitFileItems(); InitCommItems(); InitScriptItems(); InitUtilItems(); InitMenu(); SetMenuStrip(mywindow,&menu[0]); PrintIText(mywindow->RPort,&MyTitle,0L,0L); MyDir[0] = '\000'; StartLock = (struct FileLock *)((ULONG)((struct Process *) (FindTask(NULL)))->pr_CurrentDir); MyDirLock = (struct FileLock *)DupLock(StartLock); KeepGoing = TRUE; capture = FALSE; send = FALSE; maxcol = MAXX / 8; la = 0; x = MINX ; y = MINY; curmode = FS_NORMAL; script_on = FALSE; script_wait= TRUE; SetAPen(mywindow->RPort,1L); cursorflip(); cursorflip(); emit(12); mySerPort = Read_Request->IOSer.io_Message.mn_ReplyPort; SendIO(Read_Request); /* see if we had a startup script */ if (ptr != NULL) script_start(ptr); while( KeepGoing ) { /* wait for window message or serial port message */ cursorflip(); if (script_wait) /* if script ready dont wait here */ Wait( (1L << mySerPort->mp_SigBit) | (1L << mywindow->UserPort->mp_SigBit) | (1L << Script_Timer_Port->mp_SigBit)); cursorflip(); /* do ascii file send */ if (send) { if ((c=getc(trans)) != EOF) { if (c == '\n') c = '\r'; sendchar(c); } else { fclose(trans); req("File Sent","",0); send=FALSE; } } /* see if there are any characters from the host */ if (CheckIO(Read_Request)) { WaitIO(Read_Request); c = rs_in[0] & 0x7F; doremote(c); if (script_on) chk_script(c); if (capture && c != 10) { if (c == 13) c = 10; putc(c , tranr); } Read_Request->IOSer.io_Command = SDCMD_QUERY; DoIO(Read_Request); Read_Request->IOSer.io_Command = CMD_READ; actual = (int)Read_Request->IOSer.io_Actual; if (actual > 0) { if (inesc < 0 && inctrl < 0 && a[alt] == 0 && capture == FALSE) dola = 1; else dola = 0; Read_Request->IOSer.io_Length = Read_Request->IOSer.io_Actual; DoIO(Read_Request); Read_Request->IOSer.io_Length = 1; for (i = 0; i < actual; i++) { c=rs_in[i] & 0x7f; if (script_on) chk_script(c); if (dola == 1) { if (c >= ' ' && c <= '~' && la < 80) lookahead[la++] = c; else { if (la > 0) { emitbatch(la,lookahead); la = 0; } doremote(c); dola = 0; } } else { doremote(c); if (inesc < 0 && inctrl < 0 && a[alt] == 0 && capture == FALSE) dola = 1; if (capture && c != 10) { if (c == 13) c = 10; putc(c , tranr); } } } /* dump anything left in the lookahead buffer */ if (la > 0) { emitbatch(la,lookahead); la = 0; } } SendIO(Read_Request); } while((NewMessage = (struct IntuiMessage *)GetMsg(mywindow->UserPort)) != FALSE) { class = NewMessage->Class; code = NewMessage->Code; qual = NewMessage->Qualifier; ReplyMsg( NewMessage ); switch( class ) { case REQCLEAR: numreqs = 0; break; case CLOSEWINDOW: KeepGoing = FALSE; break; case RAWKEY: c = toasc(code,qual,0); if (p_echo) doremote(c); break; case NEWSIZE: emit(12); break; case MENUPICK: handle_menupick(class,code); break; default: PrintIText(mywindow->RPort,&MyTitle,0L,0L); break; } /* end of switch (class) */ } /* end of while ( newmessage )*/ if (!script_wait || (CheckIO(&Script_Timer) && script_wait == WAIT_TIMER)) do_script_cmd(NEXTCOMMAND); } /* end while ( keepgoing ) */ /* It must be time to quit, so we have to clean * up and exit. */ cleanup("",0); } /* end of main */ /* cleanup code */ cleanup(reason, fault) char *reason; int fault; { switch(fault) { case 0: /* quitting close everything */ ClearMenuStrip( mywindow ); CloseDevice(&Audio_Request); if (MyDirLock != NULL) UnLock(MyDirLock); case 8: /* error opening audio */ DeletePort(Audio_Port); FreeMem(BeepWave,BEEPSIZE); CloseDevice(&Timer); case 7: /* error opening timer */ DeletePort(Timer_Port); CloseDevice(&Script_Timer); DeletePort(Script_Timer_Port); case 6: /* error opening write device */ DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort); FreeMem(Write_Request,(long)sizeof(*Write_Request)); CloseDevice(Read_Request); case 5: /* error opening read device */ DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort); FreeMem(Read_Request,(long)sizeof(*Read_Request)); case 4: /* error opening window */ if (myfont != NULL) CloseFont( myfont ); if (mywindow != NULL) CloseWindow( mywindow ); if (p_screen != 0) CloseScreen( myscreen ); case 3: /* error opening screen */ case 2: /* error opening graphics library */ case 1: /* error opening intuition */ default: if (*reason) puts (reason); } exit(fault); } do_capture(file) char *file; { if (capture == TRUE) { capture=FALSE; fclose(tranr); req("End File Capture","",0); } else { if (file == NULL) { name[0] = '\000'; req("Ascii Capture:",name,1); } else strcpy(name, file); if ((tranr=fopen(name,"w")) == 0) { capture=FALSE; req("Error Opening File","",0); return(FALSE); } capture=TRUE; } } do_send(file) char *file; { if (send == TRUE) { send=FALSE; fclose(trans); req("File Send Cancelled","",0); } else { if (file == NULL) { name[0] = '\000'; req("Ascii Send:",name,1); } else strcpy(name, file); if ((trans=fopen(name,"r")) == 0) { send=FALSE; req("Error Opening File","",0); return(FALSE); } send=TRUE; } } void setparams() { Read_Request->IOSer.io_Command = Write_Request->IOSer.io_Command = SDCMD_SETPARAMS; DoIO(Read_Request); DoIO(Write_Request); Read_Request->IOSer.io_Command = CMD_READ; SendIO(Read_Request); Write_Request->IOSer.io_Command = CMD_WRITE; } void hangup () { AbortIO(Read_Request); CloseDevice (Read_Request); Timer.tr_time.tv_secs=0L; Timer.tr_time.tv_micro=750000L; DoIO((char *) &Timer.tr_node); OpenDevice (SERIALNAME,NULL,Read_Request,NULL); setparams(); } void redocomm() { ClearMenuStrip( mywindow ); /* Remove old menu */ InitCommItems(); /* Re-do comm menu */ SetMenuStrip(mywindow,&menu[0]); /* Re-display the menu */ } void setserbaud(baud, redomenu) int baud; LONG redomenu; { AbortIO(Read_Request); Write_Request->io_Baud = Read_Request->io_Baud = baud; setparams(); p_baud = baud; if (redomenu) redocomm(); } void redoutil() { ClearMenuStrip(mywindow); InitUtilItems(); SetMenuStrip(mywindow,&menu[0]); } void handle_menupick(class, code) ULONG class; unsigned int code; { unsigned int menunum, itemnum, subnum; if (code == MENUNULL) return; menunum = MENUNUM( code ); itemnum = ITEMNUM( code ); subnum = SUBNUM( code ); switch( menunum ) { case 0: switch( itemnum ) { case 0: do_capture(NULL); break; case 1: do_send(NULL); break; case 2: if (p_parity > 0) { req("Parity setting prevents this","",0); break; } name[0] = '\000'; req("Xmodem Receive:",name,1); multi_xfer(name,XMODEM_Read_File,0); break; case 3: if (p_parity > 0) { req("Parity setting prevents this","",0); break; } name[0] = '\000'; req("Xmodem Send:",name,1); multi_xfer(name,XMODEM_Send_File,1); break; case 4: server = TRUE; name[0] = '\000'; req("Kermit GET remote file(s):",name,1); multi_xfer(name,dokreceive,0); break; case 5: multi_xfer("",dokreceive,0); break; case 6: server = TRUE; name[0] = '\000'; req("Kermit Send local name:",name,1); multi_xfer(name,doksend,1); break; case 7: saybye(); break; } break; case 1: switch( itemnum ) { case 0: switch( subnum ) { case 0: setserbaud(300, FALSE); break; case 1: setserbaud(1200, FALSE); break; case 2: setserbaud(2400, FALSE); break; case 3: setserbaud(4800, FALSE); break; case 4: setserbaud(9600, FALSE); break; } break; case 1: /* Set Parity */ p_parity = subnum; break; case 2: /* set transfer mode */ if (subnum < 2) p_mode = subnum; else { if (p_convert) p_convert = 0; else p_convert = 1; redocomm(); } break; } break; case 2: if (!itemnum && !script_on) { name[0] = '\000'; req("Script file name:",name,1); script_start(name); } if (itemnum && script_on) exit_script(); break; case 3: switch( itemnum ) { case 0: sendbreak(); break; case 1: hangup(); break; case 2: strcpy(name,MyDir); req("Directory:",name,1); set_dir(name); break; case 3: top = MINY; bot = MAXY; savx = MINX; savy = MINY; curmode = FS_NORMAL; inesc = -1; a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0; redoutil(); emit(12); break; case 4: if (p_echo) p_echo = 0; else p_echo = 1; redoutil(); break; case 5: if (p_wrap) p_wrap = 0; else p_wrap = 1; redoutil(); break; case 6: if (p_keyapp) p_keyapp = 0; else p_keyapp = 1; redoutil(); break; case 7: if (p_curapp) p_curapp = 0; else p_curapp = 1; redoutil(); break; case 8: swap_bs_del(); redoutil(); break; } break; } /* end of switch ( menunum ) */ }