home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / utility / misc / toolmng.lzh / ToolManager / Source / starttools.c < prev    next >
C/C++ Source or Header  |  1991-10-10  |  11KB  |  370 lines

  1. /*
  2.  * starttools.c   V1.5
  3.  *
  4.  * CLI & WB startup procedure
  5.  *
  6.  * (c) 1991 by Stefan Becker
  7.  *
  8.  */
  9. #include "ToolManager.h"
  10.  
  11. #define CMDLINELEN 4096
  12.  
  13. /* Structure for path list */
  14. struct PathList {
  15.                  BPTR NextPath; /* Pointer to next PathList */
  16.                  BPTR PathLock; /* Lock on directory */
  17.                 };
  18.  
  19. /* Build a path list from a string */
  20. static BOOL BuildPathList(struct PathList **pla, struct PathList **plc, char *s)
  21. {
  22.  /* Path string valid? */
  23.  if (s)
  24.   {
  25.    char *ps;
  26.  
  27.    /* Yes, copy path string */
  28.    if (ps=strdup(s))
  29.     {
  30.      struct FileInfoBlock *fib;
  31.  
  32.      /* Get memory for FIB */
  33.      if (fib=calloc(sizeof(struct FileInfoBlock),1))
  34.       {
  35.        char *cp1,*cp2=ps;
  36.        struct PathList *pl1=*plc,*pl2=NULL;
  37.  
  38.        /* For every path part */
  39.        while (cp1=cp2)
  40.         {
  41.          /* Search next path part */
  42.          cp2=strchr(cp1,',');
  43.          if (cp2)
  44.           {
  45.            *cp2='\0'; /* Add string end character */
  46.            cp2++;     /* Move to next character */
  47.           }
  48.  
  49.          /* Get memory for path list entry */
  50.          if (!pl2 &&
  51.              !(pl2=AllocVec(sizeof(struct PathList),MEMF_PUBLIC|MEMF_CLEAR)))
  52.           {
  53.            free(fib);
  54.            free(ps);
  55.            return(FALSE);
  56.           }
  57.  
  58.          /* Get lock */
  59.          if (pl2->PathLock=Lock(cp1,SHARED_LOCK))
  60.           /* Is it a directory? */
  61.           if (Examine(pl2->PathLock,fib) && (fib->fib_DirEntryType>0))
  62.            {
  63.             /* Yes, it is a directory, append it to the list. Head of list? */
  64.             if (*pla)
  65.              {
  66.               pl1->NextPath=MKBADDR(pl2); /* No, chain new entry into list */
  67.               pl1=pl2;
  68.              }
  69.             else
  70.              *pla=pl1=pl2;                /* Yes, start of list */
  71.  
  72.             /* Invalidate pointer, next time a new PathList will be allocated */
  73.             pl2=NULL;
  74.            }
  75.           else UnLock(pl2->PathLock); /* No, it is a file */
  76.         }
  77.  
  78.        *plc=pl1;              /* Save end of list */
  79.        if (pl2) FreeVec(pl2); /* Last Lock() failed, free memory */
  80.        free(fib);
  81.       }
  82.  
  83.      free(ps);
  84.     }
  85.   }
  86.  
  87.  return(TRUE);
  88. }
  89.  
  90. /* Start tool as a CLI process */
  91. static BOOL StartCLITool(struct AppMessage *msg, struct ToolNode *tn,
  92.                          char *name)
  93. {
  94.  BPTR fl,ofh,ifh;               /* AmigaDOS file handles */
  95.  struct MsgPort *newct=NULL;    /* New ConsoleTask pointer */
  96.  struct PathList *pla=NULL,*plc=NULL;
  97.  char *cmd;                     /* Buffer for command line */
  98.  struct WBArg *wa=msg->am_ArgList;
  99.  int cmdlen;                    /* Command line length */
  100.  int i;
  101.  char dir[NAMELEN];
  102.  
  103.  /* Get memory for command line */
  104.  if (!(cmd=malloc(CMDLINELEN))) return(FALSE);
  105.  
  106.  fl=CurrentDir(tn->tn_DirLock); /* Change to tool's directory */
  107.  
  108.  strcpy(cmd,name);              /* Command name first */
  109.  cmdlen=strlen(cmd);
  110.  
  111.  for (i=msg->am_NumArgs; i; i--,wa++)
  112.   {
  113.    char *cp;
  114.    int namelen;
  115.  
  116.    if (!wa->wa_Lock) continue;  /* Skip arguments which don't support locks! */
  117.  
  118.    if (cmdlen>CMDLINELEN-2) break; /* Append a space for each parameter */
  119.    strcat(cmd," ");
  120.    cmdlen++;
  121.  
  122.    /* Build parameter from Lock & name */
  123.    if (SameLock(tn->tn_DirLock,wa->wa_Lock)==LOCK_SAME) cp=wa->wa_Name;
  124.    else
  125.     {
  126.      if (!NameFromLock(wa->wa_Lock,dir,NAMELEN)) continue;
  127.      if (!AddPart(dir,wa->wa_Name,NAMELEN)) continue;
  128.      cp=dir;
  129.     }
  130.  
  131.    namelen=strlen(cp);
  132.  
  133.    if (strchr(cp,' '))          /* Special case: Space in a filename */
  134.     if (namelen>NAMELEN-3) break;
  135.     else
  136.      {
  137.       strins(cp,"\"");          /* Set parameter in double quotes */
  138.       strcat(cp,"\"");
  139.       namelen+=2;
  140.      }
  141.  
  142.    if (cmdlen+namelen>CMDLINELEN-2) break;
  143.    strcat(cmd,cp);              /* Append parameter */
  144.    cmdlen+=namelen;             /* New command line length */
  145.   }
  146.  
  147.  /* Open input & output file */
  148.  if (tn->tn_Flags&TNFLAGS_COUT)
  149.   if (tn->tn_OutFile)
  150.    ofh=Open(tn->tn_OutFile,MODE_NEWFILE); /* Use tool output file */
  151.   else
  152.    ofh=Open(CLIOutputFile,MODE_NEWFILE); /* Use standard output file */
  153.  else
  154.   ofh=Open("NIL:",MODE_NEWFILE); /* Ignore output */
  155.  if (!ofh) goto ste1;
  156.  
  157.  /* Is the output file an interactive file? */
  158.  if (IsInteractive(ofh))
  159.   {
  160.    struct MsgPort *oldct;  /* Old ConsoleTask pointer */
  161.  
  162.    /* Yes. We need the same file as input file for CTRL-C/D/E/F redirection */
  163.    /* Set our ConsoleTask to the new output file, so that we can re-open it */
  164.    newct=((struct FileHandle *) BADDR(ofh))->fh_Type;
  165.    oldct=SetConsoleTask(newct);
  166.  
  167.    /* Open the new input file (Now ifh points to the same file as ofh) */
  168.    ifh=Open("CONSOLE:",MODE_OLDFILE);
  169.  
  170.    /* Change back to old ConsoleTask */
  171.    SetConsoleTask(oldct);
  172.   }
  173.  else
  174.   /* Non-interactive output, open dummy input file */
  175.   ifh=Open("NIL:",MODE_OLDFILE);
  176.  if (!ifh) goto ste2;
  177.  
  178.  /* Build path list */
  179.  if (!BuildPathList(&pla,&plc,tn->tn_Path)) goto ste3; /* Tool path first */
  180.  if (!BuildPathList(&pla,&plc,GlobalPath)) goto ste3;
  181.  
  182.  /* Start tool */
  183.  if (SystemTags(cmd,SYS_Output,ofh,
  184.                     SYS_Input,ifh,
  185.                     SYS_Asynch,TRUE,    /* Run tools asynchronously */
  186.                     SYS_UserShell,TRUE, /* Use user specified shell */
  187.                     NP_StackSize,tn->tn_Stack,
  188.                     NP_Path,MKBADDR(pla),
  189.                     NP_ConsoleTask,newct,
  190.                     TAG_DONE)==-1)
  191.   goto ste3;
  192.  
  193.  /* Tool started */
  194.  CurrentDir(fl);                /* Change to old directory */
  195.  free(cmd);
  196.  return(TRUE);
  197.  
  198. ste3: if (pla)                  /* Free path list */
  199.        {
  200.         struct PathList *pl1=pla,*pl2;
  201.  
  202.         do
  203.          {
  204.           pl2=BADDR(pl1->NextPath);
  205.           UnLock(pl1->PathLock);
  206.           FreeVec(pl1);
  207.          }
  208.         while (pl1=pl2);
  209.        }
  210.       Close(ifh);
  211. ste2: Close(ofh);
  212. ste1: CurrentDir(fl);           /* Change to old directory */
  213.       free(cmd);
  214.       return(FALSE);
  215. }
  216.  
  217. /* Start tool as a WB process */
  218. static BOOL StartWBTool(struct AppMessage *msg, struct ToolNode *tn,
  219.                         char *name)
  220. {
  221.  BPTR fl;                        /* AmigaDOS file handle */
  222.  register struct WBStartup *wbs; /* WBStartup message for tool */
  223.  struct DiskObject *tdob;        /* Tool icon */
  224.  LONG ssize;                     /* StackSize, default */
  225.  struct MsgPort *proc;           /* Process descriptor for tool */
  226. /* struct Process *proc;  Process descriptor for CreateNewProc */
  227.  struct WBArg *wbad,*wbas;       /* Pointers to WB arguments */
  228.  char *proname=NULL;             /* Name of Project icon */
  229.  int i;
  230.  
  231.  /* Allocate memory for WBStartup */
  232.  if (!(wbs=calloc(sizeof(struct WBStartup)+
  233.                   sizeof(struct WBArg)*(msg->am_NumArgs+2),1))) return (FALSE);
  234.  
  235.  /* Change to tool's directory */
  236.  fl=CurrentDir(tn->tn_DirLock);
  237.  
  238.  /* Is it a project? */
  239.  if (tdob=GetDiskObject(name))
  240.   if (tdob->do_Type==WBPROJECT)
  241.    {
  242.     proname=name;                      /* Save original name */
  243.     name=strdup(tdob->do_DefaultTool); /* Get name of default tool */
  244.     FreeDiskObject(tdob);
  245.     if (!name) goto e1;                /* Enough memory? */
  246.     tdob=GetDiskObject(name);          /* Get icon of the default tool */
  247.    }
  248.  
  249.  /* Is it a tool? */
  250.  ssize=tn->tn_Stack;
  251.  if (tdob)
  252.   {
  253.    if (tdob->do_Type==WBTOOL)          /* Only tools supply this information */
  254.     {
  255.      if (tdob->do_ToolWindow) wbs->sm_ToolWindow=strdup(tdob->do_ToolWindow);
  256.      if (tdob->do_StackSize>ssize) ssize=tdob->do_StackSize;
  257.     }
  258.  
  259.    FreeDiskObject(tdob);
  260.   }
  261.  
  262.  /* Load tool code */
  263.  /* if (!(wbs->sm_Segment=NewLoadSeg(name,NULL))) goto e2; */
  264.  if (!(wbs->sm_Segment=LoadSeg(name))) goto e2;
  265.  
  266.  /* Build WBStartup message */
  267.  /* wbs->sm_Message.mn_Node.ln_Type=NT_MESSAGE; PutMsg() does this for us! */
  268.  wbs->sm_Message.mn_ReplyPort=MyMP;
  269.  wbs->sm_Message.mn_Length=sizeof(struct WBStartup);
  270.  wbs->sm_NumArgs=msg->am_NumArgs+1;
  271.  wbs->sm_ArgList=wbs+1;             /* WBArg array starts after WBStartup */
  272.  
  273.  /* Initialize WBArg pointers */
  274.  wbas=msg->am_ArgList;
  275.  wbad=wbs->sm_ArgList;
  276.  
  277.  /* 1. argument is the tool itself! */
  278.  if (!(wbad->wa_Lock=DupLock(tn->tn_DirLock))) goto e3;
  279.  if (!(wbad->wa_Name=strdup(name))) goto e4;
  280.  wbad++;
  281.  
  282.  /* If tool is a project, add it as 2. parameter to the WBArg list */
  283.  if (proname)
  284.   {
  285.    if (!(wbad->wa_Lock=DupLock(tn->tn_DirLock))) goto e4;
  286.    if (!(wbad->wa_Name=strdup(proname))) goto e4;
  287.    wbad++;
  288.    wbs->sm_NumArgs++;
  289.   }
  290.  
  291.  /* Copy WB arguments */
  292.  for (i=msg->am_NumArgs; i; i--,wbas++,wbad++)
  293.   {
  294.    if (!(wbad->wa_Lock=DupLock(wbas->wa_Lock)))
  295.     {
  296.      wbad--;             /* Skip parameters, which don't support a lock */
  297.      wbs->sm_NumArgs--;
  298.      continue;           /* Next parameter */
  299.     }
  300.  
  301.    /* Sanity check for name string... Enforcer is watching you! */
  302.    if (!wbas->wa_Name || !(wbad->wa_Name=strdup(wbas->wa_Name))) goto e4;
  303.   }
  304.  
  305.  /* Create process */
  306.  if (!(wbs->sm_Process=CreateProc(wbs->sm_ArgList->wa_Name,0,wbs->sm_Segment,
  307.                                   ssize))) goto e4;
  308.  
  309. /* if (!(proc=CreateNewProcTags(NP_Seglist,wbs->sm_Segment,
  310.                               NP_FreeSeglist,TRUE,
  311.   Maybe someday I will know   NP_StackSize,ssize,
  312.   what Tags I need to make    NP_Name,wbs->sm_ArgList->wa_Name,
  313.   CreateNewProc() behave      NP_CloseInput,FALSE,
  314.   like CreateProc()           NP_CloseOutput,FALSE,
  315.                               TAG_DONE))) goto e4; */
  316.  
  317.  /* Send WBStartup message to tool */
  318. /* wbs->sm_Process=&proc->pr_MsgPort; for CreateNewProc() */
  319.  PutMsg(wbs->sm_Process,(struct Message *) wbs);
  320.  if (proname) free(name);       /* If project, then free default tool name */
  321.  CurrentDir(fl);                /* Change to old directory */
  322.  wbactive++;                    /* Tool started! */
  323.  return(TRUE);
  324.  
  325.  /* An error occurred. Free all resources */
  326. e4: wbas=wbs->sm_ArgList;
  327.     for (i=wbs->sm_NumArgs; i; i--,wbas++)
  328.      {
  329.       UnLock(wbas->wa_Lock);
  330.       if (wbas->wa_Name) free(wbas->wa_Name);
  331.      }
  332. e3: UnLoadSeg(wbs->sm_Segment);
  333. e2: if (proname) free(name);
  334. e1: CurrentDir(fl);
  335.     free(wbs);
  336.     return(FALSE);
  337. }
  338.  
  339. /* Start a tool with arguments */
  340. void StartTool(struct ToolNode *tn, struct AppMessage *msg)
  341. {
  342.  BOOL rc=TRUE;
  343.  char *cp;
  344.  struct AppMessage emsg;
  345.  
  346.  /* No Parameters? */
  347.  if (!msg || tn->tn_Flags&TNFLAGS_NARG)
  348.   {
  349.    emsg.am_NumArgs=0;       /* Dummy AppMessage has 0 arguments */
  350.    msg=&emsg;               /* Replace pointer to real message */
  351.   }
  352.  
  353.  /* Get tool name */
  354.  if (!(cp=tn->tn_RealName))
  355.   cp=tn->tn_Node.ln_Name;
  356.  
  357.  /* Tool type? */
  358.  switch(tn->tn_Type)
  359.   {
  360.    case TNTYPE_CLI:
  361.     rc=StartCLITool(msg,tn,cp);
  362.     break;
  363.    case TNTYPE_WB:
  364.     rc=StartWBTool(msg,tn,cp);
  365.     break;
  366.   }
  367.  
  368.  if (!rc) DisplayBeep(NULL); /* An error occured */
  369. }
  370.