home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
100-199
/
ff114.lzh
/
Vt100
/
vt100.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-11-22
|
20KB
|
785 lines
/********************************************************************
* vt100 terminal emulator with xmodem transfer capability
*
* v2.7 870825 ACS - Provide handling of the msgs from the
* info/status window.
* 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 <esc> 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];
#ifdef BUGFIXES
BPTR StartLock = 0;
#else
struct FileLock *MyDirLock = NULL;
struct FileLock *StartLock = NULL;
#endif
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct TextAttr myattr = {
(STRPTR) "topaz.font",
8,
0,
0};
struct TextFont *myfont = NULL;
struct NewScreen NewScreen = {
0,0,640,200,1, /* 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,0,640,200, /* left, top, width, height */
0,1, /* detailpen, blockpen */
MENUPICK|CLOSEWINDOW|RAWKEY|ACTIVEWINDOW|INACTIVEWINDOW,
SMART_REFRESH|ACTIVATE|BORDERLESS|WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG,
NULL,NULL, /* FirstGadget, CheckMark */
(UBYTE *)NULL,
NULL, /* set screen after open screen */
NULL, /* bitmap */
640, 200, 640, 200, /* minw, minh, maxw, maxh */
CUSTOMSCREEN /* Type */
};
struct NewWindow NewReqWindow = {
10, 15, ((54*8)+4+18), ((4*8)+11+2), /* left, top, width, height */
0, 1, /* detailpen, blockpen */
/* IDCMP Flags... */
CLOSEWINDOW | ACTIVEWINDOW | REQCLEAR | REQSET | NEWSIZE,
/* Flags... */
SMART_REFRESH | NOCAREREFRESH | ACTIVATE | WINDOWSIZING | SIZEBRIGHT |
WINDOWCLOSE | WINDOWDEPTH | WINDOWDRAG,
NULL, /* First gadget */
NULL, /* CheckMark */
(UBYTE *)"VT100 Info & Xfer Status", /* Title */
NULL, /* set screen after open screen */
NULL, /* bitmap */
((5*8)+4+18), ((1*8)+11+2), 640, 200, /* 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 Window *reqwindow = NULL; /* ptr to requester's 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 = {
&mystrgad,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 = {
NULL,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,0,10,340,22, /* older requester, left, top, width, height */
0,0,&mydonegad, /* 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 */
int reqwinup = 0; /* Requester window is NOT displayed */
extern int reqmaxx, reqmaxy, reqmaxlen; /* Defined in window.c */
extern void ReqNewSize(); /* New req window size -- window.c */
extern void KillReq(); /* Kill requester window in window.c */
/***** 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 = 1200; /* baud rate */
int p_screen = 0; /* 0 = WORKBENCH, 1 = CUSTOM */
int p_wbcolors = 1; /* 0 = Custom, 1 = Workbench colors */
int p_interlace = 0; /* 0 = no interlace, 1 = interlace */
int p_depth = 2; /* number of bit planes (1 or 2) */
int p_foreground = 0x840; /* default foreground RGB color */
int p_background = 0x000; /* default background RGB color */
int p_bold = 0x000; /* default BOLD RGB color */
int p_cursor = 0x00d; /* default Cursor RGB color */
int p_lines = 24; /* number of lines on the screen */
int p_mode = 0; /* 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 = 1; /* 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 = 0; /* 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, waitmask;
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';
#ifdef BUGFIXES
StartLock = ((struct Process *) FindTask(NULL))->pr_CurrentDir;
CurrentDir(DupLock(StartLock));
#else
StartLock = (struct FileLock *)((ULONG)((struct Process *)
(FindTask(NULL)))->pr_CurrentDir);
MyDirLock = (struct FileLock *)DupLock(StartLock);
#endif
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);
reqwinup = 0;
while( KeepGoing )
{
/* wait for window message or serial port message */
cursorflip();
if(reqwinup)
waitmask = (1L << mySerPort->mp_SigBit) |
(1L << mywindow->UserPort->mp_SigBit) |
(1L << Script_Timer_Port->mp_SigBit) |
(1L << reqwindow->UserPort->mp_SigBit);
else
waitmask = (1L << mySerPort->mp_SigBit) |
(1L << mywindow->UserPort->mp_SigBit) |
(1L << Script_Timer_Port->mp_SigBit);
if (script_wait) /* if script ready dont wait here */
Wait(waitmask);
cursorflip();
/* do ascii file send */
if (send)
{
if ((c=getc(trans)) != EOF) {
if (c == '\n') c = '\r';
sendchar(c);
}
else {
fclose(trans);
InfoMsg1Line("File Sent");
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 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);
while( reqwinup &&
((NewMessage = (struct IntuiMessage *)
GetMsg(reqwindow->UserPort)) != FALSE)
) {
class = NewMessage->Class;
ReplyMsg( NewMessage );
switch( class ) {
case REQCLEAR:
numreqs = 0;
break;
case CLOSEWINDOW:
KillReq(); /* Kills requester window, set reqwinup = 0 */
break;
case NEWSIZE:
ReqNewSize(reqwindow->Height, reqwindow->Width);
break;
} /* end of switch (class) */
} /* end while */
} /* 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 */
KillReq(); /* Kill the requester and its window */
ClearMenuStrip( mywindow );
CloseDevice(&Audio_Request);
#ifdef BUGFIXES
UnLock(CurrentDir(StartLock)); /* back to original directory */
#else
if (MyDirLock != NULL) UnLock(MyDirLock);
#endif
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);
InfoMsg1Line("End File Capture");
}
else
{
if (file == NULL) {
name[0] = '\000';
req("Ascii Capture:",name,1);
}
else strcpy(name, file);
if ((tranr=fopen(name,"w")) == 0) {
capture=FALSE;
InfoMsg1Line("Error Opening File");
return(FALSE);
}
capture=TRUE;
}
}
do_send(file)
char *file;
{
if (send == TRUE)
{
send=FALSE;
fclose(trans);
InfoMsg1Line("File Send Cancelled");
}
else
{
if (file == NULL) {
name[0] = '\000';
req("Ascii Send:",name,1);
}
else strcpy(name, file);
if ((trans=fopen(name,"r")) == 0) {
send=FALSE;
InfoMsg1Line("Error Opening File");
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) {
InfoMsg1Line("Parity setting prevents this");
break;
}
name[0] = '\000';
req("Xmodem Receive:",name,1);
multi_xfer(name,XMODEM_Read_File,0);
break;
case 3:
if (p_parity > 0) {
InfoMsg1Line("Parity setting prevents this");
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 ) */
}