home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 465.lha / ParM_v2.5r / Run.c < prev    next >
C/C++ Source or Header  |  1991-01-05  |  7KB  |  295 lines

  1. /*
  2.  *    Run.c - Copyright © 1990 by S.R. & P.C.
  3.  *
  4.  *    Created:    16 Jun 1990
  5.  *    Modified:    30 Nov 1990  18:56:38
  6.  *
  7.  *    Make>> make
  8.  */
  9.  
  10.  
  11. #include "Menu.h"
  12. #include "Tokens.h"
  13. #include "WB.h"
  14.  
  15.  
  16. /*****                    external functions                    *****/
  17.  
  18. extern char *copystr(char *);
  19. extern void UpDateMenus(void);
  20. extern void ParseLine(char *);
  21.  
  22. /*****                     global functions                    *****/
  23.  
  24. void DoExtMenu(USHORT);
  25. void WBFree(struct WBStartup *);
  26.  
  27.  
  28. /*****                     global variables                    *****/
  29.  
  30. extern struct Menu Menu1;
  31. extern struct MenuItem SubItem1;
  32. extern struct Process *MyProcess;
  33. extern struct ParmMsgPort *ParMPort;
  34. extern char CurCfg[];
  35. extern char CmdWindow[];
  36. extern char ShellWindow[];
  37. extern char ShellCmd[];
  38. extern char WaitCmd[];
  39. extern char TmpDir[];
  40. extern char *ReqTitle;
  41. extern long DefaultStack;
  42. extern BOOL DoNextSelect;
  43.  
  44.  
  45. /* Warn user of a load error */
  46.  
  47. static void LoadError(char *cmd)
  48. {
  49.     long err;
  50.     char *msg;
  51.     char buf[40];
  52.  
  53.     switch(err = IoErr()) {
  54.     case ERROR_NO_FREE_STORE:
  55.         msg = "Not enough memory.";
  56.         break;
  57.     case ERROR_FILE_NOT_OBJECT:
  58.         msg = "File is not an object module.";
  59.         break;
  60.     case ERROR_OBJECT_NOT_FOUND:
  61.         msg = "File not found.";
  62.         break;
  63.     default:
  64.         SPrintf(buf, "Error code %ld", err);
  65.         msg = buf;
  66.     }
  67.     SimpleRequest(ReqTitle, "Couldn't load '%s'\n%s", cmd, msg);
  68. }
  69.  
  70.  
  71. /* Execute a CLI command as background process */
  72.  
  73. static void ARun(struct Extended_MenuItem *emi)
  74. {
  75.     static struct ProcessControlBlock PCB;
  76.     long CLI;
  77.  
  78.     PCB.pcb_StackSize = emi->emi_Stack;
  79.     PCB.pcb_Pri = emi->emi_Pri;
  80.     PCB.pcb_Console.pcb_ConName = emi->emi_Window;
  81.     PCB.pcb_Control = (emi->emi_Window) ? PRF_STDIO : PRF_SAVEIO;
  82.     if ((CLI = ASyncRun(emi->emi_Cmd, emi->emi_Args, &PCB)) <= 0) {
  83.         if (CLI == PR_NOSTDIO)
  84.             SimpleRequest(ReqTitle, "Couldn't open window:\n\"%s\"", emi->emi_Window);
  85.         else
  86.             LoadError(emi->emi_Cmd);
  87.     }
  88. }
  89.  
  90.  
  91. /* Execute a CLI command as background or interactive shell */
  92.  
  93. static void Run(char *cmd, char *win, long stk, BYTE pri, BYTE mode)
  94. {
  95.     static struct NewShell NS;
  96.     BPTR fh;
  97.     short i=0;
  98.     char FromFile[32], CmdBuf[128];
  99.  
  100.     NS.nsh_StackSize = stk;
  101.     NS.nsh_Pri = pri;
  102.     NS.nsh_Input = MyProcess->pr_CIS;
  103.     NS.nsh_Output = MyProcess->pr_COS;
  104.     NS.nsh_Control = BACKGROUND_SHELL;
  105.  
  106.     if (mode == TOK_SHELL) {
  107.         for(;;) {
  108.             SPrintf(FromFile, "%sParMCmd%d", TmpDir, i++);
  109.             fh = Open(FromFile, MODE_NEWFILE);
  110.             if (fh)
  111.                 break;
  112.             else if (IoErr() != ERROR_OBJECT_IN_USE || i>32) {
  113.                 SimpleRequest(ReqTitle, "Unable to open script file");
  114.                 return;
  115.             }
  116.         }
  117.         FPrintf(fh, "%s\nEndCLI >NIL:\n", cmd);
  118.         Close(fh);
  119.         if (!win)
  120.             win = ShellWindow;
  121.         SPrintf(CmdBuf, "\"%s\" \"%s\" From %s", ShellCmd, win, FromFile);
  122.         cmd = CmdBuf;
  123.     }
  124.     ASyncRun(cmd, NULL, (struct ProcessControlBlock *)&NS);
  125. }
  126.  
  127.  
  128. /* procedures to support running WorkBench programs */
  129.  
  130. /*
  131.  *    Free up space used by a workbench startup message.  Called whenever
  132.  *    a workbench program replies to the startup message, and whenever
  133.  *    WBRun() gets an error.
  134.  */
  135.  
  136. void WBFree(struct WBStartup *WBStartup)
  137. {
  138.     register BPTR lock;
  139.     register int i;
  140.     register char *cp;
  141.  
  142.     if (WBStartup->sm_ArgList) {
  143.         for( i=0 ; i<2 ; i++ ) {
  144.             if (lock = WBStartup->sm_ArgList[i].wa_Lock)
  145.                 UnLock(lock);
  146.             if (cp = WBStartup->sm_ArgList[i].wa_Name)
  147.                 FreeMem(cp, strlen(cp)+1);
  148.         }
  149.         FreeMem(WBStartup->sm_ArgList, 2*sizeof(struct WBArg));
  150.     }
  151.     if (WBStartup->sm_Segment)
  152.         UnLoadSeg(WBStartup->sm_Segment);
  153.     FreeMem(WBStartup, sizeof(struct WBStartup));
  154. }
  155.  
  156.  
  157. /* load and run a workbench program */
  158.  
  159. static void WBRun(struct Extended_MenuItem *emi)
  160. {
  161.     struct WBStartup *WBStartup;
  162.     struct WBArg *ArgList;
  163.     struct DiskObject *DiskObject;
  164.     BPTR DirLock;
  165.     char Cmd[256], Dir[256], Name[32], *s;
  166.     long stack;
  167.     short arg;        /* Tool: arg=0, Project: arg=1 */
  168.  
  169.     strcpy(Cmd, emi->emi_Cmd);
  170.     stack = emi->emi_Stack;
  171.     if (!(WBStartup = AllocMem(sizeof(struct WBStartup), MEMF_PUBLIC|MEMF_CLEAR)))
  172.         return;
  173.     /* Allocate array for 2 args. Only one may be needed */
  174.     if (!(ArgList = AllocMem(2*sizeof(struct WBArg), MEMF_PUBLIC|MEMF_CLEAR))) {
  175.         WBFree(WBStartup);
  176.         return;
  177.     }
  178.     WBStartup->sm_ArgList = ArgList;
  179.     WBStartup->sm_NumArgs = 1;
  180.     do {
  181.         strcpy(Dir, Cmd);
  182.         strcpy(Name, s = BaseName(Dir));
  183.         if (s == Dir)
  184.             DirLock = DupLock(MyProcess->pr_CurrentDir);
  185.         else {
  186.             if (*(s-1) == '/') s--;
  187.             *s = '\0';
  188.             if (!(DirLock = Lock(Dir, ACCESS_READ))) {
  189.                 SimpleRequest(ReqTitle, "Couldn't access '%s'", Dir);
  190.                 WBFree(WBStartup);
  191.                 return;
  192.             }
  193.         }
  194.         if (!(DiskObject = GetDiskObject(Cmd))) {
  195.             arg = 0;        /* No icon, assume Tool */
  196.             if (stack == 0)
  197.                 stack = DefaultStack;
  198.         }
  199.         else if (DiskObject->do_Type == WBTOOL) {
  200.             arg = 0;
  201.             if (stack == 0) {    /* Take icon stack only if not user defined */
  202.                 stack = DiskObject->do_StackSize;
  203.                 if (stack < 4000) stack = DefaultStack;
  204.             }
  205.         }
  206.         else if (arg != 1 && DiskObject->do_Type == WBPROJECT) {
  207.             arg = 1;
  208.             WBStartup->sm_NumArgs = 2;
  209.             strcpy(Cmd, DiskObject->do_DefaultTool);
  210.         }
  211.         else {
  212.             SimpleRequest(ReqTitle, "No tool found!");
  213.             if (DiskObject)
  214.                 FreeDiskObject(DiskObject);
  215.             WBFree(WBStartup);
  216.             return;
  217.         }
  218.         ArgList[arg].wa_Lock = DirLock;
  219.         ArgList[arg].wa_Name = copystr(Name);
  220.         if (DiskObject)
  221.             FreeDiskObject(DiskObject);
  222.     } while(arg);
  223.  
  224.     WBStartup->sm_Message.mn_ReplyPort = (struct MsgPort *)ParMPort;
  225.     WBStartup->sm_Message.mn_Length = sizeof(struct WBStartup);
  226.     WBStartup->sm_Message.mn_Node.ln_Type = NT_MESSAGE;
  227.     if (!(WBStartup->sm_Segment = LoadSeg(Cmd))) {
  228.         LoadError(Cmd);
  229.         WBFree(WBStartup);
  230.         return;
  231.     }
  232.     if (!(WBStartup->sm_Process = (struct MsgPort *)CreateProc(Name, emi->emi_Pri, WBStartup->sm_Segment, stack))) {
  233.         SimpleRequest(ReqTitle, "Couldn't execute '%s'", Cmd);
  234.         WBFree(WBStartup);
  235.         return;
  236.     }
  237.     PutMsg(WBStartup->sm_Process, (struct Message *)WBStartup);
  238.     ParMPort->pmp_MsgCnt++;        /* keep track of unreplied startup messages */
  239. }
  240.  
  241.  
  242. void DoExtMenu(USHORT MenuNum)
  243. {
  244.     struct Extended_MenuItem *Item;
  245.  
  246.     Item = (struct Extended_MenuItem *) ItemAddress(&Menu1, MenuNum);
  247.     switch (Item->emi_Mode) {
  248.     case TOK_ARUN:
  249.         ARun(Item);
  250.         break;
  251.     case TOK_RUN:
  252.     case TOK_SHELL:
  253.         Run(Item->emi_Cmd, Item->emi_Window, Item->emi_Stack, Item->emi_Pri, Item->emi_Mode);
  254.         break;
  255.     case TOK_WB:
  256.         WBRun(Item);
  257.         break;
  258.     case TOK_CFG:    /* new cfg */
  259.         strcpy(CurCfg, Item->emi_Cmd);
  260.         UpDateMenus();
  261.         DoNextSelect = FALSE;    /* Tell DoIntuiMsg not to execute next menu selection */
  262.     }
  263. }
  264.  
  265.  
  266. #define CMDBUFSIZE    255
  267.  
  268. void Command(void)
  269. {
  270.     static struct NewShell NS;
  271.     static char Buffer[CMDBUFSIZE+1];
  272.     BPTR fh = NULL;
  273.     char CmdBuf[CMDBUFSIZE+12];
  274.     USHORT ExecMode;
  275.  
  276.     ExecMode = SubItem1.Flags & CHECKED;
  277.     if (ExecMode && !(fh = Open(CmdWindow, MODE_NEWFILE)))
  278.         return;
  279.     if (GetString(Buffer, "Enter command...", NULL, 45, CMDBUFSIZE)) {
  280.         if (ExecMode) {
  281.             Execute(Buffer, 0, fh);
  282.             FPrintf(fh, "Hit return...›0 p");
  283.             Read(fh, CmdBuf, 1L);
  284.         }
  285.         else {
  286.             SPrintf(CmdBuf, "%s;%s", Buffer, WaitCmd);
  287.             ParseLine(CmdBuf);
  288.             Run(CmdBuf, CmdWindow, DefaultStack, 0, TOK_SHELL);
  289.         }
  290.     }
  291.     if (ExecMode)
  292.         Close(fh);
  293. }
  294.  
  295.