- Fixed a regression in decoding 8-bit images (introduced in my r46589).
[AROS.git] / workbench / c / shellcommands / Execute.c
blobb9f144ac6e73d9846dfb5407528905260472771f
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 IPTR data[] = { (IPTR)SHArg(NAME) };
115 VFPrintf(ces, "EXECUTE: can't open %s\n", data);
116 PrintFault(IoErr(), NULL);
117 if (extraargs)
118 FreeVec(extraargs);
119 return RETURN_FAIL;
122 if (cli->cli_StandardInput == cli->cli_CurrentInput)
124 cli->cli_CurrentInput = from;
126 else
128 struct DateStamp ds;
129 BYTE tmpname[256];
130 BPTR tmpfile = BNULL;
131 ULONG count = 0;
132 BYTE tmpdir[4];
133 BPTR tmplock;
134 struct Window *win;
135 struct Process *proc = (struct Process*)FindTask(0);
137 DateStamp(&ds);
139 win = proc->pr_WindowPtr;
140 proc->pr_WindowPtr = (struct Window *)-1;
141 tmplock = Lock("T:", SHARED_LOCK);
142 proc->pr_WindowPtr = win;
143 if (tmplock) {
144 strcpy(tmpdir, "T:");
145 UnLock(tmplock);
146 } else {
147 strcpy(tmpdir, ":T/");
150 do {
151 count++;
152 __sprintf(tmpname, "%sTmp%lu%lu%lu%lu%lu", tmpdir,
153 ((struct Process *)FindTask(NULL))->pr_TaskNum,
154 ds.ds_Days, ds.ds_Minute, ds.ds_Tick, count);
155 tmpfile = Open(tmpname, MODE_NEWFILE);
156 } while (tmpfile == BNULL && IoErr() == ERROR_OBJECT_IN_USE);
158 if (tmpfile)
160 LONG c;
162 //if (FPuts(tmpfile, ".pushis\n") != -1)
163 while((c = FGetC(from)) != -1 && FPutC(tmpfile, c) != -1);
165 c = IoErr();
166 Close(from);
168 if (c)
170 FPuts(ces, "EXECUTE: error while creating temporary file\n");
171 PrintFault(c, NULL);
172 Close(tmpfile);
173 DeleteFile(tmpname);
174 if (extraargs)
175 FreeVec(extraargs);
177 return RETURN_FAIL;
180 c = '\n';
181 FPutC(tmpfile, c);
183 //FPuts(tmpfile, ".popis\n");
185 while((c = FGetC(cli->cli_CurrentInput)) != -1 && FPutC(tmpfile, c) != -1);
187 c = IoErr();
189 if (c)
191 FPuts(ces, "EXECUTE: error while creating temporary file\n");
192 PrintFault(c, NULL);
193 Close(tmpfile);
194 DeleteFile(tmpname);
195 if (extraargs)
196 FreeVec(extraargs);
198 return RETURN_FAIL;
201 Close(cli->cli_CurrentInput);
202 if (AROS_BSTR_strlen(cli->cli_CommandFile))
203 DeleteFile(AROS_BSTR_ADDR(cli->cli_CommandFile));
206 LONG len = strlen(tmpname);
207 CopyMem(tmpname, AROS_BSTR_ADDR(cli->cli_CommandFile), len);
208 AROS_BSTR_setstrlen(cli->cli_CommandFile, len);
211 cli->cli_CurrentInput = tmpfile;
212 Seek(tmpfile, 0, OFFSET_BEGINNING);
214 else
217 we should try to open ":T", but since ":"
218 is not handled correctly yet, we just give up
220 LONG c = IoErr();
221 FPuts(ces, "EXECUTE: error while creating temporary file\n");
222 PrintFault(c, NULL);
223 Close(from);
224 if (extraargs)
225 FreeVec(extraargs);
227 return RETURN_FAIL;
231 /* Update cli_CommandName to be the name of the script */
232 len = strlen(SHArg(NAME));
233 s = AROS_BSTR_ADDR(cli->cli_CommandName);
234 AROS_BSTR_setstrlen(cli->cli_CommandName, len);
235 CopyMem(SHArg(NAME), s, len);
237 if (arguments && strlen(arguments)) {
238 struct FileHandle *fh;
239 TEXT *fh_buff;
241 len = strlen(arguments);
243 /* Inject the command args into cli->cli_StandardInput
245 * It would be nice to have a standard DOS LVO that
246 * could do this for us.
248 Flush(cli->cli_StandardInput);
249 if (SetVBuf(cli->cli_StandardInput, NULL, BUF_LINE, len + 1) == 0) {
250 fh = BADDR(cli->cli_StandardInput);
251 fh->fh_Pos = 0;
252 fh->fh_End = len + 1;
253 fh_buff = BADDR(fh->fh_Buf);
254 CopyMem(arguments, fh_buff, len);
255 fh_buff[len] = '\n';
256 /* Prevent RunCommand() from flushing cli_StandardInput */
257 SelectInput(BNULL);
258 } else {
259 VFPrintf(ces, "EXECUTE: Can't inject command line\n", NULL);
260 return RETURN_FAIL;
264 return RETURN_OK;
266 AROS_SHCOMMAND_EXIT