/* Comm 1.34 -- The Communicator -- a terminal program for Amiga */ /* This program is placed in the public domain is freely distributable and is intended for personal use only. Sale of this program except for REASONABLE media costs is prohibited. */ #define COMM 1 #define RXCRLF 0xFF00 #define TXCRLF 0x00FF #include "globals.h" #include #include #include #include #define CREATE O_WRONLY | O_CREAT | O_TRUNC extern USHORT Read_RS(); extern int init_serial(), Open_Timer(), Close_Timer(), Split_Window(), MyCloseWindow(); extern UBYTE toasc(), *get_phnum(), *malloc(), *MyOpenWindow(), *OpenLibrary(); extern void dial(), Init_phone_lib(), list_plib(), Single_Window(), InitMenu(), emit_tx(), emits_tx(), emit_rx(), emits_rx(), InitReq(), hang_up(); extern struct MenuItem *ItemAddress(); extern struct IntuiMessage *GetMsg(); extern struct Window *OpenWindow(); extern struct Screen *OpenScreen(); extern struct Task *FindTask(); int KeepGoing, capture, send, ph_nums, menu_event, tranr, bcount, gotxon, close_view = FALSE, scrnpos = 13, prefbaud; char name[MAXFNAME], strbuff[ MAXFNAME + 41 ], *number, c; FILE *trans; ULONG sdelay = 0, IconBase = 0; static int lcnt = 0; /* ascii debug character counter */ static char line[17]; /* ascii debug line buffer */ static APTR err_window; static int timeron= FALSE; /* true if timer device opened */ USHORT tmpchopflg = FALSE; /* hold state of chopflg during XMODEM recv. */ USHORT eolflg = 0; #define C_OFF 0 #define C_ON 1 #define C_SUS 2 UBYTE *stat[] = {(UBYTE *)" ",(UBYTE *)"ON ",(UBYTE *)"SUS"}; struct View *View = NULL; struct ViewPort *ViewPort = NULL, *ViewPortAddress(); /******************************************************/ /* Main Program */ /* */ /* This is the main body of the program. */ /******************************************************/ main(argc,argv) int argc; char **argv; { void help(), decode_raw_key(), Process_tx_event(), Process_rx_event(); void Process_rq_event(), Process_vw_event(), InitSystem(), Process_menu_event(); void Process_screen_item(), Process_baud_rate(); SetTaskPri(FindTask(0L),install.priority);/* bump our priority a little */ InitSystem(argc,argv); /* Open windows and devices */ InitMenus(); /* init. menus */ Init_phone_lib(); /* initialize phone library */ SetMenuStrip(tx_window,menu); /* attach menus to tx window */ KeepGoing = gotxon = TRUE; close_window = send = capture = FALSE; trans = NULL; tranr = NULL; DeActivate(&Dirgadget); ph_nums = load_plib(phonedir); /* load the phone library */ if(Init_keymacros()==NULL) /* and the key macro file */ { sprintf(sbuff,"Can't open key file %s\n",commkeys); emits_rx(sbuff); } menu_event = NULL; /* no menu items selected */ BeginIO(Read_Request); /* ready serial input */ if(install.prefbaud) Process_baud_rate( prefbaud ); /* adjust baud rate */ Modem_init(); /* send init string to modem */ Xon(xonflg); /* enable XON/XOFF protocol if selected */ *name = NULL; capt_status = stat[ C_OFF ]; while( KeepGoing ) /* the big loop */ { if (send && gotxon) /* if we are in ASCII send mode and enabled */ { if ((c = getc(trans)) != EOF) /* get a byte from the file */ { Delay(sdelay); /* slider delay */ if( c == '\n') OutChar('\r'); /* if LF, send CR */ else if( c != '\r') OutChar(c); } else { fclose(trans); /* here at end of file */ emits_rx("\nFile Sent\n"); send = FALSE; /* turn off send flag */ Swap_capture(ASCSEND,START); /* normal menu entry */ } } else /* wait for requester, serial port or other windows message */ Wait((1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) | (1L << tx_window->UserPort->mp_SigBit)); Process_window_event(); while(CheckIO(Read_Request)) /* any serial activity? */ { Process_serial_chars(); BeginIO(Read_Request); Process_window_event(); } } /* end while ( keepgoing ) */ /* It must be time to quit, so we have to clean * up and exit. */ if(capture) { flush(); /* flush capture buffer */ close(tranr); } if(prt) close(prt); /* release printer */ clean_up(0L); /* shut everything down */ exit( 1 ); } /* end of main */ /************************************************************* Get and process characters from the serial device. Characters are found in array rs_in. Serlen contains the number of characters in the buffer. */ Process_serial_chars() { USHORT bfcnt, i, serlen; UBYTE dispbuf[ RSBUFSIZ * 2 ]; serlen = Read_RS(); for(bfcnt = i = 0; i < serlen; i++) { if(rs_in[i] == NULL) continue; if(debug & NOMASK) /* strip parity? */ c = rs_in[i]; /* no */ else c = rs_in[i] & 0x7f; /* yes */ if (capture && capton) /* capturing data to disk file? */ if (isprint(c)) buffer_it(c); else switch(c) /* only allow some control chars in file */ { case '\n': /* case '\r': */ case '\t': buffer_it(c); } if(debug & SHOWHEX) /* Show HEX character? */ { sprintf(sbuff,"%02.2x ",c); /* print HEX digit pair */ emits_rx(sbuff); line[lcnt++] = (isprint(c) ? c : '.'); /* buffer ASCII */ if(lcnt > 16) /* until 16 HEX chars */ { line[lcnt] = NULL; emits_rx(" "); /* dump ASCII debug buffer */ emits_rx(line); emit_rx('\n'); lcnt = 0; } } else /* not showing HEX characters */ switch (c) /* filter out control chars. */ { case XON: gotxon = TRUE; break; case XOFF: gotxon = FALSE; break; case 7: /* except BELL */ Beep(); break; case '\r': /* " CR */ if(eolflg & RXCRLF) { c = '\n'; dispbuf[bfcnt++] = '\r'; } case 8: /* BACKSPACE */ case 9: /* " TAB */ case '\n': /* " NEWLINE */ case '\f': /* " FORM FEED */ case 0x1b: /* " ESC */ dispbuf[bfcnt++] = c; break; default: if(isprint(c)) dispbuf[bfcnt++] = c; break; } } dispbuf[bfcnt] = NULL; /* end buffer with a NULL */ if((debug & SHOWHEX) == 0) emits_rx(dispbuf); /* print string to screen */ doprint(dispbuf,bfcnt); /* and to printer (if on) */ } /* print a string on the printer */ doprint(addr,cnt) UBYTE *addr; int cnt; { UBYTE *buff; int tmp; if(printon != TRUE) /* if not selected, return */ return; buff = addr; tmp = cnt; while(tmp--) { if(*addr == 8) /* BACKSPACE? */ *addr = 0x7F; /* make it DELETE */ if(isprintable(*addr)) { addr++; continue; } else *addr++ = NULL; /* zap out unprintable characters */ } if(write(prt,buff,cnt) != cnt) { printon = FALSE; close(prt); Beep(); emits_rx("\n\nERROR writing to printer -- print aborted\n"); } } /* determine what is and isn't printable on the printer */ isprintable(ch) UBYTE ch; { ch &= 0x7F; if(isprint(ch)) /* I allow all alphanumerics */ return TRUE; switch(ch) /* and these control characters */ { case 10: case 13: case 9: case 7: case 8: case 0x7F: return TRUE; } return FALSE; } /* an IDCMP port message has been received. Determine the window it came from then process the message */ Process_window_event() { while( NewMessage = GetMsg(tx_window->UserPort) ) Process_window_msg( NewMessage ); } Process_window_msg(msg) struct IntuiMessage *msg; { ULONG class; USHORT code, qual; APTR address; struct Window *which; /* which window has an event */ class = msg->Class; code = msg->Code; qual = msg->Qualifier; which = msg->IDCMPWindow; address = msg->IAddress; ReplyMsg( msg ); if(class == RAWKEY || class == MENUPICK) Process_tx_event( (long)class, code, qual, address); else if(which == tx_window) Process_tx_event( (long)class, code, qual, address); else if(which == vw_window) Process_vw_event( (long)class, code, qual); else if(which == req_window) Process_rq_event( (long)class, address); else if(which == rx_window) Process_rx_event( (long)class, code, qual, address); else if(which == st_window) { if(address == &delay_prop) sdelay = ((ULONG)propinfo.HorizPot >> 12); else { while( msg = GetMsg(st_window->UserPort) ) ReplyMsg(msg); ClearMenuStrip(st_window); MyCloseWindow(st_window); st_window = NULL; } } if(close_window) { Single_Window(); SysItems[0].Flags &= ~CHECKED; /* turn off check mark in menu */ } if(close_view) { if((close_view = MyCloseWindow(vw_window)) == FALSE) vw_window = NULL; } } /************************************************************************ Some event happened in the rx window. Process only the events we are interested in. */ void Process_rx_event( class, code, qual, address) ULONG class; USHORT code, qual; APTR address; { Process_tx_event( class, code, qual, address); } /************************************************************************** Some event happened in the tx window. Process events we are interested in. */ void Process_tx_event( class, code, qual, address ) ULONG class; USHORT code, qual; APTR address; { USHORT itemnum, menunum, subnum; struct MenuItem *Item; void Process_menu_item(); if(address == &tx_window_close) KeepGoing = FALSE; else if(address == &tx_window_front) { if(vw_window) WindowToFront(vw_window); } else if(address == &tx_window_back) ScreenToBack(commscreen); else if(address == &rx_window_close) close_window = TRUE; else if(address == &rx_window_front) { WindowToBack(tx_window); WindowToBack(rx_window); } else if(address == &rx_window_back) ScreenToBack(commscreen); else switch( class ) { case CLOSEWINDOW: /* User is ready to quit, so indicate that execution should terminate with next iteration of the loop. */ KeepGoing = FALSE; break; case RAWKEY: /* User has touched the keyboard */ switch( code ) { case 69: /* escape key */ abort = TRUE; default: c = toasc(code,qual); /* get in into ascii */ decode_raw_key( c ); break; } break; case MENUPICK: /* we had a menu selection. */ while ( code != MENUNULL ) { menunum = MENUNUM( code ); itemnum = ITEMNUM( code ); subnum = SUBNUM( code ); Process_menu_item( menunum, itemnum , subnum); Item = ItemAddress( &menu[0], (long)code ); code = Item->NextSelect; } break; } /* end of switch (class) */ } /* View window was closed */ void Process_vw_event( class, code, qual ) ULONG class; USHORT code, qual; { if( class == CLOSEWINDOW) { viewflg = FALSE; SysItems[1].Flags &= ~CHECKED; close_view = TRUE; } } /* Return was hit on string gadget */ void Process_rq_event( class, address ) ULONG class; APTR address; { struct IntuiMessage *msg; UBYTE ch; /* User just hit return in the string input requester. menu_event was set by process_tx_event() when the user selected the file transfer type. Now we have the filename he entered, so go do the file xfer. */ if(address == &Dirgadget) { ch = install.def_dir[ strlen(install.def_dir) -1 ]; if(ch != ':' && ch != '/') strcat(install.def_dir,"/"); if(dos_version == DOS12) ActivateGadget(&Strgadget,req_window,0L); return; } while( msg = GetMsg(req_window->UserPort) ) ReplyMsg(msg); #ifdef ORIGINALCODE /* Following code is bogus (fnf) */ req_window = (struct Window *)MyCloseWindow(req_window); #else (void) MyCloseWindow(req_window); req_window = NULL; #endif if( (address == &Strgadget) || (address == &OKgadget) ) Process_menu_event( menu_event ); else menu_event = NULL; } /************************************************************************** User hit HELP key, print any helpful information. */ void help() { int i; for(i = 0; i < KEYMACS; i++) if(keymacro[i]) { sprintf(sbuff,"\n%c%d: ",(i > 9) ? 'S' : 'F',(i > 9) ? i-9 : i + 1); emits_rx(sbuff); emits_rx(keymacro[i]); } emit_rx('\n'); } /************************************************************************* Decode and act upon any special function keys here. Default action is to send the key out the serial port. */ void decode_raw_key( c ) char c; { char ch; switch(c & 0xff) /* c should be unsigned */ { case NULL: break; case FN1: case FN2: case FN3: case FN4: case FN5: case FN6: case FN7: case FN8: case FN9: case F10: case SF1: case SF2: case SF3: case SF4: case SF5: case SF6: case SF7: case SF8: case SF9: case S10: expand_macro( c ); break; case SHH: help(); /* and list macros */ break; case HLP: if(st_window) { ClearMenuStrip(st_window); MyCloseWindow(st_window); st_window = NULL; } else Show_Status(); /* show status */ break; case XON: Start_line(); gotxon = TRUE; break; case TOGSCR: MoveScreen(commscreen,0L,(long)scrnpos); scrnpos *= -1; break; case TOGCAP: if(capture) /* if its on, turn it off */ { capton = !capton; if(capton) capt_status = stat[C_ON]; else capt_status = stat[C_SUS]; status_line(75,capt_status); } else /* open default file */ { if((tranr = open(install.cap_name,CREATE)) == ERROR) { sprintf(sbuff,"\007\nERROR opening %s\n",install.cap_name); emits_rx(sbuff); } else { capton = capture = TRUE; bcount = 0; Swap_capture(ASCCAPT,capture != TRUE); sprintf(sbuff,"\007\nDefault CAPTURE file %s opened\n",install.cap_name); emits_rx(sbuff); capt_status = stat[C_ON]; status_line(75,capt_status); } } RefreshStatus(); break; case TOGPRT: if(printon) /* if printer was on */ { ch = 13; doprint(&ch,1); /* print a CR to clear buffer */ close(prt); printon = FALSE; prt = NULL; } else { if((prt = open("PRT:",O_WRONLY)) == -1) { Beep(); emits_rx("\n\nERROR opening printer\n"); break; } printon = TRUE; } RefreshStatus(); break; /* wasn't a special key, so send it out the serial port */ default: OutChar(c); } } /* send a character out to the modem. Process \r and \n here */ OutChar(ch) UBYTE ch; { rs_out[0] = ch; DoIO(Write_Request); if( ch == '\r' ) { if( eolflg & TXCRLF ) OutChar('\n'); } if(halfduplex & !split_screen) emit_rx(ch); if(split_screen) { if(ch == '\r') /* make CR into LF for */ emit_tx('\n'); /* readability & scrolling */ else if(ch == 8) emits_tx("\010 \010"); /* destructive BACKSPACE */ else if(ch == 7) Beep(); else emit_tx(ch); } } /************************************************************************** Process user selected menu item. menuitem and itemnum were determined by process_tx_event() */ void Process_menu_item( menunum, itemnum, subnum) USHORT menunum, itemnum, subnum; { void Process_file_item(), Process_baud_rate(), Process_sys_item(); void Process_serial_item(); switch( menunum ) { case 0: Process_file_item( itemnum, subnum ); /* FILE transfer */ break; case 1: Process_sys_item( itemnum ,subnum ); /* SYSTEM */ break; case 2: crcflag = xfrmode = itemnum; /* MODE */ break; case 3: Process_serial_item( itemnum, subnum ); /* SERIAL */ break; case 5: Process_debug_item( itemnum, subnum ); /* DEBUG */ break; case 4: /* PHONE */ if( itemnum == 1 ) /* alternate long dist serv */ { altservflg = TRUE; PhoneItem[1].Flags |= CHECKED; } else if( itemnum == 0 ) /* hang up */ { hang_up(); } else if( pdir[ itemnum-2 ].number[0] != NULL) {/* dial resets altservflg, we reset checkmark */ itemnum -= 2; list_plib( itemnum ); set_baud(atoi(pdir[ itemnum ].baud)); dial(pdir[ itemnum ].number); PhoneItem[1].Flags &= ~CHECKED; if(install.keyload) Load_keymacros(pdir[ itemnum ].name); } break; } } Process_debug_item(itemnum, subnum) USHORT itemnum, subnum; { if(debug & (1 << itemnum)) /* if bit is set */ { debug &= ~(1 << itemnum); /* reset it */ DebugItems[itemnum].Flags &= ~CHECKED; } else { debug |= (1 << itemnum); /* else, set it */ DebugItems[itemnum].Flags |= CHECKED; lcnt = 0; } } /************************************************************************ Process the menu event the user desires. This processing was delayed until the user entered a filename using the string input requester. */ void Process_menu_event( menu_event ) { UBYTE fname[ MAXFNAME + 41 ]; int temp; fname[0] = NULL; if(index(name,':') == 0) strcpy(fname,install.def_dir); strcat(fname,name); *name = NULL; switch (menu_event) { case NULL: break; case ASCCAPT: if(file_exists(fname)) /* requested file exists */ { if(!use_file(fname)) /* he wants a new one */ { menu_event = NULL; strcpy(name,fname); Process_file_item(0,0); break; } else /* no: use the old one */ if( app_del() ) tranr = open(fname,O_WRONLY); /* append data */ else tranr = open(fname,CREATE); } else tranr = open(fname,CREATE); if (tranr == ERROR) { capture = capton = FALSE; sprintf(sbuff,"\nError Opening File %s\n",fname); emits_rx(sbuff); break; } capt_status = stat[C_ON]; status_line(75,capt_status); capton = capture = TRUE; bcount = 0; RefreshStatus(); lseek(tranr,0L,2); break; case ASCSEND: if ((trans = fopen(fname,"r")) == 0) { send = FALSE; sprintf(sbuff,"\nError Opening File %s\n",fname); emits_rx(sbuff); break; } sdelay = ((ULONG)propinfo.HorizPot >> 12); send = TRUE; break; case WXMRECV: wxflag = TRUE; case XMDRECV: if(file_exists(fname)) if(!use_file(fname)) { menu_event = NULL; Process_file_item(2,0); break; } Set_Menus(OFF); /* Ghost the menus */ if(test_4_arc(fname)) /* turn off auto chopping for */ chopflg = FALSE; /* .ARC files */ if(viewflg) WindowToFront(vw_window); if (XMODEM_Read_File(fname)) emits_rx("\nReceived File\n"); else { close(fd); emits_rx("\nXmodem Receive Failed\n"); } clear_status_line(); status_line(75,capt_status); Set_Menus(ON); Beep(); Xconfig(FALSE); wxflag = FALSE; chopflg = tmpchopflg; /* restore CHOP mode flag */ if(abort) emits_rx("User aborted transfer\n"); break; case XMDSEND: if(!file_exists(fname)) { no_file(); /* No such file requester */ menu_event = NULL; Process_file_item(4,0); /* get another name */ break; } Set_Menus(OFF); if(viewflg) WindowToFront(vw_window); if (XMODEM_Send_File(fname)) emits_rx("\nFile Sent\n"); else { close(fd); emits_rx("\nXmodem Send Failed\n"); } clear_status_line(); status_line(75,capt_status); Set_Menus(ON); Beep(); Xconfig(FALSE); asciiflg = FALSE; if(abort) emits_rx("User aborted transfer\n"); break; case EDITMAC: Add_keymacro(); break; case LOADPHONE:temp = load_plib(strbuff); if(temp) ph_nums = temp; break; case LOADKEYS: Load_keymacros(strbuff); break; case SAVEKEYS: Save_keymacros(strbuff); break; } Swap_capture(ASCCAPT,capture != TRUE); Swap_capture(ASCSEND,send != TRUE); menu_event = NULL; } /************************************************************************/ void Process_file_item( itemnum, subnum ) USHORT itemnum, subnum; { Activate(&Dirgadget); crcflag = xfrmode; /* restore selected xfer mode */ switch( itemnum ) { case 0: if (capture == TRUE) { capton = capture = FALSE; flush(); close(tranr); emits_rx("\nEnd File Capture\n"); Swap_capture(ASCCAPT,START); capt_status = stat[C_OFF]; status_line(75,capt_status); /* remove ON/SUS on screen */ } else if(getfile("Ascii Capture filename",name)) Process_menu_event( ASCCAPT ); RefreshStatus(); break; case 1: if (send == TRUE) { send = FALSE; fclose(trans); Xon(xonflg); emits_rx("\nFile Send Canceled\n"); Swap_capture(ASCSEND,START); } else if(getfile("Ascii Send filename",name)) Process_menu_event( ASCSEND ); break; case 2: tmpchopflg = chopflg; if(getfile("Xmodem Receive filename",name)) Process_menu_event( XMDRECV ); break; case 3: tmpchopflg = chopflg; if(getfile("WXmodem Receive filename",name)) Process_menu_event( WXMRECV ); break; case 5: asciiflg = TRUE; case 4: if(getfile("Xmodem Send filename",name)) Process_menu_event( XMDSEND ); else asciiflg = FALSE; break; case 6: KeepGoing = FALSE; break; } } #define FLUSH (-2) buffer_it(ch) int ch; { if( ((ch == FLUSH) && bcount) || (bcount == BufSize) ) { /* write any data in the buffer */ if(write(tranr,buffer,bcount) != bcount) { emits_rx("ERROR writing to file. File closed\n"); close(tranr); capton = capture = FALSE; } bcount = 0; } buffer[ bcount++ ] = ch; /* buffer the character */ } flush() { buffer_it( FLUSH ); } /************************************************************************ set serial port to desired baud rate */ void Process_baud_rate( itemnum ) USHORT itemnum; { int baudrate; switch( itemnum ) { case 0: baudrate = 300; break; case 1: baudrate = 1200; break; case 2: baudrate = 2400; break; case 3: baudrate = 4800; break; case 4: baudrate = 9600; break; case 5: baudrate = 19200; break; default: return; } set_baud( baudrate ); } /************************************************************************* process system menu selection. */ void Process_sys_item( itemnum, subnum ) USHORT itemnum, subnum; { UBYTE temp[80]; DeActivate(&Dirgadget); menu_event = NULL; switch ( itemnum ) { case 0: if(split_screen) { Single_Window(); SysItems[0].Flags &= ~CHECKED; } else { if( Split_Window() ) split_screen = TRUE; } break; case 1: if(viewflg) /* if view window open, close it */ { viewflg = FALSE; SysItems[1].Flags &= ~CHECKED; close_view = TRUE; } else /* else open view window */ { viewflg = TRUE; if( ( vw_window = (struct Window *) MyOpenWindow(&VWindow,(ULONG)CLOSEWINDOW | GADGETUP)) == NULL) { emits_rx("Can't open view window\n"); viewflg = FALSE; } else { vw_con = CreateStdIO(vw_con_mp); open_console(vw_window,vw_con); WindowToFront(vw_window); } } break; case 2: if(chopflg) /* fix the chop mode checkmark to match */ SysItems[2].Flags &= ~CHECKED; /* the mode desired */ else SysItems[2].Flags |= CHECKED; chopflg = !chopflg; break; case 3: switch(subnum) { case 0: eolflg &= RXCRLF; break; case 1: eolflg |= ~RXCRLF; break; case 2: eolflg &= TXCRLF; break; case 3: eolflg |= ~TXCRLF; break; } break; case 4: switch(subnum) { case 0: strcpy(strbuff,commkeys); if(getstring("LOAD","Key macro file",strbuff,MAXFNAME)== FALSE) break; menu_event = LOADKEYS; strcpy(commkeys,strbuff); break; case 1: strcpy(strbuff,commkeys); if(getstring("SAVE","Key macro file",strbuff,MAXFNAME)==FALSE) break; menu_event = SAVEKEYS; strcpy(commkeys,strbuff); break; case 2: Edit_keymacro(); menu_event = EDITMAC; break; } break; case 5: switch(subnum) { case 0: strcpy(strbuff,phonedir); if(getstring("LOAD","Phone library",strbuff,MAXFNAME)== FALSE) break; menu_event = LOADPHONE; strcpy(phonedir,strbuff); break; case 1: /* no SAVE option yet */ break; case 2: strcpy(temp,"C:ED "); strcat(temp,phonedir); WBenchToFront(); ShowTitle(commscreen,1L); Execute(temp,0L,0L); ShowTitle(commscreen,install.titlebar); WBenchToBack(); break; } break; case 6: /* title bar */ install.titlebar = (long)subnum; ShowTitle(commscreen,install.titlebar); break; } } DeActivate(gadg) struct Gadget *gadg; { gadg->Flags |= GADGDISABLED; } Activate(gadg) struct Gadget *gadg; { gadg->Flags &= ~GADGDISABLED; } /************************************************************************/ void Process_serial_item( itemnum, subnum ) USHORT itemnum, subnum; { switch( itemnum ) { case 0: Process_baud_rate( subnum ); /* BAUD rate */ break; case 1: Setparity( subnum ); /* parity */ break; case 2: Setlength( subnum ); /* word length */ break; case 3: Setstopbits( subnum ); /* stop bits */ break; case 4: halfduplex = subnum; /* duplex */ break; case 5: xonflg = subnum; /* XON/XOFF */ Xon(xonflg); break; case 6: SendBreak(); /* send break */ break; } } /************************************************************************** Initialize the system. Open windows, libraries and devices. Exit cleanly if any trouble intializing. */ void InitSystem(argc,argv) int argc; UBYTE **argv; { struct WBArg *wbarg; struct DiskObject *diskobj, *GetDiskObject(); struct WBStartup *wb_msg; struct Library *DOSbase; struct Preferences Pref; int i,args; char *ttype, *FindToolType(); UBYTE *temp; DOSbase = (struct Library *)OpenLibrary(DOSNAME,0L); if(DOSbase) dos_version = DOSbase->lh_Version; IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",(long)dos_version); if( IntuitionBase == NULL ) clean_up("Can't open intuition library\n"); GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",(long)dos_version); if( GfxBase == NULL ) clean_up("Can't open graphics library\n"); args = argc; if(argc == 0) /* called from WorkBench */ { if((IconBase = (ULONG)OpenLibrary(ICONNAME,0L)) == NULL) clean_up("Can't open Icon library\n"); PlibItems[ 2 ].Flags &= ~ITEMENABLED; /* can't use ED */ wb_msg = (struct WBStartup *)argv; wbarg = wb_msg->sm_ArgList; diskobj = GetDiskObject(wbarg->wa_Name); if( diskobj != NULL ) /* get default files from .info file */ { ttype = NULL; ttype = FindToolType(diskobj->do_ToolTypes,"PHONE"); if(ttype) strcpy(phonedir,ttype); ttype = FindToolType(diskobj->do_ToolTypes,"KEYS"); if(ttype) strcpy(commkeys,ttype); ttype = FindToolType(diskobj->do_ToolTypes,"INTERLACE"); install.interlace = (strcmp(ttype,"ON") == 0); FreeDiskObject( diskobj ); } } else { Defdir(); /* find default directory */ for(i = 1; i < argc; i++) { temp = argv[ i ]; if(*temp++ == '-') { args--; while(*temp == 'i' || *temp == 'I') { install.interlace = TRUE; temp++; } } else strcat(phonedir,argv[ i ]); } } if(*phonedir == NULL) strcpy(phonedir,PHONELIB); if(dos_version == DOS12) { RXWindow.Height = GfxBase->NormalDisplayRows - 10; RXWindow.MinHeight = GfxBase->NormalDisplayRows - 52; STWindow.TopEdge = GfxBase->NormalDisplayRows - 10; TXWindow.Height = GfxBase->NormalDisplayRows - 10; CommScreen.Height = GfxBase->NormalDisplayRows; } if(install.interlace) { CommScreen.ViewModes |= LACE; CommScreen.Height <<= 1; RXWindow.Height <<= 1; RXWindow.TopEdge <<= 1; RXWindow.MinHeight <<= 1; STWindow.TopEdge <<= 1; STWindow.TopEdge += 8; TXWindow.Height <<= 1; TXWindow.TopEdge <<= 1; TXWindow.MinHeight <<= 1; VWindow.Height <<= 1; VWindow.TopEdge <<= 1; VWindow.MaxHeight <<= 1; } /* allocate disk buffer for XMODEM must have at least 16 buffers */ for(numbufs = install.numbuffs; numbufs > 15; numbufs -= 8) if( (diskbuff = malloc( numbufs * SECSIZ)) != NULL) break; if(diskbuff == NULL) clean_up("Can't allocate disk buffers\n"); GetPrefs(&Pref,4L); commscreen = OpenScreen(&CommScreen); if(commscreen == 0) clean_up("Can't open screen\n"); prefbaud = Pref.BaudRate -1; RXWindow.Screen = STWindow.Screen = TXWindow.Screen = VWindow.Screen = STwindow.Screen = RQWindow.Screen = commscreen; if(( tx_window = OpenWindow(&TXWindow) ) == NULL) clean_up("Can't open window\n"); ViewPort = ViewPortAddress(tx_window); if(install.new_colors[0] | install.new_colors[1] | install.new_colors[2] | install.new_colors[3]) LoadRGB4(ViewPort,install.new_colors,4L); add_window_gadgets(tx_window); rx_window = tx_window; if(( stat_window = OpenWindow(&STWindow)) == NULL) clean_up("Can't open window\n"); ShowTitle(commscreen,0L); if( init_serial() == FALSE) clean_up("Can't open serial device\n"); if(Open_Timer()) clean_up("Can't open timer device\n"); timeron = TRUE; InitBeep(); tx_con_mp = CreatePort("tx_con_mp",0L); rx_con_mp = CreatePort("rx_con_mp",0L); st_con_mp = CreatePort("st_con_mp",0L); vw_con_mp = CreatePort("vw_con_mp",0L); tx_con = CreateStdIO(tx_con_mp); rx_con = CreateStdIO(rx_con_mp); st_con = CreateStdIO(st_con_mp); if( open_console(tx_window,tx_con) || open_console(rx_window,rx_con) || open_console(stat_window,st_con) ) clean_up("Error opening console device\n"); clear_status_line(); this_process = (struct Process *)FindTask(0L); if(this_process) { err_window = this_process->pr_WindowPtr; this_process->pr_WindowPtr = (APTR)rx_window; } sprintf(sbuff,"\n\t\t\t\t%s\n\n",install.version); emits_rx(sbuff); } /**********************************************************************/ clean_up(message) char *message; { if(message) puts(message); Modem_exit(); /* send parting string to modem */ Close_Beep(); /* close audio...etc. */ if( timeron ) Close_Timer(); if( diskbuff ) free( diskbuff ); Free_keymacros(); Close_Serial(); /* close serial and deallocate port and memory */ if(rx_con) { close_console(rx_con); /* close open console device */ DeleteStdIO(rx_con); } if(st_con) { close_console(st_con); /* close open console device */ DeleteStdIO(st_con); } if(tx_con) { close_console(tx_con); /* close open console device */ DeleteStdIO(tx_con); } if(vw_con) { close_console(vw_con); /* close open console device */ DeleteStdIO(vw_con); } if(tx_con_mp) DeletePort(tx_con_mp); if(vw_con_mp) DeletePort(vw_con_mp); if(rx_con_mp) DeletePort(rx_con_mp); if(st_con_mp) DeletePort(st_con_mp); if(this_process) this_process->pr_WindowPtr = err_window; if(req_window) /* if requester left around, get rid of it */ MyCloseWindow( req_window ); /* close all windows...in order */ if(stat_window) CloseWindow( stat_window ); if(st_window) MyCloseWindow( st_window ); if(vw_window ) MyCloseWindow( vw_window ); if(split_screen) MyCloseWindow( rx_window ); if(tx_window) { ClearMenuStrip( tx_window ); CloseWindow( tx_window ); } if(commscreen) CloseScreen(commscreen); if(IntuitionBase) CloseLibrary(IntuitionBase); if(GfxBase) CloseLibrary(GfxBase); if(IconBase) CloseLibrary(IconBase); exit(1); } /* end of comm 1.34 */