home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff225.lzh / MyMenu / DoRun.c < prev    next >
C/C++ Source or Header  |  1989-06-24  |  11KB  |  432 lines

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