revert between 56095 -> 55830 in arch
[AROS.git] / workbench / utilities / Installer / execute.c
blobb0ea2a72540ce99112f4e1115ef10e3b10d2d2c2
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 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);
110 else
112 cmd_type = eval_cmd(current->arg);
113 free(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 free(string);
127 if (preferences.transcriptstream != BNULL)
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 free(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 free(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 free(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 free(string);
459 free(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 free(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 free(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 = malloc(sizeof(IPTR));
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 = realloc(mclip, sizeof(char *) * (j+1));
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 = realloc(params, sizeof(IPTR)*(i+1));
664 outofmem(params);
666 /* Call RawDoFmt() with parameter list */
667 /* Store that produced string as return value */
668 string = malloc(MAXARGSIZE);
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 free(clip);
676 if (mclip)
678 while (j > 0)
680 free(mclip[--j]);
682 free(mclip);
684 /* Add surrounding quotes to string */
685 current->parent->arg = addquotes(string);
686 free(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 = malloc(MAXARGSIZE);
713 outofmem(string);
714 sprintf(string, "%ld", get_var_int(current->arg));
718 else
720 string = malloc(MAXARGSIZE);
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 free(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 = malloc(slen + 1);
751 outofmem(clip);
752 strncpy(clip, (string + i), j);
753 clip[j] = 0;
754 free(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 free(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 free(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 free(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 free(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 free(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 free(clip);
965 /* TODO: compute return values for "database" */
966 switch (i)
968 case _VBLANK :
969 clip = malloc(MAXARGSIZE);
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 free(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 free(string);
1168 free(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 /* 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 != BNULL)
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);
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 free(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 /* 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)) == BNULL)
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 != 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());
1289 UnLoadSeg(seg);
1291 free(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 free(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 /* 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 free(string);
1371 else
1373 error = SCRIPTERROR;
1374 traperr("<%s> requires a string argument!\n", current->arg);
1376 break;
1378 case _MAKEDIR: /* Create directory */
1379 /* 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 free(string);
1431 else
1433 error = SCRIPTERROR;
1434 traperr("<%s> requires a string argument!\n", current->arg);
1436 break;
1438 case _EXISTS:
1439 /* 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 free(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 = malloc(sizeof(char) * i + 3);
1507 clip[0] = '"';
1508 strcpy(&clip[1], tempnam);
1509 clip[ i + 1 ] = '"';
1510 clip[ i + 2 ] = 0;
1511 current->parent->arg = clip;
1512 free(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 = malloc(sizeof(char) * (tempnam - string + 3));
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 free(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)) == BNULL)
1574 error = DOSERROR;
1575 traperr("File not found <%s>\n", file1);
1577 if ((lock2 = Lock(file2, SHARED_LOCK)) == BNULL)
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 free(file1);
1625 free(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)) != BNULL)
1648 if (Info(lock, &infodata) != FALSE)
1650 current->parent->intval = (infodata.id_NumBlocks - infodata.id_NumBlocksUsed) * infodata.id_BytesPerBlock;
1652 UnLock(lock);
1654 free(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 free(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 /* FIXME: flag must be one of GVF_GLOBAL_ONLY or GVF_LOCAL_ONLY??? */
1705 i = GetVar(string, buffer, 1023, 0);
1707 free(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 != BNULL )
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 free(string);
1790 else
1792 if (preferences.pretend == 0 || safe)
1794 /* Remove Assign */
1795 AssignLock(string, BNULL);
1796 current->parent->intval = 1;
1799 free(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 free(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(%b:)\n",tdl->dol_Name);
1867 ret = malloc(AROS_BSTR_strlen(tdl->dol_Name)+2);
1868 outofmem(ret);
1869 sprintf(ret,"%s:",AROS_BSTR_ADDR(tdl->dol_Name));
1870 break;
1872 case LDF_ASSIGNS:
1873 DMSG("ASSIGN(%b:):\n",tdl->dol_Name);
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 = malloc(strlen(ret) + strlen(dirName) + 2);
1901 sprintf(sum, "%s %s", ret, dirName);
1902 free(ret);
1903 ret = sum;
1905 else
1907 ret = strdup(dirName);
1909 free(dirName);
1911 nextAssign = nextAssign->al_Next;
1914 break;
1916 break;
1918 case LDF_DEVICES:
1920 BPTR lockdev;
1921 char *lname;
1923 DMSG("DEV(%b:):\n",(char *)tdl->dol_Name);
1924 lname = malloc(AROS_BSTR_strlen(tdl->dol_Name) + 2);
1925 outofmem(lname);
1926 sprintf(lname,"%s:",AROS_BSTR_ADDR(tdl->dol_Name));
1927 lockdev = Lock(lname, SHARED_LOCK);
1928 if (lockdev)
1930 free(lname);
1931 ret = DynNameFromLock(lockdev);
1932 DMSG(" %s\n",ret);
1933 UnLock(lockdev);
1935 else
1937 ret = lname;
1940 break;
1943 UnLockDosList(lockBits);
1944 if (ret)
1946 current->parent->arg = addquotes(ret);
1947 free(ret);
1949 else
1951 current->parent->arg = addquotes("");
1954 free(assign);
1956 else
1958 error = SCRIPTERROR;
1959 traperr("<%s> requires at least one argument!\n", current->arg);
1961 break;
1963 case _GETDEVICE:
1964 if (current->next != NULL)
1966 char *ret = NULL;
1967 BPTR lockdev;
1969 current = current->next;
1970 ExecuteCommand();
1972 if (current->arg != NULL)
1974 GetString(current->arg);
1976 else
1978 error = SCRIPTERROR;
1979 traperr("<%s> requires a device name as argument!\n", current->parent->cmd->arg);
1982 lockdev = Lock(string, SHARED_LOCK);
1983 free(string);
1984 if (lockdev)
1986 char *send;
1987 ret = DynNameFromLock(lockdev);
1988 send = ret;
1989 while (*send && *send != ':') send++;
1990 if(*send) send[1] = 0;
1992 UnLock(lockdev);
1994 if (ret)
1996 current->parent->arg = addquotes(ret);
1997 free(ret);
1999 else
2001 current->parent->arg = addquotes("");
2005 else
2007 error = SCRIPTERROR;
2008 traperr("<%s> requires at least one argument!\n", current->arg);
2010 break;
2012 case _TACKON :
2013 if (current->next != NULL && current->next->next != NULL)
2015 char ret[MAXFILENAMELENGTH];
2017 current = current->next;
2018 ExecuteCommand();
2020 if (current->arg != NULL)
2022 GetString(current->arg);
2024 else
2026 error = SCRIPTERROR;
2027 traperr("<%s> requires a path part as argument!\n", current->parent->cmd->arg);
2029 clip = string;
2031 current = current->next;
2032 ExecuteCommand();
2034 if (current->arg != NULL)
2036 GetString(current->arg);
2038 else
2040 error = SCRIPTERROR;
2041 traperr("<%s> requires a file part as argument!\n", current->parent->cmd->arg);
2044 ret[0] = 0;
2045 if (AddPart(ret, clip, MAXFILENAMELENGTH) == 0)
2047 error = DOSERROR;
2048 traperr("AddPart(%s) failed!\n", clip);
2050 free(clip);
2051 if (AddPart(ret, string, MAXFILENAMELENGTH) == 0)
2053 error = DOSERROR;
2054 traperr("AddPart(%s) failed!\n", string);
2056 free(string);
2057 current->parent->arg = addquotes(ret);
2059 else
2061 error = SCRIPTERROR;
2062 traperr("<%s> requires two arguments!\n", current->arg);
2064 break;
2066 case _EXPANDPATH:
2067 if (current->next != NULL)
2069 char *ret = NULL;
2070 BPTR lockdev;
2072 current = current->next;
2073 ExecuteCommand();
2075 if (current->arg != NULL)
2077 GetString(current->arg);
2079 else
2081 error = BADPARAMETER;
2082 traperr("<%s> requires a path name as argument!\n", current->parent->cmd->arg);
2085 lockdev = Lock(string, SHARED_LOCK);
2086 free(string);
2087 if (lockdev)
2089 ret = DynNameFromLock(lockdev);
2090 UnLock(lockdev);
2092 if (ret)
2094 current->parent->arg = addquotes(ret);
2095 free(ret);
2097 else
2099 current->parent->arg = addquotes("");
2103 else
2105 error = SCRIPTERROR;
2106 traperr("<%s> requires one argument!\n", current->arg);
2108 break;
2110 /* Here are all unimplemented commands */
2111 case _COPYFILES :
2112 case _COPYLIB :
2113 case _FOREACH :
2114 case _GETSUM :
2115 case _GETVERSION :
2116 case _ICONINFO :
2117 case _PATMATCH :
2118 case _PROTECT :
2119 case _REXX :
2120 case _TEXTFILE :
2121 case _TOOLTYPE :
2122 fprintf(stderr, "Unimplemented command <%s>\n", current->arg);
2123 break;
2125 case _USERDEF: /* User defined routine */
2126 usrproc = find_proc(current->arg);
2127 /* Set argument variables */
2128 i = 0;
2129 while (current->next != NULL && i < usrproc->argnum)
2131 current = current->next;
2132 ExecuteCommand();
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);
2140 free(clip);
2142 else
2144 /* value is a variable */
2145 set_variable(usrproc->arglist[i], get_var_arg(current->arg), get_var_int(current->arg));
2148 else
2150 set_variable(usrproc->arglist[i], NULL, current->intval);
2152 i++;
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);
2163 break;
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);
2203 break;
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);
2247 break;
2249 #ifdef DEBUG
2250 case _ALL:
2251 case _APPEND:
2252 case _ASSIGNS:
2253 case _CHOICES:
2254 case _COMMAND:
2255 case _CONFIRM:
2256 case _DEFAULT:
2257 case _DEST:
2258 case _DISK:
2259 case _FILES:
2260 case _FONTS:
2261 case _HELP:
2262 case _INCLUDE:
2263 case _INFOS:
2264 case _NEWNAME:
2265 case _NEWPATH:
2266 case _NOGAUGE:
2267 case _NOPOSITION:
2268 case _PATTERN:
2269 case _PROMPT:
2270 case _RANGE:
2271 case _RESIDENT:
2272 case _SAFE:
2273 case _SETDEFAULTTOOL:
2274 case _SETPOSITION:
2275 case _SETSTACK:
2276 case _SETTOOLTYPE:
2277 case _SOURCE:
2278 case _SWAPCOLORS:
2279 case _QUIET:
2280 /* We are tags -- we don't want to be executed */
2281 current->parent->ignore = 1;
2282 break;
2283 #endif /* DEBUG */
2285 default:
2286 #ifdef DEBUG
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);
2289 cleanup();
2290 exit(-1);
2291 #else /* DEBUG */
2292 /* We are tags -- we don't want to be executed */
2293 current->parent->ignore = 1;
2294 #endif /* DEBUG */
2295 break;
2302 * Get an ID for the command string
2304 int eval_cmd(char * argument)
2306 int i;
2308 if (argument[0] == SQUOTE || argument[0] == DQUOTE)
2310 return _STRING;
2312 else
2314 for (i = 0 ; i < _MAXCOMMAND && strcasecmp(internal_commands[i].cmdsymbol, argument) != 0 ; i++);
2315 if (i != _MAXCOMMAND)
2317 return internal_commands[i].cmdnumber;
2319 else
2321 if (find_proc(argument) != NULL)
2323 return _USERDEF;
2325 else
2327 return _UNKNOWN;
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;
2345 i = 0;
2346 j = 1;
2348 i++;
2349 if (i > MAXARGSIZE)
2351 j++;
2352 i = 1;
2353 callbackstring = realloc(callbackstring, MAXARGSIZE * j);
2354 outofmem(callbackstring);
2355 globalstring += (callbackstring - string);
2356 string = callbackstring;
2358 *(*data)++ = chr;
2363 * Strip off quotes from a string
2364 * Does not check for quotes!
2366 char *strip_quotes(char *string)
2368 int slen;
2369 char *clip;
2371 /* Strip off quotes */
2372 slen = strlen(string);
2373 clip = (char *)malloc(slen - 1);
2374 outofmem(clip);
2375 strncpy(clip, string+1, slen-2);
2376 clip[slen-2] = 0;
2378 return clip;
2383 * Convert data entry to <int>
2384 * <string>s are atol()'d, <cmd>s are *not* executed
2386 long int getint(ScriptArg *argument)
2388 long int i;
2389 char * clip;
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);
2397 i = atol(clip);
2398 free(clip);
2400 else
2402 clip = get_var_arg(argument->arg);
2403 if (clip != NULL)
2405 i = atol(clip);
2407 else
2409 i = get_var_int(argument->arg);
2413 else
2415 i = argument->intval;
2418 return i;
2423 * Get an ID for hardware descriptor
2425 int database_keyword(char *name)
2427 if (strcasecmp(name, "vblank") == 0)
2428 return _VBLANK;
2429 else if (strcasecmp(name, "cpu") == 0)
2430 return _CPU;
2431 else if (strcasecmp(name, "graphics-mem") == 0)
2432 return _GRAPHICS_MEM;
2433 else if (strcasecmp(name, "total-mem") == 0)
2434 return _TOTAL_MEM;
2435 else if (strcasecmp(name, "fpu") == 0)
2436 return _FPU;
2437 else if (strcasecmp(name, "chiprev") == 0)
2438 return _CHIPREV;
2440 return _UNKNOWN;
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;
2453 int i;
2455 while (current != NULL)
2457 ExecuteCommand();
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);
2468 else
2470 dummy = get_var_arg(current->arg);
2471 if (dummy != NULL)
2473 clip = strdup(dummy);
2474 outofmem(clip);
2476 else
2478 clip = malloc(MAXARGSIZE);
2479 outofmem(clip);
2480 sprintf(clip, "%ld", get_var_int(current->arg));
2484 else
2486 clip = malloc(MAXARGSIZE);
2487 outofmem(clip);
2488 sprintf(clip, "%ld", current->intval);
2490 i = (string == NULL) ? 0 : strlen(string);
2491 string = realloc(string, i + strlen(clip) + 2);
2492 outofmem(string);
2493 if (i == 0)
2495 string[0] = 0;
2497 else
2499 string[i] = separator;
2500 string[i+1] = 0;
2502 strcat(string, clip);
2503 free(clip);
2505 current = current->next;
2508 return string;
2513 * Free the allocated space for string list
2515 void free_parameter(struct ParameterList pl)
2517 int j;
2519 if (pl.arg)
2521 for (j = 0 ; j < pl.intval ; j++)
2523 free(pl.arg[j]);
2525 free(pl.arg);
2526 pl.arg = NULL;
2532 * Free a complete (struct ParameterList *)
2534 void free_parameterlist(struct ParameterList *pl)
2536 int i;
2538 if (pl)
2540 for (i = 0 ; i < NUMPARAMS ; i++)
2542 free_parameter(pl[i]);
2544 free(pl);
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;
2557 ScriptArg *current;
2558 long int i;
2559 int cmd;
2560 char *string, *clip;
2562 pl = calloc(NUMPARAMS, sizeof(struct ParameterList));
2563 outofmem(pl);
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;
2584 else
2586 /* This parameter may have arguments */
2587 switch (cmd)
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)));
2605 break;
2607 case _CONFIRM: /* ($->)# */
2608 i = _EXPERT;
2609 if (current != NULL)
2611 ExecuteCommand();
2612 if (current->arg != NULL)
2614 string = NULL;
2615 if ((current->arg)[0] == SQUOTE || (current->arg)[0] == DQUOTE)
2617 /* Strip off quotes */
2618 string = strip_quotes(current->arg);
2619 clip = string;
2621 else
2623 clip = get_var_arg(current->arg);
2625 if (clip != NULL)
2627 i = atol(clip);
2628 if (strcasecmp(clip, "novice") == 0)
2630 i = _NOVICE;
2632 if (strcasecmp(clip, "average") == 0)
2634 i = _AVERAGE;
2636 if (strcasecmp(clip, "expert") == 0)
2638 i = _EXPERT;
2640 free(string);
2642 else
2644 i = get_var_int(current->arg);
2647 else
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;
2658 break;
2660 case _DEFAULT: /* * */
2661 i = 0;
2662 string = NULL;
2663 if (current != NULL)
2665 ExecuteCommand();
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);
2673 else
2675 clip = get_var_arg(current->arg);
2676 if (clip != NULL)
2678 string = strdup(clip);
2679 outofmem(string);
2681 else
2683 i = get_var_int(current->arg);
2687 else
2689 i = current->intval;
2691 GetPL(pl, cmd).intval = i;
2692 if (string != NULL)
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]);
2700 else
2702 GetPL(pl, cmd).arg = malloc(sizeof(char *));
2703 outofmem(GetPL(pl, cmd).arg);
2705 GetPL(pl, cmd).arg[0] = string;
2708 else
2710 error = SCRIPTERROR;
2711 traperr("<%s> requires one argument!\n", script->cmd->arg);
2713 break;
2715 case _RANGE : /* # # */
2716 case _SETPOSITION : /* # # */
2717 i = 0;
2718 if (current != NULL && current->next != NULL)
2720 ExecuteCommand();
2721 GetPL(pl, cmd).intval = getint(current);
2722 current = current->next;
2723 ExecuteCommand();
2724 GetPL(pl, cmd).intval2 = getint(current);
2726 else
2728 error = SCRIPTERROR;
2729 traperr("<%s> requires two arguments!\n", script->cmd->arg);
2731 break;
2733 case _SETSTACK: /* # */
2734 i = 0;
2735 if (current != NULL)
2737 ExecuteCommand();
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);
2744 i = atol(string);
2745 free(string);
2747 else
2749 clip = get_var_arg(current->arg);
2750 if (clip != NULL)
2752 i = atol(clip);
2754 else
2756 i = get_var_int(current->arg);
2760 else
2762 i = current->intval;
2764 GetPL(pl, cmd).intval = i;
2766 else
2768 error = SCRIPTERROR;
2769 traperr("<%s> requires one argument!\n", script->cmd->arg);
2771 break;
2774 default: /* We do only collect tags -- this is a command */
2775 break;
2779 else if (cmd == _IF)
2781 /* This parameter is masqueraded */
2782 switch (cmd)
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)
2792 ExecuteCommand();
2793 i = getint(current);
2794 if (i == 0)
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);
2820 else
2822 error = SCRIPTERROR;
2823 traperr("<%s> requires two arguments!\n", script->arg);
2825 break;
2827 default: /* We do only collect tags -- this is a command */
2828 break;
2833 script = script->next;
2836 return pl;
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;
2847 int j = 0;
2849 while (current != NULL)
2851 ExecuteCommand();
2852 mclip = realloc(mclip, sizeof(char *) * (j+1));
2853 outofmem(mclip);
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);
2861 else
2863 clip = get_var_arg(current->arg);
2864 if (clip != NULL)
2866 string = strdup(clip);
2867 outofmem(string);
2869 else
2871 clip = malloc(MAXARGSIZE);
2872 outofmem(clip);
2873 sprintf(clip, "%ld", get_var_int(current->arg));
2874 string = strdup(clip);
2875 outofmem(string);
2876 free(clip);
2880 else
2882 clip = malloc(MAXARGSIZE);
2883 outofmem(clip);
2884 sprintf(clip, "%ld", current->intval);
2885 string = strdup(clip);
2886 outofmem(string);
2887 free(clip);
2889 mclip[j] = string;
2890 j++;
2891 current = current->next;
2893 pl->arg = mclip;
2894 pl->intval = j;
2899 * Read in one line of a file
2901 char * get_file_line(BPTR file)
2903 char *out;
2904 char buf[1];
2905 int i=0, cnt;
2909 cnt = Read(file, buf, 1);
2910 i += cnt;
2911 } while (cnt && buf[0] != LINEFEED);
2912 if (i == 0)
2914 return NULL;
2916 Seek(file, -i, OFFSET_CURRENT);
2917 out = malloc(i * sizeof(char));
2918 outofmem(out);
2919 Read(file, out, i);
2920 out[i-1] = 0;
2922 return out;
2927 * Routine for modifying S:User-Startup
2929 void modify_userstartup(char *string, struct ParameterList *parameter)
2931 BPTR userstartup;
2932 BPTR tmpuserstartup;
2933 char *line;
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!");
2942 exit(-1);
2944 if (userstartup)
2946 while ((line = get_file_line(userstartup)) && !changed)
2948 if (strncasecmp(line, ";BEGIN ", 7) == 0)
2950 if (strcmp(&(line[7]), string) == 0)
2952 changed = 1;
2955 if (!changed)
2957 Write(tmpuserstartup, line, strlen(line));
2958 Write(tmpuserstartup, "\n", 1);
2960 free(line);
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);
2975 if (userstartup)
2977 while ((line = get_file_line(userstartup)))
2979 if (!cont)
2981 if (strncasecmp(line, ";END ", 5) == 0)
2983 if (strcmp(&(line[5]), string) == 0)
2985 cont = 1;
2989 else
2991 Write(tmpuserstartup, line, strlen(line));
2992 Write(tmpuserstartup, "\n", 1);
2994 free(line);
2998 Close(tmpuserstartup);
2999 Close(userstartup);
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)
3020 char *outmsg;
3021 int i, j;
3023 if (!doing_abort)
3025 doing_abort = TRUE;
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)
3035 /* execute trap */
3036 execute_script(preferences.trap[ error - 1 ].cmd, -99);
3038 else
3040 /* execute onerrors */
3041 if (preferences.onerror.cmd != NULL)
3043 execute_script(preferences.onerror.cmd, -99);
3048 #ifdef DEBUG
3049 dump_varlist();
3050 #endif /* DEBUG */
3052 cleanup();
3053 if (grace_exit == TRUE)
3055 exit(0);
3057 else
3059 exit(-1);
3064 char *DynNameFromLock(BPTR lock)
3066 char *dirName = NULL;
3067 ULONG size;
3069 for (size = 512 ; ; size += 512)
3071 dirName = malloc(size);
3072 if (dirName == NULL)
3074 break;
3076 if (NameFromLock(lock, dirName, size))
3078 break;
3080 free(dirName);
3081 dirName = NULL;
3082 if (IoErr() != ERROR_LINE_TOO_LONG)
3084 break;
3087 return dirName;