Hint added.
[AROS.git] / workbench / c / IconX.c
blob3311432a4410c367955eb64a49d4606ad2ac224f
1 /*
2 Copyright © 2006-2012, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: IconX WB script starter
6 Lang: English
7 */
9 /******************************************************************************
12 NAME
14 IconX
16 SYNOPSIS
18 FILE/A
20 LOCATION
24 FUNCTION
26 Starts DOS scripts from Workbench. In order to use it you need an icon for
27 your script. Set 'IconX' as default tool.
29 INPUTS
31 FILE - The script filename to execute.
33 Tooltypes for script icon:
34 WINDOW -- Specification of the shell window
35 default: con:0/50//120/IconX/AUTO/WAIT/CLOSE
36 STACK=n -- default: 40960
37 USERSHELL=YES|NO -- default: YES
38 WAIT=n -- Wait n seconds before closing window (default 2)
39 DELAY=n -- Wait n/50 seconds before closing window
41 RESULT
43 NOTES
45 EXAMPLE
47 BUGS
49 SEE ALSO
51 Execute
53 INTERNALS
55 HISTORY
57 ******************************************************************************/
59 //#define DEBUG 1
61 #include <aros/debug.h>
62 #include <proto/exec.h>
63 #include <proto/dos.h>
64 #include <proto/intuition.h>
65 #include <proto/icon.h>
66 #include <proto/alib.h>
68 #include <workbench/startup.h>
70 #include <string.h>
71 #include <stdlib.h>
72 #include <stdio.h>
74 /* some default values */
75 #define DEFWINDOW "con:0/50//120/IconX/AUTO/WAIT/CLOSE"
76 #define DEFSTACK (40960)
77 #define DEFWAIT (2 * 50) // two seconds
78 #define DEFUSHELL (TRUE)
80 #define BASECOMMAND "EXECUTE "
82 const TEXT version[] = "\0$VER: IconX 41.4 (2.8.2014)";
83 int __forceerrorrequester = 1;
84 static TEXT errbuffer[255];
87 void displayMsg(LONG code)
89 if (code)
91 Fault(code, "IconX", errbuffer, sizeof(errbuffer));
92 struct EasyStruct es = {sizeof(struct EasyStruct), 0,
93 "Error", errbuffer, "OK"};
94 EasyRequest(0, &es, 0);
98 STRPTR AllocateNameFromLock(BPTR lock)
100 ULONG length = 512;
101 STRPTR buffer = NULL;
102 BOOL done = FALSE;
104 while (!done)
106 if (buffer != NULL) FreeVec(buffer);
108 buffer = AllocVec(length, MEMF_ANY);
109 if (buffer != NULL)
111 if (NameFromLock(lock, buffer, length))
113 done = TRUE;
114 break;
116 else
118 if (IoErr() == ERROR_LINE_TOO_LONG)
120 length += 512;
121 continue;
123 else
125 break;
129 else
131 SetIoErr(ERROR_NO_FREE_STORE);
132 break;
136 if (done)
138 return buffer;
140 else
142 if (buffer != NULL) FreeVec(buffer);
143 return NULL;
149 STRPTR BuildCommandLine(struct WBStartup *startup)
151 const struct WBStartup *wbsstate = startup;
152 STRPTR buffer = NULL;
153 ULONG length = 2 /* NULL + '\n' */ + strlen(BASECOMMAND);
154 int i;
156 /*-- Calculate length of resulting string ------------------------------*/
157 for (i = 1 ; i < wbsstate->sm_NumArgs ; i++)
159 BPTR lock = Lock((STRPTR) wbsstate->sm_ArgList[i].wa_Name, ACCESS_READ);
160 if (lock != BNULL)
162 BPTR cd = CurrentDir(lock);
163 STRPTR path = AllocateNameFromLock(lock);
164 if (path != NULL)
166 length += 3 /* space + 2 '"' */ + strlen(path);
167 FreeVec(path);
169 UnLock(lock);
170 CurrentDir(cd);
174 /*-- Allocate space for command line string ----------------------------*/
175 buffer = AllocVec(length, MEMF_ANY);
176 D(bug("[IconX] buffer length: %d\n", length));
178 if (buffer != NULL)
180 /*-- Build command line --------------------------------------------*/
181 strcpy(buffer, BASECOMMAND);
183 for (i = 1 ; i < wbsstate->sm_NumArgs ; i++)
185 BPTR lock = Lock((STRPTR) wbsstate->sm_ArgList[i].wa_Name, ACCESS_READ);
186 if (lock != BNULL)
188 BPTR cd = CurrentDir(lock);
189 STRPTR path = AllocateNameFromLock(lock);
190 if (path != NULL)
192 strcat(buffer, " \"");
193 strcat(buffer, path);
194 strcat(buffer, "\"");
195 FreeVec(path);
197 UnLock(lock);
198 CurrentDir(cd);
201 strcat(buffer, "\n");
203 else
205 SetIoErr(ERROR_NO_FREE_STORE);
208 return buffer;
212 int main(int argc, char **argv)
214 LONG rc = RETURN_FAIL;
215 STRPTR filename,
216 commandLine = NULL,
217 ixWindow = DEFWINDOW;
218 LONG ixWait = 0,
219 ixStack = DEFSTACK;
220 BOOL ixUShell = DEFUSHELL;
221 BPTR oldlock = (BPTR)-1,
222 dirlock = (BPTR)-1,
223 window = BNULL;
224 struct DiskObject *dobj = NULL;
226 D(bug("IconX argc %d\n", argc));
228 if (argc != 0)
230 displayMsg(ERROR_REQUIRED_ARG_MISSING);
231 goto exit;
234 struct WBStartup *startup = (struct WBStartup *) argv;
235 if (startup->sm_NumArgs < 2)
237 displayMsg(ERROR_REQUIRED_ARG_MISSING);
238 goto exit;
241 D(bug("[IconX] startup->sm_NumArgs: %d\n", startup->sm_NumArgs));
243 dirlock = startup->sm_ArgList[1].wa_Lock;
244 filename = startup->sm_ArgList[1].wa_Name;
246 oldlock = CurrentDir(dirlock);
248 /* query diskobject for tooltypes */
249 dobj = GetDiskObject(filename);
250 if (dobj == NULL)
252 struct EasyStruct es = {sizeof(struct EasyStruct), 0,
253 "Error", "IconX\nGetDiskObject failed for:\n%s", "OK"};
254 EasyRequest(0, &es, 0, filename);
255 goto exit;
258 if (dobj->do_Type == WBPROJECT)
260 const STRPTR *toolarray = (const STRPTR *)dobj->do_ToolTypes;
261 STRPTR s;
262 if ((s = FindToolType(toolarray, "WINDOW")))
264 ixWindow = s;
266 if ((s = FindToolType(toolarray, "STACK")))
268 ixStack = atol(s);
270 if ((s = FindToolType(toolarray, "USERSHELL")))
272 if (MatchToolValue(s, "NO"))
274 ixUShell = FALSE;
277 if ((s = FindToolType(toolarray, "WAIT")))
279 ixWait += atol(s) * 50;
281 if ((s = FindToolType(toolarray, "DELAY")))
283 ixWait += atol(s);
286 else
288 displayMsg(ERROR_OBJECT_WRONG_TYPE);
289 goto exit;
292 if (ixWait <= 0)
293 ixWait = DEFWAIT;
295 if (ixStack <= 4096)
296 ixStack = DEFSTACK;
298 D(bug("wait %d stack %d usershell %d window %s\n", ixWait, ixStack, ixUShell, ixWindow));
300 D(bug("Building command line\n"));
301 commandLine = BuildCommandLine(startup);
302 if (commandLine == NULL)
304 displayMsg(IoErr());
305 goto exit;
307 D(bug("[IconX] commandLine: '%s'\n", commandLine));
309 window = Open(ixWindow, MODE_OLDFILE);
310 if (window == BNULL)
312 /* try to open default window */
313 window = Open(DEFWINDOW, MODE_OLDFILE);
316 if (window)
318 D(bug("[IconX] window ok\n"));
319 struct TagItem tags[] =
321 { SYS_Asynch, FALSE },
322 { SYS_Input, (IPTR)window },
323 { SYS_Output, (IPTR)NULL },
324 { SYS_Error, (IPTR)NULL },
325 { SYS_UserShell, ixUShell },
326 { NP_StackSize, ixStack },
327 { TAG_DONE, 0 }
330 rc = SystemTagList(commandLine, tags);
331 if (rc == -1)
333 displayMsg(IoErr());
334 rc = RETURN_FAIL;
337 else
339 displayMsg(IoErr());
340 goto exit;
343 Delay(ixWait);
344 rc = RETURN_OK;
346 exit:
347 Close(window);
348 FreeDiskObject(dobj);
350 if (oldlock != (BPTR)-1)
351 CurrentDir(oldlock);
353 return rc;