/*************************************************************** * vt100 - terminal emulator - initialization * :ts=8 * * v2.9 ACS - Support new cmds EXT. Use S and R for Send and Receive menu * items instead of ^ and V. AREXX support. * v2.8a 880331 ACS - Allow lines 0 in init file to *really* mean * "use all available lines". * v2.7 870825 ACS - Allow execution of all script files specified on * command line (companion to changes in script.c). * Rolled menu init into one routine (do_menu_init()). * v2.6 870227 DBW - bug fixes for all the stuff in v2.5 * v2.5 870214 DBW - more additions (see readme file) * v2.4 861214 DBW - lots of fixes/additions (see readme file) * v2.3 861101 DBW - minor bug fixes * v2.2 861012 DBW - more of the same * v2.1 860915 DBW - new features (see README) * 860901 ACS - Added Parity and Word Length and support code * 860823 DBW - Integrated and rewrote lots of code * v2.0 860809 DBW - Major rewrite * v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes * v1.0 860712 DBW - First version released * ***************************************************************/ #include "vt100.h" struct Device *ConsoleDevice = NULL; struct IOStdReq ConReq; extern APTR OrigWindowPtr; extern int capture; /* in vt100.c */ /* Used by script.c for script file chaining. */ int script_files_todo = 0; char **script_files = NULL; char line[256]; /* Command key equivalences per menu. Manipulated by script.c */ /* Equivalences for the File menu... */ struct filecmd { char mo; /* Mode */ char se; /* Send */ char re; /* Receive */ char kg; /* Kermit Get */ char kb; /* Kermit Bye */ char ca; /* Capture or Capturing */ char nl; } filecmd_chars = { ' ', 'S', 'R', 'G', 'B', ' ', '\0' }; /* Equivalences for Mode sub-menu... */ struct mode_cmd { char as; /* ascii mode */ char xm; /* xmodem mode */ char xmc; /* xmodemcrc mode */ char ke; /* kermit mode */ char nl; } modecmd_chars = { ' ', 'X', ' ', 'K', '\0' }; /* Equivalences for the Comm menu... */ struct commcmd { char nl0; /* Baud Sub-Item */ char nl1; /* Parity Sub-Item */ char nl2; /* Xfer mode Sub-Item */ char sh; /* Shared item */ char nl; } commcmd_chars = { ' ', ' ', ' ', ' ', '\0' }; /* Equivalences for the Baud Rate sub-menu... */ struct baudcmd { char b03; /* 0300 */ char b12; /* 1200 */ char b24; /* 2400 */ char b48; /* 4800 */ char b96; /* 9600 */ char bnl; } baudcmd_chars = { ' ', 'L', 'H', ' ', ' ', '\0' }; /* Equivalences for the Parity sub-menu... */ struct parcmd { char no; /* NOne */ char ma; /* MArk */ char sp; /* SPace */ char ev; /* EVen */ char od; /* ODd */ char nl; } parcmd_chars = { 'N', ' ', ' ', 'E', 'O', '\0' }; /* Equivalences for the Xfer Mode sub-menu... */ struct modcmd { char im; /* IMage */ char tx; /* TeXt */ char cn; /* CoNvert */ char ac; /* AutoChop */ char nl; } modcmd_chars = { 'I', 'T', ' ', ' ', '\0' }; /* Equivalences for the Script menu... */ struct scrcmd { char em; /* Execute Macro */ char ab; /* Abort Macro */ char rc; /* AREXX Macro */ char nl; } scrcmd_chars = { 'M', 'A', ' ', '\0' }; /* Equivalences for the Utility menu... */ struct utilcmd { char sb; /* Send Break */ char hu; /* Hang Up */ char cd; /* Change Dir */ char cs; /* Clear Screen */ char ec; /* ECho */ char wr; /* WRap */ char nk; /* Num Key */ char ac; /* App Cur */ char bs; /* BS<->DEL */ char xb; /* Xfer beep */ char mu; /* Mouse up events */ char md; /* Mouse down events */ char nl; } utilcmd_chars = { '.', ' ', 'D', ' ', ' ', 'W', 'K', 'C', ' ', ' ', ' ', ' ', '\0' }; static char *filetext[] = { "Protocol", "Send", "Receive", "Kermit Get", "Kermit BYE", "Capture" }; static char *modetext[] = { " Ascii", " Xmodem", " XmodemCRC", " Kermit" }; static char *commtext[] = { "Baud Rate", "Parity ", "Xfer Mode", " Shared ", }; static char *baudtext[] = { " 300", " 1200", " 2400", " 4800", " 9600" }; static char *partext[] = { " None ", " Mark ", " Space", " Even ", " Odd " }; static char *modtext[] = { " Image ", " Text ", " Convert", " AutoChop" }; static char *scrtext[] = { "Execute Macro", "Abort Execution", "AREXX Macro" }; static char *utiltext[] = { "Send Break", "Hang Up", "Change Dir", "Clear Scrn", " Echo", " Wrap", " Num Key", " App Cur", " BS<->DEL", " Xfer Beep", " Mouse Up", " Mouse Dn", }; struct HowToInit { int LeftEdge; /* in characters, NOT pixels */ int Width; /* ditto */ ULONG Flags; char **text; char *cmdkeys; }; static struct HowToInit menu_init[] = { { 0, 20, ITEMTEXT | ITEMENABLED | HIGHCOMP, filetext, (char *)(&filecmd_chars) }, {10, 17, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | MENUTOGGLE, modetext, (char *)(&modecmd_chars) }, { 0, 11, ITEMTEXT | ITEMENABLED | HIGHCOMP, commtext, (char *)(&commcmd_chars) }, { 10, 12, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | MENUTOGGLE, baudtext, (char *)(&baudcmd_chars) }, { 10, 12, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | MENUTOGGLE, partext, (char *)(&parcmd_chars) }, { 10, 15, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | MENUTOGGLE, modtext, (char *)(&modcmd_chars) }, { 0, 20, ITEMTEXT | ITEMENABLED | HIGHCOMP, scrtext, (char *)(&scrcmd_chars) }, { 0, 16, ITEMTEXT | ITEMENABLED | HIGHCOMP, utiltext, (char *)(&utilcmd_chars) } }; #define FILE_INIT_ENTRY (&(menu_init[0])) #define MODE_INIT_ENTRY (&(menu_init[1])) #define COMM_INIT_ENTRY (&(menu_init[2])) #define RS_INIT_ENTRY (&(menu_init[3])) #define PAR_INIT_ENTRY (&(menu_init[4])) #define XF_INIT_ENTRY (&(menu_init[5])) #define SCRIPT_INIT_ENTRY (&(menu_init[6])) #define UTIL_INIT_ENTRY (&(menu_init[7])) void do_menu_init(); #if AREXX char *rexxerrmsgs[] = { "", "No AREXX library - AREXX unavailable.", "Can't contact AREXX server - AREXX unavailable.", "Can't create an AREXX msg - AREXX unavailable.", "Can't get memory for hostname.", "VT100 AREXX port already present - another VT100 up?", "Can't get memory for AREXX port." }; #endif /* AREXX */ char *InitDefaults(argc,argv) int argc; char **argv; { FILE *fd = NULL; char *p = NULL, *ifile, temp[80]; int i, l, dont_init = 0, customfudge, maxrows, maxlines; for(l = 0; l < EXTMAX; l++) ExtXfer[l] = NULL; doing_init = 1; /* make sure we only allow INIT script commands */ if (argc > 1) { int start_of_script_files = 1; if(strcmp(argv[1], "-i") == 0) { /* No init file */ dont_init = 1; start_of_script_files = 2; } else if(strcmp(argv[1], "+i") == 0) { /* Use specified init file */ start_of_script_files = 3; if((fd=fopen(argv[2],"r")) == NULL) { ifile = AllocMem((LONG)(strlen(argv[2])+3), MEMF_PUBLIC|MEMF_CLEAR); strcpy(ifile, "S:"); strcat(ifile, argv[2]); fd = fopen(ifile, "r"); FreeMem(ifile, (LONG)(strlen(argv[2])+3)); ifile = NULL; } } if(start_of_script_files > argc) script_files_todo = 0; else script_files_todo = argc - start_of_script_files; /* # of cmdline script files left */ script_files = &(argv[start_of_script_files]); /* Ptr to first of 'em */ } if((p_font == NULL) || (p_font[0] == '\0')) strcpy(myfontname, "topaz"); else strcpy(myfontname, p_font); /* Init font name */ strcat(myfontname, ".font"); if((p_device == NULL) || (p_device[0] == '\0')) strcpy(mysername, SERIALNAME); else strcpy(mysername, p_device); #if AREXX /* Setup the AREXX interface now so user can use it during init. */ if( (RexxSysBase = (struct RxsLib *)OpenLibrary(RXSNAME, 0L)) == NULL) puts("Can't open rexxsyslib.library - AREXX unavailable."); else if( (i = makerexxport()) != 0) cleanup(rexxerrmsgs[i], 256); #endif /* AREXX */ if(!dont_init) if((fd == NULL) && ((fd=fopen("vt100.init","r")) == NULL)) fd=fopen("s:vt100.init","r"); if(fd != NULL) { while (fgets(line,256,fd) != 0) { if(line[strlen(line)-1] == '\n') line[strlen(line)-1] = '\000'; p = next_wrd(&line[0],&l); if (*p) { *p |= ' '; if (p[1]) p[1] |= ' '; if (*p == '#') continue; if (strncmp(p, "exi", 3) == 0) break; exe_cmd(p,l); } } fclose(fd); } doing_init = 0; IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", INTUITION_REV); if( IntuitionBase == NULL ) cleanup("can't open intuition",1); GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",GRAPHICS_REV); if( GfxBase == NULL ) cleanup("can't open graphics library",2); DiskfontBase = (struct Library *)OpenLibrary("diskfont.library", 0L); if(DiskfontBase == NULL) cleanup("can't open diskfont library", 2); if ( (myfont = (struct TextFont *)OpenFont(&myattr)) == NULL && (myfont = (struct TextFont *)OpenDiskFont(&myattr)) == NULL) { sprintf(temp, "Can't open font %s", myfontname); cleanup(temp, 4); } Xsize = myfont->tf_XSize; Ysize = myfont->tf_YSize; BaseLine = myfont->tf_Baseline; /* Now set up all the screen info as necessary */ maxrows = GfxBase->NormalDisplayRows; /* If user wants to use the current interlace setting then set p_interlace ** according to what the ViewLord says it is. */ if(p_interlace == 2) p_interlace = ((IntuitionBase->ViewLord.Modes & LACE) == LACE) ? 1 : 0; else if((p_screen == 0) && ((IntuitionBase->ViewLord.Modes & LACE) == 0)) p_interlace = 0; if(p_interlace) maxrows *= 2; customfudge = (p_screen == 1) ? 4 : 0; /* See if user wants to use everything available (specified LINES 0).If ** so then set p_lines so we'll leave room for the window title. ** (Ysize + 1) is the size of the window title bar. ** (Ysize + 1 + customfudge) is used to allow us to account for the the 4 ** scan-lines we'll allow in CUSTOM screen mode so that the user can pull ** the window down to expose the screen's depth arrangement gadgets. Note ** that it's OK to overwrite the last 2 lines or so of the window-title bar ** (that's why we take the remainder first). **/ if( ((maxrows - (Ysize + 1 - customfudge)) % Ysize) > (Ysize - 2) ) maxlines = (maxrows - Ysize + customfudge) / Ysize; else maxlines = (maxrows - (Ysize + 1 + customfudge)) / Ysize; if(p_lines == 0) p_lines = maxlines; else if (p_lines > maxlines) p_lines = maxlines; /* Set MINY. MINY will be adjusted so we'll overwrite part of the ** window title bar if necessary to get the last line to end at the bottom ** of the window. ** Remember that MINY is the location of the BASELINE of the character. */ { int end = (Ysize + 2) + (p_lines * Ysize); MINY = Ysize + 2; if(end > maxrows) MINY -= (end - maxrows); MINY += BaseLine; } if(p_screen == 1 && p_interlace == 1) NewScreen.ViewModes |= LACE; MAXY = MINY + ((p_lines - 1) * Ysize); top = MINY; bot = MAXY; savx = MINX; savy = MINY; NewWindow.Height = MAXY + customfudge + (Ysize - BaseLine); NewWindow.MinHeight = NewWindow.Height; NewWindow.MaxHeight = NewWindow.Height; NewReqWindow.MaxHeight = NewWindow.Height; NewWindow.TopEdge = 0L; if (p_screen == 1) { if (p_depth > 2) p_depth = 2; else if (p_depth < 1) p_depth = 1; NewScreen.Depth = (long)p_depth; NewScreen.Height = NewWindow.Height + customfudge; NewScreen.TopEdge = 0; } else { p_depth = 2L; NewWindow.Screen = NULL; NewReqWindow.Screen = NULL; NewWindow.Type = WBENCHSCREEN; NewReqWindow.Type = WBENCHSCREEN; } /* see if we exit with a startup script */ if (strncmp(p, "exi", 3) == 0) { p = next_wrd(p+l+1,&l); if (*p) return(p); } if (script_files_todo > 0) { script_files_todo--; return(*(script_files++)); } return(NULL); } void InitDevs() { USHORT colors[4]; int i; BYTE *b,*c; struct Process *mproc; if (p_screen == 1) { if ((myscreen = (struct Screen *)OpenScreen(&NewScreen)) == NULL) cleanup("can't open screen",3); NewWindow.Screen = myscreen; NewReqWindow.Screen = myscreen; } if ((mywindow = (struct Window *)OpenWindow(&NewWindow)) == NULL) cleanup("can't open window",4); if(OpenDevice("console.device", -1L, &ConReq, 0L)) cleanup("can't open console", 4); ConsoleDevice = ConReq.io_Device; if(p_screen == 1) { /* Cause system reqs to come to this screen */ mproc = (struct Process *)FindTask(0L); OrigWindowPtr = mproc->pr_WindowPtr; mproc->pr_WindowPtr = (APTR)mywindow; } myviewport = (struct ViewPort *)ViewPortAddress(mywindow); myrastport = (struct RastPort *)mywindow->RPort; SetFont(myrastport,myfont); if (p_depth > 1) myrequest.BackFill = 2; if (p_screen != 0 && p_wbcolors == 0) { colors[0] = p_background; colors[1] = p_foreground; colors[2] = p_bold; colors[3] = p_cursor; if (p_depth == 1) LoadRGB4(myviewport, colors, 2L); else LoadRGB4(myviewport, colors, 4L); } Read_Request = (struct IOExtSer *) AllocMem((long)sizeof(*Read_Request),MEMF_PUBLIC|MEMF_CLEAR); Read_Request->io_SerFlags = (p_shared ? SERF_SHARED : 0); Read_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L); if(OpenDevice(mysername, (LONG)p_unit, (struct IORequest *)Read_Request, NULL)) cleanup("Can't open Read device",5); rs_in = malloc(p_buffer+1); Read_Request->io_SerFlags = 0L; Read_Request->io_Baud = p_baud; Read_Request->io_ReadLen = 8L; Read_Request->io_WriteLen = 8L; Read_Request->io_CtlChar = 0x11130000L; Read_Request->io_RBufLen = p_buffer; Read_Request->io_BrkTime = p_break; Read_Request->IOSer.io_Command = SDCMD_SETPARAMS; DoIO((struct IORequest *)Read_Request); Read_Request->IOSer.io_Command = CMD_READ; Read_Request->IOSer.io_Length = 1; Read_Request->IOSer.io_Data = (APTR) &rs_in[0]; Write_Request = (struct IOExtSer *) AllocMem((long)sizeof(*Write_Request),MEMF_PUBLIC|MEMF_CLEAR); b = (BYTE *)Read_Request; c = (BYTE *)Write_Request; for (i=0;iIOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L); Write_Request->IOSer.io_Command = CMD_WRITE; Write_Request->IOSer.io_Length = 1; Write_Request->IOSer.io_Data = (APTR) &rs_out[0]; Timer_Port = CreatePort("Timer Port",0L); Script_Timer_Port = CreatePort("Timer Port",0L); if (OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)&Timer, NULL) || OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)&Script_Timer, NULL)) cleanup("can't open timer device",7); Timer.tr_node.io_Message.mn_ReplyPort = Timer_Port; Timer.tr_node.io_Command = TR_ADDREQUEST; Timer.tr_node.io_Flags = 0; Timer.tr_node.io_Error = 0; Script_Timer.tr_node.io_Message.mn_ReplyPort = Script_Timer_Port; Script_Timer.tr_node.io_Command = TR_ADDREQUEST; Script_Timer.tr_node.io_Flags = 0; Script_Timer.tr_node.io_Error = 0; BeepWave = (UBYTE *)AllocMem(BEEPSIZE,(long)(MEMF_CHIP|MEMF_CLEAR)); if (BeepWave != 0) BeepWave[0] = 100; Audio_Port = CreatePort("Audio Port",0L); Audio_Request.ioa_Request.io_Message.mn_ReplyPort = Audio_Port; Audio_Request.ioa_Request.io_Message.mn_Node.ln_Pri = 85; Audio_Request.ioa_Data = Audio_AllocMap; Audio_Request.ioa_Length = (ULONG) sizeof(Audio_AllocMap); if (OpenDevice(AUDIONAME, NULL, (struct IORequest *)&Audio_Request, NULL)) cleanup("can't open audio device",8); Audio_Request.ioa_Request.io_Command = CMD_WRITE; Audio_Request.ioa_Request.io_Flags = ADIOF_PERVOL; Audio_Request.ioa_Data = BeepWave; Audio_Request.ioa_Length = BEEPSIZE; Audio_Request.ioa_Period = COLORCLOCK / (BEEPSIZE * BEEPFREQ); Audio_Request.ioa_Volume = p_volume; Audio_Request.ioa_Cycles = 100; } /*****************************************************************/ /* The following function initializes the structure arrays */ /* needed to provide the File menu topic. */ /*****************************************************************/ void InitFileItems() { int n, nxfer; struct HowToInit Externs; /* for the external xfer pgms */ char *p, *p1; if(capture == TRUE) filetext[FILEMAX-1] = "Capturing"; else filetext[FILEMAX-1] = "Capture"; do_menu_init(FileItem, FileText, FILE_INIT_ENTRY, FILEMAX); FileItem[0].SubItem = ModeItem; do_menu_init(ModeItem, ModeText, MODE_INIT_ENTRY, MODEMAX); p = (char *)&Externs; p1 = (char *)MODE_INIT_ENTRY; for(n = 0; n < sizeof(struct HowToInit); n++) *(p++) = *(p1++); nxfer = MODEMAX; for(n = 0; n < NumExts; n++) { struct ExternalXfer *exp = ExtXfer[n]; nxfer = n + MODEMAX; ModeItem[nxfer-1].NextItem = &ModeItem[nxfer]; Externs.text = &exp->dispname; *Externs.cmdkeys = exp->cmdkey; do_menu_init(&ModeItem[nxfer], &ModeText[nxfer], &Externs, 1); ModeItem[nxfer].TopEdge = 10 * nxfer; } for(n = 0; n <= nxfer; n++ ) { ModeItem[n].MutualExclude = (~(1 << n)); } if(p_xproto > nxfer) { p_xproto = MODEMAX - 1; } ModeItem[p_xproto].Flags |= CHECKED; } /****************************************************************** ** Main Comm menu ** set up for Baud & Parity submenus *******************************************************************/ void InitCommItems() { int n; do_menu_init(CommItem, CommText, COMM_INIT_ENTRY, COMMAX); CommItem[0].SubItem = RSItem; CommItem[1].SubItem = ParItem; CommItem[2].SubItem = XFItem; CommItem[3].Flags |= CHECKIT | MENUTOGGLE; if(p_shared) CommItem[3].Flags |= CHECKED; else CommItem[3].Flags &= (-1L ^ CHECKED); /*****************************************************************/ /* The following initializes the structure arrays */ /* needed to provide the BaudRate Submenu topic. */ /*****************************************************************/ do_menu_init(RSItem, RSText, RS_INIT_ENTRY, RSMAX); for( n=0; n 3) UtilItem[n].Flags |= CHECKIT | MENUTOGGLE; } if (p_echo) UtilItem[4].Flags |= CHECKED; if (p_wrap) UtilItem[5].Flags |= CHECKED; if (p_keyapp == 0) UtilItem[6].Flags |= CHECKED; if (p_curapp) UtilItem[7].Flags |= CHECKED; if (p_bs_del) UtilItem[8].Flags |= CHECKED; if (p_xbeep) UtilItem[9].Flags |= CHECKED; if(p_mouse_up) UtilItem[10].Flags |= CHECKED; if(p_mouse_down) UtilItem[11].Flags |= CHECKED; swap_bs_del(); /* Setup keys[] properly... */ swap_bs_del(); /* ...for mode */ } /****************************************************************/ /* The following function inits the Menu structure array with */ /* appropriate values for our simple menu. Review the manual */ /* if you need to know what each value means. */ /****************************************************************/ void InitMenu() { menu[0].NextMenu = &menu[1]; menu[0].LeftEdge = 5; menu[0].TopEdge = 0; menu[0].Width = 40; menu[0].Height = 10; menu[0].Flags = MENUENABLED; menu[0].MenuName = "File"; /* text for menu-bar display */ menu[0].FirstItem = &FileItem[0]; /* pointer to first item in list */ menu[1].NextMenu = &menu[2]; menu[1].LeftEdge = 55; menu[1].TopEdge = 0; menu[1].Width = 88; menu[1].Height = 10; menu[1].Flags = MENUENABLED; menu[1].MenuName = "Comm Setup"; /* text for menu-bar display */ menu[1].FirstItem = &CommItem[0]; /* pointer to first item in list */ menu[2].NextMenu = &menu[3]; menu[2].LeftEdge = 153; menu[2].TopEdge = 0; menu[2].Width = 56; menu[2].Height = 10; menu[2].Flags = MENUENABLED; menu[2].MenuName = "Script"; /* text for menu-bar display */ menu[2].FirstItem = &ScriptItem[0]; /* pointer to first item in list*/ menu[3].NextMenu = NULL; menu[3].LeftEdge = 225; menu[3].TopEdge = 0; menu[3].Width = 64; menu[3].Height = 10; menu[3].Flags = MENUENABLED; menu[3].MenuName = "Utility"; /* text for menu-bar display */ menu[3].FirstItem = &UtilItem[0]; /* pointer to first item in list*/ } void do_menu_init(menuitem, menutext, initentry, max) struct MenuItem menuitem[]; struct IntuiText menutext[]; struct HowToInit *initentry; int max; { int n, nplus1; char **temp; /* initialize each menu item and IntuiText with loop */ for( n=0; n < max; n++ ) { nplus1 = n + 1; temp = initentry->text; menutext[n].IText = (UBYTE *)temp[n]; menuitem[n].NextItem = &menuitem[nplus1]; menuitem[n].LeftEdge = initentry->LeftEdge * Ysize; menuitem[n].TopEdge = 10 * n; menuitem[n].Width = initentry->Width * Ysize; menuitem[n].Height = 10; menuitem[n].Flags = initentry->Flags; menuitem[n].MutualExclude = 0; menuitem[n].ItemFill = (APTR)&menutext[n]; menuitem[n].SelectFill = NULL; if((initentry->cmdkeys != NULL) && (initentry->cmdkeys[n]) && (initentry->cmdkeys[n] != ' ')) { menuitem[n].Command = initentry->cmdkeys[n]; menuitem[n].Flags |= COMMSEQ; } else menuitem[n].Command = 0; menuitem[n].SubItem = NULL; menuitem[n].NextSelect = 0; menutext[n].FrontPen = 0; menutext[n].BackPen = 1; menutext[n].DrawMode = JAM2;/* render in fore and background */ menutext[n].LeftEdge = 0; menutext[n].TopEdge = 1; menutext[n].ITextFont = NULL; menutext[n].NextText = NULL; } menuitem[max-1].NextItem = NULL; } #if AREXX makerexxport() { int i, ret = 0; long hostlen = strlen(HOSTNAMEROOT) + strlen(mysername) + 1 + 2 + 1; /* "VT100-" name "-" "xx" \0 */ if(HostName) { FreeMem(HostName, (ULONG)(strlen(HostName)+1)); HostName = NULL; } if( (HostName = AllocMem(hostlen, MEMF_PUBLIC | MEMF_CLEAR)) == NULL) return NOHOSTMEM; sprintf(HostName, "%s%s-%02d", HOSTNAMEROOT, mysername, p_unit); Forbid(); if(FindPort(HostName) != NULL) ret = HAVEVT100PORT; else if( (FromRexxPort = (struct MsgPort *)AllocMem((LONG)sizeof(struct MsgPort), MEMF_PUBLIC | MEMF_CLEAR)) == NULL) ret = NOPORTMEM; else { InitPort(FromRexxPort, HostName); AddPort(FromRexxPort); } Permit(); if(ret && RexxSysBase) { CloseLibrary((struct Library *)RexxSysBase); RexxSysBase = NULL; } return ret; } #endif /* AREXX */