home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 632.lha / CLIExe_v1.1 / CLIExe.c < prev    next >
C/C++ Source or Header  |  1992-04-27  |  10KB  |  411 lines

  1. /*
  2.  *    CLIExe.c - Copyright © 1990 by S.R.
  3.  *
  4.  *    Created:    25 May 1991    09:58:27
  5.  *    Modified:    28 Jan 1992    19:39:29
  6.  *
  7.  * M ake>> delete <file>.o
  8.  *    Make>> cc -qf -ps -wp -wd -wu -wr -so -sb -hi Aztec:Include/x16.dmp <file>.c
  9.  *    Make>> ln <file>.o -larpsc -lreq
  10.  */
  11.  
  12.  
  13. /***** Same code that ParM.library, so same Struct ******/
  14. #include "ParMBase.h"
  15. #include "System2.0.h"
  16.  
  17. struct ExecBase *SysBase;
  18. struct ArpBase *ArpBase;
  19. struct GfxBase *GfxBase;
  20. struct IntuitionBase *IntuitionBase;
  21. struct IconBase *IconBase;
  22. struct ReqLib *ReqBase;
  23. struct DosLibrary *DOSBase;
  24.  
  25. struct WBStartup *WBenchMsg;
  26.  
  27. char HelpUsage[] = "CLIExe V2.0 © 1991 by S.R.\nUsage: CLIExe <FULLCMDS> command1;command2;...\n\t[MODERUN] [SHELLCMD] newshell_command\n\t[WINDOW] con:a/b/c/d/title [STACK] stacksize\n\t[TMPDIR] directory [PRI] pri [NOIO]\n";
  28. char HelpArg[] = "FULLCMDS/A,MODERUN/s,SHELLCMD/k,WINDOW/k,STACK/k,TMPDIR/k,PRI/k,NOIO/s";
  29.  
  30. long DosWrite(BPTR file, char *buffer, long length);
  31. #pragma amicall(DOSBase, 0x30, DosWrite(d1,d2,d3))
  32.  
  33. extern void setmem(void *mem, size_t size, long value);
  34.  
  35. /******* Came from ParM.library.c *********/
  36. /* Execute a CLI command as background or interactive shell */
  37.  
  38. static void BuiltIn_ASyncExec(char *Cmd, long Stack, long Pri, BPTR InputFH, APTR ConsoleTask)
  39. {
  40.     struct TagItem TagArray[] = {
  41.         { SYS_Input, 0L },
  42.         { SYS_Output, 0L },
  43.         { SYS_Asynch, 1L },
  44.         { NP_ConsoleTask, 0L },
  45.         { NP_Priority, 0L },
  46.         { NP_StackSize, 0L },
  47.         { TAG_DONE, 0L }
  48.     };
  49.  
  50.     TagArray[0].ti_Data = InputFH;
  51.     TagArray[1].ti_Data = OpenFromLock(DupLockFromFH(InputFH), MODE_OLDFILE);
  52.     TagArray[3].ti_Data = (ULONG)ConsoleTask;
  53.     TagArray[4].ti_Data = Pri;
  54.     TagArray[5].ti_Data = Stack;
  55.     System(Cmd, TagArray);
  56. }
  57.  
  58. void BuiltIn_Run(struct ParMConfig * PCfg, struct RunInfo * Command, BYTE Mode)
  59. {
  60.     struct NewShell *NS;
  61.     struct Process *pp;
  62.     char *Window, *Cmd;
  63.     BPTR fh;
  64.     short i = 0, err;
  65.     char FromFile[32], CmdBuf[128];
  66.  
  67.     if (!(NS = AllocMem(sizeof(struct NewShell), MEMF_PUBLIC | MEMF_CLEAR)))
  68.         return;
  69.     pp = (struct Process *) SysBase->ThisTask;
  70.     NS->nsh_StackSize = Command->ri_Stack;
  71.     NS->nsh_Pri = Command->ri_Pri;
  72.     NS->nsh_Input = pp->pr_CIS;
  73.     NS->nsh_Output = pp->pr_COS;
  74.     NS->nsh_Control = BACKGROUND_SHELL;
  75.  
  76.     Cmd = Command->ri_Cmd;
  77.     if (Mode == TOK_SHELL)
  78.         {
  79.             for (;;)
  80.                 {
  81.                     SPrintf(FromFile, "%sParMCmd%d", PCfg->TmpDir, i++);
  82.                     fh = Open(FromFile, MODE_NEWFILE);
  83.                     if (fh)
  84.                         break;
  85.                     else if ((err = IoErr()) != ERROR_OBJECT_IN_USE || i > 32)
  86.                         {
  87.                             if (ReqBase)
  88.                                 SimpleRequest(PCfg->ReqTitle, "Unable to open script file\n");
  89.                             FreeMem(NS, sizeof(struct NewShell));
  90.                             return;
  91.                         }
  92.                 }
  93.             FPrintf(fh, "%s\nEndCLI >NIL:\n", Cmd);
  94.             Close(fh);
  95.             if (!(Window = Command->ri_Window))
  96.                 Window = PCfg->ShellWindow;
  97.             SPrintf(CmdBuf, "\"%s\" \"%s\" From %s", PCfg->ShellCmd, Window, FromFile);
  98.             Cmd = CmdBuf;
  99.         }
  100.     /* 2.0 compatibility */
  101.     if (IntuitionBase->LibNode.lib_Version >= 36)
  102.         {
  103.             BPTR DupOutput;        /* to duplicate Output() file handle (closed on exit by System()) */
  104.             DupOutput = OpenFromLock(DupLockFromFH(pp->pr_COS), MODE_OLDFILE);
  105.             BuiltIn_ASyncExec(Cmd, Command->ri_Stack, Command->ri_Pri, DupOutput, pp->pr_ConsoleTask);
  106.         }
  107.     else
  108.         ASyncRun(Cmd, NULL, (struct ProcessControlBlock *) NS);
  109.  
  110.     FreeMem(NS, sizeof(struct NewShell));
  111. }
  112.  
  113. /*
  114.  *    Parse a line that may contain semicolons. Backslash ('\') is the override
  115.  *    char. This function is called from ParseConfig() and from Command().
  116.  */
  117.  
  118. void BuiltIn_ParseLine(char *cmd)
  119. {
  120.     char *s, *d, c;
  121.  
  122.     s = d = cmd;
  123.     while (c = *d++ = *s++)
  124.         {
  125.             if (c == '\\')
  126.                 *(d - 1) = *s++;
  127.             else if (c == ';')
  128.                 *(d - 1) = '\n';
  129.         }
  130. }
  131.  
  132. /*****  make (and allocate) a copy of the passed string *****/
  133.  
  134. char *BuiltIn_CopyStr(char *str)
  135. {
  136.     /*struct ParMBase *ParMBase;*/
  137.     char *newstr;
  138.  
  139.     if (newstr = AllocMem(strlen(str) + 1, MEMF_PUBLIC))
  140.         strcpy(newstr, str);
  141.     return newstr;
  142. }
  143.  
  144.  
  145. void BuiltIn_FreeStr(char *str)
  146. {
  147.     /*struct ParMBase *ParMBase;*/
  148.  
  149.     if (str)
  150.         FreeMem(str, strlen(str) + 1);
  151. }
  152.  
  153. /***** End of ParM.library.c import *****/
  154.  
  155. void main(int argc, char **argv)
  156. {
  157.     struct ParMConfig ParMConfig;
  158.     struct RunInfo Command;
  159.     long Stack = 0;        /* Stack=0 mean use IconStack */
  160.     BYTE Pri = 0, i;
  161.     char Cmd[255];
  162.     struct DiskObject *dop;
  163.     char *ToolArg;
  164.     BYTE Mode = TOK_SHELL;
  165.  
  166.     APTR OldWindowPtr;
  167.     BPTR Nfh;
  168.     struct Process *MainProcess;
  169.     BOOL NoIO;
  170.  
  171.     setmem(&ParMConfig, sizeof(struct ParMConfig), 0);
  172.     setmem(&Command, sizeof(struct RunInfo), 0);
  173.  
  174.     MainProcess = (struct Process *) SysBase->ThisTask;
  175.  
  176.     ParMConfig.ReqTitle = "CliExe";
  177.     strcpy(ParMConfig.TmpDir, DEFAULT_TMP_DIR);
  178.  
  179.     if (WBenchMsg)
  180.         {        /* Tool Types parsing */
  181.             for (i = 1; i < WBenchMsg->sm_NumArgs; i++)
  182.                 {
  183.                     CurrentDir(WBenchMsg->sm_ArgList[i].wa_Lock);    /* enter in the dir containing the Icon */
  184.                     if (dop = GetDiskObject(WBenchMsg->sm_ArgList[i].wa_Name))
  185.                         {
  186.                             ParMConfig.DefaultStack = dop->do_StackSize;
  187.  
  188.                             if (ToolArg = FindToolType(dop->do_ToolTypes, "FULLCMD"))
  189.                                 {
  190.                                     strcpy(Cmd, ToolArg);
  191.                                     BuiltIn_ParseLine(Cmd);
  192.                                     Command.ri_Cmd = Cmd;
  193.                                 }
  194.                             else
  195.                                 {
  196.                                     /* Error: no Cmd !! */
  197.                                     FreeDiskObject(dop);
  198.                                     if (ReqBase)
  199.                                         SimpleRequest(ParMConfig.ReqTitle, "I can't find the CMD.");
  200.                                     return;
  201.                                 }
  202.  
  203.                             if (ToolArg = FindToolType(dop->do_ToolTypes, "MODERUN"))
  204.                                 {
  205.                                     /* MODERUN so run mode is TOK_RUN */
  206.                                     Mode = TOK_RUN;
  207.                                     if (ToolArg = FindToolType(dop->do_ToolTypes, "PRI"))
  208.                                         Command.ri_Pri = Atol(ToolArg);
  209.                                     else
  210.                                         Command.ri_Pri = 0;
  211.                                 }
  212.                             else
  213.                                 {
  214.                                     Mode = TOK_SHELL;
  215.                                     if (ToolArg = FindToolType(dop->do_ToolTypes, "SHELLCMD"))
  216.                                         strcpy(ParMConfig.ShellCmd, ToolArg);
  217.                                     else
  218.                                         strcpy(ParMConfig.ShellCmd, DEFAULT_SHELL_CMD);
  219.  
  220.                                     if (ToolArg = FindToolType(dop->do_ToolTypes, "WINDOW"))
  221.                                         Command.ri_Window = BuiltIn_CopyStr(ToolArg);
  222.                                     else
  223.                                         Command.ri_Window = BuiltIn_CopyStr(DEFAULT_SHELL_WINDOW);
  224.  
  225.                                     if (ToolArg = FindToolType(dop->do_ToolTypes, "STACK"))
  226.                                         Command.ri_Stack = Atol(ToolArg);
  227.                                     else
  228.                                         Command.ri_Stack = 4096;
  229.  
  230.                                     Command.ri_Pri = 0;    /* in SHELL mode pri can't be something else */
  231.  
  232.                                     if (ToolArg = FindToolType(dop->do_ToolTypes, "TMPDIR"))
  233.                                         strcpy(ParMConfig.TmpDir, ToolArg);
  234.                                     else
  235.                                         strcpy(ParMConfig.TmpDir, DEFAULT_TMP_DIR);
  236.                                 }
  237.                             if (ToolArg = FindToolType(dop->do_ToolTypes, "NOIO"))
  238.                                 NoIO = TRUE;
  239.                             else
  240.                                 NoIO = FALSE;
  241.  
  242.                             FreeDiskObject(dop);
  243.  
  244.                         }
  245.                     else
  246.                         {
  247.                             /* no icon: I can't do anything ! */
  248.                             if (ReqBase)
  249.                                 SimpleRequest(ParMConfig.ReqTitle, "I can't find the icon:\"%s\".", WBenchMsg->sm_ArgList[i].wa_Name);
  250.                             return;
  251.                         }
  252.                 }
  253.         }
  254.     else
  255.         {        /* CLI parsing */
  256.  
  257.             if (!argc)
  258.                 {
  259.                     Printf("%s", HelpUsage);
  260.                     return;
  261.                 }
  262.  
  263.             /* record line */
  264.             strcpy(Cmd, argv[0]);
  265.             BuiltIn_ParseLine(Cmd);
  266.             Command.ri_Cmd = Cmd;
  267.  
  268.             /* test PRI */
  269.             if (argv[6])
  270.                 Command.ri_Pri = Atol( argv[6]);
  271.             else
  272.                 Command.ri_Pri = 0;
  273.  
  274.             if (argv[7])
  275.                 NoIO = TRUE;
  276.             else
  277.                 NoIO = FALSE;
  278.  
  279.             /* test run mode */
  280.             if (argv[1])
  281.                 {
  282.                     /* MODERUN so run mode is TOK_RUN */
  283.                     Mode = TOK_RUN;
  284.                 }
  285.             else
  286.                 {
  287.                     Mode = TOK_SHELL;
  288.  
  289.                     if (argv[2])
  290.                         strcpy(ParMConfig.ShellCmd, argv[2]);
  291.                     else
  292.                         strcpy(ParMConfig.ShellCmd, DEFAULT_SHELL_CMD);
  293.  
  294.                     if (argv[3])
  295.                         Command.ri_Window = BuiltIn_CopyStr(argv[3]);
  296.                     else
  297.                         Command.ri_Window = BuiltIn_CopyStr(DEFAULT_SHELL_WINDOW);
  298.  
  299.                     if (argv[4])
  300.                         Command.ri_Stack = Atol(argv[4]);
  301.                     else
  302.                         Command.ri_Stack = 4096;
  303.  
  304.                     if (argv[5])
  305.                         strcpy(ParMConfig.TmpDir, argv[5]);
  306.                     else
  307.                         strcpy(ParMConfig.TmpDir, DEFAULT_TMP_DIR);
  308.  
  309.                         }
  310.  
  311.  
  312.         }
  313.  
  314.     if ( NoIO)
  315.         {
  316.             /* this is for redirection problem in RUN mode */
  317.             OldWindowPtr = MainProcess->pr_WindowPtr;
  318.             MainProcess->pr_WindowPtr = (APTR) - 1;    /* Prevent request if NULL: is not mounted */
  319.             if ((Nfh = Open("NULL:", MODE_NEWFILE)) || (Nfh = Open("NIL:", MODE_NEWFILE)))
  320.                 {
  321.                     MainProcess->pr_CIS = Nfh;
  322.                     MainProcess->pr_COS = Nfh;
  323.                     MainProcess->pr_ConsoleTask = (APTR) ((struct FileHandle *) (Nfh << 2))->fh_Type;
  324.                 }
  325.             MainProcess->pr_WindowPtr = OldWindowPtr;
  326.         }
  327.  
  328.     BuiltIn_Run(&ParMConfig, &Command, Mode);
  329.     BuiltIn_FreeStr(Command.ri_Window);
  330.  
  331. }
  332.  
  333.  
  334. /**** Start *********************************/
  335. void exit(int code)
  336. {
  337.     if (WBenchMsg)
  338.         {
  339.             Forbid();
  340.             ReplyMsg((struct Message *) WBenchMsg);
  341.         }
  342.     CloseLibrary(ArpBase);
  343.     Exit(code);
  344. }
  345.  
  346.  
  347. void _main(long alen, char *aptr)
  348. {
  349.     register struct Process *pp;
  350.     int _argc;
  351.     char **_argv;
  352.  
  353.     pp = (struct Process *) SysBase->ThisTask;
  354.     if (!pp->pr_CLI)
  355.         {
  356.             WaitPort(&pp->pr_MsgPort);
  357.             WBenchMsg = (struct WBStartup *) GetMsg(&pp->pr_MsgPort);
  358.         }
  359.     if (!(ArpBase = (struct ArpBase *) OpenLibrary("arp.library", 39L)))
  360.         {
  361.             if (pp->pr_CLI && (DOSBase = OpenLibrary("dos.library", 0L)))
  362.                 {
  363.                     DosWrite(pp->pr_COS, "You need arp.library V39+\n", 26L);
  364.                     DosWrite(pp->pr_COS, "You need Req.library V1.22+\n", 27L);
  365.                     CloseLibrary(DOSBase);
  366.                 }
  367.             return;
  368.         }
  369.     DOSBase = (struct DosLibrary *) ArpBase->DosBase;
  370.     IntuitionBase = (struct IntuitionBase *) ArpBase->IntuiBase;
  371.     GfxBase = (struct GfxBase *) ArpBase->GfxBase;
  372.  
  373.     ReqBase = (struct ReqLib *) ArpOpenLibrary("req.library", 1L);
  374.     IconBase = (struct IconBase *) ArpOpenLibrary("icon.library", 1L);
  375.     if (!(IconBase = (struct IconBase *) ArpOpenLibrary("icon.library", 1L)))
  376.         {
  377.             if (pp->pr_CLI && DOSBase)
  378.                 {
  379.                     DosWrite(pp->pr_COS, "You need icon.library V1+ \n", 27L);
  380.                 }
  381.             return;
  382.         }
  383.  
  384.  
  385.     if (WBenchMsg)
  386.         {
  387.             CurrentDir(WBenchMsg->sm_ArgList->wa_Lock);
  388.             _argv = (char **) WBenchMsg;
  389.             _argc = 0;
  390.         }
  391.     else
  392.         {
  393.             /*
  394.              *    WARNING: With that function, argv[] array will not start with the program
  395.              *    name but with it's first argument. If there's no args, argc will be zero.
  396.              */
  397.             _argv = ArpAlloc(4 * 7);
  398.             _argc = (int) GADS(aptr, alen, HelpUsage, _argv, HelpArg);
  399.             if (_argc < 0)
  400.                 {
  401.                     Puts(_argv[0]);
  402.                     exit(20);
  403.                 }
  404.         }
  405.  
  406.  
  407.     main(_argc, _argv);
  408.  
  409.     exit(0);
  410. }
  411.