home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 552.lha / ParM_v3.0 / source.LZH / source / Run.c < prev    next >
C/C++ Source or Header  |  1991-07-28  |  8KB  |  291 lines

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