home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 1
/
GoldFishApril1994_CD2.img
/
d4xx
/
d419
/
parm
/
run.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-12-18
|
7KB
|
295 lines
/*
* 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);
}