home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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 */
- }
-