Updated PCI IDs to latest snapshot.
[tangerine.git] / arch / .unmaintained / amiga / boot / config.c
blob24b5a689116b0c242d7de2c4ae644dcbdc24dbf7
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Amiga bootloader -- config file routines
6 Lang: C
7 */
9 #include <exec/types.h>
10 #include <exec/lists.h>
11 #include <exec/nodes.h>
12 #include <exec/memory.h>
13 #include <dos/dos.h>
14 #include <dos/rdargs.h>
16 #include <ctype.h>
17 #include <string.h>
19 #include <proto/exec.h>
20 #include <proto/alib.h>
21 #include <proto/dos.h>
23 #include "boot.h"
24 #include "main.h"
25 #include "config.h"
27 #define D(x) if (debug) x
28 #define bug Printf
31 * Maximum config file length. Is actually 100, but we add 2 for the newline
32 * character and the \0 character. Add another character for the V36/V37 FGets
33 * bug. All of this still implies a maximum line length of 100 to the user.
35 #define MAX_LINE_LEN 103
37 char txt_module[] = "MODULE";
38 char args_module[] = "MODULE/K/A";
39 #define ARG_MOD_MODULE 0
40 #define ARG_MOD_END 1
41 LONG vec_module[ARG_MOD_END];
43 char txt_function[] = "FUNCTION";
44 char args_function[] = "FUNCTION/N/K/A,MODULE/A,ON/S,OFF/S";
45 #define ARG_FUNC_FUNCTION 0
46 #define ARG_FUNC_MODULE 1
47 #define ARG_FUNC_ON 2
48 #define ARG_FUNC_OFF 3
49 #define ARG_FUNC_END 4
50 LONG vec_function[ARG_FUNC_END];
52 BOOL isconfigline(char *, char *);
53 struct Node *FindNameNC(struct List *, UBYTE *);
55 struct BootConfig *ReadConfig(char *file)
57 BPTR fh;
58 LONG ioerr = 0;
59 BOOL running = TRUE;
60 struct RDArgs *rdargs;
61 struct BootConfig *config;
62 struct ModNode *modnode;
63 struct FuncNode *funcnode;
64 UBYTE *linebuffer;
66 D(bug("Processing config file\n"));
68 D(bug("Allocating Config..."));
69 if( (config = AllocVec(sizeof(*config), MEMF_CLEAR)))
71 D(bug(" ok\n"));
72 NewList(&config->bc_Modules);
73 config->bc_Num = 0;
75 D(bug("Allocating RDArgs..."));
76 if( (rdargs = AllocDosObject(DOS_RDARGS, NULL)))
78 D(bug(" ok\n"));
79 D(bug("Allocating linebuffer..."));
80 if( (linebuffer = AllocMem(MAX_LINE_LEN, MEMF_CLEAR)))
82 D(bug(" ok\n"));
84 D(bug("Opening config file \"%s\"", (ULONG)file));
85 if( (fh = Open(file, MODE_OLDFILE)))
87 D(bug(" ok\n"));
89 while(running)
91 /* MAX_LINE_LEN-1 because of V36/V37 bug */
92 if( (FGets(fh, linebuffer, MAX_LINE_LEN-1)))
94 rdargs->RDA_Source.CS_Buffer = linebuffer;
95 rdargs->RDA_Source.CS_Length = MAX_LINE_LEN;
96 rdargs->RDA_Source.CS_CurChr = 0;
97 rdargs->RDA_Buffer = NULL;
99 if( (isconfigline(linebuffer, txt_module)))
101 vec_module[0] = NULL;
103 D(bug("About to ReadArgs()..."));
104 if( (ReadArgs(args_module, vec_module, rdargs)))
106 D(bug(" ok\n"));
108 D(bug("Found module: \"%s\"\n", vec_module[ARG_MOD_MODULE]));
110 D(bug("Looking if module already included..."));
111 if(!(FindNameNC(&config->bc_Modules,
112 (STRPTR)vec_module[ARG_MOD_MODULE])))
114 D(bug(" no\n"));
116 D(bug("Allocating module node..."));
117 if( (modnode = AllocVec(sizeof(*modnode), MEMF_CLEAR)))
119 D(bug(" ok\n"));
121 NewList(&modnode->mn_FuncList);
123 D(bug("Allocating space for module name..."));
124 if( (modnode->mn_Node.ln_Name =
125 AllocVec(strlen((char *)vec_module[ARG_MOD_MODULE])+1,
126 MEMF_CLEAR)))
128 D(bug(" ok\n"));
130 strcpy(modnode->mn_Node.ln_Name, (char *)vec_module[ARG_MOD_MODULE]);
131 D(bug("Copied name \"%s\"\n", (ULONG)modnode->mn_Node.ln_Name));
133 D(bug("Adding node to list\n"));
134 AddTail(&config->bc_Modules, &modnode->mn_Node);
135 config->bc_Num++;
137 else
139 FreeVec(modnode);
140 ioerr = ERROR_NO_FREE_STORE;
141 D(bug(" fail\n"));
144 else
146 ioerr = ERROR_NO_FREE_STORE;
147 D(bug(" fail\n"));
150 else
152 D(bug(" yes\n"));
153 if(!quiet)
154 Printf("Module \"%s\" declared twice. Ignored second occurence.\n",
155 (ULONG)vec_module[ARG_MOD_MODULE]
159 FreeArgs(rdargs);
161 else
163 ioerr = IoErr();
164 D(bug(" fail or incomplete parameters\n"));
167 else if( (isconfigline(linebuffer, txt_function)))
169 vec_module[ARG_FUNC_FUNCTION] =
170 vec_module[ARG_FUNC_MODULE] =
171 vec_module[ARG_FUNC_OFF] = 0;
172 vec_module[ARG_FUNC_ON] = 1;
174 D(bug("About to ReadArgs()..."));
175 if( (ReadArgs(args_function, vec_function, rdargs)))
177 D(bug(" ok\n"));
179 /* ON has precedence */
180 if(vec_function[ARG_FUNC_ON] & vec_function[ARG_FUNC_OFF])
181 vec_function[ARG_FUNC_OFF] = 0;
183 /* Both flags off: ON is default */
184 if(!vec_function[ARG_FUNC_ON] & !vec_function[ARG_FUNC_OFF])
185 vec_function[ARG_FUNC_ON] = 1;
187 D(bug("Found function: \"%ld\" in \"%s\" status \"%s\"\n",
188 *(LONG *)vec_function[ARG_FUNC_FUNCTION],
189 vec_function[ARG_FUNC_MODULE],
190 vec_function[ARG_FUNC_ON] ? (ULONG)"on" : (ULONG)"off"
193 if( *(LONG *)vec_function[ARG_FUNC_FUNCTION] % 6 )
195 if(!quiet)
196 Printf("Function offset %ld is not a multiple of -6! Ignoring this function line.\n",
197 *(LONG *)vec_function[ARG_FUNC_FUNCTION]
200 else
202 D(bug("Finding correct module..."));
203 if( (modnode = (struct ModNode *)FindNameNC(&config->bc_Modules,
204 (STRPTR)vec_function[ARG_FUNC_MODULE])))
206 D(bug(" ok\n"));
208 D(bug("Allocating function node..."));
209 if( (funcnode = AllocVec(sizeof(*funcnode), MEMF_CLEAR)))
211 D(bug(" ok\n"));
213 D(bug("Setting function status in function node..."));
214 funcnode->fn_Slot = *(LONG *)vec_function[ARG_FUNC_FUNCTION] / -6;
215 funcnode->fn_Status =
216 vec_function[ARG_FUNC_ON] ? 1 : 0;
217 D(bug(" ok\n"));
219 D(bug("Adding function node to list..."));
220 AddTail(&modnode->mn_FuncList, &funcnode->fn_Node);
221 D(bug(" ok\n"));
223 else
225 ioerr = ERROR_NO_FREE_STORE;
226 D(bug(" fail\n"));
229 else
231 if(!quiet)
232 Printf("Function %ld \"%s\" not in any known module. Ignored.\n",
233 *(LONG *)vec_function[ARG_FUNC_FUNCTION],
234 vec_function[ARG_FUNC_MODULE]
239 FreeArgs(rdargs);
241 else
243 ioerr = IoErr();
244 D(bug(" fail or incomplete parameters\n"));
248 else
250 ioerr = IoErr(); /* will be 0 in case of EOF */
251 running = FALSE;
255 D(bug("Closing file \"%s\"...", (ULONG)file));
256 if(!(Close(fh)))
258 ioerr = IoErr();
259 D(bug(" fail\n"));
261 else
263 D(bug(" ok\n"));
266 else
268 ioerr = IoErr();
269 D(bug(" fail\n"));
272 D(bug("Freeing linebuffer..."));
273 FreeMem(linebuffer, MAX_LINE_LEN);
274 D(bug(" ok\n"));
276 else
278 ioerr = ERROR_NO_FREE_STORE;
279 D(bug(" fail\n"));
282 D(bug("Freeing RDArgs..."));
283 FreeDosObject(DOS_RDARGS, rdargs);
284 D(bug(" ok\n"));
286 else
288 D(bug(" fail\n"));
289 ioerr = ERROR_NO_FREE_STORE;
292 else
294 D(bug(" fail\n"));
295 ioerr = ERROR_NO_FREE_STORE;
299 if(ioerr)
301 if(!quiet) PrintFault(ioerr, "arosboot");
302 FreeConfig(config);
303 return 0;
306 if(config->bc_Modules.lh_TailPred == (struct Node *)&config->bc_Modules)
308 /* empty list: no modules */
309 if(!quiet) Printf("No modules found in config file\n");
310 FreeConfig(config);
311 return 0;
314 D(bug("End of config file processing\n"));
315 return config;
318 void FreeConfig(struct BootConfig *config)
320 struct ModNode *modnode, *modnext;
321 struct FuncNode *funcnode, *funcnext;
323 D(bug("FreeConfig...\n"));
325 if(config)
327 for(modnode = (struct ModNode *)config->bc_Modules.lh_Head;
328 modnode->mn_Node.ln_Succ;
329 modnode = modnext)
331 /* Get the next node here, because after the Remove() it is undefined. */
332 modnext = (struct ModNode *)modnode->mn_Node.ln_Succ;
334 for(funcnode = (struct FuncNode *)modnode->mn_FuncList.lh_Head;
335 funcnode->fn_Node.ln_Succ;
336 funcnode = funcnext)
338 funcnext = (struct FuncNode *)funcnode->fn_Node.ln_Succ;
339 D(bug(" Free funcnode\n"));
340 FreeVec(funcnode);
343 Remove(&modnode->mn_Node);
344 if(modnode->mn_Node.ln_Name)
346 D(bug(" Free modname\n"));
347 FreeVec(modnode->mn_Node.ln_Name);
349 D(bug(" Free modnode\n"));
350 FreeVec(modnode);
352 D(bug(" Free config\n"));
353 FreeVec(config);
357 BOOL isconfigline(char *buffer, char *keyword)
359 /* account for indented lines */
360 while(isspace(*buffer) && *buffer != '\n') buffer++;
362 /* comment? */
363 if(*buffer == ';') return FALSE;
365 while(*keyword && *buffer)
367 if(*keyword != toupper(*buffer)) return FALSE;
368 keyword++;
369 buffer++;
372 return TRUE;
375 /* FindName case-insensitive */
376 struct Node *FindNameNC(struct List *list, UBYTE *name)
378 struct Node * node;
380 /* Look through the list */
381 for (node=GetHead(list); node; node=GetSucc(node))
383 /* Only compare the names if this node has one. */
384 if(node->ln_Name)
386 /* Check the node. If we found it, stop. */
387 if (!strcasecmp (node->ln_Name, name))
388 break;
392 * If we found a node, this will contain the pointer to it. If we
393 * didn't, this will be NULL (either because the list was
394 * empty or because we tried all nodes in the list)
396 return node;