2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
6 /* execute.c -- Here are all functions used to execute the script */
13 #include "procedure.h"
15 #include "variables.h"
17 #define VOID_FUNC APTR
18 #define MAXFILENAMELENGTH 108
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) \
35 execute_script(current->cmd, level + 1); \
37 #define ExecuteNextCommand() \
38 if (current->next->cmd != NULL) \
40 execute_script(current->next->cmd, level + 1); \
43 #define GetString(arg) \
44 if((arg)[0] == SQUOTE || (arg)[0] == DQUOTE) \
46 string = strip_quotes(arg); \
51 if((clip = get_var_arg(arg)) == NULL) \
53 string = strdup(arg); \
57 string = strip_quotes(clip); \
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
;
77 char *clip
= NULL
, **mclip
= NULL
, *string
= NULL
;
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);
98 traperr("Argument in list of commands!\n", NULL
);
101 free(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
);
112 cmd_type
= eval_cmd(current
->arg
);
113 free(current
->parent
->arg
);
114 current
->parent
->arg
= NULL
;
115 current
->parent
->intval
= 0;
118 case _UNKNOWN
: /* Unknown command */
120 traperr("Unknown command <%s>!\n", current
->arg
);
123 case _ABORT
: /* Output all strings, execute onerrors and exit abnormally */
124 string
= collect_strings(current
->next
, LINEFEED
, level
);
127 if (preferences
.transcriptstream
!= BNULL
)
129 Write(preferences
.transcriptstream
, "Aborting script.\n", 17);
132 traperr("Aborting!", NULL
);
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
;
155 ExecuteNextCommand();
157 current
= current
->next
;
162 current
->parent
->intval
= i
&& j
;
165 current
->parent
->intval
= i
& j
;
168 current
->parent
->intval
= i
| j
;
171 current
->parent
->intval
= i
^ j
;
174 current
->parent
->intval
= (i
!= j
) ? 1 : 0;
179 error
= BADPARAMETER
;
180 traperr("Division by zero!\n", NULL
);
182 current
->parent
->intval
= (int)(i
/ j
);
185 current
->parent
->intval
= (i
== j
) ? 1 : 0;
188 current
->parent
->intval
= (i
< j
) ? 1 : 0;
191 current
->parent
->intval
= (i
<= j
) ? 1 : 0;
194 current
->parent
->intval
= i
- j
;
197 current
->parent
->intval
= (i
> j
) ? 1 : 0;
200 current
->parent
->intval
= (i
>= j
) ? 1 : 0;
203 current
->parent
->intval
= i
|| j
;
206 current
->parent
->intval
= i
<< j
;
209 current
->parent
->intval
= i
>> j
;
212 current
->parent
->intval
= (i
&& !j
) || (j
&& !i
);
219 traperr("<%s> requires two arguments!\n", current
->arg
);
223 case _CAT
: /* Return concatenated strings */
224 string
= collect_strings(current
->next
, 0, level
);
225 current
->parent
->arg
= addquotes(string
);
229 case _COMPLETE
: /* Display how much we have done in percent */
230 if (current
->next
!= NULL
)
232 current
= current
->next
;
240 current
->parent
->intval
= i
;
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
);
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
);
260 if (GetPL(parameter
, _QUIET
).intval
== 0)
265 free_parameterlist(parameter
);
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
;
282 current
= current
->next
;
283 stringarg
= current
->arg
;
285 if (current
->next
!= NULL
)
287 current
= current
->next
;
289 current
->parent
->intval
= current
->intval
;
290 if (current
->arg
!= NULL
)
292 current
->parent
->arg
= strdup(current
->arg
);
293 outofmem(current
->parent
->arg
);
298 current
->parent
->arg
= strdup("\"\"");
299 outofmem(current
->parent
->arg
);
305 traperr("<%s> requires two arguments!\n", current
->arg
);
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
;
317 /* Write the corresponding bits of i into parent */
318 while (current
->next
!= NULL
)
320 current
= current
->next
;
323 current
->parent
->intval
|= i
& (1 << j
);
327 case _BITNOT
: /* bitwise invert argument */
328 case _NOT
: /* logically invert argument */
329 if (current
->next
!= NULL
)
331 current
= current
->next
;
334 current
->parent
->intval
= (cmd_type
== _NOT
) ? !i
: ~i
;
339 traperr("<%s> requires one argument!\n", current
->arg
);
343 case _PLUS
: /* Sum up all arguments and return that value */
344 while (current
->next
!= NULL
)
346 current
= current
->next
;
349 current
->parent
->intval
+= i
;
353 case _PROCEDURE
: /* Link user function to global function name-space */
354 link_function(current
->next
->arg
, current
->next
->intval
);
357 case _SELECT
: /* Return the nth item of arguments, NULL|0 if 0 */
358 if (current
->next
!= NULL
)
360 current
= current
->next
;
368 if (current
->next
!= NULL
)
370 current
= current
->next
;
379 current
->parent
->intval
= current
->intval
;
380 if (current
->arg
!= NULL
)
382 current
->parent
->arg
= strdup(current
->arg
);
383 outofmem(current
->parent
->arg
);
391 traperr("<%s> requires two arguments!\n", current
->arg
);
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
)
400 current
= current
->next
;
401 while (current
!= NULL
&& current
->next
!= NULL
)
403 i
= current
->next
->intval
;
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
);
421 /* Varname is stored in variable */
422 clip2
= get_var_arg(current
->arg
);
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
);
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
);
443 /* value is a variable */
444 clip2
= get_var_arg(current
->next
->arg
);
451 clip
= strdup(clip2
);
454 i
= get_var_int(current
->next
->arg
);
457 set_variable(string
, clip
, i
);
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
);
474 clip
= get_var_arg(dummy
->next
->arg
);
477 /* Add surrounding quotes to string */
478 dummy
->parent
->arg
= addquotes(clip
);
480 dummy
->parent
->intval
= get_var_int(dummy
->next
->arg
);
485 dummy
->parent
->intval
= dummy
->next
->intval
;
489 case _SYMBOLVAL
: /* return values of variables -- allow strings and commands as variablenames */
490 if (current
->next
!= NULL
)
494 current
= current
->next
;
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
);
513 /* Varname is stored in variable */
514 current
->parent
->arg
= get_var_arg(current
->arg
);
515 current
->parent
->intval
= get_var_int(current
->arg
);
521 traperr("<%s> requires one argument!\n", current
->arg
);
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
);
562 /* value is a variable */
563 set_variable(current
->arg
, get_var_arg(current
->next
->arg
), get_var_int(current
->next
->arg
));
568 set_variable(current
->arg
, current
->next
->arg
, current
->next
->intval
);
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
);
584 clip
= get_var_arg(dummy
->next
->arg
);
587 /* Add surrounding quotes to string */
588 dummy
->parent
->arg
= addquotes(clip
);
590 dummy
->parent
->intval
= get_var_int(dummy
->next
->arg
);
595 dummy
->parent
->intval
= dummy
->next
->intval
;
599 case _STRLEN
: /* Return the length of the string, 0 for integer argument */
600 if (current
->next
!= NULL
)
602 current
= current
->next
;
604 if (current
->arg
!= NULL
)
606 if ((current
->arg
)[0] == SQUOTE
|| (current
->arg
)[0] == DQUOTE
)
608 current
->parent
->intval
= strlen(current
->arg
) - 2;
612 if ((clip
= get_var_arg(current
->arg
)) == NULL
)
614 current
->parent
->intval
= 0;
618 current
->parent
->intval
= strlen(clip
);
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
= malloc(sizeof(IPTR
));
634 ((char **)params
)[0] = NULL
;
638 while (current
->next
!= NULL
)
640 current
= current
->next
;
642 if (current
->arg
!= NULL
)
644 if ((current
->arg
)[0] == SQUOTE
|| (current
->arg
)[0] == DQUOTE
)
646 /* Strip off quotes */
647 mclip
= realloc(mclip
, sizeof(char *) * (j
+1));
649 mclip
[j
] = strip_quotes(current
->arg
);
650 ((char **)params
)[i
] = mclip
[j
];
655 ((char **)params
)[i
] = (char *)get_variable(current
->arg
);
660 ((char **)params
)[i
] = (char *)(current
->intval
);
663 params
= realloc(params
, sizeof(IPTR
)*(i
+1));
666 /* Call RawDoFmt() with parameter list */
667 /* Store that produced string as return value */
668 string
= malloc(MAXARGSIZE
);
670 callbackstring
= string
;
671 globalstring
= callbackstring
;
672 RawDoFmt(clip
, params
, (VOID_FUNC
)&callback
, &globalstring
);
673 string
= callbackstring
;
674 /* Free temporary space */
684 /* Add surrounding quotes to string */
685 current
->parent
->arg
= addquotes(string
);
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
)
693 current
= current
->next
;
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
);
704 clip
= get_var_arg(current
->arg
);
707 string
= strdup(clip
);
712 string
= malloc(MAXARGSIZE
);
714 sprintf(string
, "%ld", get_var_int(current
->arg
));
720 string
= malloc(MAXARGSIZE
);
722 sprintf(string
, "%ld", current
->intval
);
724 current
= current
->next
;
727 slen
= strlen(string
) - i
;
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
;
750 clip
= malloc(slen
+ 1);
752 strncpy(clip
, (string
+ i
), j
);
755 current
->parent
->arg
= clip
;
760 traperr("<%s> requires at least two arguments!\n", current
->arg
);
764 case _TIMES
: /* Multiply all arguments and return that value */
765 if (current
->next
== NULL
)
768 traperr("No arguments to <%s>!\n", current
->arg
);
770 current
->parent
->intval
= 1;
771 while (current
->next
!= NULL
)
773 current
= current
->next
;
776 current
->parent
->intval
*= i
;
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
);
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 ??? */
800 traperr("<%s> has no command-block!\n", current
->parent
->cmd
->arg
);
805 /* Execute command */
806 ExecuteNextCommand();
808 /* Now check condition */
812 /* condition is true -> return values and exit */
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
);
827 traperr("<%s> requires two arguments!\n", current
->arg
);
831 case _USER
: /* Change the current user-level -- Use only to debug scripts */
832 if (current
->next
!= NULL
)
834 current
= current
->next
;
836 if (current
->arg
!= NULL
)
839 if ((current
->arg
[0] == SQUOTE
|| current
->arg
[0] == DQUOTE
))
841 /* Strip off quotes */
842 string
= strip_quotes(current
->arg
);
847 clip
= get_var_arg(current
->arg
);
852 if (strcasecmp(clip
, "novice") == 0)
854 if (strcasecmp(clip
, "average") == 0)
856 if (strcasecmp(clip
, "expert") == 0)
862 i
= get_var_int(current
->arg
);
869 if (i
< _NOVICE
|| i
> _EXPERT
)
871 error
= BADPARAMETER
;
872 traperr("New user-level not in [Novice|Average|Expert] !\n", NULL
);
876 set_variable("@user-level", NULL
, i
);
877 current
->parent
->intval
= i
;
883 traperr("<%s> requires one argument!\n", current
->arg
);
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
);
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 ??? */
905 traperr("<%s> has no command-block!\n", current
->parent
->cmd
->arg
);
912 /* Now check condition */
916 ExecuteNextCommand();
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
);
932 traperr("<%s> requires two arguments!\n", current
->arg
);
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
);
945 free_parameterlist(parameter
);
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
);
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
);
965 /* TODO: compute return values for "database" */
969 clip
= malloc(MAXARGSIZE
);
971 sprintf(clip
, "%c%d%c", DQUOTE
, SysBase
->VBlankFrequency
, DQUOTE
);
972 current
->parent
->arg
= strdup(clip
);
973 outofmem(current
->parent
->arg
);
981 current
->parent
->intval
= AvailMem(MEMF_CHIP
);
985 current
->parent
->intval
= AvailMem(MEMF_TOTAL
);
1000 error
= SCRIPTERROR
;
1001 traperr("<%s> requires one argument!\n", current
->arg
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
;
1074 case _TRAP
: /* link trap to preferences */
1075 if (current
->next
!= NULL
&& current
->next
->next
->cmd
!= NULL
)
1077 current
= current
->next
;
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
;
1101 error
= SCRIPTERROR
;
1102 traperr("<%s> requires two arguments!\n", current
->arg
);
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
,
1112 current
= current
->next
;
1114 ExecuteNextCommand();
1115 if (current
->arg
!= NULL
&& current
->next
->arg
!= NULL
)
1117 string
= strip_quotes(current
->arg
);
1118 clip
= strip_quotes(current
->next
->arg
);
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)
1135 if ((preferences
.pretend
== 0 || GetPL(parameter
, _SAFE
).used
== 1) && usrconfirm
)
1138 success
= Relabel(string
,clip
);
1144 if ((preferences
.pretend
== 0 || GetPL(parameter
, _SAFE
).used
== 1) && usrconfirm
)
1146 success
= Rename(string
,clip
);
1149 free_parameterlist(parameter
);
1153 if (preferences
.pretend
== 0)
1155 success
= Rename(string
,clip
);
1158 if (success
== DOSTRUE
)
1160 current
->parent
->intval
= 1;
1164 current
->parent
->intval
= 0;
1165 set_variable("@ioerr", NULL
, IoErr());
1172 error
= SCRIPTERROR
;
1173 traperr("<%s> requires two arguments!\n", current
->arg
);
1177 case _EXECUTE
: /* Execute an AmigaDOS script */
1178 /* TODO: Check me for correctness */
1179 if (current
->next
!= NULL
)
1185 current
= current
->next
;
1188 if (current
->arg
!= NULL
)
1190 GetString(current
->arg
);
1194 error
= BADPARAMETER
;
1195 traperr("<%s> requires a file string as argument!\n", current
->parent
->cmd
->arg
);
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
);
1208 if (preferences
.transcriptstream
!= BNULL
)
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
);
1224 current
->parent
->intval
= 1;
1228 current
->parent
->intval
= 0;
1229 set_variable("@ioerr", NULL
, IoErr());
1235 error
= SCRIPTERROR
;
1236 traperr("<%s> requires one argument!\n", current
->arg
);
1240 case _RUN
: /* Execute a command line */
1241 /* TODO: Check me for correctness */
1242 if (current
->next
!= NULL
)
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
);
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
)
1258 clip
= &(string
[i
+1]);
1266 if (get_var_int("@user-level") >= GetPL(parameter
, _CONFIRM
).intval
)
1268 if ((seg
= LoadSeg(string
)) == BNULL
)
1270 /* Couldn't load file -- set @ioerr and handle trap/onerror */
1273 PrintFault(i
, INSTALLER_NAME
);
1275 set_variable("@ioerr", NULL
, i
);
1277 traperr("Couldn't load binary %s\n", string
);
1279 if (preferences
.transcriptstream
!= BNULL
)
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 /* FIXME: is @ioerr set if command not run? */
1288 set_variable("@ioerr", NULL
, IoErr());
1296 error
= SCRIPTERROR
;
1297 traperr("<%s> requires arguments!\n", current
->arg
);
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
);
1316 error
= SCRIPTERROR
;
1317 traperr("<%s> requires a name-string as argument!\n", current
->arg
);
1321 case _DELETE
: /* Delete file */
1322 /* TODO: Implement (optional) and (delopts) */
1323 if (current
->next
!= NULL
)
1325 int success
= -1, usrconfirm
= FALSE
;
1327 current
= current
->next
;
1330 if (current
->arg
!= NULL
)
1332 GetString(current
->arg
);
1336 error
= SCRIPTERROR
;
1337 traperr("<%s> requires a file string as argument!\n", current
->parent
->cmd
->arg
);
1341 parameter
= get_parameters(current
->next
, level
);
1342 if (GetPL(parameter
, _CONFIRM
).used
== 1)
1344 usrconfirm
= request_confirm(parameter
);
1347 if ((preferences
.pretend
== 0 || GetPL(parameter
, _SAFE
).used
== 1) && usrconfirm
)
1349 success
= DeleteFile(string
);
1351 free_parameterlist(parameter
);
1355 if (preferences
.pretend
== 0)
1357 success
= DeleteFile(string
);
1362 current
->parent
->intval
= 1;
1366 current
->parent
->intval
= 0;
1367 set_variable("@ioerr", NULL
, IoErr());
1373 error
= SCRIPTERROR
;
1374 traperr("<%s> requires a string argument!\n", current
->arg
);
1378 case _MAKEDIR
: /* Create directory */
1379 /* TODO: Implement (infos) */
1380 if (current
->next
!= NULL
)
1383 int usrconfirm
= FALSE
;
1385 current
= current
->next
;
1388 if (current
->arg
!= NULL
)
1390 GetString(current
->arg
);
1394 error
= SCRIPTERROR
;
1395 traperr("<%s> requires a file string as argument!\n", current
->parent
->cmd
->arg
);
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
);
1413 if (preferences
.pretend
== 0)
1415 success
= CreateDir(string
);
1418 /* return value of CreateDir() is a lock or 0 */
1422 current
->parent
->intval
= 1;
1426 current
->parent
->intval
= 0;
1427 set_variable("@ioerr", NULL
, IoErr());
1433 error
= SCRIPTERROR
;
1434 traperr("<%s> requires a string argument!\n", current
->arg
);
1439 /* TODO: Implement (noreq) */
1440 if (current
->next
!= NULL
)
1444 current
= current
->next
;
1447 if (current
->arg
!= NULL
)
1449 GetString(current
->arg
);
1453 error
= SCRIPTERROR
;
1454 traperr("<%s> requires a file string as argument!\n", current
->parent
->cmd
->arg
);
1459 parameter
= get_parameters(current
->next
, level
);
1463 free_parameterlist(parameter
);
1465 if(stat(string
, &sb
) == -1)
1467 current
->parent
->intval
= 0;
1471 if(sb
.st_mode
& S_IFDIR
)
1474 current
->parent
->intval
= 2;
1476 else if(sb
.st_mode
& S_IFREG
)
1479 current
->parent
->intval
= 1;
1483 current
->parent
->intval
= 0;
1490 error
= SCRIPTERROR
;
1491 traperr("<%s> requires a string argument!\n", current
->arg
);
1495 case _FILEONLY
: /* Return the file part of a pathname */
1496 if (current
->next
!= NULL
)
1498 current
= current
->next
;
1500 if (current
->arg
!= NULL
)
1503 GetString(current
->arg
);
1504 tempnam
= FilePart(string
);
1505 i
= strlen(tempnam
);
1506 clip
= malloc(sizeof(char) * i
+ 3);
1508 strcpy(&clip
[1], tempnam
);
1509 clip
[ i
+ 1 ] = '"';
1511 current
->parent
->arg
= clip
;
1517 case _PATHONLY
: /* Return the path part of a pathname */
1518 if (current
->next
!= NULL
)
1522 current
= current
->next
;
1524 if (current
->arg
!= NULL
)
1526 GetString(current
->arg
);
1527 tempnam
= PathPart(string
);
1528 clip
= malloc(sizeof(char) * (tempnam
- string
+ 3));
1530 strncpy(&clip
[1], string
, tempnam
- string
);
1531 clip
[ tempnam
- string
+ 1 ] = '"';
1532 clip
[ tempnam
- string
+ 2 ] = 0;
1533 current
->parent
->arg
= clip
;
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
;
1544 struct FileInfoBlock
*fib1
, *fib2
;
1546 current
= current
->next
;
1548 if (current
->arg
!= NULL
)
1550 GetString(current
->arg
);
1555 error
= BADPARAMETER
;
1556 traperr("<%s> requires two string arguments!\n", current
->arg
);
1559 current
= current
->next
;
1561 if (current
->arg
!= NULL
)
1563 GetString(current
->arg
);
1568 error
= BADPARAMETER
;
1569 traperr("<%s> requires two string arguments!\n", current
->arg
);
1572 if ((lock1
= Lock(file1
, SHARED_LOCK
)) == BNULL
)
1575 traperr("File not found <%s>\n", file1
);
1577 if ((lock2
= Lock(file2
, SHARED_LOCK
)) == BNULL
)
1580 traperr("File not found <%s>\n", file2
);
1582 if ((fib1
= AllocDosObject((ULONG
)DOS_FIB
, NULL
)) == NULL
)
1585 traperr("Could not AllocDosObject FIB for file <%s>\n", file1
);
1587 if ((fib2
= AllocDosObject((ULONG
)DOS_FIB
, NULL
)) == NULL
)
1590 traperr("Could not AllocDosObject FIB for file <%s>\n", file2
);
1592 if (Examine(lock1
, fib1
) == FALSE
)
1595 traperr("Could not Examine() file <%s>\n", file1
);
1597 if (Examine(lock2
, fib2
) == FALSE
)
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
);
1629 error
= SCRIPTERROR
;
1630 traperr("<%s> requires two string arguments!\n", current
->arg
);
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
)
1638 struct InfoData infodata
;
1640 current
= current
->next
;
1642 if (current
->arg
!= NULL
)
1644 GetString(current
->arg
);
1645 current
->parent
->intval
= -1;
1646 if ((lock
= Lock(string
, SHARED_LOCK
)) != BNULL
)
1648 if (Info(lock
, &infodata
) != FALSE
)
1650 current
->parent
->intval
= (infodata
.id_NumBlocks
- infodata
.id_NumBlocksUsed
) * infodata
.id_BytesPerBlock
;
1659 case _GETSIZE
: /* Get the size of a file in bytes */
1660 if (current
->next
!= NULL
)
1664 current
= current
->next
;
1667 if (current
->arg
!= NULL
)
1669 GetString(current
->arg
);
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;
1682 current
->parent
->intval
= sb
.st_size
;
1688 error
= SCRIPTERROR
;
1689 traperr("<%s> requires a string argument!\n", current
->arg
);
1693 case _GETENV
: /* Get Variable from ENV: */
1694 if (current
->next
!= NULL
)
1696 current
= current
->next
;
1699 if (current
->arg
!= NULL
)
1701 char buffer
[1024] = {0};
1702 string
= strip_quotes(current
->arg
);
1704 /* FIXME: flag must be one of GVF_GLOBAL_ONLY or GVF_LOCAL_ONLY??? */
1705 i
= GetVar(string
, buffer
, 1023, 0);
1711 current
->parent
->arg
= strdup(buffer
);
1716 error
= SCRIPTERROR
;
1717 traperr("<%s> requires a string as argument!\n", current
->parent
->cmd
->arg
);
1722 error
= SCRIPTERROR
;
1723 traperr("<%s> requires a string as argument!\n", current
->arg
);
1728 if (current
->next
!= NULL
)
1735 parameter
= get_parameters(current
->next
, level
);
1736 safe
= GetPL(parameter
, _SAFE
).used
;
1737 free_parameterlist(parameter
);
1739 current
= current
->next
;
1742 if (current
->arg
!= NULL
)
1744 GetString(current
->arg
);
1748 error
= SCRIPTERROR
;
1749 traperr("<%s> requires an assign name as argument!\n", current
->parent
->cmd
->arg
);
1753 if (current
->next
!= NULL
)
1755 /* Add Path to Assign */
1758 current
= current
->next
;
1761 if (current
->arg
!= NULL
)
1763 GetString(current
->arg
);
1765 lock
= Lock(string
, SHARED_LOCK
);
1766 if ( lock
!= BNULL
)
1768 if (preferences
.pretend
== 0 || safe
)
1770 if (AssignAdd(assign
, lock
) == DOSFALSE
)
1772 if (AssignLock(assign
, lock
) == DOSFALSE
)
1779 current
->parent
->intval
= 1;
1784 current
->parent
->intval
= 1;
1792 if (preferences
.pretend
== 0 || safe
)
1795 AssignLock(string
, BNULL
);
1796 current
->parent
->intval
= 1;
1803 error
= SCRIPTERROR
;
1804 traperr("<%s> requires at least one argument!\n", current
->arg
);
1809 if (current
->next
!= NULL
)
1811 ULONG lockBits
= LDF_ASSIGNS
;
1812 struct DosList
*dl
, *tdl
;
1813 char *assign
, *ret
= NULL
;
1815 current
= current
->next
;
1818 if (current
->arg
!= NULL
)
1820 GetString(current
->arg
);
1824 error
= SCRIPTERROR
;
1825 traperr("<%s> requires an assign name as argument!\n", current
->parent
->cmd
->arg
);
1829 if (current
->next
!= NULL
)
1831 current
= current
->next
;
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
;
1851 error
= SCRIPTERROR
;
1852 traperr("Invalid option <%s> to getassign!\n", string
);
1857 /* get the assign */
1859 dl
= LockDosList(LDF_READ
| LDF_VOLUMES
| LDF_ASSIGNS
| LDF_DEVICES
);
1860 tdl
= FindDosEntry(dl
, assign
, lockBits
);
1866 DMSG("VOLUME(%b:)\n",tdl
->dol_Name
);
1867 ret
= malloc(AROS_BSTR_strlen(tdl
->dol_Name
)+2);
1869 sprintf(ret
,"%s:",AROS_BSTR_ADDR(tdl
->dol_Name
));
1873 DMSG("ASSIGN(%b:):\n",tdl
->dol_Name
);
1874 switch (tdl
->dol_Type
)
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
);
1884 struct AssignList
*nextAssign
; /* For multiassigns */
1886 ret
= DynNameFromLock(tdl
->dol_Lock
);
1889 nextAssign
= tdl
->dol_misc
.dol_assign
.dol_List
;
1890 while (nextAssign
!= NULL
)
1893 dirName
= DynNameFromLock(nextAssign
->al_Lock
);
1894 if (dirName
!= NULL
)
1896 DMSG(" +%s\n", dirName
);
1900 sum
= malloc(strlen(ret
) + strlen(dirName
) + 2);
1901 sprintf(sum
, "%s %s", ret
, dirName
);
1907 ret
= strdup(dirName
);
1911 nextAssign
= nextAssign
->al_Next
;
1923 DMSG("DEV(%b:):\n",(char *)tdl
->dol_Name
);
1924 lname
= malloc(AROS_BSTR_strlen(tdl
->dol_Name
) + 2);
1926 sprintf(lname
,"%s:",AROS_BSTR_ADDR(tdl
->dol_Name
));
1927 lockdev
= Lock(lname
, SHARED_LOCK
);
1931 ret
= DynNameFromLock(lockdev
);
1943 UnLockDosList(lockBits
);
1946 current
->parent
->arg
= addquotes(ret
);
1951 current
->parent
->arg
= addquotes("");
1958 error
= SCRIPTERROR
;
1959 traperr("<%s> requires at least one argument!\n", current
->arg
);
1964 if (current
->next
!= NULL
)
1969 current
= current
->next
;
1972 if (current
->arg
!= NULL
)
1974 GetString(current
->arg
);
1978 error
= SCRIPTERROR
;
1979 traperr("<%s> requires a device name as argument!\n", current
->parent
->cmd
->arg
);
1982 lockdev
= Lock(string
, SHARED_LOCK
);
1987 ret
= DynNameFromLock(lockdev
);
1989 while (*send
&& *send
!= ':') send
++;
1990 if(*send
) send
[1] = 0;
1996 current
->parent
->arg
= addquotes(ret
);
2001 current
->parent
->arg
= addquotes("");
2007 error
= SCRIPTERROR
;
2008 traperr("<%s> requires at least one argument!\n", current
->arg
);
2013 if (current
->next
!= NULL
&& current
->next
->next
!= NULL
)
2015 char ret
[MAXFILENAMELENGTH
];
2017 current
= current
->next
;
2020 if (current
->arg
!= NULL
)
2022 GetString(current
->arg
);
2026 error
= SCRIPTERROR
;
2027 traperr("<%s> requires a path part as argument!\n", current
->parent
->cmd
->arg
);
2031 current
= current
->next
;
2034 if (current
->arg
!= NULL
)
2036 GetString(current
->arg
);
2040 error
= SCRIPTERROR
;
2041 traperr("<%s> requires a file part as argument!\n", current
->parent
->cmd
->arg
);
2045 if (AddPart(ret
, clip
, MAXFILENAMELENGTH
) == 0)
2048 traperr("AddPart(%s) failed!\n", clip
);
2051 if (AddPart(ret
, string
, MAXFILENAMELENGTH
) == 0)
2054 traperr("AddPart(%s) failed!\n", string
);
2057 current
->parent
->arg
= addquotes(ret
);
2061 error
= SCRIPTERROR
;
2062 traperr("<%s> requires two arguments!\n", current
->arg
);
2067 if (current
->next
!= NULL
)
2072 current
= current
->next
;
2075 if (current
->arg
!= NULL
)
2077 GetString(current
->arg
);
2081 error
= BADPARAMETER
;
2082 traperr("<%s> requires a path name as argument!\n", current
->parent
->cmd
->arg
);
2085 lockdev
= Lock(string
, SHARED_LOCK
);
2089 ret
= DynNameFromLock(lockdev
);
2094 current
->parent
->arg
= addquotes(ret
);
2099 current
->parent
->arg
= addquotes("");
2105 error
= SCRIPTERROR
;
2106 traperr("<%s> requires one argument!\n", current
->arg
);
2110 /* Here are all unimplemented commands */
2122 fprintf(stderr
, "Unimplemented command <%s>\n", current
->arg
);
2125 case _USERDEF
: /* User defined routine */
2126 usrproc
= find_proc(current
->arg
);
2127 /* Set argument variables */
2129 while (current
->next
!= NULL
&& i
< usrproc
->argnum
)
2131 current
= current
->next
;
2133 if (current
->arg
!= NULL
)
2135 if ((current
->arg
)[0] == SQUOTE
|| (current
->arg
)[0] == DQUOTE
)
2137 /* Strip off quotes */
2138 clip
= strip_quotes(current
->arg
);
2139 set_variable(usrproc
->arglist
[i
], clip
, 0);
2144 /* value is a variable */
2145 set_variable(usrproc
->arglist
[i
], get_var_arg(current
->arg
), get_var_int(current
->arg
));
2150 set_variable(usrproc
->arglist
[i
], NULL
, current
->intval
);
2154 /* Execute procedure */
2155 dummy
= usrproc
->procbody
;
2156 execute_script(dummy
->cmd
, level
+ 1);
2157 current
->parent
->intval
= dummy
->intval
;
2158 if (dummy
->arg
!= NULL
)
2160 current
->parent
->arg
= strdup(dummy
->arg
);
2161 outofmem(current
->parent
->arg
);
2165 /* Here are all tags, first the ones which have to be executed */
2166 case _DELOPTS
: /* unset copying/deleting options if we are called global */
2167 /* as parameter to a function we have got an ignore=1 before */
2168 /* FIXME: (delopts) is only local */
2169 if (current
->parent
->ignore
== 0)
2171 /* Read in strings */
2172 parameter
= malloc(sizeof(struct ParameterList
));
2173 outofmem(parameter
);
2174 collect_stringargs(current
, level
, parameter
);
2175 /* Store data in preferences */
2176 for (i
= 0 ; i
< parameter
->intval
; i
++)
2178 /* These are mutually exclusive */
2179 /* FIXME: How are (fail-)strings interpreted in "delopts" ? */
2180 if (strcasecmp(parameter
->arg
[i
], "fail") == 0)
2183 if (strcasecmp(parameter
->arg
[i
], "nofail") == 0)
2186 if (strcasecmp(parameter
->arg
[i
], "oknodelete") == 0)
2190 /* These may be combined in any way */
2191 if (strcasecmp(parameter
->arg
[i
], "force") == 0)
2193 preferences
.copyflags
&= ~COPY_ASKUSER
;
2195 if (strcasecmp(parameter
->arg
[i
], "askuser") == 0)
2197 preferences
.copyflags
&= ~COPY_ASKUSER
;
2201 free_parameterlist(parameter
);
2205 case _OPTIONAL
: /* set copying/deleting options if we are called global */
2206 /* as parameter to a function we have got an ignore=1 before */
2207 /* FIXME: (optional) is only local */
2208 if (current
->parent
->ignore
== 0)
2210 /* Read in strings */
2211 parameter
= malloc(sizeof(struct ParameterList
));
2212 outofmem(parameter
);
2213 collect_stringargs(current
, level
, parameter
);
2214 /* Store data in preferences */
2215 for (i
= 0 ; i
< parameter
->intval
; i
++)
2217 /* These are mutually exclusive */
2218 if (strcasecmp(parameter
->arg
[i
], "fail") == 0)
2220 preferences
.copyfail
&= ~(COPY_FAIL
| COPY_NOFAIL
| COPY_OKNODELETE
);
2221 preferences
.copyfail
|= COPY_FAIL
;
2223 if (strcasecmp(parameter
->arg
[i
], "nofail") == 0)
2225 preferences
.copyfail
&= ~(COPY_FAIL
| COPY_NOFAIL
| COPY_OKNODELETE
);
2226 preferences
.copyfail
|= COPY_NOFAIL
;
2228 if (strcasecmp(parameter
->arg
[i
], "oknodelete") == 0)
2230 preferences
.copyfail
&= ~(COPY_FAIL
| COPY_NOFAIL
| COPY_OKNODELETE
);
2231 preferences
.copyfail
|= COPY_OKNODELETE
;
2234 /* These may be combined in any way */
2235 if (strcasecmp(parameter
->arg
[i
], "force") == 0)
2237 preferences
.copyflags
|= COPY_ASKUSER
;
2239 if (strcasecmp(parameter
->arg
[i
], "askuser") == 0)
2241 preferences
.copyflags
|= COPY_ASKUSER
;
2245 free_parameterlist(parameter
);
2273 case _SETDEFAULTTOOL
:
2280 /* We are tags -- we don't want to be executed */
2281 current
->parent
->ignore
= 1;
2287 /* Hey! Where did you get this number from??? It's invalid -- must be a bug. */
2288 fprintf(stderr
, "Unknown command ID %d called <%s>!\n", cmd_type
, current
->arg
);
2292 /* We are tags -- we don't want to be executed */
2293 current
->parent
->ignore
= 1;
2302 * Get an ID for the command string
2304 int eval_cmd(char * argument
)
2308 if (argument
[0] == SQUOTE
|| argument
[0] == DQUOTE
)
2314 for (i
= 0 ; i
< _MAXCOMMAND
&& strcasecmp(internal_commands
[i
].cmdsymbol
, argument
) != 0 ; i
++);
2315 if (i
!= _MAXCOMMAND
)
2317 return internal_commands
[i
].cmdnumber
;
2321 if (find_proc(argument
) != NULL
)
2335 * Callback function for RawDoFmt()
2337 static void callback(char chr
, char ** data
)
2339 static int i
= 0, j
= 1;
2340 static char * string
= NULL
;
2342 if (callbackstring
!= string
)
2344 string
= callbackstring
;
2353 callbackstring
= realloc(callbackstring
, MAXARGSIZE
* j
);
2354 outofmem(callbackstring
);
2355 globalstring
+= (callbackstring
- string
);
2356 string
= callbackstring
;
2363 * Strip off quotes from a string
2364 * Does not check for quotes!
2366 char *strip_quotes(char *string
)
2371 /* Strip off quotes */
2372 slen
= strlen(string
);
2373 clip
= (char *)malloc(slen
- 1);
2375 strncpy(clip
, string
+1, slen
-2);
2383 * Convert data entry to <int>
2384 * <string>s are atol()'d, <cmd>s are *not* executed
2386 long int getint(ScriptArg
*argument
)
2391 if (argument
->arg
!= NULL
)
2393 if ((argument
->arg
)[0] == SQUOTE
|| (argument
->arg
)[0] == DQUOTE
)
2395 /* Strip off quotes */
2396 clip
= strip_quotes(argument
->arg
);
2402 clip
= get_var_arg(argument
->arg
);
2409 i
= get_var_int(argument
->arg
);
2415 i
= argument
->intval
;
2423 * Get an ID for hardware descriptor
2425 int database_keyword(char *name
)
2427 if (strcasecmp(name
, "vblank") == 0)
2429 else if (strcasecmp(name
, "cpu") == 0)
2431 else if (strcasecmp(name
, "graphics-mem") == 0)
2432 return _GRAPHICS_MEM
;
2433 else if (strcasecmp(name
, "total-mem") == 0)
2435 else if (strcasecmp(name
, "fpu") == 0)
2437 else if (strcasecmp(name
, "chiprev") == 0)
2445 * Concatenate all arguments as a string with separating character
2446 * if character is 0 strings are concatenated without separator
2447 * <int>s are converted to strings, <cmd>s are executed,
2448 * <parameter>s are not considered
2450 char *collect_strings(ScriptArg
*current
, char separator
, int level
)
2452 char *string
= NULL
, *clip
, *dummy
;
2455 while (current
!= NULL
)
2458 /* Concatenate string unless it was a parameter which will be ignored */
2459 if (current
->ignore
== 0)
2461 if (current
->arg
!= NULL
)
2463 if ((current
->arg
)[0] == SQUOTE
|| (current
->arg
)[0] == DQUOTE
)
2465 /* Strip off quotes */
2466 clip
= strip_quotes(current
->arg
);
2470 dummy
= get_var_arg(current
->arg
);
2473 clip
= strdup(dummy
);
2478 clip
= malloc(MAXARGSIZE
);
2480 sprintf(clip
, "%ld", get_var_int(current
->arg
));
2486 clip
= malloc(MAXARGSIZE
);
2488 sprintf(clip
, "%ld", current
->intval
);
2490 i
= (string
== NULL
) ? 0 : strlen(string
);
2491 string
= realloc(string
, i
+ strlen(clip
) + 2);
2499 string
[i
] = separator
;
2502 strcat(string
, clip
);
2505 current
= current
->next
;
2513 * Free the allocated space for string list
2515 void free_parameter(struct ParameterList pl
)
2521 for (j
= 0 ; j
< pl
.intval
; j
++)
2532 * Free a complete (struct ParameterList *)
2534 void free_parameterlist(struct ParameterList
*pl
)
2540 for (i
= 0 ; i
< NUMPARAMS
; i
++)
2542 free_parameter(pl
[i
]);
2550 * args are scanned for known parameters
2551 * the used entry will be set and <int>s and <string>s read in ParameterList
2552 * intval contains number of <string>s
2554 struct ParameterList
*get_parameters(ScriptArg
*script
, int level
)
2556 struct ParameterList
*pl
;
2560 char *string
, *clip
;
2562 pl
= calloc(NUMPARAMS
, sizeof(struct ParameterList
));
2564 while (script
!= NULL
)
2566 /* Check if we have a command as argument */
2567 if (script
->cmd
!= NULL
)
2569 current
= script
->cmd
->next
;
2570 /* Check if we don't have a block as argument */
2571 if (script
->cmd
->arg
!= NULL
)
2573 /* Check if we have a parameter as command */
2574 cmd
= eval_cmd(script
->cmd
->arg
);
2575 if (cmd
> _PARAMETER
&& cmd
<= (_PARAMETER
+ NUMPARAMS
))
2577 /* This is a parameter */
2578 GetPL(pl
, cmd
).used
= 1;
2579 if (cmd
> (_PARAMETER
+ NUMARGPARAMS
))
2581 /* This is a boolean parameter */
2582 GetPL(pl
, cmd
).intval
= 1;
2586 /* This parameter may have arguments */
2589 /* Parameters with args */
2590 case _APPEND
: /* $ */
2591 case _CHOICES
: /* $... */
2592 case _COMMAND
: /* $... */
2593 case _DELOPTS
: /* $... */
2594 case _DEST
: /* $ */
2595 case _HELP
: /* $... */
2596 case _INCLUDE
: /* $ */
2597 case _NEWNAME
: /* $ */
2598 case _OPTIONAL
: /* $... */
2599 case _PATTERN
: /* $ */
2600 case _PROMPT
: /* $... */
2601 case _SETDEFAULTTOOL
: /* $ */
2602 case _SETTOOLTYPE
: /* $ [$] */
2603 case _SOURCE
: /* $ */
2604 collect_stringargs(current
, level
, &(GetPL(pl
, cmd
)));
2607 case _CONFIRM
: /* ($->)# */
2609 if (current
!= NULL
)
2612 if (current
->arg
!= NULL
)
2615 if ((current
->arg
)[0] == SQUOTE
|| (current
->arg
)[0] == DQUOTE
)
2617 /* Strip off quotes */
2618 string
= strip_quotes(current
->arg
);
2623 clip
= get_var_arg(current
->arg
);
2628 if (strcasecmp(clip
, "novice") == 0)
2632 if (strcasecmp(clip
, "average") == 0)
2636 if (strcasecmp(clip
, "expert") == 0)
2644 i
= get_var_int(current
->arg
);
2649 i
= current
->intval
;
2652 if (i
< _NOVICE
|| i
> _EXPERT
)
2654 error
= BADPARAMETER
;
2655 traperr("Userlevel out of range!\n", NULL
);
2657 GetPL(pl
, cmd
).intval
= i
;
2660 case _DEFAULT
: /* * */
2663 if (current
!= NULL
)
2666 if (current
->arg
!= NULL
)
2668 if ((current
->arg
)[0] == SQUOTE
|| (current
->arg
)[0] == DQUOTE
)
2670 /* Strip off quotes */
2671 string
= strip_quotes(current
->arg
);
2675 clip
= get_var_arg(current
->arg
);
2678 string
= strdup(clip
);
2683 i
= get_var_int(current
->arg
);
2689 i
= current
->intval
;
2691 GetPL(pl
, cmd
).intval
= i
;
2694 /* To avoid problems with multiple definitions of default */
2695 /* take last (this) one as true and clear previous */
2696 if (GetPL(pl
, cmd
).arg
!= NULL
)
2698 free(GetPL(pl
, cmd
).arg
[0]);
2702 GetPL(pl
, cmd
).arg
= malloc(sizeof(char *));
2703 outofmem(GetPL(pl
, cmd
).arg
);
2705 GetPL(pl
, cmd
).arg
[0] = string
;
2710 error
= SCRIPTERROR
;
2711 traperr("<%s> requires one argument!\n", script
->cmd
->arg
);
2715 case _RANGE
: /* # # */
2716 case _SETPOSITION
: /* # # */
2718 if (current
!= NULL
&& current
->next
!= NULL
)
2721 GetPL(pl
, cmd
).intval
= getint(current
);
2722 current
= current
->next
;
2724 GetPL(pl
, cmd
).intval2
= getint(current
);
2728 error
= SCRIPTERROR
;
2729 traperr("<%s> requires two arguments!\n", script
->cmd
->arg
);
2733 case _SETSTACK
: /* # */
2735 if (current
!= NULL
)
2738 if (current
->arg
!= NULL
)
2740 if ((current
->arg
)[0] == SQUOTE
|| (current
->arg
)[0] == DQUOTE
)
2742 /* Strip off quotes */
2743 string
= strip_quotes(current
->arg
);
2749 clip
= get_var_arg(current
->arg
);
2756 i
= get_var_int(current
->arg
);
2762 i
= current
->intval
;
2764 GetPL(pl
, cmd
).intval
= i
;
2768 error
= SCRIPTERROR
;
2769 traperr("<%s> requires one argument!\n", script
->cmd
->arg
);
2774 default: /* We do only collect tags -- this is a command */
2779 else if (cmd
== _IF
)
2781 /* This parameter is masqueraded */
2784 /* "Allowed" Commands (for compatibility) */
2786 /* (if (= 1 1) (command "blah")) is allowed, but should be
2787 * (command (if (= 1 1) "blah"))
2789 case _IF
: /* if 1st arg != 0 get parameter from 2nd cmd else get optional 3rd cmd parameter */
2790 if (current
!= NULL
&& current
->next
!= NULL
)
2793 i
= getint(current
);
2796 current
= current
->next
;
2798 if (current
->next
!= NULL
)
2800 current
= current
->next
;
2801 if (current
->cmd
!= NULL
)
2803 struct ParameterList
*subpl
;
2804 subpl
= get_parameters(current
, level
+ 1);
2805 for (i
= 0 ; i
< NUMPARAMS
; i
++)
2807 if (subpl
[i
].used
== 1)
2809 free_parameter(pl
[i
]);
2810 pl
[i
].arg
= subpl
[i
].arg
;
2811 pl
[i
].intval
= subpl
[i
].intval
;
2812 pl
[i
].intval2
= subpl
[i
].intval2
;
2813 subpl
[i
].arg
= NULL
;
2816 free_parameterlist(subpl
);
2822 error
= SCRIPTERROR
;
2823 traperr("<%s> requires two arguments!\n", script
->arg
);
2827 default: /* We do only collect tags -- this is a command */
2833 script
= script
->next
;
2841 * read <string>s in ParameterList
2842 * <int>s are converted, <cmd>s executed
2844 void collect_stringargs(ScriptArg
*current
, int level
, struct ParameterList
*pl
)
2846 char *string
, *clip
, **mclip
= NULL
;
2849 while (current
!= NULL
)
2852 mclip
= realloc(mclip
, sizeof(char *) * (j
+1));
2854 if (current
->arg
!= NULL
)
2856 if ((current
->arg
)[0] == SQUOTE
|| (current
->arg
)[0] == DQUOTE
)
2858 /* Strip off quotes */
2859 string
= strip_quotes(current
->arg
);
2863 clip
= get_var_arg(current
->arg
);
2866 string
= strdup(clip
);
2871 clip
= malloc(MAXARGSIZE
);
2873 sprintf(clip
, "%ld", get_var_int(current
->arg
));
2874 string
= strdup(clip
);
2882 clip
= malloc(MAXARGSIZE
);
2884 sprintf(clip
, "%ld", current
->intval
);
2885 string
= strdup(clip
);
2891 current
= current
->next
;
2899 * Read in one line of a file
2901 char * get_file_line(BPTR file
)
2909 cnt
= Read(file
, buf
, 1);
2911 } while (cnt
&& buf
[0] != LINEFEED
);
2916 Seek(file
, -i
, OFFSET_CURRENT
);
2917 out
= malloc(i
* sizeof(char));
2927 * Routine for modifying S:User-Startup
2929 void modify_userstartup(char *string
, struct ParameterList
*parameter
)
2932 BPTR tmpuserstartup
;
2934 int i
, changed
= 0, cont
= 0;
2936 userstartup
= Open("S:User-Startup", MODE_OLDFILE
);
2937 tmpuserstartup
= Open("S:User-Startup.tmp", MODE_NEWFILE
);
2938 if (!tmpuserstartup
)
2940 /* TODO: Complain more smoothly... */
2941 fprintf(stderr
, "Could not open S:User-Startup for writing!");
2946 while ((line
= get_file_line(userstartup
)) && !changed
)
2948 if (strncasecmp(line
, ";BEGIN ", 7) == 0)
2950 if (strcmp(&(line
[7]), string
) == 0)
2957 Write(tmpuserstartup
, line
, strlen(line
));
2958 Write(tmpuserstartup
, "\n", 1);
2964 Write(tmpuserstartup
, ";BEGIN ", 7);
2965 Write(tmpuserstartup
, string
, strlen(string
));
2966 Write(tmpuserstartup
, "\n", 1);
2967 for (i
= 0 ; i
< GetPL(parameter
, _COMMAND
).intval
; i
++)
2969 Write(tmpuserstartup
, GetPL(parameter
, _COMMAND
).arg
[i
], strlen(GetPL(parameter
, _COMMAND
).arg
[i
]));
2971 Write(tmpuserstartup
, ";END ", 5);
2972 Write(tmpuserstartup
, string
, strlen(string
));
2973 Write(tmpuserstartup
, "\n", 1);
2977 while ((line
= get_file_line(userstartup
)))
2981 if (strncasecmp(line
, ";END ", 5) == 0)
2983 if (strcmp(&(line
[5]), string
) == 0)
2991 Write(tmpuserstartup
, line
, strlen(line
));
2992 Write(tmpuserstartup
, "\n", 1);
2998 Close(tmpuserstartup
);
3001 DeleteFile("S:User-Startup");
3002 /* FIXME: Check correctness of Rename() */
3004 IMO both arguments to Rename() should contain S:, check again if
3005 Rename() is proven to work as expected
3007 if (Rename("S:User-Startup.tmp", "User-Startup") == DOSFALSE
)
3009 printf("Rename failed because of %s\n", DosGetString(IoErr()));
3016 * Execute "(traperr)" from preferences
3018 void traperr(char * msg
, char * name
)
3027 i
= (msg
!= NULL
) ? strlen(msg
) : 0 ;
3028 j
= (name
!= NULL
) ? strlen(name
) : 0 ;
3029 outmsg
= malloc(i
+ j
+ 1);
3030 sprintf(outmsg
, msg
, name
);
3031 display_text(outmsg
);
3033 if (preferences
.trap
[ error
- 1 ].cmd
!= NULL
)
3036 execute_script(preferences
.trap
[ error
- 1 ].cmd
, -99);
3040 /* execute onerrors */
3041 if (preferences
.onerror
.cmd
!= NULL
)
3043 execute_script(preferences
.onerror
.cmd
, -99);
3053 if (grace_exit
== TRUE
)
3064 char *DynNameFromLock(BPTR lock
)
3066 char *dirName
= NULL
;
3069 for (size
= 512 ; ; size
+= 512)
3071 dirName
= malloc(size
);
3072 if (dirName
== NULL
)
3076 if (NameFromLock(lock
, dirName
, size
))
3082 if (IoErr() != ERROR_LINE_TOO_LONG
)