home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff330.lzh / Vt100 / Src.lzh / Src / vt100.c < prev    next >
C/C++ Source or Header  |  1990-03-01  |  32KB  |  1,116 lines

  1. static char rcsid[] = "$RCSfile: vt100.c,v $ $Revision: 1.8 $";
  2. static char hrcsid[] = HRCSID;
  3.  
  4. /********************************************************************
  5.  *  vt100 terminal emulator with xmodem transfer capability
  6.  *        :ts=8
  7.  *
  8.  * $Log:    vt100.c,v $
  9.  * Revision 1.8  90/02/12  20:25:05  acs
  10.  * Include reference to HRCSID defined in vt100.h.
  11.  * 
  12.  * Revision 1.7  90/01/01  21:03:53  acs
  13.  * 1) do_capture() shouldn't strcpy() to XferredFileName.
  14.  * 2) do_capture() should use name instead of XferredFileName.
  15.  * 3) do_send() would only prompt for filename once.
  16.  * 
  17.  * Revision 1.6  89/12/18  20:52:38  acs
  18.  * Strip parity from inbound serial data if p_strip or p_parity is set.
  19.  * Used to be that this module would only strip parity if p_parity was
  20.  * set; it was up to subordinate routines to strip parity if p_strip
  21.  * was set (notably, emit() and doremote()).
  22.  * 
  23.  * Revision 1.5  89/12/13  22:02:17  acs
  24.  * p_bs_del is now based on flag set in selected menu item, too.
  25.  * 
  26.  * Revision 1.4  89/12/12  22:18:02  acs
  27.  * 1) Give selected menu item to handle_menupick().
  28.  * 2) Base new values of p_* on flags set in selected menu item.
  29.  * 
  30.  * Revision 1.3  89/11/06  22:07:46  acs
  31.  * 1) Used 8 instead of Xsize and Ysize and 6 instead of BaseLine in mouse
  32.  *    location calculation.  Thanks to Evan Harris (evan@cs.mu.oz.au).
  33.  * 2) Mouse location routine would call sendchar() with 2 parameters
  34.  *    (thanks again Evan!).
  35.  * 3) Support new STRIP command and menu option (p_strip).
  36.  * 
  37.  * 
  38.  * Revision 1.2  89/11/01  20:37:10  acs
  39.  * 1) Don't poll serial port while executing a script unless we're waiting
  40.  *    or delaying.
  41.  * 2) ASCII Capture would only prompt for filename once.
  42.  * 3) Add RCS id and change log.
  43.  * 
  44.  *    v2.9 ACS - Only strip parity if parity is enabled; handle external xfer
  45.  *           items in handle_menupick(); new p_interlace value (2).
  46.  *    v2.8a 880331 ACS - Don't ReplyMsg too soon.
  47.  *    v2.7 870825 ACS - Provide handling of the msgs from the
  48.  *              info/status window.
  49.  *    v2.6 870227 DBW - bug fixes for all the stuff in v2.5
  50.  *    v2.5 870214 DBW - more additions (see readme file)
  51.  *    v2.4 861214 DBW - lots of fixes/additions (see readme file)
  52.  *    v2.3 861101 DBW - minor bug fixes
  53.  *    v2.2 861012 DBW - more of the same
  54.  *    v2.1 860915 DBW - new features (see README)
  55.  *         860901 ACS - Added Parity and Word Length and support code
  56.  *         860823 DBW - Integrated and rewrote lots of code
  57.  *    v2.0 860809 DBW - Major rewrite
  58.  *    v1.1 860720 DBW    - Switches, 80 cols, colors, bug fixes
  59.  *    v1.0 860712 DBW    - First version released
  60.  *
  61.  *  use <esc> to abort xmodem or kermit transfers
  62.  *
  63.  *  written by Michael Mounier
  64.  *  new version by Dave Wecker
  65.  *******************************************************************/
  66.  
  67. /*  all includes defines and globals */
  68. #include "vt100.h"
  69.  
  70. APTR OrigWindowPtr;    /* Used by init.c when opening a new screen */
  71.  
  72. /**************************************************************/
  73. /* here are all the global definitions that appear in vt100.h */
  74. /**************************************************************/
  75.  
  76. int    CmdFromRexx = 0;
  77.  
  78. #if AREXX
  79. struct MsgPort *FromRexxPort = NULL;
  80. char    *HostName;
  81. extern int    RexxReplies;
  82. #endif /* AREXX */
  83.  
  84. char    *bufr;
  85. int     fd, timeout = FALSE, ttime;
  86. int    multi = FALSE, server;
  87.  
  88. long    bytes_xferred;
  89. char    MyDir[60];
  90. BPTR    StartLock = 0;
  91. struct    IntuitionBase *IntuitionBase;
  92. struct    GfxBase *GfxBase;
  93. struct    Library *DiskfontBase;
  94.  
  95. #if AREXX
  96. struct    RxsLib  *RexxSysBase;
  97. #endif    /* AREXX */
  98.  
  99. struct    TextAttr myattr = {
  100.     (STRPTR)(&(myfontname[0])),
  101.     8,
  102.     0,
  103.     0};
  104. struct    TextFont *myfont = NULL;
  105. struct NewScreen NewScreen = {
  106.    0,0,640,200,1,        /* left, top, width, height, depth */
  107.    0,1,HIRES,            /* DetailPen, BlockPen, ViewModes */
  108.    CUSTOMSCREEN,&myattr,    /* Type, Font */
  109.    (UBYTE *)"VT100",        /* Title */
  110.    NULL,NULL };            /* Gadgets, Bitmap */
  111. struct NewWindow NewWindow = {
  112.    0,0,640,200,            /* left, top, width, height */
  113.    0,1,                /* detailpen, blockpen */
  114.    MENUPICK | CLOSEWINDOW | RAWKEY | ACTIVEWINDOW | INACTIVEWINDOW | MOUSEBUTTONS,
  115.    SMART_REFRESH | ACTIVATE | BORDERLESS | WINDOWCLOSE | WINDOWDEPTH | WINDOWDRAG,
  116.    NULL,NULL,            /* FirstGadget, CheckMark */
  117.    (UBYTE *)NULL,
  118.    NULL,            /* set screen after open screen */
  119.    NULL,            /* bitmap */
  120.    640, 200, 640, 200,        /* minw, minh, maxw, maxh */
  121.    CUSTOMSCREEN            /* Type */
  122.    };
  123.  
  124. /*   LeftEdge, TopEdge, Width and Height are in CHARACTERS.  They are
  125. ** converted to pixels in OpenReqWindow() in window.c based on the current
  126. ** font's characteristics. */
  127. struct NewWindow NewReqWindow = {
  128.    0, 1, 54, 4,            /* left (set in window.c), top, width, height */
  129.    0, 1,            /* detailpen, blockpen */
  130.     /* IDCMP Flags... */
  131.    CLOSEWINDOW | ACTIVEWINDOW | REQCLEAR | REQSET | NEWSIZE,
  132.     /* Flags... */
  133.    SMART_REFRESH | NOCAREREFRESH | ACTIVATE | WINDOWSIZING | SIZEBRIGHT |
  134.    WINDOWCLOSE | WINDOWDEPTH | WINDOWDRAG,
  135.  
  136.    NULL,            /* First gadget */
  137.    NULL,            /* CheckMark */
  138.    (UBYTE *)"VT100 Info & Xfer Status",    /* Title */
  139.    NULL,            /* set screen after open screen */
  140.    NULL,            /* bitmap */
  141.    ((5*8)+4+18), ((1*8)+11+2), 640, 200,    /* minw, minh, maxw, maxh */
  142.    CUSTOMSCREEN            /* Type */
  143.    };
  144. struct IntuiText MyTitle = {
  145.     0,1,JAM2,26,0,        /* front pen, back pen, mode, left, top */
  146.     &myattr,            /* font */
  147.     (UBYTE *)VERSION,        /* title */
  148.     NULL};            /* next text */
  149.  
  150. struct Screen *myscreen = NULL;        /* ptr to applications screen */
  151. struct Window *mywindow = NULL;        /* ptr to applications window */
  152. struct Window *reqwindow = NULL;    /* ptr to requester's window */
  153. struct ViewPort *myviewport;
  154. struct RastPort *myrastport;
  155. struct IntuiMessage *NewMessage;    /* msg structure for GetMsg() */
  156. struct Preferences  *Prefs;        /* preferences from GetPrefs() */
  157.  
  158. /**** String requester support ******/
  159. /*   The Top, Left, Width and Height are all in CHARACTERS.  This is converted
  160. ** to pixels in OpenReqWindow() in window.c.  Things which contain strings of
  161. ** known length are initialized from their string length */
  162.  
  163. char    InpBuf[MAXGADSTR],UndoBuf[MAXGADSTR],Prompt[MAXGADSTR];
  164. struct IntuiText donetxt = {
  165.     1,0,JAM2,0,0,    /* front pen, back pen, mode, left, top */
  166.     &myattr,        /* font */
  167.     (UBYTE *)"DONE",    /* question to ask */
  168.     NULL};        /* next text */
  169. struct Gadget mydonegad = {
  170.     &mystrgad,36,0,0,1,    /* next,left,top,width,height */
  171.     GADGHCOMP|REQGADGET,    /* flags */
  172.     RELVERIFY|ENDGADGET,    /* activation */
  173.     BOOLGADGET,            /* gadget type */
  174.     NULL,NULL,&donetxt,        /* gad render, sel render, gad text */
  175.     0L,NULL,2,NULL};        /* mutual exclude, special, ID, user data */
  176. struct    StringInfo mystrinfo = {
  177.     (UBYTE *)InpBuf,
  178.     (UBYTE *)UndoBuf,
  179.     0,MAXGADSTR-1,0,0,0,0,    /* initial, max, disp, undo, #chrs, dsp chrs */
  180.     0,0,NULL,0L,NULL};    /* left,top,layer,longint,keymap */
  181. struct Gadget mystrgad = {
  182.     NULL,1,1,40,1,    /* next,left,top,width,height */
  183.     GADGHCOMP|REQGADGET,/* flags */
  184.     ENDGADGET,STRGADGET,/* activation, type */
  185.     NULL,NULL,NULL,    /* gad render, sel render, gad text */
  186.     0L,            /* mutual exclude */
  187.     (APTR)&mystrinfo,    /* special info */
  188.     1,NULL};        /* gadget ID, user data */
  189. struct IntuiText mystrtxt= {
  190.     0,1,JAM2,1,0,    /* front pen, back pen, mode, left, top */
  191.     &myattr,        /* font */
  192.     (UBYTE *)Prompt,    /* question to ask */
  193.     NULL};        /* next text */
  194. struct Requester myrequest = {
  195.     NULL,0,1,42,2,    /* older requester, left, top, width, height */
  196.     0,0,&mydonegad,    /* relleft reltop, gadgets */
  197.     NULL,        /* border */
  198.     &mystrtxt,        /* text */
  199.     NULL,1,NULL,    /* flags, back fill pen, layer */
  200.     {0,0,0,0,0,0,0,0,
  201.      0,0,0,0,0,0,0,0,
  202.      0,0,0,0,0,0,0,0,
  203.      0,0,0,0,0,0,0,0},    /* pad1 */
  204.     NULL,NULL,        /* image bit map, rquest window */
  205.     {0,0,0,0,0,0,0,0,0,
  206.      0,0,0,0,0,0,0,0,0,
  207.      0,0,0,0,0,0,0,0,0,
  208.      0,0,0,0,0,0,0,0,0} /* pad2 */
  209.     };
  210.  
  211. int numreqs = 0;        /* number of outstanding requestors */
  212. int reqwinup = 0;        /* Requester window is NOT displayed */
  213. extern int reqmaxx, reqmaxy, reqmaxlen;    /* Defined in window.c */
  214. extern void ReqNewSize();    /* New req window size -- window.c */
  215. extern void KillReq();        /* Kill requester window in window.c */    
  216.  
  217. struct ExternalXfer *(ExtXfer[EXTMAX]);    /* Possible external protocol routines */
  218. int NumExts = 0;            /* Number of ExtXfers */
  219.  
  220. /***** menu structures *****/
  221. struct MenuItem FileItem[FILEMAX];
  222. struct IntuiText FileText[FILEMAX];
  223. struct MenuItem ModeItem[MODEMAX+EXTMAX];
  224. struct IntuiText ModeText[MODEMAX+EXTMAX];
  225. struct MenuItem CommItem[COMMAX];
  226. struct IntuiText CommText[COMMAX];
  227. struct MenuItem RSItem[RSMAX];
  228. struct IntuiText RSText[RSMAX];
  229. struct MenuItem ParItem[PARMAX];
  230. struct IntuiText ParText[PARMAX];
  231. struct MenuItem XFItem[XFMAX];
  232. struct IntuiText XFText[XFMAX];
  233. struct MenuItem ScriptItem[SCRIPTMAX];
  234. struct IntuiText ScriptText[SCRIPTMAX];
  235. struct MenuItem UtilItem[UTILMAX];
  236. struct IntuiText UtilText[UTILMAX];
  237. struct Menu menu[MAXMENU];
  238. struct IOExtSer *Read_Request;
  239. char *rs_in;
  240. struct IOExtSer *Write_Request;
  241. char rs_out[2];
  242. struct timerequest Timer;
  243. struct MsgPort *Timer_Port = NULL;
  244. struct timerequest Script_Timer;
  245. struct MsgPort *Script_Timer_Port = NULL;
  246. struct IOAudio Audio_Request;
  247. struct MsgPort *Audio_Port = NULL;
  248. UBYTE  *BeepWave;
  249. UBYTE  Audio_AllocMap[4] = { 1, 8, 2, 4 };
  250. int x,y,curmode;
  251. int Xsize    = 0;    /* From struct TextFont for user's font */
  252. int MINX    = 0;
  253. int MAXX    = 632;
  254. int Ysize    = 0;    /* From struct TextFont for user's font */
  255. int MINY    = 14;
  256. int MAXY    = 198;
  257. int BaseLine    = 0;    /* From struct TextFont for user's font */
  258. int top        = 14;
  259. int bot        = 198;
  260. int savx    = 0;
  261. int savy    = 14;
  262. int savmode    = 0;
  263. int nlmode    = 0;
  264. int alt        = 0;
  265. int savalt    = 0;
  266. int a[2]    = { 0, 0 };
  267. int sa[2]    = { 0, 0 };
  268. int  inesc    = -1;
  269. int  inctrl    = -1;
  270. int  private    = 0;
  271. int  badseq    = 0;
  272. int  maxcol    = 79;
  273.  
  274. /*************************** defaults *******************************/
  275. char    *p_font        = "topaz";    /* Default font. Name must be < 34 chars */
  276. char    *p_device    = SERIALNAME;    /* Default serial device name to use */
  277. int    p_fontsize    = 8;    /* Default vertical font size        */
  278. int    p_baud        = 1200;    /* baud rate                */
  279. int    p_shared    = 1;    /* Open serial device in shared mode    */
  280. int    p_screen    = 0;    /* 0 = WORKBENCH, 1 = CUSTOM        */
  281. int    p_wbcolors    = 1;    /* 0 = Custom, 1 = Workbench colors    */
  282. int    p_interlace    = 2;    /* 0 = no interlace, 1 = interlace, 2 = ASIS */
  283. int    p_depth        = 2;    /* number of bit planes (1 or 2)    */
  284. int    p_foreground    = 0x840;    /* default foreground RGB color */
  285. int    p_background    = 0x000;    /* default background RGB color */
  286. int    p_bold        = 0x000;    /* default BOLD       RGB color */
  287. int    p_cursor    = 0x00d;    /* default Cursor      RGB color */
  288. int    p_strip        = 1;    /* Strip parity from data for terminal    */
  289. int    p_mouse_up    = 0;    /* 1 = send mouse UP events        */
  290. int    p_mouse_down    = 0;    /* 1 = send mouse DOWN events        */
  291. int    p_lines        = 0;    /* 0 == use all available (MoreRows)    */
  292. int    p_mode        = 0;    /* 0 = image, 1 = CRLF (for kermit)    */
  293. int    p_unit        = 0;    /* unit of serial.device to open    */
  294. int    p_xproto    = 3;    /* 0=ASCII, 1=Xmodem, 2=XmodemCRC, 3 = Kermit */
  295. int    p_buffer    = 512;    /* read buffer size (>= 512 bytes)    */
  296. int     p_parity    = 0;    /* 0=none,1=mark,2=space,3=even,4=odd    */
  297. long    p_break        = 750000;    /* break time (in micro seconds)*/
  298. int    p_volume    = 64;    /* beep volume (0 = DisplayBeep)    */
  299. int    p_wrap        = 1;    /* 0 = truncate, 1 = wrap long lines    */
  300. int    p_keyapp    = 0;    /* 0 = numeric, 1 = application keypad    */
  301. int    p_curapp    = 0;    /* 0 = cursor, 1 = application cursor    */
  302. int    p_echo        = 0;    /* 0 = full duplex, 1 = half duplex    */
  303. int    p_bs_del    = 0;    /* 0 = normal, 1 = swap bs and delete    */
  304. int    p_convert    = 0;    /* 1 = convert filenames to lower case    */
  305. int    p_autochop    = 1;    /* 1 = enable xmodem autochop        */
  306. int    p_kmaxpack    = 1000;    /* Max packet size for Kermit xfers    */
  307. /*    Must be <= 1000.  <= 94 is standard, > 94 requires a kermit capable
  308. **    of long packet support. */
  309. int    p_xbeep        = 1;    /* 1 = beep at end of xfer        */
  310. char    p_keyscript    = 0x7E;    /* function key script introducer = ~    */
  311. char    *p_f[11]    = {    /* function key defaults and mouse prefix */
  312.     "\033OP","\033OQ","\033OR","\033OS",
  313.     "f5","f6","f7","f8","f9","f10",
  314.     "\033M" /* Mouse prefix here */ };
  315.  
  316. char    *p_F[10]     = {        /* shifted function key defaults    */
  317.     "F1","F2","F3","F4","F5",
  318.     "F6","F7","F8","F9","F10"};
  319.  
  320. char myfontname[FONTNAMESIZE];
  321. char mysername[SERNAMESIZE];
  322.  
  323. /* for script file */
  324. extern char on_string[], wait_string[];
  325. extern int cmd_from_script;        /* in script.c */
  326. int script_on, script_wait;
  327. int doing_init = 0;
  328.  
  329. /******************************************************/
  330. /*                   Main Program                     */
  331. /*                                                    */
  332. /*      This is the main body of the program.         */
  333. /******************************************************/
  334.  
  335. char lookahead[80];
  336. FILE *tranr = NULL;
  337. FILE *trans = NULL;
  338. int capture,send;
  339. char XferredFileName[MAXGADSTR];/* Name of last transferred file    */
  340. char ScriptFileName[MAXGADSTR];    /* Name of last script file        */
  341. char DirName[MAXGADSTR];    /* Name of last directory        */
  342. struct MsgPort *mySerPort;
  343.  
  344. #if AREXX
  345. int forwarding = 0;        /* Forwarding received data to AREXX    */
  346. char *ForwardPortName;        /* Port name to which we forward data    */
  347. struct RexxMsg *FwdMsg;        /* Message to send            */
  348. char *extension = "vt100";    /* extension of VT100 AREXX macros    */
  349. #endif /* AREXX */
  350.  
  351. void
  352. main(argc,argv)
  353. int    argc;
  354. char    **argv;
  355.     {
  356.     ULONG class, waitmask, redo = 0;
  357.     unsigned int code, qual;
  358.     SHORT mouse_x, mouse_y, mouse_qual;
  359.     APTR iaddr;
  360. #if AREXX
  361.     struct RexxMsg *RexxMsg;
  362.     char    fwdchars[256];
  363. #endif /* AREXX */
  364.     int KeepGoing,i,la,dola,actual, len;
  365.     char c,*ptr;
  366.     char ascstr[100];    /* Area for string returned by toasc() */
  367.  
  368.     XferredFileName[0] = ScriptFileName[0] = '\0';
  369.  
  370.     ptr = InitDefaults(argc,argv);
  371.     InitDevs();
  372.     InitFileItems();
  373.     InitCommItems();
  374.     InitScriptItems();
  375.     InitUtilItems();
  376.     InitMenu();
  377.     SetMenuStrip(mywindow,&menu[0]);
  378.     PrintIText(mywindow->RPort,&MyTitle,0L,0L);
  379.  
  380.     MyDir[0]  =        '\0';
  381.     StartLock = ((struct Process *) FindTask(NULL))->pr_CurrentDir;
  382.     CurrentDir(DupLock(StartLock));
  383.     KeepGoing =        TRUE;
  384.     capture   =        FALSE;
  385.     send      =        FALSE;
  386.     maxcol    =        MAXX / Xsize;
  387.     la          =        0;
  388.     x          =        MINX ;
  389.     y          =        MINY;
  390.     curmode   =        FS_NORMAL;
  391.     script_on =     FALSE;
  392.     script_wait=    TRUE;
  393.     on_string[0] = wait_string[0] = '\0';
  394.     SetAPen(mywindow->RPort,1L);
  395.     cursorflip();
  396.     cursorflip();
  397.     emit(12);
  398.     mySerPort = Read_Request->IOSer.io_Message.mn_ReplyPort;
  399.     SendIO((struct IORequest *)Read_Request);
  400.  
  401.     /* see if we had a startup script */
  402.     if (ptr != NULL) script_start(ptr);
  403.  
  404.     while( KeepGoing ) {
  405.     /* wait for window message or serial port message */
  406.     cursorflip();
  407.     waitmask = (1L << mySerPort->mp_SigBit) |
  408.            (1L << mywindow->UserPort->mp_SigBit) |
  409.            (1L << Script_Timer_Port->mp_SigBit);
  410.  
  411.     if(reqwinup)
  412.         waitmask |= (1L << reqwindow->UserPort->mp_SigBit);
  413.  
  414. #if AREXX
  415.     if(FromRexxPort)
  416.         waitmask |= (1L << FromRexxPort->mp_SigBit);
  417. #endif /* AREXX */
  418.  
  419.     if (script_wait)    /* if script ready dont wait here */
  420.         Wait(waitmask);
  421.     cursorflip();
  422.  
  423.     /* do ascii file send */
  424.     if (send) {
  425.         if ((c=getc(trans)) != EOF) {
  426.         if (c == '\n')
  427.             c = '\r';
  428.         sendchar(c);
  429.         } else {
  430.             fclose(trans);
  431.             InfoMsg1Line("File Sent");
  432.             send=FALSE;
  433.         }
  434.     }
  435.  
  436.     /* see if there are any characters from the host */
  437.     if (  (!script_on || (script_on && script_wait)) 
  438.        && CheckIO((struct IORequest *)Read_Request)) {
  439.         register int fwdndx = 0;
  440.         struct MsgPort *FwdPort;
  441.  
  442.         WaitIO((struct IORequest *)Read_Request);
  443.         if(p_parity || p_strip)
  444.         c = rs_in[0] & 0x7f;
  445.         else
  446.         c = rs_in[0];
  447. #if AREXX
  448.         fwdchars[fwdndx++] = c;
  449. #endif
  450.         doremote(c);
  451.         if (*on_string || *wait_string)
  452.         chk_script(c);
  453.         if (capture && c != 10) {
  454.         if (c == 13) c = 10;
  455.         putc(c , tranr);
  456.         }
  457.         Read_Request->IOSer.io_Command = SDCMD_QUERY;
  458.         DoIO((struct IORequest *)Read_Request);
  459.         Read_Request->IOSer.io_Command = CMD_READ;
  460.         actual = (int)Read_Request->IOSer.io_Actual;
  461.         if (actual > 0) {
  462.         if (inesc   <  0 &&
  463.             inctrl  <  0 &&
  464.             a[alt]  == 0 &&
  465.             capture == FALSE)
  466.                 dola = 1;
  467.         else
  468.             dola = 0;
  469.         if(actual > sizeof(lookahead))
  470.             actual = sizeof(lookahead);
  471.         Read_Request->IOSer.io_Length = actual;
  472.         DoIO((struct IORequest *)Read_Request);
  473.         Read_Request->IOSer.io_Length = 1;
  474.  
  475.         for (i = 0; i < actual; i++) {
  476.             if(p_parity || p_strip)
  477.             c = rs_in[i] & 0x7f;
  478.             else
  479.             c = rs_in[i];
  480. #if AREXX
  481.             if(fwdndx < 255)
  482.             fwdchars[fwdndx++] = c;
  483. #endif
  484.             if (*on_string || *wait_string)
  485.             chk_script(c);
  486.  
  487.             if (dola == 1) {
  488.             if (c >= ' ' && c <= '~' && la < 80)
  489.                 lookahead[la++] = c;
  490.             else {
  491.                 if (la > 0) {
  492.                 emitbatch(la,lookahead);
  493.                 la = 0;
  494.                 }
  495.                 doremote(c);
  496.                 dola = 0;
  497.             }
  498.             } else {
  499.             doremote(c);
  500.             if (inesc   <  0 &&
  501.                 inctrl  <  0 &&
  502.                 a[alt]  == 0 &&
  503.                 capture == FALSE)
  504.                 dola = 1;
  505.             if (capture && c != 10) {
  506.                 if (c == 13) c = 10;
  507.                 putc(c , tranr);
  508.             }
  509.             }
  510.         }
  511.  
  512.         /* dump anything left in the lookahead buffer */
  513.         if (la > 0) {
  514.             emitbatch(la,lookahead);
  515.             la = 0;
  516.         }
  517.         }
  518. #if AREXX
  519.         if(forwarding && fwdndx) {
  520.         fwdchars[fwdndx] = '\0';
  521.         Forbid();
  522.         /*   Since forwarding is set we can assume that the AREXX
  523.         ** library is available.  This is assured in cmd_fwd() in
  524.         ** script.c
  525.         **/
  526.         if( ((FwdPort = FindPort(ForwardPortName)) != NULL)
  527.          && (FwdMsg = CreateRexxMsg(FromRexxPort, extension, HostName))
  528.          && (ARG0(FwdMsg) = (STRPTR)CreateArgstring(fwdchars, (LONG)fwdndx)) ) {
  529.             ARG1(FwdMsg) = (STRPTR)1;
  530.             FwdMsg->rm_Action = RXCOMM;
  531.             PutMsg(FwdPort, (struct Message *)FwdMsg);
  532.             RexxReplies++;
  533.         }
  534.         Permit();
  535.         }
  536. #endif /* AREXX */
  537.         SendIO((struct IORequest *)Read_Request);
  538.      }
  539.  
  540.     while((NewMessage =
  541.         (struct IntuiMessage *)GetMsg(mywindow->UserPort))
  542.             != FALSE) {
  543.  
  544.         class = NewMessage->Class;
  545.         code = NewMessage->Code;
  546.         qual = NewMessage->Qualifier;
  547.         mouse_x = NewMessage->MouseX;
  548.         mouse_y = NewMessage->MouseY;
  549.         if(class == RAWKEY)
  550.         iaddr = *((APTR *)NewMessage->IAddress);
  551.         else
  552.         ReplyMsg((struct Message *)NewMessage);
  553.         switch( class ) {
  554.         case CLOSEWINDOW:
  555.         KeepGoing = FALSE;
  556.         break;
  557.  
  558.         case RAWKEY:
  559.         len = toasc(&(ascstr[0]), code,qual, 100, iaddr, 0);
  560.         ReplyMsg((struct Msg *)NewMessage);
  561.         if (p_echo) {
  562.             ptr = &(ascstr[0]);
  563.             for(i = 0; i < len; i++)
  564.             doremote(*(ptr++));
  565.         }
  566.         break;
  567.  
  568.         case NEWSIZE:
  569.         emit(12);
  570.         break;
  571.  
  572.         case MENUPICK:
  573.         while(code != MENUNULL) {
  574.             struct MenuItem *Item =
  575.             ItemAddress(mywindow->MenuStrip, (long)code);
  576.             unsigned int newcode =
  577.             (Item ? Item->NextSelect : code);
  578.  
  579.             redo |= handle_menupick(class,code, Item);
  580.             if(code == newcode)
  581.             code = MENUNULL;
  582.             else
  583.             code = newcode;
  584.         }
  585.         if(redo & REDOFILE)
  586.             redofile();
  587.         if(redo & REDOCOMM)
  588.             redocomm();
  589.         if(redo & REDOUTIL)
  590.             redoutil();
  591.         redo = 0;
  592.         break;
  593.  
  594.         case MOUSEBUTTONS:
  595.         if((p_mouse_down && (code == SELECTDOWN))
  596.         || (p_mouse_up   && (code == SELECTUP)) ) {
  597.             mouse_qual = 0;
  598.             if (qual & IEQUALIFIER_CONTROL)
  599.             mouse_qual |= 1;
  600.             if (qual & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT))
  601.             mouse_qual |= 2;
  602.             if (qual & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  603.             mouse_qual |= 4;
  604.             if (qual & (IEQUALIFIER_CAPSLOCK))
  605.             mouse_qual |= 8;
  606.             mouse_qual |= (code == SELECTDOWN) ? 16 : 32;
  607.  
  608.             sendstring(p_f[10]);
  609.             sendchar(mouse_qual + '@');
  610.             sendchar(' ' + ((mouse_x - MINX) / Xsize));  /* column */
  611.             sendchar(' ' + ((mouse_y - MINY + BaseLine ) / Ysize));/* row */
  612.         }
  613.         break;
  614.  
  615.         default:
  616.         PrintIText(mywindow->RPort,&MyTitle,0L,0L);
  617.         break;
  618.         }   /* end of switch (class) */
  619.     }   /* end of while ( newmessage )*/
  620.  
  621.     if (!script_wait ||
  622.        (script_wait == WAIT_TIMER &&
  623.         CheckIO((struct IORequest *)&Script_Timer)))
  624.         do_script_cmd(NEXTCOMMAND);
  625.  
  626.     while( reqwinup && ((NewMessage = (struct IntuiMessage *)
  627.                   GetMsg(reqwindow->UserPort)) != FALSE)
  628.          ) {
  629.         class = NewMessage->Class;
  630.         ReplyMsg((struct Msg *)NewMessage);
  631.         switch( class ) {
  632.         case REQCLEAR:
  633.         numreqs = 0;
  634.         break;
  635.  
  636.         case CLOSEWINDOW:
  637.         KillReq(); /* Kills requester window, set reqwinup = 0 */
  638.         break;
  639.  
  640.         case NEWSIZE:
  641.         ReqNewSize(reqwindow->Height, reqwindow->Width);
  642.         break;
  643.         }   /* end of switch (class) */
  644.     } /* end while reqwinup */
  645. #if AREXX
  646.     while(FromRexxPort && (RexxMsg = (struct RexxMsg *)GetMsg(FromRexxPort)) != NULL) {
  647.         processrexxmsg(RexxMsg);
  648.     }
  649. #endif /* AREXX */
  650.     }  /* end while ( keepgoing ) */
  651.  
  652.     /*   It must be time to quit, so we have to clean
  653.     **   up and exit.
  654.     */
  655.  
  656.     if(!CheckIO((struct IORequest *)Read_Request))
  657.     AbortIO((struct IORequest *)Read_Request);
  658.     Wait (1L <<mySerPort->mp_SigBit);
  659.     WaitIO((struct IORequest *)Read_Request);
  660.     cleanup("",0);
  661.  
  662. } /* end of main */
  663.  
  664. /* cleanup code */
  665. void
  666. cleanup(reason, fault)
  667. char *reason;
  668. int fault;
  669. {
  670.     extern struct Device *ConsoleDevice;    /* In init.c */
  671.     extern struct IOStdReq ConReq;        /* In init.c */
  672.     int i;
  673.  
  674.     switch(fault) {
  675.     case 0:        /* quitting close everything */
  676.     KillReq();    /* Kill the requester and its window */
  677.     ClearMenuStrip( mywindow );
  678.     CloseDevice((struct IORequest *)&Audio_Request);
  679.     UnLock(CurrentDir(StartLock));    /* back to original directory */
  680.  
  681.     case 8:        /* error opening audio */
  682.     DeletePort(Audio_Port);
  683.     FreeMem(BeepWave,BEEPSIZE);
  684.     CloseDevice((struct IORequest *)&Timer);
  685.  
  686.     case 7:        /* error opening timer */
  687.     DeletePort(Timer_Port);
  688.     CloseDevice((struct IORequest *)&Script_Timer);
  689.     DeletePort(Script_Timer_Port);
  690.  
  691. /*    case 6: */    /* error opening write device is unused */
  692.     DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
  693.     FreeMem(Write_Request,(long)sizeof(*Write_Request));
  694.     CloseDevice((struct IORequest *)Read_Request);
  695.  
  696.     case 5:        /* error opening read device */
  697.     DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
  698.     FreeMem(Read_Request,(long)sizeof(*Read_Request));
  699.  
  700.     case 4:        /* error opening window */
  701.     if (ConsoleDevice != NULL)
  702.         CloseDevice(&ConReq);
  703.     if (myfont   != NULL)
  704.         CloseFont( myfont );
  705.     if (mywindow != NULL)
  706.         CloseWindow( mywindow );
  707.     if (p_screen && myscreen) {
  708.         struct Process *mproc;
  709.  
  710.         mproc = (struct Process *)FindTask(0L);
  711.         mproc->pr_WindowPtr = OrigWindowPtr;
  712.         CloseScreen( myscreen );
  713.     }
  714.     for(i = 0; i < NumExts; i++) {
  715.         struct ExternalXfer *xfer = ExtXfer[i];
  716.  
  717.         FreeMem(xfer->dispname, (long)(strlen(xfer->dispname)+1));
  718.         FreeMem(xfer->downname, (long)(strlen(xfer->downname)+1));
  719.         FreeMem(xfer->send, (long)(strlen(xfer->send)+1));
  720.         FreeMem(xfer->receive, (long)(strlen(xfer->receive)+1));
  721.         FreeMem(xfer, (long)sizeof(struct ExternalXfer));
  722.     }        
  723.  
  724.     case 3:        /* error opening screen */
  725.     case 2:        /* error opening graphics library */
  726.     if(GfxBase)
  727.         CloseLibrary((struct Library *)GfxBase);
  728.     if(DiskfontBase)
  729.         CloseLibrary(DiskfontBase);
  730.     case 1:        /* error opening intuition */
  731.     if(IntuitionBase)
  732.         CloseLibrary((struct Library *)IntuitionBase);
  733.     default:
  734.     if (*reason) puts (reason);
  735.     }
  736.  
  737. #if AREXX
  738.     if(HostName)
  739.     FreeMem(HostName, (LONG)(strlen(HostName)+1));
  740.  
  741.     if(FromRexxPort) {
  742.     RemPort(FromRexxPort);
  743.     FreePort(FromRexxPort);
  744.     FreeMem(FromRexxPort, (LONG)sizeof(struct MsgPort));
  745.     }
  746.     if(RexxSysBase)
  747.     CloseLibrary((struct Library *)RexxSysBase);
  748. #endif /* AREXX */
  749.     exit(fault);
  750. }
  751.  
  752. do_capture(file)
  753. char *file;
  754. {
  755.     char name[MAXGADSTR];
  756.  
  757.     if (capture == TRUE) {
  758.     capture=FALSE;
  759.     fclose(tranr);
  760.     InfoMsg1Line("End File Capture");
  761.     } else {
  762.     if(file)
  763.         strcpy(name, file);
  764.     else
  765.         name[0] = '\0';
  766.  
  767.     if (file == NULL || *file == '\0' || !cmd_from_script) {
  768.         req("Ascii Capture:",name,1);
  769.         if(file && !cmd_from_script)
  770.         strcpy(file, name);
  771.     }
  772.     if ((tranr=fopen(name,"w")) == 0) {
  773.         capture=FALSE;
  774.         InfoMsg2Line("Error Opening File:", name);
  775.         return(FALSE);
  776.     }
  777.     capture=TRUE;
  778.     }
  779.     redofile();
  780. }
  781.  
  782. do_send(file)
  783. char *file;
  784. {
  785.     char name[MAXGADSTR];
  786.  
  787.     if (send == TRUE) {
  788.     send=FALSE;
  789.     fclose(trans);
  790.     InfoMsg1Line("File Send Cancelled");
  791.     } else {
  792.     if(file)
  793.         strcpy(name, file);
  794.     else
  795.         name[0] = '\0';
  796.  
  797.     if (file == NULL || *file == '\0' || !cmd_from_script) {
  798.         req("Ascii Send:",name,1);
  799.         if(file && !cmd_from_script)
  800.         strcpy(file, name);
  801.     }
  802.     if ((trans=fopen(name, "r")) == 0) {
  803.         send=FALSE;
  804.         InfoMsg2Line("Error Opening File:", name);
  805.         return(FALSE);
  806.     }
  807.     send=TRUE;
  808.     }
  809. }
  810.  
  811. void setparams()
  812. {
  813.     Read_Request->IOSer.io_Command =
  814.     Write_Request->IOSer.io_Command =
  815.         SDCMD_SETPARAMS;
  816.     DoIO((struct IORequest *)Read_Request);
  817.     DoIO((struct IORequest *)Write_Request);
  818.     Read_Request->IOSer.io_Command = CMD_READ;
  819.     SendIO((struct IORequest *)Read_Request);
  820.     Write_Request->IOSer.io_Command = CMD_WRITE;
  821. }
  822.  
  823. void hangup ()
  824.     {
  825.     if(!CheckIO((struct IORequest *)Read_Request))
  826.     AbortIO((struct IORequest *)Read_Request);
  827.     Wait (1L <<mySerPort->mp_SigBit);
  828.     WaitIO((struct IORequest *)Read_Request);
  829.     CloseDevice((struct IORequest *)Read_Request);
  830.     Timer.tr_time.tv_secs=0L;
  831.     Timer.tr_time.tv_micro=750000L;
  832.     DoIO((struct IORequest *)&Timer.tr_node);
  833.     OpenDevice(mysername, (LONG)p_unit, (struct IORequest *)Read_Request, NULL);
  834.     setparams();
  835. }
  836.  
  837. void redocomm() {
  838.     ClearMenuStrip( mywindow );         /* Remove old menu */
  839.     InitCommItems();                    /* Re-do comm menu   */
  840.     SetMenuStrip(mywindow,&menu[0]);    /* Re-display the menu */
  841. }
  842.  
  843. void redofile() {
  844.     ClearMenuStrip( mywindow );         /* Remove old menu */
  845.     InitFileItems();                    /* Re-do file menu   */
  846.     SetMenuStrip(mywindow,&menu[0]);    /* Re-display the menu */
  847. }
  848.  
  849. void setserbaud(baud, redomenu)
  850. int baud;
  851. LONG redomenu;
  852. {
  853.     if(!CheckIO((struct IORequest *)Read_Request))
  854.     AbortIO((struct IORequest *)Read_Request);
  855.     Wait (1L <<mySerPort->mp_SigBit);
  856.     WaitIO((struct IORequest *)Read_Request);
  857.     Write_Request->io_Baud = Read_Request->io_Baud = baud;
  858.     setparams();
  859.     p_baud = baud;
  860.     if (redomenu)
  861.     redocomm();
  862. }
  863.  
  864. void redoutil() {
  865.     ClearMenuStrip(mywindow);
  866.     InitUtilItems();
  867.     SetMenuStrip(mywindow,&menu[0]);
  868. }
  869.  
  870. ULONG handle_menupick(class, code, Item)
  871. ULONG class;
  872. unsigned int code;
  873. struct MenuItem *Item;
  874. {
  875.     unsigned int menunum, itemnum, subnum, i;
  876.     int nxfer;
  877.     unsigned long retval = 0;
  878.  
  879.     if (code == MENUNULL)
  880.     return retval;
  881.  
  882.     menunum = MENUNUM( code );
  883.     itemnum = ITEMNUM( code );
  884.     subnum  = SUBNUM( code );
  885.     switch( menunum ) {
  886.     case 0:
  887.     switch( itemnum ) {
  888.     case 0:    /* menunum case 0 itemnum case 0 -- Set xfer mode */
  889.         switch( subnum ) {
  890.         case 0:    /* Ascii */
  891.         case 1:    /* Xmodem */
  892.         case 2:    /* XmodemCRC */
  893.         case 3:    /* Kermit */
  894.         i = subnum;
  895.         break;
  896.         default:
  897.         nxfer = MODEMAX + NumExts - 1;
  898.         if(subnum > nxfer)
  899.             i = MODEMAX-1;
  900.         else
  901.             i = subnum;
  902.         }
  903.         p_xproto = i;
  904.         retval |= REDOFILE;
  905.         break;
  906.  
  907.     case 1:    /* menunum case 0 itemnum case 1 -- Send a file */
  908.         cmd_sendf(XferredFileName);
  909.         break;
  910.  
  911.     case 2:    /* menunum case 0 itemnum case 2 -- Receive a file */
  912.         cmd_recf(XferredFileName);
  913.         break;
  914.  
  915.     case 3:    /* menunum case 0 itemnum case 3 -- Kermit GET */
  916.         cmd_kg(XferredFileName);
  917.         break;
  918.  
  919.     case 4:    /* menunum case 0 itemnum case 4 -- Kermit BYE */
  920.         saybye();
  921.         break;
  922.     case 5: /* menunum case 0 itemnum case 5 -- ASCII capture */
  923.         do_capture(XferredFileName);
  924.         break;
  925.     } /* End of itemnum switch for menunum case 0 */
  926.     break;
  927.  
  928.     case 1:        /* menunum case 1 - Comm Setup */
  929.     switch( itemnum ) {
  930.     case 0:    /* Baud */
  931.         switch( subnum ) {
  932.         case 0:
  933.         setserbaud(300, FALSE);
  934.         break;
  935.  
  936.         case 1:
  937.         setserbaud(1200, FALSE);
  938.         break;
  939.  
  940.         case 2:
  941.         setserbaud(2400, FALSE);
  942.         break;
  943.  
  944.         case 3:
  945.         setserbaud(4800, FALSE);
  946.         break;
  947.  
  948.         case 4:
  949.         setserbaud(9600, FALSE);
  950.         break;
  951.         } /* End of subnum switch for itemnum 0 of menunum 1 */
  952.         break;
  953.  
  954.     case 1:    /* menunum case 1 itemnum 1 -- Set  Parity */
  955.         switch(subnum) {
  956.         case 0: case 1: case 2: case 3: case 4:
  957.         p_parity = subnum;
  958.         break;
  959.         case 6:
  960.         if(Item->Flags & CHECKED)
  961.             p_strip = 1;
  962.         else
  963.             p_strip = 0;
  964.         break;
  965.         }
  966.         retval |= REDOCOMM;
  967.         break;
  968.     case 2:    /* menunum case 1 itemnum 2 -- set transfer mode */
  969.         switch(subnum) {
  970.         case 0:
  971.         case 1:
  972.         p_mode = subnum;
  973.         break;
  974.         case 2:
  975.         if(Item->Flags & CHECKED)
  976.             p_convert = 1;
  977.         else
  978.             p_convert = 0;
  979.         break;
  980.         case 3:
  981.         if(Item->Flags & CHECKED)
  982.             p_autochop = 1;
  983.         else
  984.             p_autochop = 0;
  985.         break;
  986.         }
  987.         retval |= REDOCOMM;
  988.         break;
  989.     case 3:   /* menunum case 1 itemnum 3 -- Shared */
  990.         {
  991.         char onoff[4];
  992.  
  993.         if(Item->Flags & CHECKED)
  994.             strcpy(onoff, "on");
  995.         else
  996.             strcpy(onoff, "off");
  997.         cmd_share(onoff);
  998.         }
  999.         break;
  1000.     }
  1001.     break;    /* End of menunum case 1 */
  1002.  
  1003.     case 2:    /* menunum case 2 - Script */
  1004.     switch( itemnum ) {
  1005.     case 0:            /* Execute macro    */
  1006.     case 1:            /* Abort macro        */
  1007.         if (!itemnum && !script_on) {
  1008.         req("Script file name:", ScriptFileName, 1);
  1009.         script_start(ScriptFileName);
  1010.         }
  1011.         if (itemnum && script_on)
  1012.         exit_script();
  1013.         break;
  1014.     case 2: {            /* AREXX macro        */
  1015.  
  1016.         req("AREXX macro and args:", ScriptFileName, 1);
  1017.         cmd_rx(ScriptFileName);
  1018.         break;
  1019.         }
  1020.     }
  1021.     break;
  1022.  
  1023.     case 3:    /* menunum case 3 -- Utility */
  1024.     switch( itemnum ) {
  1025.     case 0:
  1026.         sendbreak();
  1027.         break;
  1028.  
  1029.     case 1:    /* menunum case 3 itemnum case 1 -- Hang Up */
  1030.         hangup();
  1031.         break;
  1032.  
  1033.     case 2:    /* menunum case 3 itemnum case 2 -- Cd */
  1034.         strcpy(DirName, MyDir);
  1035.         req("Directory:", DirName, 1);
  1036.         set_dir(DirName);
  1037.         break;
  1038.  
  1039.     case 3:    /* menunum case 3 itemnum case 3 -- Clear Screen */
  1040.         top = MINY; bot = MAXY; savx = MINX; savy = MINY;
  1041.         curmode = FS_NORMAL; inesc = -1;
  1042.         a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
  1043.         retval |= REDOUTIL;
  1044.         emit(12);
  1045.         break;
  1046.  
  1047.     case 4:    /* menunum case 3 itemnum case 4 -- Echo mode */
  1048.         if(Item->Flags & CHECKED)
  1049.         p_echo = 1;
  1050.         else
  1051.         p_echo = 0;
  1052.         retval |= REDOUTIL;
  1053.         break;
  1054.  
  1055.     case 5:    /* menunum case 3 itemnum case 5 -- Wrap mode */
  1056.         if(Item->Flags & CHECKED)
  1057.         p_wrap = 1;
  1058.         else
  1059.         p_wrap = 0;
  1060.         retval |= REDOUTIL;
  1061.         break;
  1062.  
  1063.     case 6:    /* menunum case 3 itemnum case 6 -- NumKey */
  1064.         if(Item->Flags & CHECKED)
  1065.         p_keyapp = 1;
  1066.         else
  1067.         p_keyapp = 0;
  1068.         retval |= REDOUTIL;
  1069.         break;
  1070.  
  1071.     case 7:    /* menunum case 3 itemnum case 7 -- App Cur */
  1072.         if(Item->Flags & CHECKED)
  1073.         p_curapp = 1;
  1074.         else
  1075.         p_curapp = 0;
  1076.         retval |= REDOUTIL;
  1077.         break;
  1078.  
  1079.     case 8:    /* menunum case 3 itemnum case 8 -- BS <-> DEL */
  1080.         if(Item->Flags & CHECKED)
  1081.         p_bs_del = 1;
  1082.         else
  1083.         p_bs_del = 0;
  1084.         retval |= REDOUTIL;
  1085.         break;
  1086.  
  1087.     case 9:    /* menunum case 3 itemnum case 9 -- Xfer Beep */
  1088.         if(Item->Flags & CHECKED)
  1089.         p_xbeep = 1;
  1090.         else
  1091.         p_xbeep = 0;
  1092.         retval |= REDOUTIL;
  1093.         break;
  1094.  
  1095.     case 10: /* menunum case 3 itemnum case 10 - Mouse Up */
  1096.         if(Item->Flags & CHECKED)
  1097.         p_mouse_up = 1;
  1098.         else
  1099.         p_mouse_up = 0;
  1100.         retval |= REDOUTIL;
  1101.         break;
  1102.  
  1103.     case 11: /* menunum case 3 itemnum case 11 - Mouse Down */
  1104.         if(Item->Flags & CHECKED)
  1105.         p_mouse_down = 1;
  1106.         else
  1107.         p_mouse_down = 0;
  1108.         retval |= REDOUTIL;
  1109.         break;
  1110.     }
  1111.  
  1112.     break;
  1113.     } /* end of switch ( menunum ) */
  1114.     return retval;
  1115. }
  1116.