2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
25 * Copyright 1993 NeXT, Inc.
26 * All rights reserved.
30 #import "kernBootStruct.h"
31 #import <driverkit/configTablePrivate.h>
33 extern KERNBOOTSTRUCT
*kernBootStruct
;
34 extern char *Language
;
35 extern char *LoadableFamilies
;
37 static void eatThru(char val
, char **table_p
);
39 static inline int isspace(char c
)
41 return (c
== ' ' || c
== '\t');
45 * Compare a string to a key with quoted characters
48 keyncmp(char *str
, char *key
, int n
)
67 } else if (c
== '\"') {
68 /* Premature end of key */
78 static void eatThru(char val
, char **table_p
)
80 register char *table
= *table_p
;
81 register BOOL found
= NO
;
83 while (*table
&& !found
)
85 if (*table
== '\\') table
+= 2;
88 if (*table
== val
) found
= YES
;
101 char *begin
= *list
, *end
;
105 while (*begin
&& newsize
&& isspace(*begin
)) {
110 while (*end
&& newsize
&& !isspace(*end
)) {
116 newstr
= malloc(end
- begin
+ 1);
117 strncpy(newstr
, begin
, end
- begin
);
124 * compress == compress escaped characters to one character
126 int stringLength(char *table
, int compress
)
135 ret
+= 1 + (compress
? 0 : 1);
139 if (*table
== '\"') return ret
;
148 // looks in table for strings of format << "key" = "value"; >>
150 BOOL
getValueForStringTableKey(char *table
, char *key
, char **val
, int *size
)
157 eatThru('\"',&table
);
159 keyLength
= strlen(key
);
161 (stringLength(table
,1) == keyLength
) &&
162 (keyncmp(key
, table
, keyLength
) == 0))
166 /* found the key; now look for either
174 } else if (c
== '=' || c
== ';') {
181 eatThru('\"',&table
);
184 *size
= stringLength(table
,0);
197 * Returns a new malloc'ed string if one is found
198 * in the string table matching 'key'. Also translates
199 * \n escapes in the string.
201 char *newStringForStringTableKey(
206 char *val
, *newstr
, *p
;
209 if (getValueForStringTableKey(table
, key
, &val
, &size
)) {
210 newstr
= malloc(size
+1);
211 for (p
= newstr
; size
; size
--, p
++, val
++) {
212 if ((*p
= *val
) == '\\') {
238 newStringForKey(char *key
)
243 if (getValueForKey(key
, &val
, &size
) && size
) {
244 newstr
= malloc(size
+ 1);
245 strncpy(newstr
, val
, size
);
252 /* parse a command line
253 * in the form: [<argument> ...] [<option>=<value> ...]
254 * both <option> and <value> must be either composed of
255 * non-whitespace characters, or enclosed in quotes.
258 static char *getToken(char *line
, char **begin
, int *len
)
262 while (*line
&& *line
!= '\"')
264 *len
= line
++ - *begin
;
267 while (*line
&& !isspace(*line
) && *line
!= '=')
269 *len
= line
- *begin
;
274 BOOL
getValueForBootKey(char *line
, char *match
, char **matchval
, int *len
)
277 int key_len
, value_len
;
280 /* look for keyword or argument */
281 while (isspace(*line
)) line
++;
283 /* now look for '=' or whitespace */
284 line
= getToken(line
, &key
, &key_len
);
285 /* line now points to '=' or space */
286 if (!isspace(*line
++)) {
287 line
= getToken(line
, &value
, &value_len
);
288 if ((strlen(match
) == key_len
)
289 && strncmp(match
, key
, key_len
) == 0) {
306 if (getValueForKey(key
, &val
, &size
) && (size
>= 1) &&
307 val
[0] == 'Y' || val
[0] == 'y')
318 if (getValueForBootKey(kernBootStruct
->bootString
, key
, val
, size
))
320 else if (getValueForStringTableKey(kernBootStruct
->config
, key
, val
, size
))
326 #define LOCALIZABLE \
327 "/usr/Devices/%s.config/%s.lproj/Localizable.strings"
330 loadLocalizableStrings(
334 char buf
[256], *config
;
335 register int count
, fd
;
337 sprintf(buf
, LOCALIZABLE
, name
, Language
);
338 if ((fd
= open(buf
,0)) < 0) {
339 sprintf(buf
, LOCALIZABLE
, name
, "English");
340 if ((fd
= open(buf
,0)) < 0)
343 count
= file_size(fd
);
344 config
= malloc(count
);
345 count
= read(fd
, config
, count
);
359 char *table
, *name
, *val
;
362 if ((table
= loadLocalizableStrings(bundleName
)) != 0 &&
363 getValueForStringTableKey(table
,"Long Name", &val
, &size
) == YES
) {
364 name
= malloc(size
+1);
365 strncpy(name
, val
, size
);
368 name
= newString(bundleName
);
377 * Returns 0 if file loaded OK,
378 * -1 if file was not loaded
379 * Does not print error messages.
380 * Returns pointer to table in memory in *table.
383 loadConfigFile( char *configFile
, char **table
, int allocTable
)
385 char *configPtr
= kernBootStruct
->configEnd
;
388 /* Read config file into memory */
389 if ((fd
= open(configFile
, 0)) >= 0)
392 configPtr
= malloc(file_size(fd
)+2);
394 if ((configPtr
- kernBootStruct
->config
) > CONFIG_SIZE
) {
395 error("No room in memory for config file %s\n",configFile
);
399 localPrintf("Reading config: %s\n",configFile
);
401 if (table
) *table
= configPtr
;
402 count
= read(fd
, configPtr
, IO_CONFIG_DATA_SIZE
);
409 kernBootStruct
->configEnd
= configPtr
;
417 /* Returns 0 if requested config files were loaded,
418 * 1 if default files were loaded,
419 * -1 if no files were loaded.
420 * Prints error message if files cannot be loaded.
425 char *bundleName
, // bundle directory name (e.g. "System.config")
426 int useDefault
, // use Default.table instead of instance tables
427 char **table
, // returns pointer to config table
428 int allocTable
// malloc the table and return in *table
437 // load up to 99 instance tables
438 for (i
=0; i
< 99; i
++) {
439 sprintf(buf
, "%s%s.config/Instance%d.table", IO_CONFIG_DIR
,
441 if (useDefault
|| (loadConfigFile(buf
, table
, allocTable
) != 0)) {
443 // couldn't load first instance table;
444 // try the default table
445 sprintf(buf
, "%s%s.config/%s", IO_CONFIG_DIR
, bundleName
,
446 IO_DEFAULT_TABLE_FILENAME
);
447 if (loadConfigFile(buf
, table
, allocTable
) == 0) {
451 error("Config file \"%s\" not found\n", buf
);
464 #define SYSTEM_DEFAULT_FILE \
465 IO_SYSTEM_CONFIG_DIR IO_DEFAULT_TABLE_FILENAME
466 #define SYSTEM_CONFIG "System"
470 /* Returns 0 if requested config files were loaded,
471 * 1 if default files were loaded,
472 * -1 if no files were loaded.
473 * Prints error message if files cannot be loaded.
482 int ret
, len
, doDefault
=0;
484 buf
= bp
= malloc(256);
487 for(cp
= which
, len
= size
; len
&& *cp
&& *cp
!= LP
; cp
++, len
--) ;
489 while (len
-- && *cp
&& *cp
++ != RP
) ;
490 /* cp now points past device */
491 strncpy(buf
,which
,cp
- which
);
498 strcpy(bp
, IO_SYSTEM_CONFIG_DIR
);
499 strncat(bp
, cp
, len
);
500 if (strncmp(cp
+ len
- strlen(IO_TABLE_EXTENSION
),
501 IO_TABLE_EXTENSION
, strlen(IO_TABLE_EXTENSION
)) != 0)
502 strcat(bp
, IO_TABLE_EXTENSION
);
504 strncpy(bp
, cp
, len
);
507 if (strcmp(bp
, SYSTEM_DEFAULT_FILE
) == 0)
509 ret
= loadConfigFile(bp
= buf
, 0, 0);
511 ret
= loadConfigDir((bp
= SYSTEM_CONFIG
), 0, 0, 0);
514 error("System config file '%s' not found\n", bp
);
518 return (ret
< 0 ? ret
: doDefault
);
532 if (getValueForKey( "Boot Drivers", &val
, &count
))
534 while (string
= newStringFromList(&val
, &count
)) {
535 ret
= loadConfigDir(string
, useDefault
, &table
, 0);
537 if ((fd
= openDriverReloc(string
)) >= 0) {
538 localPrintf("Loading binary for %s\n",string
);
539 if (loadDriver(string
, fd
) < 0)
540 error("Error loading driver %s\n",string
);
543 driverWasLoaded(string
, table
);
546 driverIsMissing(string
);
549 useDefault
= 1; // use defaults from now on
552 error("Warning: No active drivers specified in system config\n");
555 kernBootStruct
->first_addr0
=
556 (int)kernBootStruct
->configEnd
+ 1024;