home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 632.lha / ParM_v3.6 / ParM_Src.lzh / ParM_Src / Run.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-13  |  9.0 KB  |  341 lines

  1. /*
  2.  *    Run.c - Copyright © 1990 by S.R. & P.C.
  3.  *
  4.  *    Created:    16 Jun 1990
  5.  *    Modified:    12 Feb 1992  22:37:36
  6.  *
  7.  *    Make>> make
  8.  */
  9.  
  10. #include "ParMBase.h"
  11. #include "System2.0.h"
  12.  
  13.  
  14. /*****                     global variables                    *****/
  15.  
  16. extern struct ExecBase *SysBase;
  17. extern struct IntuitionBase *IntuitionBase;
  18. extern struct ParMBase *ParMBase;
  19.  
  20.  
  21. /* Execute a CLI command as background process */
  22.  
  23. long ARun(struct ParMConfig *PCfg, struct RunInfo *Command)
  24. {
  25.     struct ParMBase *ParMBase;
  26.     struct ProcessControlBlock *PCB;
  27.     long CLI, Ok = TRUE;
  28.  
  29.     if (!(PCB = AllocMem(sizeof(struct ProcessControlBlock), MEMF_PUBLIC|MEMF_CLEAR)))
  30.         return FALSE;
  31.     PCB->pcb_StackSize = Command->ri_Stack;
  32.     PCB->pcb_Pri = Command->ri_Pri;
  33.     PCB->pcb_Console.pcb_ConName = Command->ri_Window;
  34.     PCB->pcb_Control = (Command->ri_Window) ? PRF_STDIO : PRF_SAVEIO;
  35.     if ((CLI = ASyncRun(Command->ri_Cmd, Command->ri_Args, PCB)) <= 0) {
  36.         if (CLI == PR_NOSTDIO)
  37.             SimpleRequest(PCfg->ReqTitle, "Couldn't open window:\n\"%s\"", Command->ri_Window);
  38.         else
  39.             SimpleRequest(PCfg->ReqTitle, "Couldn't load \"%s\"\n%s.", Command->ri_Cmd, StrIoErr());
  40.         Ok = FALSE;
  41.     }
  42.     FreeMem(PCB, sizeof(struct ProcessControlBlock));
  43.     return Ok;
  44. }
  45.  
  46.  
  47. static void ASyncExec(char *Cmd, long Stack, long Pri, BPTR InputFH)
  48. {
  49.     struct TagItem TagArray[] = {
  50.         { SYS_Input, 0L },
  51.         { SYS_Output, 0L },
  52.         { SYS_Asynch, 1L },
  53.         { NP_ConsoleTask, 0L },
  54.         { NP_Priority, 0L },
  55.         { NP_StackSize, 0L },
  56.         { TAG_DONE, 0L }
  57.     };
  58.  
  59.     TagArray[0].ti_Data = InputFH;
  60.     TagArray[1].ti_Data = OpenFromLock(DupLockFromFH(InputFH), MODE_OLDFILE);
  61.     TagArray[3].ti_Data = (ULONG)((struct FileHandle *)(InputFH<<2))->fh_Type;
  62.     TagArray[4].ti_Data = Pri;
  63.     TagArray[5].ti_Data = Stack;
  64.     System(Cmd, TagArray);
  65. }
  66.  
  67.  
  68. /* Execute a CLI command as background or interactive shell */
  69.  
  70. long Run(struct ParMConfig *PCfg, struct RunInfo *Command, BYTE Mode)
  71. {
  72.     struct ParMBase *ParMBase;
  73.     struct NewShell *NS;
  74.     struct Process *pp;
  75.     char *Window, *Cmd;
  76.     BPTR fh;
  77.     short i=0, err;
  78.     char FromFile[32], CmdBuf[128];
  79.  
  80.     if (!(NS = AllocMem(sizeof(struct NewShell), MEMF_PUBLIC|MEMF_CLEAR)))
  81.         return FALSE;
  82.     pp = (struct Process *)SysBase->ThisTask;
  83.     NS->nsh_StackSize = Command->ri_Stack;
  84.     NS->nsh_Pri = Command->ri_Pri;
  85.     NS->nsh_Input = pp->pr_CIS;
  86.     NS->nsh_Output = pp->pr_COS;
  87.     NS->nsh_Control = BACKGROUND_SHELL;
  88.  
  89.     Cmd = Command->ri_Cmd;
  90.     if (Mode == TOK_SHELL) {
  91.         for(;;) {
  92.             SPrintf(FromFile, "%sParMCmd%d", PCfg->TmpDir, i++);
  93.             fh = Open(FromFile, MODE_NEWFILE);
  94.             if (fh)
  95.                 break;
  96.             else if ((err = IoErr()) != ERROR_OBJECT_IN_USE || i>32) {
  97.                 SimpleRequest(PCfg->ReqTitle, "Unable to open script file\n%s.", DosError(err));
  98.                 FreeMem(NS, sizeof(struct NewShell));
  99.                 return FALSE;
  100.             }
  101.         }
  102.         FPrintf(fh, "%s\nEndCLI >NIL:\n", Cmd);
  103.         Close(fh);
  104.         if (!(Window = Command->ri_Window))
  105.             Window = PCfg->ShellWindow;
  106.         SPrintf(CmdBuf, "\"%s\" \"%s\" From %s", PCfg->ShellCmd, Window, FromFile);
  107.         Cmd = CmdBuf;
  108.     }
  109.     /* 2.0 compatibility */
  110.     if (IntuitionBase->LibNode.lib_Version >= 36) {
  111.         BPTR InputFH;        /* Input() file handle (closed on exit by System()) */
  112.         Window = (Command->ri_Window && Mode == TOK_RUN) ? Command->ri_Window : "*";
  113.         if (!(InputFH = Open(Window, MODE_NEWFILE))) {
  114.             SimpleRequest(PCfg->ReqTitle, "Couldn't open console:\n%s", Window);
  115.             return FALSE;
  116.         }
  117.         ASyncExec(Cmd, Command->ri_Stack, Command->ri_Pri, InputFH);
  118.     }
  119.     else
  120.         ASyncRun(Cmd, NULL, (struct ProcessControlBlock *)NS);
  121.     FreeMem(NS, sizeof(struct NewShell));
  122.     return TRUE;
  123. }
  124.  
  125.  
  126. /* procedures to support running WorkBench programs */
  127.  
  128. /*
  129.  *    Free up space used by a workbench startup message.  Called whenever
  130.  *    a workbench program replies to the startup message, and whenever
  131.  *    WBRun() gets an error.
  132.  */
  133.  
  134. void WBFree(struct Extended_WBStartup *EWBS)
  135. {
  136.     struct ParMBase *ParMBase;
  137.     register BPTR lock;
  138.     register int i;
  139.  
  140.     if (EWBS->WBStartup.sm_ArgList) {
  141.         for( i=0 ; i<EWBS->WBStartup.sm_NumArgs ; i++ ) {
  142.             if (lock = EWBS->WBStartup.sm_ArgList[i].wa_Lock)
  143.                 UnLock(lock);
  144.             FreeStr(EWBS->WBStartup.sm_ArgList[i].wa_Name);
  145.         }
  146.         FreeMem(EWBS->ArgArray, EWBS->ArrayLength*sizeof(struct WBArg));
  147.     }
  148.     if (EWBS->WBStartup.sm_Segment)
  149.         UnLoadPrg(EWBS->WBStartup.sm_Segment);
  150.     FreeMem(EWBS, sizeof(struct Extended_WBStartup));
  151. }
  152.  
  153.  
  154. long MakeWBArg(struct ParMConfig *PCfg, struct WBArg *WBArg, char *Cmd)
  155. {
  156.     struct ParMBase *ParMBase;
  157.     struct Process *pp;
  158.     BPTR DirLock;
  159.     char Dir[256], *s, *n;
  160.  
  161.     strcpy(Dir, Cmd);
  162.     s = BaseName(Dir);
  163.     if (!(n = CopyStr(s)))
  164.         return FALSE;
  165.     pp = (struct Process *)SysBase->ThisTask;
  166.     if (s == Dir)
  167.         DirLock = DupLock(pp->pr_CurrentDir);
  168.     else {
  169.         if (*(s-1) == '/') s--;
  170.         *s = '\0';
  171.         if (!(DirLock = Lock(Dir, ACCESS_READ))) {
  172.             SimpleRequest(PCfg->ReqTitle, "Couldn't access \"%s\"", Dir);
  173.             FreeStr(n);
  174.             return FALSE;
  175.         }
  176.     }
  177.     WBArg->wa_Name = n;
  178.     WBArg->wa_Lock = DirLock;
  179.     return TRUE;
  180. }
  181.  
  182.  
  183. long GetTool(struct ParMConfig *PCfg, struct Extended_WBStartup *EWBS, long Stack)
  184. {
  185.     struct ParMBase *ParMBase;
  186.     struct Process *pp;
  187.     struct DiskObject *DiskObject;
  188.     char *DefTool;
  189.     long IconStack = 0;
  190.     BPTR OldDir;
  191.     BOOL ToolFound = FALSE;
  192.     BOOL ProjectFound = FALSE;
  193.     BOOL Error = FALSE;
  194.  
  195.     pp = (struct Process *)SysBase->ThisTask;
  196.     OldDir = pp->pr_CurrentDir;
  197.     do {
  198.         CurrentDir(EWBS->WBStartup.sm_ArgList->wa_Lock);
  199.         if (!(DiskObject = GetDiskObject(EWBS->WBStartup.sm_ArgList->wa_Name))) {
  200.             ToolFound = TRUE;    /* No icon, assume tool */
  201.         }
  202.         else if (DiskObject->do_Type == WBTOOL) {
  203.             ToolFound = TRUE;
  204.             IconStack = DiskObject->do_StackSize;
  205.         }
  206.         else if (ProjectFound == FALSE && DiskObject->do_Type == WBPROJECT) {
  207.             ProjectFound = TRUE;
  208.             EWBS->WBStartup.sm_NumArgs++;
  209.             EWBS->WBStartup.sm_ArgList = EWBS->ArgArray;
  210.             DefTool = DiskObject->do_DefaultTool;
  211.             if (!DefTool || !strlen(DefTool) || !(MakeWBArg(PCfg, EWBS->ArgArray, DefTool))) {
  212.                 SimpleRequest(PCfg->ReqTitle, "No tool found!");
  213.                 Error = TRUE;
  214.             }
  215.         }
  216.         else {
  217.             SimpleRequest(PCfg->ReqTitle, "No tool found!");
  218.             Error = TRUE;
  219.         }
  220.         if (DiskObject)
  221.             FreeDiskObject(DiskObject);
  222.     } while(!ToolFound && !Error);
  223.     CurrentDir(OldDir);
  224.     if (Stack)
  225.         EWBS->Stack = Stack;
  226.     else if (IconStack < 4000)
  227.         EWBS->Stack = PCfg->DefaultStack;
  228.     else
  229.         EWBS->Stack = IconStack;
  230.     return ToolFound;
  231. }
  232.  
  233.  
  234. struct Extended_WBStartup *MakeWBStartup(struct ParMConfig *PCfg, struct RunInfo *Command)
  235. {
  236.     struct ParMBase *ParMBase;
  237.     struct Extended_WBStartup *EWBS;
  238.  
  239.     if (!(EWBS = AllocMem(sizeof(struct Extended_WBStartup), MEMF_PUBLIC|MEMF_CLEAR)))
  240.         return NULL;
  241.     /* Allocate array for 2 args. Only one may be needed */
  242.     if (!(EWBS->ArgArray = AllocMem(2*sizeof(struct WBArg), MEMF_PUBLIC|MEMF_CLEAR))) {
  243.         WBFree(EWBS);
  244.         return NULL;
  245.     }
  246.     EWBS->ArrayLength = 2;
  247.     EWBS->WBStartup.sm_NumArgs = 1;
  248.     EWBS->WBStartup.sm_ArgList = &EWBS->ArgArray[1];
  249.     if (!MakeWBArg(PCfg, &EWBS->ArgArray[1], Command->ri_Cmd)) {
  250.         WBFree(EWBS);
  251.         return NULL;
  252.     }
  253.     if (!GetTool(PCfg, EWBS, Command->ri_Stack)) {
  254.         WBFree(EWBS);
  255.         return NULL;
  256.     }
  257.     return EWBS;
  258. }
  259.  
  260.  
  261. /* load and run a workbench program */
  262.  
  263. long WBRun(struct ParMConfig *PCfg, struct Extended_WBStartup *EWBS, BYTE Pri)
  264. {
  265.     struct ParMBase *ParMBase;
  266.     struct Process *pp;
  267.     APTR OldPtr;
  268.     BPTR OldDir, CmdDir;
  269.     char *Cmd;
  270.     char Path[256];
  271.     long Ok = FALSE;
  272.  
  273.     OldDir = CurrentDir(CmdDir = EWBS->WBStartup.sm_ArgList->wa_Lock);
  274.     Cmd = EWBS->WBStartup.sm_ArgList->wa_Name;
  275.     PathName(CmdDir, Path, 255-32);
  276.     TackOn(Path, Cmd);
  277.     EWBS->WBStartup.sm_Message.mn_ReplyPort = &ParMBase->pb_MsgPort;
  278.     EWBS->WBStartup.sm_Message.mn_Length = sizeof(struct Extended_WBStartup);
  279.     EWBS->WBStartup.sm_Message.mn_Node.ln_Type = NT_MESSAGE;
  280.     if (EWBS->WBStartup.sm_Segment = LoadPrg(Cmd)) {
  281.         pp = (struct Process *)SysBase->ThisTask;
  282.         OldPtr = pp->pr_WindowPtr;
  283.         pp->pr_WindowPtr = NULL;
  284.         if (EWBS->WBStartup.sm_Process = CreateProc(Cmd, Pri, EWBS->WBStartup.sm_Segment, EWBS->Stack)) {
  285.             PutMsg(EWBS->WBStartup.sm_Process, (struct Message *)EWBS);
  286.             ParMBase->pb_MsgCnt++;        /* keep track of unreplied startup messages */
  287.             Ok = TRUE;
  288.         }
  289.         else {
  290.             SimpleRequest(PCfg->ReqTitle, "Couldn't execute \"%s\"\n%s.", Path, StrIoErr());
  291.             WBFree(EWBS);
  292.         }
  293.         pp->pr_WindowPtr = OldPtr;
  294.     }
  295.     else {
  296.         SimpleRequest(PCfg->ReqTitle, "Couldn't load \"%s\"\n%s.", Path, StrIoErr());
  297.         WBFree(EWBS);
  298.     }
  299.     CurrentDir(OldDir);
  300.     return Ok;
  301. }
  302.  
  303.  
  304. void Command(struct ParMConfig *PCfg)
  305. {
  306.     struct RunInfo Command;
  307.     BPTR fh;
  308.     char *Cmd, CmdBuf[CMDBUFSIZE+40];
  309.  
  310.     Command.ri_Cmd = CmdBuf;
  311.     Command.ri_Args = 0;
  312.     Command.ri_Window = PCfg->CmdWindow;
  313.     Command.ri_Stack = PCfg->DefaultStack;
  314.     Command.ri_Pri = 0;
  315.     Cmd = PCfg->CommandBuffer;
  316.     if (GetString(Cmd, "Enter Command...", NULL, 60, CMDBUFSIZE) && Cmd[0]) {
  317.         if (PCfg->SimpleCmdMode) {
  318.             if (!(fh = Open(PCfg->CmdWindow, MODE_NEWFILE))) {
  319.                 SimpleRequest(PCfg->ReqTitle, "Couldn't open console:\n%s", PCfg->CmdWindow);
  320.                 return;
  321.             }
  322.             strcpy(CmdBuf, Cmd);
  323.             ParseLine(CmdBuf);
  324.             if (IntuitionBase->LibNode.lib_Version < 36) {
  325.                 Execute(CmdBuf, 0, fh);
  326.                 FPrintf(fh, "Hit return...›0 p");
  327.                 Read(fh, CmdBuf, 1L);
  328.                 Close(fh);
  329.             }
  330.             else
  331.                 ASyncExec(CmdBuf, PCfg->DefaultStack, 0, fh);
  332.         }
  333.         else {
  334.             SPrintf(CmdBuf, "%s;%s", Cmd, PCfg->WaitCmd);
  335.             ParseLine(CmdBuf);
  336.             Run(PCfg, &Command, TOK_SHELL);
  337.         }
  338.     }
  339. }
  340.  
  341.