home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Otherware
/
Otherware_1_SB_Development.iso
/
amiga
/
utility
/
misc
/
toolmng.lzh
/
ToolManager
/
Source
/
starttools.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-10
|
11KB
|
370 lines
/*
* starttools.c V1.5
*
* CLI & WB startup procedure
*
* (c) 1991 by Stefan Becker
*
*/
#include "ToolManager.h"
#define CMDLINELEN 4096
/* Structure for path list */
struct PathList {
BPTR NextPath; /* Pointer to next PathList */
BPTR PathLock; /* Lock on directory */
};
/* Build a path list from a string */
static BOOL BuildPathList(struct PathList **pla, struct PathList **plc, char *s)
{
/* Path string valid? */
if (s)
{
char *ps;
/* Yes, copy path string */
if (ps=strdup(s))
{
struct FileInfoBlock *fib;
/* Get memory for FIB */
if (fib=calloc(sizeof(struct FileInfoBlock),1))
{
char *cp1,*cp2=ps;
struct PathList *pl1=*plc,*pl2=NULL;
/* For every path part */
while (cp1=cp2)
{
/* Search next path part */
cp2=strchr(cp1,',');
if (cp2)
{
*cp2='\0'; /* Add string end character */
cp2++; /* Move to next character */
}
/* Get memory for path list entry */
if (!pl2 &&
!(pl2=AllocVec(sizeof(struct PathList),MEMF_PUBLIC|MEMF_CLEAR)))
{
free(fib);
free(ps);
return(FALSE);
}
/* Get lock */
if (pl2->PathLock=Lock(cp1,SHARED_LOCK))
/* Is it a directory? */
if (Examine(pl2->PathLock,fib) && (fib->fib_DirEntryType>0))
{
/* Yes, it is a directory, append it to the list. Head of list? */
if (*pla)
{
pl1->NextPath=MKBADDR(pl2); /* No, chain new entry into list */
pl1=pl2;
}
else
*pla=pl1=pl2; /* Yes, start of list */
/* Invalidate pointer, next time a new PathList will be allocated */
pl2=NULL;
}
else UnLock(pl2->PathLock); /* No, it is a file */
}
*plc=pl1; /* Save end of list */
if (pl2) FreeVec(pl2); /* Last Lock() failed, free memory */
free(fib);
}
free(ps);
}
}
return(TRUE);
}
/* Start tool as a CLI process */
static BOOL StartCLITool(struct AppMessage *msg, struct ToolNode *tn,
char *name)
{
BPTR fl,ofh,ifh; /* AmigaDOS file handles */
struct MsgPort *newct=NULL; /* New ConsoleTask pointer */
struct PathList *pla=NULL,*plc=NULL;
char *cmd; /* Buffer for command line */
struct WBArg *wa=msg->am_ArgList;
int cmdlen; /* Command line length */
int i;
char dir[NAMELEN];
/* Get memory for command line */
if (!(cmd=malloc(CMDLINELEN))) return(FALSE);
fl=CurrentDir(tn->tn_DirLock); /* Change to tool's directory */
strcpy(cmd,name); /* Command name first */
cmdlen=strlen(cmd);
for (i=msg->am_NumArgs; i; i--,wa++)
{
char *cp;
int namelen;
if (!wa->wa_Lock) continue; /* Skip arguments which don't support locks! */
if (cmdlen>CMDLINELEN-2) break; /* Append a space for each parameter */
strcat(cmd," ");
cmdlen++;
/* Build parameter from Lock & name */
if (SameLock(tn->tn_DirLock,wa->wa_Lock)==LOCK_SAME) cp=wa->wa_Name;
else
{
if (!NameFromLock(wa->wa_Lock,dir,NAMELEN)) continue;
if (!AddPart(dir,wa->wa_Name,NAMELEN)) continue;
cp=dir;
}
namelen=strlen(cp);
if (strchr(cp,' ')) /* Special case: Space in a filename */
if (namelen>NAMELEN-3) break;
else
{
strins(cp,"\""); /* Set parameter in double quotes */
strcat(cp,"\"");
namelen+=2;
}
if (cmdlen+namelen>CMDLINELEN-2) break;
strcat(cmd,cp); /* Append parameter */
cmdlen+=namelen; /* New command line length */
}
/* Open input & output file */
if (tn->tn_Flags&TNFLAGS_COUT)
if (tn->tn_OutFile)
ofh=Open(tn->tn_OutFile,MODE_NEWFILE); /* Use tool output file */
else
ofh=Open(CLIOutputFile,MODE_NEWFILE); /* Use standard output file */
else
ofh=Open("NIL:",MODE_NEWFILE); /* Ignore output */
if (!ofh) goto ste1;
/* Is the output file an interactive file? */
if (IsInteractive(ofh))
{
struct MsgPort *oldct; /* Old ConsoleTask pointer */
/* Yes. We need the same file as input file for CTRL-C/D/E/F redirection */
/* Set our ConsoleTask to the new output file, so that we can re-open it */
newct=((struct FileHandle *) BADDR(ofh))->fh_Type;
oldct=SetConsoleTask(newct);
/* Open the new input file (Now ifh points to the same file as ofh) */
ifh=Open("CONSOLE:",MODE_OLDFILE);
/* Change back to old ConsoleTask */
SetConsoleTask(oldct);
}
else
/* Non-interactive output, open dummy input file */
ifh=Open("NIL:",MODE_OLDFILE);
if (!ifh) goto ste2;
/* Build path list */
if (!BuildPathList(&pla,&plc,tn->tn_Path)) goto ste3; /* Tool path first */
if (!BuildPathList(&pla,&plc,GlobalPath)) goto ste3;
/* Start tool */
if (SystemTags(cmd,SYS_Output,ofh,
SYS_Input,ifh,
SYS_Asynch,TRUE, /* Run tools asynchronously */
SYS_UserShell,TRUE, /* Use user specified shell */
NP_StackSize,tn->tn_Stack,
NP_Path,MKBADDR(pla),
NP_ConsoleTask,newct,
TAG_DONE)==-1)
goto ste3;
/* Tool started */
CurrentDir(fl); /* Change to old directory */
free(cmd);
return(TRUE);
ste3: if (pla) /* Free path list */
{
struct PathList *pl1=pla,*pl2;
do
{
pl2=BADDR(pl1->NextPath);
UnLock(pl1->PathLock);
FreeVec(pl1);
}
while (pl1=pl2);
}
Close(ifh);
ste2: Close(ofh);
ste1: CurrentDir(fl); /* Change to old directory */
free(cmd);
return(FALSE);
}
/* Start tool as a WB process */
static BOOL StartWBTool(struct AppMessage *msg, struct ToolNode *tn,
char *name)
{
BPTR fl; /* AmigaDOS file handle */
register struct WBStartup *wbs; /* WBStartup message for tool */
struct DiskObject *tdob; /* Tool icon */
LONG ssize; /* StackSize, default */
struct MsgPort *proc; /* Process descriptor for tool */
/* struct Process *proc; Process descriptor for CreateNewProc */
struct WBArg *wbad,*wbas; /* Pointers to WB arguments */
char *proname=NULL; /* Name of Project icon */
int i;
/* Allocate memory for WBStartup */
if (!(wbs=calloc(sizeof(struct WBStartup)+
sizeof(struct WBArg)*(msg->am_NumArgs+2),1))) return (FALSE);
/* Change to tool's directory */
fl=CurrentDir(tn->tn_DirLock);
/* Is it a project? */
if (tdob=GetDiskObject(name))
if (tdob->do_Type==WBPROJECT)
{
proname=name; /* Save original name */
name=strdup(tdob->do_DefaultTool); /* Get name of default tool */
FreeDiskObject(tdob);
if (!name) goto e1; /* Enough memory? */
tdob=GetDiskObject(name); /* Get icon of the default tool */
}
/* Is it a tool? */
ssize=tn->tn_Stack;
if (tdob)
{
if (tdob->do_Type==WBTOOL) /* Only tools supply this information */
{
if (tdob->do_ToolWindow) wbs->sm_ToolWindow=strdup(tdob->do_ToolWindow);
if (tdob->do_StackSize>ssize) ssize=tdob->do_StackSize;
}
FreeDiskObject(tdob);
}
/* Load tool code */
/* if (!(wbs->sm_Segment=NewLoadSeg(name,NULL))) goto e2; */
if (!(wbs->sm_Segment=LoadSeg(name))) goto e2;
/* Build WBStartup message */
/* wbs->sm_Message.mn_Node.ln_Type=NT_MESSAGE; PutMsg() does this for us! */
wbs->sm_Message.mn_ReplyPort=MyMP;
wbs->sm_Message.mn_Length=sizeof(struct WBStartup);
wbs->sm_NumArgs=msg->am_NumArgs+1;
wbs->sm_ArgList=wbs+1; /* WBArg array starts after WBStartup */
/* Initialize WBArg pointers */
wbas=msg->am_ArgList;
wbad=wbs->sm_ArgList;
/* 1. argument is the tool itself! */
if (!(wbad->wa_Lock=DupLock(tn->tn_DirLock))) goto e3;
if (!(wbad->wa_Name=strdup(name))) goto e4;
wbad++;
/* If tool is a project, add it as 2. parameter to the WBArg list */
if (proname)
{
if (!(wbad->wa_Lock=DupLock(tn->tn_DirLock))) goto e4;
if (!(wbad->wa_Name=strdup(proname))) goto e4;
wbad++;
wbs->sm_NumArgs++;
}
/* Copy WB arguments */
for (i=msg->am_NumArgs; i; i--,wbas++,wbad++)
{
if (!(wbad->wa_Lock=DupLock(wbas->wa_Lock)))
{
wbad--; /* Skip parameters, which don't support a lock */
wbs->sm_NumArgs--;
continue; /* Next parameter */
}
/* Sanity check for name string... Enforcer is watching you! */
if (!wbas->wa_Name || !(wbad->wa_Name=strdup(wbas->wa_Name))) goto e4;
}
/* Create process */
if (!(wbs->sm_Process=CreateProc(wbs->sm_ArgList->wa_Name,0,wbs->sm_Segment,
ssize))) goto e4;
/* if (!(proc=CreateNewProcTags(NP_Seglist,wbs->sm_Segment,
NP_FreeSeglist,TRUE,
Maybe someday I will know NP_StackSize,ssize,
what Tags I need to make NP_Name,wbs->sm_ArgList->wa_Name,
CreateNewProc() behave NP_CloseInput,FALSE,
like CreateProc() NP_CloseOutput,FALSE,
TAG_DONE))) goto e4; */
/* Send WBStartup message to tool */
/* wbs->sm_Process=&proc->pr_MsgPort; for CreateNewProc() */
PutMsg(wbs->sm_Process,(struct Message *) wbs);
if (proname) free(name); /* If project, then free default tool name */
CurrentDir(fl); /* Change to old directory */
wbactive++; /* Tool started! */
return(TRUE);
/* An error occurred. Free all resources */
e4: wbas=wbs->sm_ArgList;
for (i=wbs->sm_NumArgs; i; i--,wbas++)
{
UnLock(wbas->wa_Lock);
if (wbas->wa_Name) free(wbas->wa_Name);
}
e3: UnLoadSeg(wbs->sm_Segment);
e2: if (proname) free(name);
e1: CurrentDir(fl);
free(wbs);
return(FALSE);
}
/* Start a tool with arguments */
void StartTool(struct ToolNode *tn, struct AppMessage *msg)
{
BOOL rc=TRUE;
char *cp;
struct AppMessage emsg;
/* No Parameters? */
if (!msg || tn->tn_Flags&TNFLAGS_NARG)
{
emsg.am_NumArgs=0; /* Dummy AppMessage has 0 arguments */
msg=&emsg; /* Replace pointer to real message */
}
/* Get tool name */
if (!(cp=tn->tn_RealName))
cp=tn->tn_Node.ln_Name;
/* Tool type? */
switch(tn->tn_Type)
{
case TNTYPE_CLI:
rc=StartCLITool(msg,tn,cp);
break;
case TNTYPE_WB:
rc=StartWBTool(msg,tn,cp);
break;
}
if (!rc) DisplayBeep(NULL); /* An error occured */
}