grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / c / shellcommands / Execute.c
blobe9b75200f499de51efad95b9af96989f7a14ff52
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang:
7 */
9 /******************************************************************************
11 NAME
13 Execute <script> [{<arguments>}]
15 SYNOPSIS
17 FILE/A
19 LOCATION
23 FUNCTION
25 Executes a script with DOS commands.
27 INPUTS
29 FILE -- file to execute
31 RESULT
33 NOTES
35 EXAMPLE
37 BUGS
39 SEE ALSO
41 INTERNALS
43 HISTORY
45 ******************************************************************************/
47 #include <proto/exec.h>
48 #include <dos/dos.h>
49 #include <dos/bptr.h>
50 #include <dos/stdio.h>
51 #include <proto/dos.h>
52 #include <proto/alib.h>
53 #include <string.h>
55 #define DEBUG 0
56 #include <aros/debug.h>
58 #ifndef USE_EMBEDDED_COMMANDS
59 #define SH_GLOBAL_SYSBASE 1 /* For __sprintf */
60 #endif
61 #include <aros/shcommands.h>
63 AROS_SH2(Execute, 41.1,
64 AROS_SHA(STRPTR, ,NAME , /A, NULL),
65 AROS_SHA(STRPTR, ,ARGUMENTS, /F, NULL))
67 AROS_SHCOMMAND_INIT
69 struct CommandLineInterface *cli = Cli();
70 STRPTR arguments = SHArg(ARGUMENTS), s;
71 STRPTR extraargs = NULL;
72 BPTR from;
73 LONG len;
74 BPTR ces;
75 struct Process *me = (struct Process *)FindTask(NULL);
77 if (!cli)
78 return RETURN_ERROR;
80 /* pr_CES can be NULL, so use pr_COS */
81 if(! (ces=me->pr_CES))
82 ces=me->pr_COS;
84 if (! arguments)
85 arguments = "";
87 /* See if we have extra arguments buffered in Input()
89 if (Input() != BNULL) {
90 struct FileHandle *fh = BADDR(Input());
92 if (fh->fh_Pos > 0 && fh->fh_End > 0) {
93 LONG extraargsize = fh->fh_End - fh->fh_Pos;
95 if (extraargsize > 0) {
96 LONG argsize = strlen(arguments);
97 extraargs = AllocVec(argsize + 1 + extraargsize + 1, MEMF_ANY);
98 if (extraargs) {
99 CopyMem(arguments, extraargs, argsize);
100 extraargs[argsize++] = '\n';
101 CopyMem(BADDR(fh->fh_Buf)+fh->fh_Pos, &extraargs[argsize], extraargsize);
102 argsize += extraargsize;
103 extraargs[argsize++] = 0;
104 arguments = extraargs;
110 from = Open(SHArg(NAME), MODE_OLDFILE);
112 if (!from)
114 FPrintf(ces, "EXECUTE: can't open %s\n", SHArg(NAME));
115 PrintFault(IoErr(), NULL);
116 if (extraargs)
117 FreeVec(extraargs);
118 return RETURN_FAIL;
121 if (cli->cli_StandardInput == cli->cli_CurrentInput)
123 cli->cli_CurrentInput = from;
125 else
127 struct DateStamp ds;
128 BYTE tmpname[256];
129 BPTR tmpfile = BNULL;
130 ULONG count = 0;
131 BYTE tmpdir[4];
132 BPTR tmplock;
133 struct Window *win;
134 struct Process *proc = (struct Process*)FindTask(0);
136 DateStamp(&ds);
138 win = proc->pr_WindowPtr;
139 proc->pr_WindowPtr = (struct Window *)-1;
140 tmplock = Lock("T:", SHARED_LOCK);
141 proc->pr_WindowPtr = win;
142 if (tmplock) {
143 strcpy(tmpdir, "T:");
144 UnLock(tmplock);
145 } else {
146 strcpy(tmpdir, ":T/");
149 do {
150 count++;
151 __sprintf(tmpname, "%sTmp%lu%lu%lu%lu%lu", tmpdir,
152 ((struct Process *)FindTask(NULL))->pr_TaskNum,
153 ds.ds_Days, ds.ds_Minute, ds.ds_Tick, count);
154 tmpfile = Open(tmpname, MODE_NEWFILE);
155 } while (tmpfile == BNULL && IoErr() == ERROR_OBJECT_IN_USE);
157 if (tmpfile)
159 LONG c;
161 //if (FPuts(tmpfile, ".pushis\n") != -1)
162 while((c = FGetC(from)) != -1 && FPutC(tmpfile, c) != -1);
164 c = IoErr();
165 Close(from);
167 if (c)
169 FPuts(ces, "EXECUTE: error while creating temporary file\n");
170 PrintFault(c, NULL);
171 Close(tmpfile);
172 DeleteFile(tmpname);
173 if (extraargs)
174 FreeVec(extraargs);
176 return RETURN_FAIL;
179 c = '\n';
180 FPutC(tmpfile, c);
182 //FPuts(tmpfile, ".popis\n");
184 while((c = FGetC(cli->cli_CurrentInput)) != -1 && FPutC(tmpfile, c) != -1);
186 c = IoErr();
188 if (c)
190 FPuts(ces, "EXECUTE: error while creating temporary file\n");
191 PrintFault(c, NULL);
192 Close(tmpfile);
193 DeleteFile(tmpname);
194 if (extraargs)
195 FreeVec(extraargs);
197 return RETURN_FAIL;
200 Close(cli->cli_CurrentInput);
201 if (AROS_BSTR_strlen(cli->cli_CommandFile))
202 DeleteFile(AROS_BSTR_ADDR(cli->cli_CommandFile));
205 LONG len = strlen(tmpname);
206 CopyMem(tmpname, AROS_BSTR_ADDR(cli->cli_CommandFile), len);
207 AROS_BSTR_setstrlen(cli->cli_CommandFile, len);
210 cli->cli_CurrentInput = tmpfile;
211 Seek(tmpfile, 0, OFFSET_BEGINNING);
213 else
216 we should try to open ":T", but since ":"
217 is not handled correctly yet, we just give up
219 LONG c = IoErr();
220 FPuts(ces, "EXECUTE: error while creating temporary file\n");
221 PrintFault(c, NULL);
222 Close(from);
223 if (extraargs)
224 FreeVec(extraargs);
226 return RETURN_FAIL;
230 /* Update cli_CommandName to be the name of the script */
231 len = strlen(SHArg(NAME));
232 s = AROS_BSTR_ADDR(cli->cli_CommandName);
233 AROS_BSTR_setstrlen(cli->cli_CommandName, len);
234 CopyMem(SHArg(NAME), s, len);
236 if (arguments && strlen(arguments)) {
237 struct FileHandle *fh;
238 TEXT *fh_buff;
240 len = strlen(arguments);
242 /* Inject the command args into cli->cli_StandardInput
244 * It would be nice to have a standard DOS LVO that
245 * could do this for us.
247 Flush(cli->cli_StandardInput);
248 if (SetVBuf(cli->cli_StandardInput, NULL, BUF_LINE, len + 1) == 0) {
249 fh = BADDR(cli->cli_StandardInput);
250 fh->fh_Pos = 0;
251 fh->fh_End = len + 1;
252 fh_buff = BADDR(fh->fh_Buf);
253 CopyMem(arguments, fh_buff, len);
254 fh_buff[len] = '\n';
255 /* Prevent RunCommand() from flushing cli_StandardInput */
256 SelectInput(BNULL);
257 } else {
258 VFPrintf(ces, "EXECUTE: Can't inject command line\n", NULL);
259 return RETURN_FAIL;
263 return RETURN_OK;
265 AROS_SHCOMMAND_EXIT