home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
455.lha
/
ParM
/
Run.c
< prev
Wrap
C/C++ Source or Header
|
1990-12-10
|
7KB
|
276 lines
/*
* Run.c - Copyright © 1990 by S.R. & P.C.
*
* Created: 16 Jun 1990
* Modified: 07 Jul 1990
*
* Make>> make
*/
/*
#define DO_ARP_COPIES
#include <libraries/arpbase.h>
#include <functions.h>
#include <exec/memory.h>
#include <workbench/startup.h>
#include <libraries/dosextens.h>
#include <workbench/workbench.h>
*/
#include <dos_functions.h>
#include <arpdos_pragmas.h>
#include "ParM.h"
/* Error messages */
static const char *ErrNoMem = "Out of memory!";
static const char *NoCmd = "Can't execute command!";
static const char *NoInfo = "Can't open info file!";
/***** external functions *****/
extern char *copystr( char * );
extern void Warn( const char * );
/***** global functions *****/
void DoExtMenu( USHORT );
void WBFree( struct WBStartup * );
/***** global variables *****/
extern struct Menu Menu1;
extern struct Process *MyProcess;
extern struct MsgPort *WBReplyPort;
extern short WBCnt;
/* execute a RB command */
static BOOL RunBack(char *cmd, char *args)
{
BPTR NilFh;
char buf[256];
BOOL ret;
SPrintf(buf,"Run >NIL: <NIL: \"%s\" >NIL: <NIL: %s",cmd,args);
NilFh = Open("NIL:",MODE_NEWFILE);
if( NilFh ) {
ret = Execute(buf,NULL,(struct FileHandle *)NilFh);
Close(NilFh);
}
else
ret = FALSE;
return ret;
}
/* execute a CLI command */
static void CLIRun(struct Extended_MenuItem *emi)
{
struct ProcessControlBlock *pcb;
long CLI;
if( pcb=AllocMem(sizeof(struct ProcessControlBlock),MEMF_PUBLIC|MEMF_CLEAR) ) {
pcb->pcb_StackSize = emi->emi_Stack;
pcb->pcb_Pri = emi->emi_Pri;
pcb->pcb_Console.pcb_ConName = emi->emi_Window;
pcb->pcb_Control = PRF_STDIO;
CLI = ASyncRun(emi->emi_Cmd, emi->emi_Args, pcb);
FreeMem(pcb, sizeof(struct ProcessControlBlock));
if (CLI<=0) {
switch( CLI ) {
case PR_NOFILE :
Warn("Command not found");
break;
case PR_NOSTDIO :
Warn("Can't open window");
break;
default :
Warn(NoCmd);
}
}
}
else
Warn(ErrNoMem);
}
/* 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 ) {
if( WBStartup->sm_ArgList ) {
for (i=0; i<WBStartup->sm_NumArgs; 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,sizeof(struct WBArg)*WBStartup->sm_NumArgs);
}
if( WBStartup->sm_Segment ) UnLoadSeg(WBStartup->sm_Segment);
if( cp=WBStartup->sm_ToolWindow ) FreeMem(cp, strlen(cp)+1);
FreeMem( WBStartup , sizeof(struct WBStartup) );
}
}
/* take the path passed, and split it into a lock and name,
suitable for putting into a WBArg structure */
static void SplitPath( char *path, BPTR *dir_lock, char **name)
{
register BPTR lock;
*name = BaseName(path);
lock = Lock(path, ACCESS_READ);
if( lock ) {
*dir_lock = (BPTR)ParentDir((struct FileLock *)lock);
UnLock(lock);
} else
*dir_lock = DupLock(MyProcess->pr_CurrentDir);
}
/* load and run a workbench program */
static void WBRun( char *cmd )
{
BPTR lock = NULL, OldLock = NULL;
struct WBStartup *WBStartup = NULL;
struct DiskObject *disk_object = NULL;
char *name, buf[128];
BOOL error = TRUE; /* assume the worst */
/* allocate the startup message */
if( !(WBStartup = (struct WBStartup *)AllocMem(sizeof(struct WBStartup),MEMF_PUBLIC|MEMF_CLEAR)) ) {
Warn(ErrNoMem);
return; /* don't go to finish:, nothing allocated yet */
}
/* find the directory and name of the program to run */
SplitPath(cmd, &lock, &name);
if( !lock ) {
Warn(NoCmd);
goto finish;
}
/* try to load in the .info file */
OldLock = (BPTR)CurrentDir((struct FileLock *)lock);
if( !(disk_object = GetDiskObject(name)) ) {
Warn(NoInfo);
goto finish;
}
/* allocate the WBArgs - if we are a tool, we allocate one */
/* of these, else two (one for tool, one for project) */
if( disk_object->do_Type == WBTOOL ) {
if( !(WBStartup->sm_ArgList = (struct WBArg *)AllocMem(sizeof(struct WBArg), MEMF_PUBLIC|MEMF_CLEAR)) ) {
Warn(ErrNoMem);
goto finish;
}
WBStartup->sm_NumArgs = 1;
} else if( disk_object->do_Type == WBPROJECT ) {
if( !(WBStartup->sm_ArgList = (struct WBArg *)AllocMem(sizeof(struct WBArg)*2, MEMF_PUBLIC|MEMF_CLEAR)) ) {
Warn(ErrNoMem);
goto finish;
}
WBStartup->sm_NumArgs = 2;
/* fill in arg #2 with the info we already have */
WBStartup->sm_ArgList[1].wa_Lock = (BPTR)lock;
WBStartup->sm_ArgList[1].wa_Name = copystr(name);
/* now find the tool */
strcpy( buf , disk_object->do_DefaultTool );
SplitPath( buf , &lock , &name );
FreeDiskObject( disk_object );
CurrentDir( (struct FileLock *)lock );
if( !(disk_object = GetDiskObject(name)) ) {
Warn(NoInfo);
goto finish;
}
/* we have to have a tool at this point - or else */
if( disk_object->do_Type != WBTOOL ) {
Warn("Not a tool or project!");
goto finish;
}
}
/* fill in arguments */
WBStartup->sm_ArgList[0].wa_Lock = (BPTR)lock;
WBStartup->sm_ArgList[0].wa_Name = copystr(name);
/* initialize rest of startup message */
WBStartup->sm_Message.mn_ReplyPort = WBReplyPort;
WBStartup->sm_Message.mn_Length = sizeof(struct WBStartup);
WBStartup->sm_Message.mn_Node.ln_Type = NT_MESSAGE;
WBStartup->sm_ToolWindow = copystr(disk_object->do_ToolWindow);
/* get a decent stack size, there are a few progs that set this to zero */
if( disk_object->do_StackSize < 4000 ) disk_object->do_StackSize = 4000;
/* load in the program */
if( !(WBStartup->sm_Segment = (BPTR)LoadPrg(name)) ) {
Warn(NoCmd);
goto finish;
}
/* create process */
if( !(WBStartup->sm_Process = (struct MsgPort *)CreateProc(name, 0, WBStartup->sm_Segment, disk_object->do_StackSize)) ) {
Warn(NoCmd);
goto finish;
}
/* everything's ok -- start 'er up */
PutMsg( WBStartup->sm_Process , (struct Message *)WBStartup );
error = FALSE;
WBCnt++; /* keep track of unreplied startup messages */
finish:
if( disk_object ) FreeDiskObject( disk_object );
CurrentDir( (struct FileLock *)OldLock );
if( error ) WBFree( WBStartup );
}
void DoExtMenu( USHORT MenuNum )
{
struct Extended_MenuItem *Item;
Item = (struct Extended_MenuItem *)ItemAddress( &Menu1 , MenuNum );
switch( Item->emi_Mode ) {
case 'r' :
if( !RunBack(Item->emi_Cmd,Item->emi_Args) ) Warn(NoCmd);
break;
case 'c' :
CLIRun(Item);
break;
case 'w' :
WBRun( Item->emi_Cmd );
break;
}
}