/* * starttools.c V1.4 * * CLI & WB startup procedure * * (c) 1991 by Stefan Becker * */ #include "ToolManager.h" /* Start tool as a CLI process */ static BOOL StartCLITool(struct AppMessage *msg, struct ToolNode *tn, char *name) { BPTR fl; /* AmigaDOS file handle */ BOOL rc=TRUE; char cmd[NAMELEN]; /* Buffer for command line */ int cmdlen; /* Command line length */ char dir[NAMELEN]; struct WBArg *wa=msg->am_ArgList; int i; 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>NAMELEN-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>NAMELEN-2) break; strcat(cmd,cp); /* Append parameter */ cmdlen+=namelen; /* New command line length */ } /* Start tool */ if (SystemTags(cmd,SYS_Input,Open("NIL:",MODE_NEWFILE), SYS_Output,Open("NIL:",MODE_NEWFILE), SYS_Asynch,TRUE, /* Run tools asynchronously */ NP_StackSize,tn->tn_Stack, TAG_DONE)==-1) rc=FALSE; /* An error occured */ CurrentDir(fl); /* Change to old directory */ return(rc); } /* 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; /* 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 */ }