added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / workbench / utilities / Installer / execute.c
blob53eb13f99d1fc0798f0970c0a150a62168f2d1cb
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 /* execute.c -- Here are all functions used to execute the script */
8 #include "Installer.h"
9 #include "execute.h"
10 #include "cmdlist.h"
11 #include "misc.h"
12 #include "gui.h"
13 #include "procedure.h"
14 #include "cleanup.h"
15 #include "variables.h"
16 #ifndef __AROS__
17 #define VOID_FUNC APTR
18 #define MAXFILENAMELENGTH 108
19 #define DosGetString
20 #endif
22 #include <sys/stat.h>
24 /* External variables */
25 extern InstallerPrefs preferences;
26 extern int error, grace_exit;
28 /* Internal function declarations */
29 static void callback(char, char **);
32 #define ExecuteCommand() \
33 if (current->cmd != NULL) \
34 { \
35 execute_script(current->cmd, level + 1); \
37 #define ExecuteNextCommand() \
38 if (current->next->cmd != NULL) \
39 { \
40 execute_script(current->next->cmd, level + 1); \
43 #define GetString(arg) \
44 if((arg)[0] == SQUOTE || (arg)[0] == DQUOTE) \
45 { \
46 string = strip_quotes(arg); \
47 } \
48 else \
49 { \
50 char *clip; \
51 if((clip = get_var_arg(arg)) == NULL) \
52 { \
53 string = StrDup(arg); \
54 } \
55 else \
56 { \
57 string = strip_quotes(clip); \
58 } \
61 int doing_abort = FALSE;
62 char * callbackstring = NULL, * globalstring = NULL;
66 * identify first arg with command and next ones as parameters to it
67 * command has to be keyword or quoted string
68 * parameters are converted as needed, <cmd> executed
70 void execute_script(ScriptArg *commands, int level)
72 ScriptArg *current, *dummy = NULL;
73 struct ParameterList *parameter;
74 struct ProcedureList *usrproc;
75 int cmd_type, slen;
76 long int i = 0, j;
77 char *clip = NULL, **mclip = NULL, *string = NULL;
78 void *params;
80 current = commands;
81 /* Assume commands->cmd/arg to be first cmd/arg in parentheses */
83 /* If first one is a (...)-function execute it */
84 if (current->cmd != NULL)
86 execute_script(current->cmd, level + 1);
87 /* So next ones are (...)-functions, too: execute them */
88 while (current->next != NULL)
90 current = current->next;
91 if (current->cmd != NULL)
93 execute_script(current->cmd, level + 1);
95 else
97 error = SCRIPTERROR;
98 traperr("Argument in list of commands!\n", NULL);
101 FreeVec(current->parent->arg);
102 current->parent->arg = NULL;
103 current->parent->intval = current->intval;
104 if (current->arg != NULL)
106 current->parent->arg = StrDup(current->arg);
107 outofmem(current->parent->arg);
110 else
112 cmd_type = eval_cmd(current->arg);
113 FreeVec(current->parent->arg);
114 current->parent->arg = NULL;
115 current->parent->intval = 0;
116 switch (cmd_type)
118 case _UNKNOWN: /* Unknown command */
119 error = SCRIPTERROR;
120 traperr("Unknown command <%s>!\n", current->arg);
121 break;
123 case _ABORT: /* Output all strings, execute onerrors and exit abnormally */
124 string = collect_strings(current->next, LINEFEED, level);
125 show_abort(string);
126 FreeVec(string);
127 if (preferences.transcriptstream != NULL)
129 Write(preferences.transcriptstream, "Aborting script.\n", 17);
131 error = USERABORT;
132 traperr("Aborting!", NULL);
133 break;
135 case _AND: /* logically AND two arguments */
136 case _BITAND: /* bitwise AND two arguments */
137 case _BITOR: /* bitwise OR two arguments */
138 case _BITXOR: /* bitwise XOR two arguments */
139 case _DIFF: /* returns 1 if 1st != 2nd else 0 */
140 case _DIV: /* divide 1st by 2nd intval */
141 case _EQUAL: /* returns 1 if 1st = 2nd else 0 */
142 case _LESS: /* returns 1 if 1st < 2nd else 0 */
143 case _LESSEQ: /* returns 1 if 1st <= 2nd else 0 */
144 case _MINUS: /* subtract 2nd from 1st intval */
145 case _MORE: /* returns 1 if 1st > 2nd else 0 */
146 case _MOREEQ: /* returns 1 if 1st >= 2nd else 0 */
147 case _OR: /* logically OR two arguments */
148 case _SHIFTLEFT: /* shift 1st left by 2nd arg bits */
149 case _SHIFTRGHT: /* shift 1st right by 2nd arg bits */
150 case _XOR: /* logically XOR two arguments */
151 if (current->next != NULL && current->next->next != NULL)
153 current = current->next;
154 ExecuteCommand();
155 ExecuteNextCommand();
156 i = getint(current);
157 current = current->next;
158 j = getint(current);
159 switch (cmd_type)
161 case _AND :
162 current->parent->intval = i && j;
163 break;
164 case _BITAND :
165 current->parent->intval = i & j;
166 break;
167 case _BITOR :
168 current->parent->intval = i | j;
169 break;
170 case _BITXOR :
171 current->parent->intval = i ^ j;
172 break;
173 case _DIFF :
174 current->parent->intval = (i != j) ? 1 : 0;
175 break;
176 case _DIV :
177 if (j == 0)
179 error = BADPARAMETER;
180 traperr("Division by zero!\n", NULL);
182 current->parent->intval = (int)(i / j);
183 break;
184 case _EQUAL :
185 current->parent->intval = (i == j) ? 1 : 0;
186 break;
187 case _LESS :
188 current->parent->intval = (i < j) ? 1 : 0;
189 break;
190 case _LESSEQ :
191 current->parent->intval = (i <= j) ? 1 : 0;
192 break;
193 case _MINUS :
194 current->parent->intval = i - j;
195 break;
196 case _MORE :
197 current->parent->intval = (i > j) ? 1 : 0;
198 break;
199 case _MOREEQ :
200 current->parent->intval = (i >= j) ? 1 : 0;
201 break;
202 case _OR :
203 current->parent->intval = i || j;
204 break;
205 case _SHIFTLEFT :
206 current->parent->intval = i << j;
207 break;
208 case _SHIFTRGHT :
209 current->parent->intval = i >> j;
210 break;
211 case _XOR :
212 current->parent->intval = (i && !j) || (j && !i);
213 break;
216 else
218 error = SCRIPTERROR;
219 traperr("<%s> requires two arguments!\n", current->arg);
221 break;
223 case _CAT: /* Return concatenated strings */
224 string = collect_strings(current->next, 0, level);
225 current->parent->arg = addquotes(string);
226 FreeVec(string);
227 break;
229 case _COMPLETE: /* Display how much we have done in percent */
230 if (current->next != NULL)
232 current = current->next;
233 ExecuteCommand();
234 i = getint(current);
236 else
238 i = 0;
240 current->parent->intval = i;
241 show_complete(i);
242 break;
244 case _DEBUG: /* printf() all strings to shell */
245 string = collect_strings(current->next, 0, level);
246 if (preferences.debug && preferences.fromcli)
248 printf("%s\n", string);
250 /* Set return value */
251 current->parent->arg = addquotes(string);
252 FreeVec(string);
253 break;
255 case _EXIT: /* Output all strings and exit */
256 /* print summary where app has been installed unless (quiet) is given */
257 parameter = get_parameters(current->next, level);
258 string = collect_strings(current->next, LINEFEED, level);
259 show_exit(string);
260 if (GetPL(parameter, _QUIET).intval == 0)
262 final_report();
264 FreeVec(string);
265 free_parameterlist(parameter);
266 #ifdef DEBUG
267 dump_varlist();
268 #endif /* DEBUG */
269 cleanup();
270 exit(0);
271 break;
273 case _IF: /* if 1st arg != 0 execute 2nd cmd else execute optional 3rd cmd */
274 if (current->next != NULL && current->next->next != NULL)
276 char *stringarg = NULL;
277 current = current->next;
278 ExecuteCommand();
279 i = getint(current);
280 if (i == 0)
282 current = current->next;
283 stringarg = current->arg;
285 if (current->next != NULL)
287 current = current->next;
288 ExecuteCommand();
289 current->parent->intval = current->intval;
290 if (current->arg != NULL)
292 current->parent->arg = StrDup(current->arg);
293 outofmem(current->parent->arg);
296 else if (stringarg)
298 current->parent->arg = StrDup("\"\"");
299 outofmem(current->parent->arg);
302 else
304 error = SCRIPTERROR;
305 traperr("<%s> requires two arguments!\n", current->arg);
307 break;
309 case _IN: /* Return (arg1) bitwise-and with bit numbers given as following args */
310 /* Get base integer into i */
311 if (current->next != NULL)
313 current = current->next;
314 ExecuteCommand();
315 i = getint(current);
317 /* Write the corresponding bits of i into parent */
318 while (current->next != NULL)
320 current = current->next;
321 ExecuteCommand();
322 j = getint(current);
323 current->parent->intval |= i & (1 << j);
325 break;
327 case _BITNOT: /* bitwise invert argument */
328 case _NOT: /* logically invert argument */
329 if (current->next != NULL)
331 current = current->next;
332 ExecuteCommand();
333 i = getint(current);
334 current->parent->intval = (cmd_type == _NOT) ? !i : ~i;
336 else
338 error = SCRIPTERROR;
339 traperr("<%s> requires one argument!\n", current->arg);
341 break;
343 case _PLUS: /* Sum up all arguments and return that value */
344 while (current->next != NULL)
346 current = current->next;
347 ExecuteCommand();
348 i = getint(current);
349 current->parent->intval += i;
351 break;
353 case _PROCEDURE: /* Link user function to global function name-space */
354 link_function(current->next->arg, current->next->intval);
355 break;
357 case _SELECT: /* Return the nth item of arguments, NULL|0 if 0 */
358 if (current->next != NULL)
360 current = current->next;
361 ExecuteCommand();
362 i = getint(current);
363 if (i > 0)
365 j = 0;
366 for (; i > 0 ; i--)
368 if (current->next != NULL)
370 current = current->next;
372 else
374 j = 1;
377 if (j == 0)
379 current->parent->intval = current->intval;
380 if (current->arg != NULL)
382 current->parent->arg = StrDup(current->arg);
383 outofmem(current->parent->arg);
388 else
390 error = SCRIPTERROR;
391 traperr("<%s> requires two arguments!\n", current->arg);
393 break;
395 case _SYMBOLSET: /* assign values to variables -- allow strings and commands as variablenames */
396 /* take odd args as names and even as values */
397 if (current->next != NULL)
399 char *clip2;
400 current = current->next;
401 while (current != NULL && current->next != NULL)
403 i = current->next->intval;
404 clip = NULL;
405 string = NULL;
406 ExecuteCommand();
407 if (current->arg == NULL)
409 /* There is no varname */
410 error = BADPARAMETER;
411 traperr("Variable name to <%s> is not a string!\n", current->parent->cmd->arg);
413 if (current->arg != NULL && (current->arg[0] == SQUOTE || current->arg[0] == DQUOTE))
415 /* There is a quoted varname */
416 /* Strip off quotes */
417 string = strip_quotes(current->arg);
419 else
421 /* Varname is stored in variable */
422 clip2 = get_var_arg(current->arg);
423 if (clip2 == NULL)
425 /* There is no varname */
426 error = BADPARAMETER;
427 traperr("Variable name to <%s> is not a string!\n", current->parent->cmd->arg);
429 string = StrDup(clip2);
430 outofmem(string);
432 ExecuteNextCommand();
433 if (current->next->arg != NULL)
435 if ((current->next->arg)[0] == SQUOTE || (current->next->arg)[0] == DQUOTE)
437 /* Strip off quotes */
438 clip = strip_quotes(current->next->arg);
439 i = 0;
441 else
443 /* value is a variable */
444 clip2 = get_var_arg(current->next->arg);
445 if (clip2 == NULL)
447 clip = NULL;
449 else
451 clip = StrDup(clip2);
452 outofmem(clip);
454 i = get_var_int(current->next->arg);
457 set_variable(string, clip, i);
458 FreeVec(string);
459 FreeVec(clip);
460 dummy = current;
461 current = current->next->next;
464 /* SET returns the value of the of the last assignment */
465 if (dummy->next->arg != NULL)
467 if ((dummy->next->arg)[0] == SQUOTE || (dummy->next->arg)[0] == DQUOTE)
469 dummy->parent->arg = StrDup(dummy->next->arg);
470 outofmem(dummy->parent->arg);
472 else
474 clip = get_var_arg(dummy->next->arg);
475 if (clip)
477 /* Add surrounding quotes to string */
478 dummy->parent->arg = addquotes(clip);
480 dummy->parent->intval = get_var_int(dummy->next->arg);
483 else
485 dummy->parent->intval = dummy->next->intval;
487 break;
489 case _SYMBOLVAL: /* return values of variables -- allow strings and commands as variablenames */
490 if (current->next != NULL)
492 string = NULL;
493 clip = NULL;
494 current = current->next;
495 ExecuteCommand();
496 if (current->arg == NULL)
498 /* There is no varname */
499 error = BADPARAMETER;
500 traperr("Variable name to <%s> is not a string!\n", current->parent->cmd->arg);
502 if (current->arg[0] == SQUOTE || current->arg[0] == DQUOTE)
504 /* There is a quoted varname */
505 /* Strip off quotes */
506 string = strip_quotes(current->arg);
507 current->parent->arg = get_var_arg(string);
508 current->parent->intval = get_var_int(string);
509 FreeVec(string);
511 else
513 /* Varname is stored in variable */
514 current->parent->arg = get_var_arg(current->arg);
515 current->parent->intval = get_var_int(current->arg);
518 else
520 error = SCRIPTERROR;
521 traperr("<%s> requires one argument!\n", current->arg);
523 break;
525 case _SET: /* assign values to variables */
526 /* take odd args as names and even as values */
527 if (current->next != NULL)
529 current = current->next;
530 while (current != NULL && current->next != NULL)
532 if (current->cmd != NULL)
534 /* There is a command instead of a varname */
535 error = BADPARAMETER;
536 traperr("<%s> expected variablename, found function instead!\n", current->parent->cmd->arg);
538 if (current->arg == NULL)
540 /* There is no varname */
541 error = BADPARAMETER;
542 traperr("Variable name to <%s> is not a string!\n", current->parent->cmd->arg);
544 if (current->arg != NULL && (current->arg[0] == SQUOTE || current->arg[0] == DQUOTE))
546 /* There is a quoted varname */
547 error = BADPARAMETER;
548 traperr("<%s> expected symbol, found quoted string instead!\n", current->parent->cmd->arg);
550 ExecuteNextCommand();
551 if (current->next->arg != NULL)
553 if ((current->next->arg)[0] == SQUOTE || (current->next->arg)[0] == DQUOTE)
555 /* Strip off quotes */
556 clip = strip_quotes(current->next->arg);
557 set_variable(current->arg, clip, current->next->intval);
558 FreeVec(clip);
560 else
562 /* value is a variable */
563 set_variable(current->arg, get_var_arg(current->next->arg), get_var_int(current->next->arg));
566 else
568 set_variable(current->arg, current->next->arg, current->next->intval);
570 dummy = current;
571 current = current->next->next;
574 /* SET returns the value of the of the last assignment */
575 if (dummy->next->arg != NULL)
577 if ((dummy->next->arg)[0] == SQUOTE || (dummy->next->arg)[0] == DQUOTE)
579 dummy->parent->arg = StrDup(dummy->next->arg);
580 outofmem(dummy->parent->arg);
582 else
584 clip = get_var_arg(dummy->next->arg);
585 if (clip)
587 /* Add surrounding quotes to string */
588 dummy->parent->arg = addquotes(clip);
590 dummy->parent->intval = get_var_int(dummy->next->arg);
593 else
595 dummy->parent->intval = dummy->next->intval;
597 break;
599 case _STRLEN: /* Return the length of the string, 0 for integer argument */
600 if (current->next != NULL)
602 current = current->next;
603 ExecuteCommand();
604 if (current->arg != NULL)
606 if ((current->arg)[0] == SQUOTE || (current->arg)[0] == DQUOTE)
608 current->parent->intval = strlen(current->arg) - 2;
610 else
612 if ((clip = get_var_arg(current->arg)) == NULL)
614 current->parent->intval = 0;
616 else
618 current->parent->intval = strlen(clip);
623 break;
625 case _STRING: /* Call RawDoFmt with string as format and args and return output */
627 /* Prepare base string */
628 /* Strip off quotes */
629 clip = strip_quotes(current->arg);
631 /* Now get arguments into typeless array (void *params) */
632 params = AllocVec(sizeof(IPTR), MEMF_PUBLIC);
633 outofmem(params);
634 ((char **)params)[0] = NULL;
635 mclip = NULL;
636 i = 0;
637 j = 0;
638 while (current->next != NULL)
640 current = current->next;
641 ExecuteCommand();
642 if (current->arg != NULL)
644 if ((current->arg)[0] == SQUOTE || (current->arg)[0] == DQUOTE)
646 /* Strip off quotes */
647 mclip = ReAllocVec(mclip, sizeof(char *) * (j+1), MEMF_PUBLIC);
648 outofmem(mclip);
649 mclip[j] = strip_quotes(current->arg);
650 ((char **)params)[i] = mclip[j];
651 j++;
653 else
655 ((char **)params)[i] = (char *)get_variable(current->arg);
658 else
660 ((char **)params)[i] = (char *)(current->intval);
662 i++;
663 params = ReAllocVec(params, sizeof(IPTR)*(i+1), MEMF_PUBLIC);
664 outofmem(params);
666 /* Call RawDoFmt() with parameter list */
667 /* Store that produced string as return value */
668 string = AllocVec(MAXARGSIZE, MEMF_PUBLIC);
669 outofmem(string);
670 callbackstring = string;
671 globalstring = callbackstring;
672 RawDoFmt(clip, params, (VOID_FUNC)&callback, &globalstring);
673 string = callbackstring;
674 /* Free temporary space */
675 FreeVec(clip);
676 if (mclip)
678 while (j > 0)
680 FreeVec(mclip[--j]);
682 FreeVec(mclip);
684 /* Add surrounding quotes to string */
685 current->parent->arg = addquotes(string);
686 FreeVec(string);
687 break;
689 case _SUBSTR: /* Return the substring of arg1 starting with arg2+1 character up to arg3 or end if !arg3 */
690 if (current->next != NULL && current->next->next != NULL)
692 /* Get string */
693 current = current->next;
694 ExecuteCommand();
695 if (current->arg != NULL)
697 if ((current->arg)[0] == SQUOTE || (current->arg)[0] == DQUOTE)
699 /* Strip off quotes */
700 string = strip_quotes(current->arg);
702 else
704 clip = get_var_arg(current->arg);
705 if (clip != NULL)
707 string = StrDup(clip);
708 outofmem(string);
710 else
712 string = AllocVec(MAXARGSIZE, MEMF_PUBLIC);
713 outofmem(string);
714 sprintf(string, "%ld", get_var_int(current->arg));
718 else
720 string = AllocVec(MAXARGSIZE, MEMF_PUBLIC);
721 outofmem(string);
722 sprintf(string, "%ld", current->intval);
724 current = current->next;
725 /* Get offset */
726 i = getint(current);
727 slen = strlen(string) - i;
728 if (i < 0)
730 FreeVec(string);
731 error = BADPARAMETER;
732 traperr("Negative argument to <%s>!\n", current->parent->cmd->arg);
734 /* Get number of chars to copy */
735 if (current->next != NULL)
737 current = current->next;
738 ExecuteCommand();
739 j = getint(current);
740 if (j < 0)
742 j = 0;
744 slen = j;
746 else
748 j = slen;
750 clip = AllocVec(slen + 1, MEMF_PUBLIC);
751 outofmem(clip);
752 strncpy(clip, (string + i), j);
753 clip[j] = 0;
754 FreeVec(string);
755 current->parent->arg = clip;
757 else
759 error = SCRIPTERROR;
760 traperr("<%s> requires at least two arguments!\n", current->arg);
762 break;
764 case _TIMES: /* Multiply all arguments and return that value */
765 if (current->next == NULL)
767 error = SCRIPTERROR;
768 traperr("No arguments to <%s>!\n", current->arg);
770 current->parent->intval = 1;
771 while (current->next != NULL)
773 current = current->next;
774 ExecuteCommand();
775 i = getint(current);
776 current->parent->intval *= i;
778 break;
780 case _TRANSCRIPT: /* concatenate strings into logfile */
781 string = collect_strings(current->next, 0, level);
782 if (preferences.transcriptfile != NULL)
784 Write(preferences.transcriptstream, string, strlen(string));
785 Write(preferences.transcriptstream, "\n", 1);
787 /* Add surrounding quotes to string */
788 current->parent->arg = addquotes(string);
789 FreeVec(string);
790 break;
792 case _UNTIL: /* execute 2nd cmd until 1st arg != 0 */
793 if (current->next != NULL && current->next->next != NULL)
795 current = current->next;
796 if (current->next->cmd == NULL)
798 /* We don't have a block, so what can we execute ??? */
799 error = SCRIPTERROR;
800 traperr("<%s> has no command-block!\n", current->parent->cmd->arg);
802 i = 0;
803 while (i == 0)
805 /* Execute command */
806 ExecuteNextCommand();
808 /* Now check condition */
809 ExecuteCommand();
810 i = getint(current);
812 /* condition is true -> return values and exit */
813 if (i != 0)
815 current->parent->intval = current->next->intval;
816 if (current->next->arg != NULL)
818 current->parent->arg = StrDup(current->next->arg);
819 outofmem(current->parent->arg);
824 else
826 error = SCRIPTERROR;
827 traperr("<%s> requires two arguments!\n", current->arg);
829 break;
831 case _USER: /* Change the current user-level -- Use only to debug scripts */
832 if (current->next != NULL)
834 current = current->next;
835 ExecuteCommand();
836 if (current->arg != NULL)
838 string = NULL;
839 if ((current->arg[0] == SQUOTE || current->arg[0] == DQUOTE))
841 /* Strip off quotes */
842 string = strip_quotes(current->arg);
843 clip = string;
845 else
847 clip = get_var_arg(current->arg);
849 if (clip != NULL)
851 i = atol(clip);
852 if (strcasecmp(clip, "novice") == 0)
853 i = _NOVICE;
854 if (strcasecmp(clip, "average") == 0)
855 i = _AVERAGE;
856 if (strcasecmp(clip, "expert") == 0)
857 i = _EXPERT;
858 FreeVec(string);
860 else
862 i = get_var_int(current->arg);
865 else
867 i = current->intval;
869 if (i < _NOVICE || i > _EXPERT)
871 error = BADPARAMETER;
872 traperr("New user-level not in [Novice|Average|Expert] !\n", NULL);
874 else
876 set_variable("@user-level", NULL, i);
877 current->parent->intval = i;
880 else
882 error = SCRIPTERROR;
883 traperr("<%s> requires one argument!\n", current->arg);
885 break;
887 case _WELCOME: /* Display strings instead of "Welcome to the <APPNAME> App installation utility" */
888 string = collect_strings(current->next, SPACE, level);
889 request_userlevel(string);
891 /* Set return value */
892 /* Add surrounding quotes to string */
893 current->parent->arg = addquotes(string);
894 FreeVec(string);
895 break;
897 case _WHILE: /* while 1st arg != 0 execute 2nd cmd */
898 if (current->next != NULL && current->next->next != NULL)
900 current = current->next;
901 if (current->next->cmd == NULL)
903 /* We don't have a block, so what can we execute ??? */
904 error = SCRIPTERROR;
905 traperr("<%s> has no command-block!\n", current->parent->cmd->arg);
907 i = 1;
908 while (i != 0)
910 ExecuteCommand();
912 /* Now check condition */
913 i = getint(current);
914 if (i != 0)
916 ExecuteNextCommand();
918 else
920 current->parent->intval = current->next->intval;
921 if (current->next->arg != NULL)
923 current->parent->arg = StrDup(current->next->arg);
924 outofmem(current->parent->arg);
929 else
931 error = SCRIPTERROR;
932 traperr("<%s> requires two arguments!\n", current->arg);
934 break;
936 case _MESSAGE: /* Display strings and offer Proceed, Abort, Help */
937 string = collect_strings(current->next, LINEFEED, level);
938 parameter = get_parameters(current->next, level);
939 show_message(string, parameter);
941 /* Set return value */
942 /* Add surrounding quotes to string */
943 current->parent->arg = addquotes(string);
944 FreeVec(string);
945 free_parameterlist(parameter);
946 break;
948 case _WORKING: /* Display strings below "Working on Installation" */
949 string = collect_strings(current->next, LINEFEED, level);
950 show_working(string);
952 /* Set return value */
953 /* Add surrounding quotes to string */
954 current->parent->arg = addquotes(string);
955 FreeVec(string);
956 break;
958 case _DATABASE: /* Return information on the hardware Installer is running on */
959 if (current->next != NULL)
961 current = current->next;
962 clip = strip_quotes(current->arg);
963 i = database_keyword(clip);
964 FreeVec(clip);
965 #warning TODO: compute return values for "database"
966 switch (i)
968 case _VBLANK :
969 clip = AllocVec(MAXARGSIZE, MEMF_PUBLIC);
970 outofmem(clip);
971 sprintf(clip, "%c%d%c", DQUOTE, SysBase->VBlankFrequency, DQUOTE);
972 current->parent->arg = StrDup(clip);
973 outofmem(current->parent->arg);
974 FreeVec(clip);
975 break;
977 case _CPU:
978 break;
980 case _GRAPHICS_MEM:
981 current->parent->intval = AvailMem(MEMF_CHIP);
982 break;
984 case _TOTAL_MEM:
985 current->parent->intval = AvailMem(MEMF_TOTAL);
986 break;
988 case _FPU:
989 break;
991 case _CHIPREV:
992 break;
994 default :
995 break;
998 else
1000 error = SCRIPTERROR;
1001 traperr("<%s> requires one argument!\n", current->arg);
1003 break;
1005 case _ASKBOOL: /* Ask user for a boolean */
1006 parameter = get_parameters(current->next, level);
1007 current->parent->intval = request_bool(parameter);
1008 free_parameterlist(parameter);
1009 break;
1011 case _ASKNUMBER: /* Ask user for a number */
1012 parameter = get_parameters(current->next, level);
1013 current->parent->intval = request_number(parameter);
1014 free_parameterlist(parameter);
1015 break;
1017 case _ASKSTRING: /* Ask user for a string */
1018 parameter = get_parameters(current->next, level);
1019 current->parent->arg = request_string(parameter);
1020 free_parameterlist(parameter);
1021 break;
1023 case _ASKCHOICE: /* Ask user to choose one item */
1024 parameter = get_parameters(current->next, level);
1025 current->parent->intval = request_choice(parameter);
1026 free_parameterlist(parameter);
1027 break;
1029 case _ASKDIR: /* Ask user for a directory */
1030 parameter = get_parameters(current->next, level);
1031 current->parent->arg = request_dir(parameter);
1032 free_parameterlist(parameter);
1033 break;
1035 case _ASKDISK: /* Ask user to insert a disk */
1036 parameter = get_parameters(current->next, level);
1037 current->parent->arg = request_disk(parameter);
1038 free_parameterlist(parameter);
1039 break;
1041 case _ASKFILE: /* Ask user for a filename */
1042 parameter = get_parameters(current->next, level);
1043 current->parent->arg = request_file(parameter);
1044 free_parameterlist(parameter);
1045 break;
1047 case _ASKOPTIONS: /* Ask user to choose multiple items */
1048 parameter = get_parameters(current->next, level);
1049 current->parent->intval = request_options(parameter);
1050 free_parameterlist(parameter);
1051 break;
1053 case _ONERROR: /* link onerror to preferences */
1054 current = current->next;
1055 /* reset parent of old onerror statement */
1056 dummy = preferences.onerror.cmd;
1057 while (dummy != NULL)
1059 dummy->parent = preferences.onerrorparent;
1060 dummy = dummy->next;
1062 /* set new onerror statement */
1063 preferences.onerror.cmd = current->cmd;
1064 preferences.onerrorparent = current;
1065 /* set new parent of new onerror statement */
1066 dummy = current->cmd;
1067 while (dummy != NULL)
1069 dummy->parent = &(preferences.onerror);
1070 dummy = dummy->next;
1072 break;
1074 case _TRAP: /* link trap to preferences */
1075 if (current->next != NULL && current->next->next->cmd != NULL)
1077 current = current->next;
1078 ExecuteCommand();
1079 i = getint(current) - 1;
1080 current = current->next;
1081 /* reset parent of old trap statement */
1082 dummy = preferences.trap[i].cmd;
1083 while (dummy != NULL)
1085 dummy->parent = preferences.trapparent[i];
1086 dummy = dummy->next;
1088 /* set new onerror statement */
1089 preferences.trap[i].cmd = current->cmd;
1090 preferences.trapparent[i] = current;
1091 /* set new parent of new onerror statement */
1092 dummy = current->cmd;
1093 while (dummy != NULL)
1095 dummy->parent = &(preferences.trap[i]);
1096 dummy = dummy->next;
1099 else
1101 error = SCRIPTERROR;
1102 traperr("<%s> requires two arguments!\n", current->arg);
1104 break;
1106 case _RENAME: /* Rename a file or relabel a disk if disk parameter */
1107 if (current->next != NULL && current->next->next != NULL)
1109 int success = DOSFALSE,
1110 usrconfirm = FALSE;
1111 /* Get strings */
1112 current = current->next;
1113 ExecuteCommand();
1114 ExecuteNextCommand();
1115 if (current->arg != NULL && current->next->arg != NULL)
1117 string = strip_quotes(current->arg);
1118 clip = strip_quotes(current->next->arg);
1120 else
1122 error = BADPARAMETER;
1123 traperr("<%s> requires two strings as arguments!\n", current->parent->cmd->arg);
1125 if (current->next->next)
1127 parameter = get_parameters(current->next->next, level);
1128 if (GetPL(parameter, _CONFIRM).used == 1)
1130 usrconfirm = request_confirm(parameter);
1132 if (GetPL(parameter, _DISK).used == 1)
1134 /* Relabel disk */
1135 if ((preferences.pretend == 0 || GetPL(parameter, _SAFE).used == 1) && usrconfirm)
1138 success = Relabel(string,clip);
1141 else
1143 /* Rename file */
1144 if ((preferences.pretend == 0 || GetPL(parameter, _SAFE).used == 1) && usrconfirm)
1146 success = Rename(string,clip);
1149 free_parameterlist(parameter);
1151 else
1153 if (preferences.pretend == 0)
1155 success = Rename(string,clip);
1158 if (success == DOSTRUE)
1160 current->parent->intval = 1;
1162 else
1164 current->parent->intval = 0;
1165 set_variable("@ioerr", NULL, IoErr());
1167 FreeVec(string);
1168 FreeVec(clip);
1170 else
1172 error = SCRIPTERROR;
1173 traperr("<%s> requires two arguments!\n", current->arg);
1175 break;
1177 case _EXECUTE: /* Execute an AmigaDOS script */
1178 #warning TODO: Check me for correctness
1179 if (current->next != NULL)
1181 int success = 0;
1182 BPTR infile;
1183 int safe = FALSE;
1185 current = current->next;
1186 ExecuteCommand();
1188 if (current->arg != NULL)
1190 GetString(current->arg);
1192 else
1194 error = BADPARAMETER;
1195 traperr("<%s> requires a file string as argument!\n", current->parent->cmd->arg);
1197 if (current->next)
1199 parameter = get_parameters(current->next, level);
1200 safe = GetPL(parameter, _SAFE).used;
1201 free_parameterlist(parameter);
1203 if (preferences.pretend == 0 || safe)
1205 infile = Open(string, MODE_OLDFILE);
1206 if(infile != NULL)
1208 if (preferences.transcriptstream != NULL)
1210 Write(preferences.transcriptstream, "Started AmigaDOS script: \"", 26);
1211 Write(preferences.transcriptstream, string, strlen(string));
1212 Write(preferences.transcriptstream, "\"\n", 2);
1214 success = Execute(NULL, infile, preferences.transcriptstream);
1215 Close(infile);
1217 else
1219 success = FALSE;
1222 if (success)
1224 current->parent->intval = 1;
1226 else
1228 current->parent->intval = 0;
1229 set_variable("@ioerr", NULL, IoErr());
1231 FreeVec(string);
1233 else
1235 error = SCRIPTERROR;
1236 traperr("<%s> requires one argument!\n", current->arg);
1238 break;
1240 case _RUN: /* Execute a command line */
1241 #warning TODO: Check me for correctness
1242 if (current->next != NULL)
1244 BPTR seg;
1245 parameter = get_parameters(current->next, level);
1246 if (preferences.pretend == 0 || GetPL(parameter, _SAFE).used == 1)
1248 string = collect_strings(current->next, SPACE, level);
1249 if (string == NULL)
1251 error = BADPARAMETER;
1252 traperr("<%s> requires a string parameter!\n", current->parent->cmd->arg);
1254 for (i = 0 ; string[i] != 0 && string[i] != SPACE ; i++);
1255 if (string[i] == SPACE)
1257 string[i] = 0;
1258 clip = &(string[i+1]);
1259 j = strlen(clip);
1261 else
1263 clip = NULL;
1264 j = 0;
1266 if (get_var_int("@user-level") >= GetPL(parameter, _CONFIRM).intval)
1268 if ((seg = LoadSeg(string)) == NULL)
1270 /* Couldn't load file -- set @ioerr and handle trap/onerror */
1271 i = IoErr();
1272 #ifdef DEBUG
1273 PrintFault(i, INSTALLER_NAME);
1274 #endif /* DEBUG */
1275 set_variable("@ioerr", NULL, i);
1276 error = DOSERROR;
1277 traperr("Couldn't load binary %s\n", string);
1279 if (preferences.transcriptstream != NULL)
1281 Write(preferences.transcriptstream, "Started program: \"", 18);
1282 Write(preferences.transcriptstream, string, strlen(string));
1283 Write(preferences.transcriptstream, "\"\n", 2);
1285 #define STACKSIZE 10000
1286 current->parent->intval = RunCommand(seg, STACKSIZE, clip, j);
1287 #warning FIXME: is @ioerr set if command not run?
1288 set_variable("@ioerr", NULL, IoErr());
1289 UnLoadSeg(seg);
1291 FreeVec(string);
1294 else
1296 error = SCRIPTERROR;
1297 traperr("<%s> requires arguments!\n", current->arg);
1299 break;
1301 case _STARTUP: /* Add a section to S:Startup-Sequence */
1302 ExecuteNextCommand();
1303 if (current->next->arg != NULL)
1305 string = strip_quotes(current->next->arg);
1306 parameter = get_parameters(current->next, level);
1307 if (request_confirm(parameter))
1309 modify_userstartup(string, parameter);
1311 free_parameterlist(parameter);
1312 FreeVec(string);
1314 else
1316 error = SCRIPTERROR;
1317 traperr("<%s> requires a name-string as argument!\n", current->arg);
1319 break;
1321 case _DELETE: /* Delete file */
1322 #warning TODO: Implement (optional) and (delopts)
1323 if (current->next != NULL)
1325 int success = -1, usrconfirm = FALSE;
1327 current = current->next;
1328 ExecuteCommand();
1330 if (current->arg != NULL)
1332 GetString(current->arg);
1334 else
1336 error = SCRIPTERROR;
1337 traperr("<%s> requires a file string as argument!\n", current->parent->cmd->arg);
1339 if (current->next)
1341 parameter = get_parameters(current->next, level);
1342 if (GetPL(parameter, _CONFIRM).used == 1)
1344 usrconfirm = request_confirm(parameter);
1346 /* Delete file */
1347 if ((preferences.pretend == 0 || GetPL(parameter, _SAFE).used == 1) && usrconfirm)
1349 success = DeleteFile(string);
1351 free_parameterlist(parameter);
1353 else
1355 if (preferences.pretend == 0)
1357 success = DeleteFile(string);
1360 if (success == 0)
1362 current->parent->intval = 1;
1364 else
1366 current->parent->intval = 0;
1367 set_variable("@ioerr", NULL, IoErr());
1369 FreeVec(string);
1371 else
1373 error = SCRIPTERROR;
1374 traperr("<%s> requires a string argument!\n", current->arg);
1376 break;
1378 case _MAKEDIR: /* Create directory */
1379 #warning TODO: Implement (infos)
1380 if (current->next != NULL)
1382 BPTR success = 0;
1383 int usrconfirm = FALSE;
1385 current = current->next;
1386 ExecuteCommand();
1388 if (current->arg != NULL)
1390 GetString(current->arg);
1392 else
1394 error = SCRIPTERROR;
1395 traperr("<%s> requires a file string as argument!\n", current->parent->cmd->arg);
1397 if (current->next)
1399 parameter = get_parameters(current->next, level);
1400 if (GetPL(parameter, _CONFIRM).used == 1)
1402 usrconfirm = request_confirm(parameter);
1404 /* Create directory */
1405 if ((preferences.pretend == 0 || GetPL(parameter, _SAFE).used == 1) && usrconfirm)
1407 success = CreateDir(string);
1409 free_parameterlist(parameter);
1411 else
1413 if (preferences.pretend == 0)
1415 success = CreateDir(string);
1418 /* return value of CreateDir() is a lock or 0 */
1419 if (success != 0)
1421 UnLock(success);
1422 current->parent->intval = 1;
1424 else
1426 current->parent->intval = 0;
1427 set_variable("@ioerr", NULL, IoErr());
1429 FreeVec(string);
1431 else
1433 error = SCRIPTERROR;
1434 traperr("<%s> requires a string argument!\n", current->arg);
1436 break;
1438 case _EXISTS:
1439 #warning TODO: Implement (noreq)
1440 if (current->next != NULL)
1442 struct stat sb;
1444 current = current->next;
1445 ExecuteCommand();
1447 if (current->arg != NULL)
1449 GetString(current->arg);
1451 else
1453 error = SCRIPTERROR;
1454 traperr("<%s> requires a file string as argument!\n", current->parent->cmd->arg);
1456 parameter = NULL;
1457 if (current->next)
1459 parameter = get_parameters(current->next, level);
1461 if (parameter)
1463 free_parameterlist(parameter);
1465 if(stat(string, &sb) == -1)
1467 current->parent->intval = 0;
1469 else
1471 if(sb.st_mode & S_IFDIR)
1473 /* Directory */
1474 current->parent->intval = 2;
1476 else if(sb.st_mode & S_IFREG)
1478 /* File */
1479 current->parent->intval = 1;
1481 else
1483 current->parent->intval = 0;
1486 FreeVec(string);
1488 else
1490 error = SCRIPTERROR;
1491 traperr("<%s> requires a string argument!\n", current->arg);
1493 break;
1495 case _FILEONLY: /* Return the file part of a pathname */
1496 if (current->next != NULL)
1498 current = current->next;
1499 ExecuteCommand();
1500 if (current->arg != NULL)
1502 char *tempnam;
1503 GetString(current->arg);
1504 tempnam = FilePart(string);
1505 i = strlen(tempnam);
1506 clip = AllocVec(sizeof(char) * i + 3, MEMF_PUBLIC);
1507 clip[0] = '"';
1508 strcpy(&clip[1], tempnam);
1509 clip[ i + 1 ] = '"';
1510 clip[ i + 2 ] = 0;
1511 current->parent->arg = clip;
1512 FreeVec(string);
1515 break;
1517 case _PATHONLY: /* Return the path part of a pathname */
1518 if (current->next != NULL)
1520 char *tempnam;
1522 current = current->next;
1523 ExecuteCommand();
1524 if (current->arg != NULL)
1526 GetString(current->arg);
1527 tempnam = PathPart(string);
1528 clip = AllocVec(sizeof(char) * (tempnam - string + 3), MEMF_PUBLIC);
1529 clip[0] = '"';
1530 strncpy(&clip[1], string, tempnam - string);
1531 clip[ tempnam - string + 1 ] = '"';
1532 clip[ tempnam - string + 2 ] = 0;
1533 current->parent->arg = clip;
1534 FreeVec(string);
1537 break;
1539 case _EARLIER: /* Return TRUE if file1 is older than file2 */
1540 if (current->next != NULL && current->next->next != NULL)
1542 char *file1 = NULL, *file2 = NULL;
1543 BPTR lock1, lock2;
1544 struct FileInfoBlock *fib1, *fib2;
1546 current = current->next;
1547 ExecuteCommand();
1548 if (current->arg != NULL)
1550 GetString(current->arg);
1551 file1 = string;
1553 else
1555 error = BADPARAMETER;
1556 traperr("<%s> requires two string arguments!\n", current->arg);
1559 current = current->next;
1560 ExecuteCommand();
1561 if (current->arg != NULL)
1563 GetString(current->arg);
1564 file2 = string;
1566 else
1568 error = BADPARAMETER;
1569 traperr("<%s> requires two string arguments!\n", current->arg);
1572 if ((lock1 = Lock(file1, SHARED_LOCK)) == NULL)
1574 error = DOSERROR;
1575 traperr("File not found <%s>\n", file1);
1577 if ((lock2 = Lock(file2, SHARED_LOCK)) == NULL)
1579 error = DOSERROR;
1580 traperr("File not found <%s>\n", file2);
1582 if ((fib1 = AllocDosObject((ULONG)DOS_FIB, NULL)) == NULL)
1584 error = DOSERROR;
1585 traperr("Could not AllocDosObject FIB for file <%s>\n", file1);
1587 if ((fib2 = AllocDosObject((ULONG)DOS_FIB, NULL)) == NULL)
1589 error = DOSERROR;
1590 traperr("Could not AllocDosObject FIB for file <%s>\n", file2);
1592 if (Examine(lock1, fib1) == FALSE)
1594 error = DOSERROR;
1595 traperr("Could not Examine() file <%s>\n", file1);
1597 if (Examine(lock2, fib2) == FALSE)
1599 error = DOSERROR;
1600 traperr("Could not Examine() file <%s>\n", file2);
1602 if (fib1->fib_Date.ds_Days < fib2->fib_Date.ds_Days)
1604 current->parent->intval = 1;
1606 else if (fib1->fib_Date.ds_Days == fib2->fib_Date.ds_Days)
1608 if (fib1->fib_Date.ds_Minute < fib2->fib_Date.ds_Minute)
1610 current->parent->intval = 1;
1612 else if (fib1->fib_Date.ds_Minute == fib2->fib_Date.ds_Minute)
1614 if (fib1->fib_Date.ds_Tick < fib2->fib_Date.ds_Tick)
1616 current->parent->intval = 1;
1620 FreeDosObject(DOS_FIB, fib2);
1621 FreeDosObject(DOS_FIB, fib1);
1622 UnLock(lock2);
1623 UnLock(lock1);
1624 FreeVec(file1);
1625 FreeVec(file2);
1627 else
1629 error = SCRIPTERROR;
1630 traperr("<%s> requires two string arguments!\n", current->arg);
1632 break;
1634 case _GETDISKSPACE: /* Return the number of free bytes on a device, or -1 on bad pathname or when info could not be obtained */
1635 if (current->next != NULL)
1637 BPTR lock;
1638 struct InfoData infodata;
1640 current = current->next;
1641 ExecuteCommand();
1642 if (current->arg != NULL)
1644 GetString(current->arg);
1645 current->parent->intval = -1;
1646 if ((lock = Lock(string, SHARED_LOCK)) != NULL)
1648 if (Info(lock, &infodata) != FALSE)
1650 current->parent->intval = (infodata.id_NumBlocks - infodata.id_NumBlocksUsed) * infodata.id_BytesPerBlock;
1652 UnLock(lock);
1654 FreeVec(string);
1657 break;
1659 case _GETSIZE: /* Get the size of a file in bytes */
1660 if (current->next != NULL)
1662 struct stat sb;
1664 current = current->next;
1665 ExecuteCommand();
1667 if (current->arg != NULL)
1669 GetString(current->arg);
1671 else
1673 error = SCRIPTERROR;
1674 traperr("<%s> requires a file string as argument!\n", current->parent->cmd->arg);
1676 if(stat(string, &sb) == -1)
1678 current->parent->intval = 0;
1680 else
1682 current->parent->intval = sb.st_size;
1684 FreeVec(string);
1686 else
1688 error = SCRIPTERROR;
1689 traperr("<%s> requires a string argument!\n", current->arg);
1691 break;
1693 case _GETENV: /* Get Variable from ENV: */
1694 if (current->next != NULL)
1696 current = current->next;
1697 ExecuteCommand();
1699 if (current->arg != NULL)
1701 char buffer[1024] = {0};
1702 string = strip_quotes(current->arg);
1704 #warning FIXME: flag must be one of GVF_GLOBAL_ONLY or GVF_LOCAL_ONLY???
1705 i = GetVar(string, buffer, 1023, 0);
1707 FreeVec(string);
1709 if(i != -1)
1711 current->parent->arg = StrDup(buffer);
1714 else
1716 error = SCRIPTERROR;
1717 traperr("<%s> requires a string as argument!\n", current->parent->cmd->arg);
1720 else
1722 error = SCRIPTERROR;
1723 traperr("<%s> requires a string as argument!\n", current->arg);
1725 break;
1727 case _MAKEASSIGN:
1728 if (current->next != NULL)
1730 char *assign;
1731 int safe = FALSE;
1733 if (current->next)
1735 parameter = get_parameters(current->next, level);
1736 safe = GetPL(parameter, _SAFE).used;
1737 free_parameterlist(parameter);
1739 current = current->next;
1740 ExecuteCommand();
1742 if (current->arg != NULL)
1744 GetString(current->arg);
1746 else
1748 error = SCRIPTERROR;
1749 traperr("<%s> requires an assign name as argument!\n", current->parent->cmd->arg);
1751 assign = string;
1753 if (current->next != NULL)
1755 /* Add Path to Assign */
1756 BPTR lock;
1758 current = current->next;
1759 ExecuteCommand();
1761 if (current->arg != NULL)
1763 GetString(current->arg);
1765 lock = Lock(string, SHARED_LOCK);
1766 if ( lock != NULL )
1768 if (preferences.pretend == 0 || safe)
1770 if (AssignAdd(assign, lock) == DOSFALSE)
1772 if (AssignLock(assign, lock) == DOSFALSE)
1774 error = DOSERROR;
1775 UnLock(lock);
1777 else
1779 current->parent->intval = 1;
1782 else
1784 current->parent->intval = 1;
1788 FreeVec(string);
1790 else
1792 if (preferences.pretend == 0 || safe)
1794 /* Remove Assign */
1795 AssignLock(string,NULL);
1796 current->parent->intval = 1;
1799 FreeVec(assign);
1801 else
1803 error = SCRIPTERROR;
1804 traperr("<%s> requires at least one argument!\n", current->arg);
1806 break;
1808 case _GETASSIGN :
1809 if (current->next != NULL)
1811 ULONG lockBits = LDF_ASSIGNS;
1812 struct DosList *dl, *tdl;
1813 char *assign, *ret = NULL;
1815 current = current->next;
1816 ExecuteCommand();
1818 if (current->arg != NULL)
1820 GetString(current->arg);
1822 else
1824 error = SCRIPTERROR;
1825 traperr("<%s> requires an assign name as argument!\n", current->parent->cmd->arg);
1827 assign = string;
1829 if (current->next != NULL)
1831 current = current->next;
1832 ExecuteCommand();
1834 if (current->arg != NULL)
1836 GetString(current->arg);
1837 if (string[0]=='v' || string[0]=='V')
1839 lockBits = LDF_VOLUMES;
1841 else if (string[0]=='a' || string[0]=='A')
1843 lockBits = LDF_ASSIGNS;
1845 else if (string[0]=='d' || string[0]=='D')
1847 lockBits = LDF_DEVICES;
1849 else
1851 error = SCRIPTERROR;
1852 traperr("Invalid option <%s> to getassign!\n", string);
1855 FreeVec(string);
1857 /* get the assign */
1859 dl = LockDosList(LDF_READ | LDF_VOLUMES | LDF_ASSIGNS | LDF_DEVICES);
1860 tdl = FindDosEntry(dl, assign, lockBits);
1861 if (tdl != NULL)
1863 switch (lockBits)
1865 case LDF_VOLUMES:
1866 DMSG("VOLUME(%s:)\n",(char *)tdl->dol_Ext.dol_AROS.dol_DevName);
1867 ret = AllocVec(strlen((char *)tdl->dol_Ext.dol_AROS.dol_DevName) + 2, MEMF_ANY);
1868 outofmem(ret);
1869 sprintf(ret,"%s:",(char *)tdl->dol_Ext.dol_AROS.dol_DevName);
1870 break;
1872 case LDF_ASSIGNS:
1873 DMSG("ASSIGN(%s:):\n",(char *)tdl->dol_Ext.dol_AROS.dol_DevName);
1874 switch (tdl->dol_Type)
1876 case DLT_LATE:
1877 case DLT_NONBINDING:
1878 DMSG(" %s\n",tdl->dol_misc.dol_assign.dol_AssignName);
1879 ret = StrDup(tdl->dol_misc.dol_assign.dol_AssignName);
1880 break;
1882 default:
1884 struct AssignList *nextAssign; /* For multiassigns */
1886 ret = DynNameFromLock(tdl->dol_Lock);
1887 DMSG(" %s\n", ret);
1889 nextAssign = tdl->dol_misc.dol_assign.dol_List;
1890 while (nextAssign != NULL)
1892 char *dirName;
1893 dirName = DynNameFromLock(nextAssign->al_Lock);
1894 if (dirName != NULL)
1896 DMSG(" +%s\n", dirName);
1897 if (ret)
1899 char *sum;
1900 sum = AllocVec(strlen(ret) + strlen(dirName) + 2, MEMF_ANY);
1901 sprintf(sum, "%s %s", ret, dirName);
1902 FreeVec(ret);
1903 ret = sum;
1905 else
1907 ret = StrDup(dirName);
1909 FreeVec(dirName);
1911 nextAssign = nextAssign->al_Next;
1914 break;
1916 break;
1918 case LDF_DEVICES:
1920 BPTR lockdev;
1921 char *lname;
1923 DMSG("DEV(%s:):\n",(char *)tdl->dol_Ext.dol_AROS.dol_DevName);
1924 lname = AllocVec(strlen(tdl->dol_Ext.dol_AROS.dol_DevName) + 2, MEMF_ANY);
1925 sprintf(lname,"%s:",tdl->dol_Ext.dol_AROS.dol_DevName);
1926 lockdev = Lock(lname, SHARED_LOCK);
1927 FreeVec(lname);
1928 if (lockdev)
1930 ret = DynNameFromLock(lockdev);
1931 DMSG(" %s\n",ret);
1932 UnLock(lockdev);
1934 else
1936 ret = AllocVec(strlen((char *)tdl->dol_Ext.dol_AROS.dol_DevName) + 2, MEMF_ANY);
1937 outofmem(ret);
1938 sprintf(ret,"%s:",(char *)tdl->dol_Ext.dol_AROS.dol_DevName);
1941 break;
1944 UnLockDosList(lockBits);
1945 if (ret)
1947 current->parent->arg = addquotes(ret);
1948 FreeVec(ret);
1950 else
1952 current->parent->arg = addquotes("");
1955 FreeVec(assign);
1957 else
1959 error = SCRIPTERROR;
1960 traperr("<%s> requires at least one argument!\n", current->arg);
1962 break;
1964 case _GETDEVICE:
1965 if (current->next != NULL)
1967 char *ret = NULL;
1968 BPTR lockdev;
1970 current = current->next;
1971 ExecuteCommand();
1973 if (current->arg != NULL)
1975 GetString(current->arg);
1977 else
1979 error = SCRIPTERROR;
1980 traperr("<%s> requires a device name as argument!\n", current->parent->cmd->arg);
1983 lockdev = Lock(string, SHARED_LOCK);
1984 FreeVec(string);
1985 if (lockdev)
1987 char *send;
1988 ret = DynNameFromLock(lockdev);
1989 send = ret;
1990 while (*send && *send != ':') send++;
1991 if(*send) send[1] = 0;
1993 UnLock(lockdev);
1995 if (ret)
1997 current->parent->arg = addquotes(ret);
1998 FreeVec(ret);
2000 else
2002 current->parent->arg = addquotes("");
2006 else
2008 error = SCRIPTERROR;
2009 traperr("<%s> requires at least one argument!\n", current->arg);
2011 break;
2013 case _TACKON :
2014 if (current->next != NULL && current->next->next != NULL)
2016 char ret[MAXFILENAMELENGTH];
2018 current = current->next;
2019 ExecuteCommand();
2021 if (current->arg != NULL)
2023 GetString(current->arg);
2025 else
2027 error = SCRIPTERROR;
2028 traperr("<%s> requires a path part as argument!\n", current->parent->cmd->arg);
2030 clip = string;
2032 current = current->next;
2033 ExecuteCommand();
2035 if (current->arg != NULL)
2037 GetString(current->arg);
2039 else
2041 error = SCRIPTERROR;
2042 traperr("<%s> requires a file part as argument!\n", current->parent->cmd->arg);
2045 ret[0] = 0;
2046 if (AddPart(ret, clip, MAXFILENAMELENGTH) == 0)
2048 error = DOSERROR;
2049 traperr("AddPart(%s) failed!\n", clip);
2051 FreeVec(clip);
2052 if (AddPart(ret, string, MAXFILENAMELENGTH) == 0)
2054 error = DOSERROR;
2055 traperr("AddPart(%s) failed!\n", string);
2057 FreeVec(string);
2058 current->parent->arg = addquotes(ret);
2060 else
2062 error = SCRIPTERROR;
2063 traperr("<%s> requires two arguments!\n", current->arg);
2065 break;
2067 case _EXPANDPATH:
2068 if (current->next != NULL)
2070 char *ret = NULL;
2071 BPTR lockdev;
2073 current = current->next;
2074 ExecuteCommand();
2076 if (current->arg != NULL)
2078 GetString(current->arg);
2080 else
2082 error = BADPARAMETER;
2083 traperr("<%s> requires a path name as argument!\n", current->parent->cmd->arg);
2086 lockdev = Lock(string, SHARED_LOCK);
2087 FreeVec(string);
2088 if (lockdev)
2090 ret = DynNameFromLock(lockdev);
2091 UnLock(lockdev);
2093 if (ret)
2095 current->parent->arg = addquotes(ret);
2096 FreeVec(ret);
2098 else
2100 current->parent->arg = addquotes("");
2104 else
2106 error = SCRIPTERROR;
2107 traperr("<%s> requires one argument!\n", current->arg);
2109 break;
2111 /* Here are all unimplemented commands */
2112 case _COPYFILES :
2113 case _COPYLIB :
2114 case _FOREACH :
2115 case _GETSUM :
2116 case _GETVERSION :
2117 case _ICONINFO :
2118 case _PATMATCH :
2119 case _PROTECT :
2120 case _REXX :
2121 case _TEXTFILE :
2122 case _TOOLTYPE :
2123 fprintf(stderr, "Unimplemented command <%s>\n", current->arg);
2124 break;
2126 case _USERDEF: /* User defined routine */
2127 usrproc = find_proc(current->arg);
2128 /* Set argument variables */
2129 i = 0;
2130 while (current->next != NULL && i < usrproc->argnum)
2132 current = current->next;
2133 ExecuteCommand();
2134 if (current->arg != NULL)
2136 if ((current->arg)[0] == SQUOTE || (current->arg)[0] == DQUOTE)
2138 /* Strip off quotes */
2139 clip = strip_quotes(current->arg);
2140 set_variable(usrproc->arglist[i], clip, 0);
2141 FreeVec(clip);
2143 else
2145 /* value is a variable */
2146 set_variable(usrproc->arglist[i], get_var_arg(current->arg), get_var_int(current->arg));
2149 else
2151 set_variable(usrproc->arglist[i], NULL, current->intval);
2153 i++;
2155 /* Execute procedure */
2156 dummy = usrproc->procbody;
2157 execute_script(dummy->cmd, level + 1);
2158 current->parent->intval = dummy->intval;
2159 if (dummy->arg != NULL)
2161 current->parent->arg = StrDup(dummy->arg);
2162 outofmem(current->parent->arg);
2164 break;
2166 /* Here are all tags, first the ones which have to be executed */
2167 case _DELOPTS: /* unset copying/deleting options if we are called global */
2168 /* as parameter to a function we have got an ignore=1 before */
2169 #warning FIXME: (delopts) is only local
2170 if (current->parent->ignore == 0)
2172 /* Read in strings */
2173 parameter = AllocVec(sizeof(struct ParameterList), MEMF_PUBLIC);
2174 outofmem(parameter);
2175 collect_stringargs(current, level, parameter);
2176 /* Store data in preferences */
2177 for (i = 0 ; i < parameter->intval ; i++)
2179 /* These are mutually exclusive */
2180 #warning FIXME: How are (fail-)strings interpreted in "delopts" ?
2181 if (strcasecmp(parameter->arg[i], "fail") == 0)
2184 if (strcasecmp(parameter->arg[i], "nofail") == 0)
2187 if (strcasecmp(parameter->arg[i], "oknodelete") == 0)
2191 /* These may be combined in any way */
2192 if (strcasecmp(parameter->arg[i], "force") == 0)
2194 preferences.copyflags &= ~COPY_ASKUSER;
2196 if (strcasecmp(parameter->arg[i], "askuser") == 0)
2198 preferences.copyflags &= ~COPY_ASKUSER;
2202 free_parameterlist(parameter);
2204 break;
2206 case _OPTIONAL: /* set copying/deleting options if we are called global */
2207 /* as parameter to a function we have got an ignore=1 before */
2208 #warning FIXME: (optional) is only local
2209 if (current->parent->ignore == 0)
2211 /* Read in strings */
2212 parameter = AllocVec(sizeof(struct ParameterList), MEMF_PUBLIC);
2213 outofmem(parameter);
2214 collect_stringargs(current, level, parameter);
2215 /* Store data in preferences */
2216 for (i = 0 ; i < parameter->intval ; i++)
2218 /* These are mutually exclusive */
2219 if (strcasecmp(parameter->arg[i], "fail") == 0)
2221 preferences.copyfail &= ~(COPY_FAIL | COPY_NOFAIL | COPY_OKNODELETE);
2222 preferences.copyfail |= COPY_FAIL;
2224 if (strcasecmp(parameter->arg[i], "nofail") == 0)
2226 preferences.copyfail &= ~(COPY_FAIL | COPY_NOFAIL | COPY_OKNODELETE);
2227 preferences.copyfail |= COPY_NOFAIL;
2229 if (strcasecmp(parameter->arg[i], "oknodelete") == 0)
2231 preferences.copyfail &= ~(COPY_FAIL | COPY_NOFAIL | COPY_OKNODELETE);
2232 preferences.copyfail |= COPY_OKNODELETE;
2235 /* These may be combined in any way */
2236 if (strcasecmp(parameter->arg[i], "force") == 0)
2238 preferences.copyflags |= COPY_ASKUSER;
2240 if (strcasecmp(parameter->arg[i], "askuser") == 0)
2242 preferences.copyflags |= COPY_ASKUSER;
2246 free_parameterlist(parameter);
2248 break;
2250 #ifdef DEBUG
2251 case _ALL:
2252 case _APPEND:
2253 case _ASSIGNS:
2254 case _CHOICES:
2255 case _COMMAND:
2256 case _CONFIRM:
2257 case _DEFAULT:
2258 case _DEST:
2259 case _DISK:
2260 case _FILES:
2261 case _FONTS:
2262 case _HELP:
2263 case _INCLUDE:
2264 case _INFOS:
2265 case _NEWNAME:
2266 case _NEWPATH:
2267 case _NOGAUGE:
2268 case _NOPOSITION:
2269 case _PATTERN:
2270 case _PROMPT:
2271 case _RANGE:
2272 case _RESIDENT:
2273 case _SAFE:
2274 case _SETDEFAULTTOOL:
2275 case _SETPOSITION:
2276 case _SETSTACK:
2277 case _SETTOOLTYPE:
2278 case _SOURCE:
2279 case _SWAPCOLORS:
2280 case _QUIET:
2281 /* We are tags -- we don't want to be executed */
2282 current->parent->ignore = 1;
2283 break;
2284 #endif /* DEBUG */
2286 default:
2287 #ifdef DEBUG
2288 /* Hey! Where did you get this number from??? It's invalid -- must be a bug. */
2289 fprintf(stderr, "Unknown command ID %d called <%s>!\n", cmd_type, current->arg);
2290 cleanup();
2291 exit(-1);
2292 #else /* DEBUG */
2293 /* We are tags -- we don't want to be executed */
2294 current->parent->ignore = 1;
2295 #endif /* DEBUG */
2296 break;
2303 * Get an ID for the command string
2305 int eval_cmd(char * argument)
2307 int i;
2309 if (argument[0] == SQUOTE || argument[0] == DQUOTE)
2311 return _STRING;
2313 else
2315 for (i = 0 ; i < _MAXCOMMAND && strcasecmp(internal_commands[i].cmdsymbol, argument) != 0 ; i++);
2316 if (i != _MAXCOMMAND)
2318 return internal_commands[i].cmdnumber;
2320 else
2322 if (find_proc(argument) != NULL)
2324 return _USERDEF;
2326 else
2328 return _UNKNOWN;
2336 * Callback function for RawDoFmt()
2338 static void callback(char chr, char ** data)
2340 static int i = 0, j = 1;
2341 static char * string = NULL;
2343 if (callbackstring != string)
2345 string = callbackstring;
2346 i = 0;
2347 j = 1;
2349 i++;
2350 if (i > MAXARGSIZE)
2352 j++;
2353 i = 1;
2354 callbackstring = ReAllocVec(callbackstring, MAXARGSIZE * j, MEMF_PUBLIC);
2355 outofmem(callbackstring);
2356 globalstring += (callbackstring - string);
2357 string = callbackstring;
2359 *(*data)++ = chr;
2364 * Strip off quotes from a string
2365 * Does not check for quotes!
2367 char *strip_quotes(char *string)
2369 int slen;
2370 char *clip;
2372 /* Strip off quotes */
2373 slen = strlen(string);
2374 clip = (char *)AllocVec(slen - 1, MEMF_PUBLIC);
2375 outofmem(clip);
2376 strncpy(clip, string+1, slen-2);
2377 clip[slen-2] = 0;
2379 return clip;
2384 * Convert data entry to <int>
2385 * <string>s are atol()'d, <cmd>s are *not* executed
2387 long int getint(ScriptArg *argument)
2389 long int i;
2390 char * clip;
2392 if (argument->arg != NULL)
2394 if ((argument->arg)[0] == SQUOTE || (argument->arg)[0] == DQUOTE)
2396 /* Strip off quotes */
2397 clip = strip_quotes(argument->arg);
2398 i = atol(clip);
2399 FreeVec(clip);
2401 else
2403 clip = get_var_arg(argument->arg);
2404 if (clip != NULL)
2406 i = atol(clip);
2408 else
2410 i = get_var_int(argument->arg);
2414 else
2416 i = argument->intval;
2419 return i;
2424 * Get an ID for hardware descriptor
2426 int database_keyword(char *name)
2428 if (strcasecmp(name, "vblank") == 0)
2429 return _VBLANK;
2430 else if (strcasecmp(name, "cpu") == 0)
2431 return _CPU;
2432 else if (strcasecmp(name, "graphics-mem") == 0)
2433 return _GRAPHICS_MEM;
2434 else if (strcasecmp(name, "total-mem") == 0)
2435 return _TOTAL_MEM;
2436 else if (strcasecmp(name, "fpu") == 0)
2437 return _FPU;
2438 else if (strcasecmp(name, "chiprev") == 0)
2439 return _CHIPREV;
2441 return _UNKNOWN;
2446 * Concatenate all arguments as a string with separating character
2447 * if character is 0 strings are concatenated without separator
2448 * <int>s are converted to strings, <cmd>s are executed,
2449 * <parameter>s are not considered
2451 char *collect_strings(ScriptArg *current, char separator, int level)
2453 char *string = NULL, *clip, *dummy;
2454 int i;
2456 while (current != NULL)
2458 ExecuteCommand();
2459 /* Concatenate string unless it was a parameter which will be ignored */
2460 if (current->ignore == 0)
2462 if (current->arg != NULL)
2464 if ((current->arg)[0] == SQUOTE || (current->arg)[0] == DQUOTE)
2466 /* Strip off quotes */
2467 clip = strip_quotes(current->arg);
2469 else
2471 dummy = get_var_arg(current->arg);
2472 if (dummy != NULL)
2474 clip = StrDup(dummy);
2475 outofmem(clip);
2477 else
2479 clip = AllocVec(MAXARGSIZE, MEMF_PUBLIC);
2480 outofmem(clip);
2481 sprintf(clip, "%ld", get_var_int(current->arg));
2485 else
2487 clip = AllocVec(MAXARGSIZE, MEMF_PUBLIC);
2488 outofmem(clip);
2489 sprintf(clip, "%ld", current->intval);
2491 i = (string == NULL) ? 0 : strlen(string);
2492 string = ReAllocVec(string, i + strlen(clip) + 2, MEMF_PUBLIC);
2493 outofmem(string);
2494 if (i == 0)
2496 string[0] = 0;
2498 else
2500 string[i] = separator;
2501 string[i+1] = 0;
2503 strcat(string, clip);
2504 FreeVec(clip);
2506 current = current->next;
2509 return string;
2514 * Free the allocated space for string list
2516 void free_parameter(struct ParameterList pl)
2518 int j;
2520 if (pl.arg)
2522 for (j = 0 ; j < pl.intval ; j++)
2524 FreeVec(pl.arg[j]);
2526 FreeVec(pl.arg);
2527 pl.arg = NULL;
2533 * Free a complete (struct ParameterList *)
2535 void free_parameterlist(struct ParameterList *pl)
2537 int i;
2539 if (pl)
2541 for (i = 0 ; i < NUMPARAMS ; i++)
2543 free_parameter(pl[i]);
2545 FreeVec(pl);
2551 * args are scanned for known parameters
2552 * the used entry will be set and <int>s and <string>s read in ParameterList
2553 * intval contains number of <string>s
2555 struct ParameterList *get_parameters(ScriptArg *script, int level)
2557 struct ParameterList *pl;
2558 ScriptArg *current;
2559 long int i;
2560 int cmd;
2561 char *string, *clip;
2563 pl = AllocVec(NUMPARAMS * sizeof(struct ParameterList), MEMF_PUBLIC|MEMF_CLEAR);
2564 outofmem(pl);
2565 while (script != NULL)
2567 /* Check if we have a command as argument */
2568 if (script->cmd != NULL)
2570 current = script->cmd->next;
2571 /* Check if we don't have a block as argument */
2572 if (script->cmd->arg != NULL)
2574 /* Check if we have a parameter as command */
2575 cmd = eval_cmd(script->cmd->arg);
2576 if (cmd > _PARAMETER && cmd <= (_PARAMETER + NUMPARAMS))
2578 /* This is a parameter */
2579 GetPL(pl, cmd).used = 1;
2580 if (cmd > (_PARAMETER + NUMARGPARAMS))
2582 /* This is a boolean parameter */
2583 GetPL(pl, cmd).intval = 1;
2585 else
2587 /* This parameter may have arguments */
2588 switch (cmd)
2590 /* Parameters with args */
2591 case _APPEND : /* $ */
2592 case _CHOICES : /* $... */
2593 case _COMMAND : /* $... */
2594 case _DELOPTS : /* $... */
2595 case _DEST : /* $ */
2596 case _HELP : /* $... */
2597 case _INCLUDE : /* $ */
2598 case _NEWNAME : /* $ */
2599 case _OPTIONAL : /* $... */
2600 case _PATTERN : /* $ */
2601 case _PROMPT : /* $... */
2602 case _SETDEFAULTTOOL: /* $ */
2603 case _SETTOOLTYPE : /* $ [$] */
2604 case _SOURCE : /* $ */
2605 collect_stringargs(current, level, &(GetPL(pl, cmd)));
2606 break;
2608 case _CONFIRM: /* ($->)# */
2609 i = _EXPERT;
2610 if (current != NULL)
2612 ExecuteCommand();
2613 if (current->arg != NULL)
2615 string = NULL;
2616 if ((current->arg)[0] == SQUOTE || (current->arg)[0] == DQUOTE)
2618 /* Strip off quotes */
2619 string = strip_quotes(current->arg);
2620 clip = string;
2622 else
2624 clip = get_var_arg(current->arg);
2626 if (clip != NULL)
2628 i = atol(clip);
2629 if (strcasecmp(clip, "novice") == 0)
2631 i = _NOVICE;
2633 if (strcasecmp(clip, "average") == 0)
2635 i = _AVERAGE;
2637 if (strcasecmp(clip, "expert") == 0)
2639 i = _EXPERT;
2641 FreeVec(string);
2643 else
2645 i = get_var_int(current->arg);
2648 else
2650 i = current->intval;
2653 if (i < _NOVICE || i > _EXPERT)
2655 error = BADPARAMETER;
2656 traperr("Userlevel out of range!\n", NULL);
2658 GetPL(pl, cmd).intval = i;
2659 break;
2661 case _DEFAULT: /* * */
2662 i = 0;
2663 string = NULL;
2664 if (current != NULL)
2666 ExecuteCommand();
2667 if (current->arg != NULL)
2669 if ((current->arg)[0] == SQUOTE || (current->arg)[0] == DQUOTE)
2671 /* Strip off quotes */
2672 string = strip_quotes(current->arg);
2674 else
2676 clip = get_var_arg(current->arg);
2677 if (clip != NULL)
2679 string = StrDup(clip);
2680 outofmem(string);
2682 else
2684 i = get_var_int(current->arg);
2688 else
2690 i = current->intval;
2692 GetPL(pl, cmd).intval = i;
2693 if (string != NULL)
2695 /* To avoid problems with multiple definitions of default */
2696 /* take last (this) one as true and clear previous */
2697 if (GetPL(pl, cmd).arg != NULL)
2699 FreeVec(GetPL(pl, cmd).arg[0]);
2701 else
2703 GetPL(pl, cmd).arg = AllocVec(sizeof(char *), MEMF_PUBLIC);
2704 outofmem(GetPL(pl, cmd).arg);
2706 GetPL(pl, cmd).arg[0] = string;
2709 else
2711 error = SCRIPTERROR;
2712 traperr("<%s> requires one argument!\n", script->cmd->arg);
2714 break;
2716 case _RANGE : /* # # */
2717 case _SETPOSITION : /* # # */
2718 i = 0;
2719 if (current != NULL && current->next != NULL)
2721 ExecuteCommand();
2722 GetPL(pl, cmd).intval = getint(current);
2723 current = current->next;
2724 ExecuteCommand();
2725 GetPL(pl, cmd).intval2 = getint(current);
2727 else
2729 error = SCRIPTERROR;
2730 traperr("<%s> requires two arguments!\n", script->cmd->arg);
2732 break;
2734 case _SETSTACK: /* # */
2735 i = 0;
2736 if (current != NULL)
2738 ExecuteCommand();
2739 if (current->arg != NULL)
2741 if ((current->arg)[0] == SQUOTE || (current->arg)[0] == DQUOTE)
2743 /* Strip off quotes */
2744 string = strip_quotes(current->arg);
2745 i = atol(string);
2746 FreeVec(string);
2748 else
2750 clip = get_var_arg(current->arg);
2751 if (clip != NULL)
2753 i = atol(clip);
2755 else
2757 i = get_var_int(current->arg);
2761 else
2763 i = current->intval;
2765 GetPL(pl, cmd).intval = i;
2767 else
2769 error = SCRIPTERROR;
2770 traperr("<%s> requires one argument!\n", script->cmd->arg);
2772 break;
2775 default: /* We do only collect tags -- this is a command */
2776 break;
2780 else if (cmd == _IF)
2782 /* This parameter is masqueraded */
2783 switch (cmd)
2785 /* "Allowed" Commands (for compatibility) */
2787 /* (if (= 1 1) (command "blah")) is allowed, but should be
2788 * (command (if (= 1 1) "blah"))
2790 case _IF: /* if 1st arg != 0 get parameter from 2nd cmd else get optional 3rd cmd parameter */
2791 if (current != NULL && current->next != NULL)
2793 ExecuteCommand();
2794 i = getint(current);
2795 if (i == 0)
2797 current = current->next;
2799 if (current->next != NULL)
2801 current = current->next;
2802 if (current->cmd != NULL)
2804 struct ParameterList *subpl;
2805 subpl = get_parameters(current, level + 1);
2806 for (i = 0 ; i < NUMPARAMS ; i++)
2808 if (subpl[i].used == 1)
2810 free_parameter(pl[i]);
2811 pl[i].arg = subpl[i].arg;
2812 pl[i].intval = subpl[i].intval;
2813 pl[i].intval2 = subpl[i].intval2;
2814 subpl[i].arg = NULL;
2817 free_parameterlist(subpl);
2821 else
2823 error = SCRIPTERROR;
2824 traperr("<%s> requires two arguments!\n", script->arg);
2826 break;
2828 default: /* We do only collect tags -- this is a command */
2829 break;
2834 script = script->next;
2837 return pl;
2842 * read <string>s in ParameterList
2843 * <int>s are converted, <cmd>s executed
2845 void collect_stringargs(ScriptArg *current, int level, struct ParameterList *pl)
2847 char *string, *clip, **mclip = NULL;
2848 int j = 0;
2850 while (current != NULL)
2852 ExecuteCommand();
2853 mclip = ReAllocVec(mclip, sizeof(char *) * (j+1), MEMF_PUBLIC);
2854 outofmem(mclip);
2855 if (current->arg != NULL)
2857 if ((current->arg)[0] == SQUOTE || (current->arg)[0] == DQUOTE)
2859 /* Strip off quotes */
2860 string = strip_quotes(current->arg);
2862 else
2864 clip = get_var_arg(current->arg);
2865 if (clip != NULL)
2867 string = StrDup(clip);
2868 outofmem(string);
2870 else
2872 clip = AllocVec(MAXARGSIZE, MEMF_PUBLIC);
2873 outofmem(clip);
2874 sprintf(clip, "%ld", get_var_int(current->arg));
2875 string = StrDup(clip);
2876 outofmem(string);
2877 FreeVec(clip);
2881 else
2883 clip = AllocVec(MAXARGSIZE, MEMF_PUBLIC);
2884 outofmem(clip);
2885 sprintf(clip, "%ld", current->intval);
2886 string = StrDup(clip);
2887 outofmem(string);
2888 FreeVec(clip);
2890 mclip[j] = string;
2891 j++;
2892 current = current->next;
2894 pl->arg = mclip;
2895 pl->intval = j;
2900 * Read in one line of a file
2902 char * get_file_line(BPTR file)
2904 char *out;
2905 char buf[1];
2906 int i=0, cnt;
2910 cnt = Read(file, buf, 1);
2911 i += cnt;
2912 } while (cnt && buf[0] != LINEFEED);
2913 if (i == 0)
2915 return NULL;
2917 Seek(file, -i, OFFSET_CURRENT);
2918 out = AllocVec(i * sizeof(char), MEMF_PUBLIC);
2919 outofmem(out);
2920 Read(file, out, i);
2921 out[i-1] = 0;
2923 return out;
2928 * Routine for modifying S:User-Startup
2930 void modify_userstartup(char *string, struct ParameterList *parameter)
2932 BPTR userstartup;
2933 BPTR tmpuserstartup;
2934 char *line;
2935 int i, changed = 0, cont = 0;
2937 userstartup = Open("S:User-Startup", MODE_OLDFILE);
2938 tmpuserstartup = Open("S:User-Startup.tmp", MODE_NEWFILE);
2939 if (!tmpuserstartup)
2941 #warning TODO: Complain more smoothly...
2942 fprintf(stderr, "Could not open S:User-Startup for writing!");
2943 exit(-1);
2945 if (userstartup)
2947 while ((line = get_file_line(userstartup)) && !changed)
2949 if (strncasecmp(line, ";BEGIN ", 7) == 0)
2951 if (strcmp(&(line[7]), string) == 0)
2953 changed = 1;
2956 if (!changed)
2958 Write(tmpuserstartup, line, strlen(line));
2959 Write(tmpuserstartup, "\n", 1);
2961 FreeVec(line);
2965 Write(tmpuserstartup, ";BEGIN ", 7);
2966 Write(tmpuserstartup, string, strlen(string));
2967 Write(tmpuserstartup, "\n", 1);
2968 for (i = 0 ; i < GetPL(parameter, _COMMAND).intval ; i++)
2970 Write(tmpuserstartup, GetPL(parameter, _COMMAND).arg[i], strlen(GetPL(parameter, _COMMAND).arg[i]));
2972 Write(tmpuserstartup, ";END ", 5);
2973 Write(tmpuserstartup, string, strlen(string));
2974 Write(tmpuserstartup, "\n", 1);
2976 if (userstartup)
2978 while ((line = get_file_line(userstartup)))
2980 if (!cont)
2982 if (strncasecmp(line, ";END ", 5) == 0)
2984 if (strcmp(&(line[5]), string) == 0)
2986 cont = 1;
2990 else
2992 Write(tmpuserstartup, line, strlen(line));
2993 Write(tmpuserstartup, "\n", 1);
2995 FreeVec(line);
2999 Close(tmpuserstartup);
3000 Close(userstartup);
3002 DeleteFile("S:User-Startup");
3003 #warning FIXME: Check correctness of Rename()
3005 IMO both arguments to Rename() should contain S:, check again if
3006 Rename() is proven to work as expected
3008 if (Rename("S:User-Startup.tmp", "User-Startup") == DOSFALSE)
3010 printf("Rename failed because of %s\n", DosGetString(IoErr()));
3017 * Execute "(traperr)" from preferences
3019 void traperr(char * msg, char * name)
3021 char *outmsg;
3022 int i, j;
3024 if (!doing_abort)
3026 doing_abort = TRUE;
3028 i = (msg != NULL) ? strlen(msg) : 0 ;
3029 j = (name != NULL) ? strlen(name) : 0 ;
3030 outmsg = AllocVec(i + j + 1, MEMF_PUBLIC);
3031 sprintf(outmsg, msg, name);
3032 display_text(outmsg);
3034 if (preferences.trap[ error - 1 ].cmd != NULL)
3036 /* execute trap */
3037 execute_script(preferences.trap[ error - 1 ].cmd, -99);
3039 else
3041 /* execute onerrors */
3042 if (preferences.onerror.cmd != NULL)
3044 execute_script(preferences.onerror.cmd, -99);
3049 #ifdef DEBUG
3050 dump_varlist();
3051 #endif /* DEBUG */
3053 cleanup();
3054 if (grace_exit == TRUE)
3056 exit(0);
3058 else
3060 exit(-1);
3065 char *DynNameFromLock(BPTR lock)
3067 char *dirName = NULL;
3068 ULONG size;
3070 for (size = 512 ; ; size += 512)
3072 dirName = AllocVec(size, MEMF_ANY);
3073 if (dirName == NULL)
3075 break;
3077 if (NameFromLock(lock, dirName, size))
3079 break;
3081 FreeVec(dirName);
3082 dirName = NULL;
3083 if (IoErr() != ERROR_LINE_TOO_LONG)
3085 break;
3088 return dirName;