home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 408.lha / MyMenu_v1.1 / sources / DoRun.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-04  |  12.2 KB  |  483 lines

  1. /* Copyright (c) Darin Johnson, 1989 */
  2.  
  3. /* DoRun.c -- I met her on a Monday, and my heart stood still... */
  4.  
  5. /* Modifications under 1.01:
  6.     All allocations do MEMF_CLEAR
  7.  
  8.     CLIRun:
  9.     Modified string and parameters passed to Execute
  10.     Starts tasks with a priority of 0
  11.  
  12.     WBRun:
  13.     Returns to CurrentDir(oldlock) even when oldlock=NULL (still valid)
  14.     Sets sm_ToolWindow to NULL as it is not used under 1.3
  15.     Does not load "default tool" info file - uses the project info file
  16. */
  17.  
  18. #include <exec/types.h>
  19. #include <exec/memory.h>
  20. #include <libraries/dos.h>
  21. #include <libraries/dosextens.h>
  22. #include <intuition/intuition.h>
  23. #include <workbench/icon.h>
  24. #include <workbench/startup.h>
  25. #include <workbench/workbench.h>
  26. #include <functions.h>
  27. #include "mymenu.h"
  28.  
  29. /* no more _BUILTIN_strlen stuff, flag for version 5.0 of Manx */
  30.  
  31. #ifdef DO_PATH
  32. #define CMDSIZ 256
  33. #define CBUFSZ 80
  34. #endif
  35.  
  36. extern struct Process *MyProcess;
  37.  
  38. /* text to put into autorequesters */
  39. struct IntuiText err_nocmd = { 0,1,JAM2, 20,10, NULL, 
  40.     (UBYTE*)"MyMenu: can't execute command", NULL };
  41. struct IntuiText err_nomem = { 0,1,JAM2, 20,10, NULL, 
  42.     (UBYTE*)"MyMenu: out of memory!", NULL };
  43. struct IntuiText err_noinfo = { 0,1,JAM2, 20,10, NULL, 
  44.     (UBYTE*)"MyMenu: can't open .info file", NULL };
  45. struct IntuiText err_notool = { 0,1,JAM2, 20,10, NULL, 
  46.     (UBYTE*)"MyMenu: not a tool or project", NULL };
  47. struct IntuiText req_neg = { 0,1,JAM2, 7,3, NULL,
  48.     (UBYTE*)"Okay", NULL };
  49.  
  50. /* process a menu item */
  51. int run_item(item)
  52.   struct ext_MenuItem *item;
  53. {
  54.   if (item->cmd) {
  55.     if (item->type == 'C') {
  56.       do_clirun(item->cmd, item->args);
  57.     }
  58. #ifdef DO_WB
  59.     else if (item->type == 'W') {
  60.       do_wbrun(item->cmd);
  61.     }
  62. #endif
  63.   }
  64. }
  65.  
  66. #ifdef DO_PATH
  67. char *FindIt();
  68. #endif
  69.  
  70. /* execute a CLI command */
  71. do_clirun(cmd, args)
  72.   char *cmd, *args;
  73. {
  74.   struct FileHandle *NilFh;
  75.   register char *buf;
  76.   register short siz;
  77.   BYTE oldpri;
  78.  
  79. #ifdef DO_PATH
  80.   cmd = FindIt(cmd);
  81. #endif
  82.   if (cmd==NULL) {
  83.     AutoRequest(NULL, &err_nocmd, NULL, &req_neg, 0,0,300,60);
  84.     return;
  85.   }
  86.  
  87.   siz = 22 + strlen(cmd);
  88.   if (args)
  89.     siz += strlen(args);
  90.   if ((buf = (char *)AllocMem(siz, MEMF_PUBLIC|MEMF_CLEAR)) == NULL) {
  91.     AutoRequest(NULL, &err_nomem, NULL, &req_neg, 0,0,300,60);
  92.     return;
  93.   }
  94.   strcpy(buf, "C:RUN >NIL: <NIL: \"");
  95.   strcat(buf, cmd);
  96.   strcat(buf, "\" ");
  97.   if (args)
  98.     strcat(buf, args);
  99.     
  100.   NilFh = (struct FileHandle *)Open("NIL:", MODE_NEWFILE);
  101.   if (NilFh) {
  102.  
  103.       /* Start the task at priority 0 - we should be higher... */
  104.     oldpri = SetTaskPri(MM->handler_task, 0);
  105.     Execute(buf, NULL, NilFh);
  106.     SetTaskPri(MM->handler_task, oldpri);
  107.  
  108. /* Both runback and runbackground leave out the next line, but if removed */
  109. /* there is permanent fastmem lost.  And I don't see improved reliability */
  110. /* when using the parameters to Execute above.                  */
  111.  
  112.     Close((BPTR)NilFh);
  113.   }
  114.   FreeMem(buf, siz);
  115. }
  116.  
  117. /* procedures to support running WorkBench programs */
  118.  
  119. #ifdef DO_WB
  120. extern int wb_cnt;
  121. extern struct MsgPort *wb_reply_port;
  122.  
  123. /* create (and allocate) a copy of a string */
  124. char *copystr(str) {
  125.   char *tmpstr;
  126.   if (!str)
  127.     return NULL;
  128.   tmpstr = (char *)AllocMem(strlen(str)+1, MEMF_PUBLIC|MEMF_CLEAR);
  129.   strcpy(tmpstr, str);
  130.   return tmpstr;
  131. }
  132.  
  133. /* Free up space used by a workbench startup message.  Called whenever
  134.    a workbench program replies to the startup message, and whenever
  135.    do_wbrun() gets an error */
  136. wbfree(WBStartup)
  137.   struct WBStartup *WBStartup;
  138. {
  139.   register BPTR lock;
  140.   register int i;
  141.   register char *cp;
  142.   if (WBStartup != NULL) {
  143.     if (WBStartup->sm_ArgList != NULL) {
  144.  
  145. /*****************unlocking occurs here***************/
  146.  
  147.       for (i=0; i<WBStartup->sm_NumArgs; i++) {
  148.         if ((lock=WBStartup->sm_ArgList[i].wa_Lock) != NULL) {
  149.           UnLock(lock);
  150.     }
  151.     if ((cp=WBStartup->sm_ArgList[i].wa_Name) != NULL)
  152.       FreeMem(cp, strlen(cp)+1);
  153.       }
  154.       FreeMem(WBStartup->sm_ArgList,
  155.       sizeof(struct WBArg)*WBStartup->sm_NumArgs);
  156.     }
  157.     if (WBStartup->sm_Segment != NULL) {
  158.       UnLoadSeg(WBStartup->sm_Segment);
  159.     }
  160.     if ((cp=WBStartup->sm_ToolWindow) != NULL)
  161.       FreeMem(cp, strlen(cp)+1);
  162.     FreeMem(WBStartup, sizeof(struct WBStartup));
  163.   }
  164. }
  165.  
  166. /* take the path passed, and split it into a lock and name,
  167.    suitable for putting into a WBArg structure */
  168. split_path(path, dir_lock, name)
  169.   char *path, **name;
  170.   BPTR *dir_lock;
  171. {
  172.   char *tmppath;
  173.   register short siz=0,n;
  174.   register char *p;
  175.  
  176.   *dir_lock = NULL;
  177.  
  178.   for (p=path, n=1, *name=path; *p; p++, n++)
  179.     if (*p == '/' || *p == ':') {
  180.       *name = p+1;
  181.       siz = n;
  182.     }
  183.  
  184.   if (siz) {
  185.     tmppath = (char *) AllocMem(siz, MEMF_CLEAR);
  186.     if (tmppath==NULL) {
  187.       AutoRequest(NULL, &err_nomem, NULL, &req_neg, 0,0,300,60);
  188.       return;
  189.     }
  190.     strncpy(tmppath, path, siz);
  191.  
  192.     *dir_lock = (BPTR)Lock(tmppath, ACCESS_READ);
  193.  
  194.     FreeMem(tmppath, siz);
  195.   }
  196.  
  197.   if (!(*dir_lock)) {
  198.     *dir_lock = (BPTR)DupLock(MyProcess->pr_CurrentDir);
  199.   }
  200. }
  201.  
  202. /* load and run a workbench program */
  203. int do_wbrun(cmd)
  204.   char *cmd;
  205. {
  206.   BPTR lock, oldlock;
  207.   struct WBStartup *WBStartup;
  208.   struct DiskObject *disk_object;
  209.   char argc, *name, buf[128];
  210.   char error;
  211.     
  212.   disk_object = WBStartup = NULL;
  213.   lock = oldlock = NULL;
  214.   name = NULL;
  215.   error = TRUE;    /* assume the worst */
  216.  
  217.     /* allocate the startup message */
  218.   if ((WBStartup = (struct WBStartup *)AllocMem(sizeof(struct WBStartup),
  219.               MEMF_PUBLIC|MEMF_CLEAR)) == NULL) {
  220.     AutoRequest(NULL, &err_nomem, NULL, &req_neg, 0,0,300,60);
  221.     return TRUE;    /* don't go to finish:, nothing allocated yet */
  222.   }
  223. #ifdef DO_PATH
  224.   if ((cmd = FindIt(cmd)) == NULL)
  225.     goto finish2;
  226. #endif
  227.     /* find the directory and name of the program to run */
  228.   split_path(cmd, &lock, &name);
  229.  
  230. /* This will be caught later if caused by an error, but might not be an error
  231.   if (lock == NULL) {
  232.     AutoRequest(NULL, &err_noinfo, NULL, &req_neg, 0,0,300,60);
  233.     goto finish2;
  234.   }
  235. */
  236.  
  237.     /* try to load in the .info file */
  238.   oldlock = CurrentDir((struct FileLock *)lock);
  239.   if ((disk_object = GetDiskObject(name)) == NULL) {
  240.     AutoRequest(NULL, &err_noinfo, NULL, &req_neg, 0,0,300,60);
  241.     goto finish;
  242.   }
  243.  
  244.     /* allocate the WBArgs - if we are a tool, we allocate one */
  245.     /* of these, else two (one for tool, one for project)      */
  246.   if (disk_object->do_Type == WBTOOL) {
  247.     if ((WBStartup->sm_ArgList = (struct WBArg *)
  248.     AllocMem(sizeof(struct WBArg), MEMF_PUBLIC|MEMF_CLEAR)) == NULL) {
  249.       AutoRequest(NULL, &err_nomem, NULL, &req_neg, 0,0,300,60);
  250.       goto finish;
  251.     }
  252.     WBStartup->sm_NumArgs = 1;
  253.   } else if (disk_object->do_Type == WBPROJECT) {
  254.     if ((WBStartup->sm_ArgList = (struct WBArg *)
  255.     AllocMem(sizeof(struct WBArg)*2, MEMF_PUBLIC|MEMF_CLEAR)) == NULL) {
  256.       AutoRequest(NULL, &err_nomem, NULL, &req_neg, 0,0,300,60);
  257.       goto finish;
  258.     }
  259.     WBStartup->sm_NumArgs = 2;
  260.       /* fill in arg #2 with the info we already have */
  261.     WBStartup->sm_ArgList[1].wa_Lock = (BPTR)lock;
  262.     WBStartup->sm_ArgList[1].wa_Name = copystr(name);
  263.       /* now find the tool */
  264.     strcpy(buf, disk_object->do_DefaultTool);
  265.     split_path(buf, &lock, &name);
  266.     /* FreeDiskObject(disk_object); */  /* DO NOT USE TOOL INFO!!! */
  267.  
  268.     CurrentDir((struct FileLock *)lock);
  269.  
  270. /** DO NOT USE TOOL INFO!  Default tool for project icon need not have icon!
  271.     if ((disk_object = GetDiskObject(name)) == NULL) {
  272.       AutoRequest(NULL, &err_noinfo, NULL, &req_neg, 0,0,300,60);
  273.       goto finish;
  274.     }
  275. */
  276.  
  277.   } else {
  278.     /* we did not find a tool or project */
  279.     AutoRequest(NULL, &err_notool, NULL, &req_neg, 0,0,300,60);
  280.     goto finish;
  281.   }
  282.  
  283.     /* fill in arguments */
  284.   WBStartup->sm_ArgList[0].wa_Lock = (BPTR)lock;
  285.   WBStartup->sm_ArgList[0].wa_Name = copystr(name);
  286.   
  287.     /* initialize rest of startup message */
  288.   WBStartup->sm_Message.mn_ReplyPort = wb_reply_port;
  289.   WBStartup->sm_Message.mn_Length = sizeof(struct WBStartup);
  290.   WBStartup->sm_Message.mn_Node.ln_Type = NT_MESSAGE;
  291.  
  292. /************ sm_ToolWindow is unused/reserved for future use ************/
  293.  
  294.   WBStartup->sm_ToolWindow = NULL; /*copystr(disk_object->do_ToolWindow);*/
  295.  
  296.     /* get a decent stack size, there are a few progs that set this to zero */
  297.   if (!(disk_object->do_StackSize))
  298.     disk_object->do_StackSize = 4096;
  299.  
  300.     /* load in the program */
  301.   if ((WBStartup->sm_Segment = (BPTR)LoadSeg(name)) == NULL) {
  302.     AutoRequest(NULL, &err_nocmd, NULL, &req_neg, 0,0,300,60);
  303.     goto finish;
  304.   }
  305.  
  306.     /* create process */
  307.   if ((WBStartup->sm_Process = (struct MsgPort *)CreateProc(name,
  308.      0, WBStartup->sm_Segment, disk_object->do_StackSize)) == NULL) {
  309.     AutoRequest(NULL, &err_nocmd, NULL, &req_neg, 0,0,300,60);
  310.     goto finish;
  311.   }
  312.     /* everything's ok -- start 'er up */
  313.   PutMsg(WBStartup->sm_Process, WBStartup);
  314.   error = FALSE;
  315.   wb_cnt++;    /* keep track of unreplied startup messages */
  316. finish:
  317.   CurrentDir((struct FileLock *)oldlock);
  318.  
  319. #ifdef DO_PATH
  320. finish2:
  321. #endif
  322.  
  323.   if (disk_object) FreeDiskObject(disk_object);
  324.   if (error)
  325.     wbfree(WBStartup);
  326.   return error;
  327. }
  328. #endif
  329.  
  330. #ifdef DO_PATH
  331. /* This section is largely taken from RunBack
  332.   (which was largely taken from which.c by Carolyn Scheppner).
  333.   This handles path searching.
  334. */
  335.  
  336. /***** currently these routines can cause guru's
  337.        Run a workbench program, and then run a program that
  338.        uses the path searching - often causes a Guru, but can't
  339.        tell why.  If the wbfree() does NOT free its locks, then
  340.        it doesn't guru.
  341. *****/
  342.  
  343. static char sbuf[CMDSIZ];
  344.  
  345. /* search for a command in our path */
  346. char *FindIt(command)
  347.   char *command;
  348. {
  349.   BOOL getPath();
  350.   struct Path *path;
  351.   struct FileInfoBlock *fib;
  352.   BPTR lock, startcd;
  353.   BOOL Found, InitialCD;
  354.  
  355.      /* Were we given full path in command name (':' in name) ? */
  356.   {
  357.     register char *p;
  358.     for (p=command; *p; p++) {
  359.       if (*p == ':') {
  360.         lock = (BPTR)Lock(command,ACCESS_READ);
  361.     if (lock==NULL)
  362.       return NULL;        /* command not found */
  363.     UnLock(lock);
  364.         return command;
  365.       }
  366.     }
  367.   }
  368.  
  369.     /* allocate this for Examine() calls */ 
  370.   fib = (struct FileInfoBlock *)
  371.     AllocMem(sizeof(struct FileInfoBlock), MEMF_PUBLIC|MEMF_CLEAR);
  372.   if (fib == NULL)
  373.     return NULL;
  374.  
  375.     /* Check current directory */
  376.   Found = getPath(command, fib, sbuf);
  377.  
  378.     /* Check along paths */
  379.   if (!Found) {
  380.     InitialCD = TRUE;
  381.  
  382.     for (path = MM->CLI_path; (path) && (!Found); path = path->path_Next) {
  383.         /* CD to each path */
  384.       lock = (BPTR)CurrentDir(path->path_Lock);
  385.       if (InitialCD) {
  386.         startcd = lock; InitialCD = FALSE;
  387.       }
  388.         /* See if command is there */
  389.       Found = getPath(command, fib, sbuf);
  390.     }
  391.       /* If we CD'd anywhere, restore initial CD */
  392.     if (!InitialCD)
  393.       CurrentDir(startcd);
  394.   }
  395.  
  396.     /* Check C: */
  397.   if (!Found) {
  398.     char cbuf[CBUFSZ];
  399.     strcpy(cbuf,"C:");
  400.     strcpy(&cbuf[2], command);
  401.     Found = getPath(cbuf, fib, sbuf);
  402.   }
  403.  
  404.     /* Free fib */
  405.   if (fib != NULL)
  406.     FreeMem(fib, sizeof(struct FileInfoBlock));
  407.  
  408.   if (Found)
  409.     return(sbuf);
  410.   else
  411.     return(NULL);
  412. }
  413.  
  414. /* see if command is in current directory, if so, return path name
  415.    in 'buf' */
  416. BOOL
  417. getPath(command,fib,buf)
  418.   char *command;
  419.   struct FileInfoBlock *fib;
  420.   char *buf;
  421. {
  422.   BPTR lock;
  423.   BOOL success = FALSE;
  424.   if (lock = (BPTR)Lock(command, ACCESS_READ)) {
  425.     if (Examine(lock, fib)) {
  426.       buildPath(lock, fib, buf);
  427.       success = TRUE;
  428.     }
  429.     UnLock(lock);
  430.   }
  431.   return(success);
  432. }
  433.  
  434. /* builds up a path name from 'inlock' and returns it in 'buf' */
  435. buildPath(inlock,fib,buf)
  436.   BPTR inlock;
  437.   struct FileInfoBlock *fib;
  438.   char *buf;
  439. {
  440.   int i;
  441.   BPTR lock, oldlock;
  442.   buf[0] = NULL;
  443.   lock = inlock;
  444.  
  445.     /* follow path up, building up name as we go */
  446.   while (lock) {
  447.     if (Examine(lock, fib)) {
  448.       if (fib->fib_FileName[0] > ' ') {
  449.         if (buf[0]) insert(buf,"/");
  450.         insert(buf,fib->fib_FileName);
  451.       }
  452.     }
  453.     oldlock = lock;
  454.     lock = (BPTR)ParentDir(lock);
  455.       /* make sure we don't unlock the lock passed to us */
  456.     if (oldlock != inlock)
  457.        UnLock(oldlock);
  458.   }
  459.  
  460.     /* fix up path name */
  461.   if (fib->fib_FileName[0] > ' ') {
  462.     register char *p;
  463.     for (p=buf; *p; p++) {
  464.       if (*p == '/') {
  465.         *p = ':';
  466.     break;
  467.       }
  468.     }
  469.   } else
  470.     insert(buf,"RAM:");    /* why? */
  471. }
  472.  
  473. /* insert 's' at the beginning of 'buf' */
  474. insert(buf,s)
  475.   char *buf,*s;
  476. {
  477.   char tmp[CMDSIZ];
  478.   strcpy(tmp, buf);
  479.   strcpy(buf, s);
  480.   strcpy(&buf[strlen(s)], tmp);
  481. }
  482. #endif
  483.