/* * Run.c - Copyright © 1990 by S.R. & P.C. * * Created: 16 Jun 1990 * Modified: 30 Nov 1990 18:56:38 * * Make>> make */ #include "Menu.h" #include "Tokens.h" #include "WB.h" /***** external functions *****/ extern char *copystr(char *); extern void UpDateMenus(void); extern void ParseLine(char *); /***** global functions *****/ void DoExtMenu(USHORT); void WBFree(struct WBStartup *); /***** global variables *****/ extern struct Menu Menu1; extern struct MenuItem SubItem1; extern struct Process *MyProcess; extern struct ParmMsgPort *ParMPort; extern char CurCfg[]; extern char CmdWindow[]; extern char ShellWindow[]; extern char ShellCmd[]; extern char WaitCmd[]; extern char TmpDir[]; extern char *ReqTitle; extern long DefaultStack; extern BOOL DoNextSelect; /* Warn user of a load error */ static void LoadError(char *cmd) { long err; char *msg; char buf[40]; switch(err = IoErr()) { case ERROR_NO_FREE_STORE: msg = "Not enough memory."; break; case ERROR_FILE_NOT_OBJECT: msg = "File is not an object module."; break; case ERROR_OBJECT_NOT_FOUND: msg = "File not found."; break; default: SPrintf(buf, "Error code %ld", err); msg = buf; } SimpleRequest(ReqTitle, "Couldn't load '%s'\n%s", cmd, msg); } /* Execute a CLI command as background process */ static void ARun(struct Extended_MenuItem *emi) { static struct ProcessControlBlock PCB; long CLI; PCB.pcb_StackSize = emi->emi_Stack; PCB.pcb_Pri = emi->emi_Pri; PCB.pcb_Console.pcb_ConName = emi->emi_Window; PCB.pcb_Control = (emi->emi_Window) ? PRF_STDIO : PRF_SAVEIO; if ((CLI = ASyncRun(emi->emi_Cmd, emi->emi_Args, &PCB)) <= 0) { if (CLI == PR_NOSTDIO) SimpleRequest(ReqTitle, "Couldn't open window:\n\"%s\"", emi->emi_Window); else LoadError(emi->emi_Cmd); } } /* Execute a CLI command as background or interactive shell */ static void Run(char *cmd, char *win, long stk, BYTE pri, BYTE mode) { static struct NewShell NS; BPTR fh; short i=0; char FromFile[32], CmdBuf[128]; NS.nsh_StackSize = stk; NS.nsh_Pri = pri; NS.nsh_Input = MyProcess->pr_CIS; NS.nsh_Output = MyProcess->pr_COS; NS.nsh_Control = BACKGROUND_SHELL; if (mode == TOK_SHELL) { for(;;) { SPrintf(FromFile, "%sParMCmd%d", TmpDir, i++); fh = Open(FromFile, MODE_NEWFILE); if (fh) break; else if (IoErr() != ERROR_OBJECT_IN_USE || i>32) { SimpleRequest(ReqTitle, "Unable to open script file"); return; } } FPrintf(fh, "%s\nEndCLI >NIL:\n", cmd); Close(fh); if (!win) win = ShellWindow; SPrintf(CmdBuf, "\"%s\" \"%s\" From %s", ShellCmd, win, FromFile); cmd = CmdBuf; } ASyncRun(cmd, NULL, (struct ProcessControlBlock *)&NS); } /* procedures to support running WorkBench programs */ /* * Free up space used by a workbench startup message. Called whenever * a workbench program replies to the startup message, and whenever * WBRun() gets an error. */ void WBFree(struct WBStartup *WBStartup) { register BPTR lock; register int i; register char *cp; if (WBStartup->sm_ArgList) { for( i=0 ; i<2 ; i++ ) { if (lock = WBStartup->sm_ArgList[i].wa_Lock) UnLock(lock); if (cp = WBStartup->sm_ArgList[i].wa_Name) FreeMem(cp, strlen(cp)+1); } FreeMem(WBStartup->sm_ArgList, 2*sizeof(struct WBArg)); } if (WBStartup->sm_Segment) UnLoadSeg(WBStartup->sm_Segment); FreeMem(WBStartup, sizeof(struct WBStartup)); } /* load and run a workbench program */ static void WBRun(struct Extended_MenuItem *emi) { struct WBStartup *WBStartup; struct WBArg *ArgList; struct DiskObject *DiskObject; BPTR DirLock; char Cmd[256], Dir[256], Name[32], *s; long stack; short arg; /* Tool: arg=0, Project: arg=1 */ strcpy(Cmd, emi->emi_Cmd); stack = emi->emi_Stack; if (!(WBStartup = AllocMem(sizeof(struct WBStartup), MEMF_PUBLIC|MEMF_CLEAR))) return; /* Allocate array for 2 args. Only one may be needed */ if (!(ArgList = AllocMem(2*sizeof(struct WBArg), MEMF_PUBLIC|MEMF_CLEAR))) { WBFree(WBStartup); return; } WBStartup->sm_ArgList = ArgList; WBStartup->sm_NumArgs = 1; do { strcpy(Dir, Cmd); strcpy(Name, s = BaseName(Dir)); if (s == Dir) DirLock = DupLock(MyProcess->pr_CurrentDir); else { if (*(s-1) == '/') s--; *s = '\0'; if (!(DirLock = Lock(Dir, ACCESS_READ))) { SimpleRequest(ReqTitle, "Couldn't access '%s'", Dir); WBFree(WBStartup); return; } } if (!(DiskObject = GetDiskObject(Cmd))) { arg = 0; /* No icon, assume Tool */ if (stack == 0) stack = DefaultStack; } else if (DiskObject->do_Type == WBTOOL) { arg = 0; if (stack == 0) { /* Take icon stack only if not user defined */ stack = DiskObject->do_StackSize; if (stack < 4000) stack = DefaultStack; } } else if (arg != 1 && DiskObject->do_Type == WBPROJECT) { arg = 1; WBStartup->sm_NumArgs = 2; strcpy(Cmd, DiskObject->do_DefaultTool); } else { SimpleRequest(ReqTitle, "No tool found!"); if (DiskObject) FreeDiskObject(DiskObject); WBFree(WBStartup); return; } ArgList[arg].wa_Lock = DirLock; ArgList[arg].wa_Name = copystr(Name); if (DiskObject) FreeDiskObject(DiskObject); } while(arg); WBStartup->sm_Message.mn_ReplyPort = (struct MsgPort *)ParMPort; WBStartup->sm_Message.mn_Length = sizeof(struct WBStartup); WBStartup->sm_Message.mn_Node.ln_Type = NT_MESSAGE; if (!(WBStartup->sm_Segment = LoadSeg(Cmd))) { LoadError(Cmd); WBFree(WBStartup); return; } if (!(WBStartup->sm_Process = (struct MsgPort *)CreateProc(Name, emi->emi_Pri, WBStartup->sm_Segment, stack))) { SimpleRequest(ReqTitle, "Couldn't execute '%s'", Cmd); WBFree(WBStartup); return; } PutMsg(WBStartup->sm_Process, (struct Message *)WBStartup); ParMPort->pmp_MsgCnt++; /* keep track of unreplied startup messages */ } void DoExtMenu(USHORT MenuNum) { struct Extended_MenuItem *Item; Item = (struct Extended_MenuItem *) ItemAddress(&Menu1, MenuNum); switch (Item->emi_Mode) { case TOK_ARUN: ARun(Item); break; case TOK_RUN: case TOK_SHELL: Run(Item->emi_Cmd, Item->emi_Window, Item->emi_Stack, Item->emi_Pri, Item->emi_Mode); break; case TOK_WB: WBRun(Item); break; case TOK_CFG: /* new cfg */ strcpy(CurCfg, Item->emi_Cmd); UpDateMenus(); DoNextSelect = FALSE; /* Tell DoIntuiMsg not to execute next menu selection */ } } #define CMDBUFSIZE 255 void Command(void) { static struct NewShell NS; static char Buffer[CMDBUFSIZE+1]; BPTR fh = NULL; char CmdBuf[CMDBUFSIZE+12]; USHORT ExecMode; ExecMode = SubItem1.Flags & CHECKED; if (ExecMode && !(fh = Open(CmdWindow, MODE_NEWFILE))) return; if (GetString(Buffer, "Enter command...", NULL, 45, CMDBUFSIZE)) { if (ExecMode) { Execute(Buffer, 0, fh); FPrintf(fh, "Hit return...›0 p"); Read(fh, CmdBuf, 1L); } else { SPrintf(CmdBuf, "%s;%s", Buffer, WaitCmd); ParseLine(CmdBuf); Run(CmdBuf, CmdWindow, DefaultStack, 0, TOK_SHELL); } } if (ExecMode) Close(fh); }