/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights
* Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
+ * Source License Version 2.0 (the "License"). You may not use this file
* except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
* All rights reserved.
*/
+#include "bootstruct.h"
#include "libsaio.h"
-#include "kernBootStruct.h"
#include "stringConstants.h"
#include "legacy/configTablePrivate.h"
+#include "xml.h"
-extern KERNBOOTSTRUCT *kernBootStruct;
extern char *Language;
extern char *LoadableFamilies;
-static void eatThru(char val, char **table_p);
+static TagPtr gConfigDict;
+
+static void eatThru(char val, const char **table_p);
static inline int isspace(char c)
{
* Compare a string to a key with quoted characters
*/
static inline int
-keyncmp(char *str, char *key, int n)
+keyncmp(const char *str, const char *key, int n)
{
int c;
while (n--) {
return 0;
}
-static void eatThru(char val, char **table_p)
+static void eatThru(char val, const char **table_p)
{
- register char *table = *table_p;
+ register const char *table = *table_p;
register BOOL found = NO;
while (*table && !found)
*table_p = table;
}
+#if UNUSED
+
/* Remove key and its associated value from the table. */
BOOL
char *begin = *list, *end;
char *newstr;
int newsize = *size;
+ int bufsize;
while (*begin && newsize && isspace(*begin)) {
begin++;
}
if (begin == end)
return 0;
- newstr = malloc(end - begin + 1);
- strncpy(newstr, begin, end - begin);
+ bufsize = end - begin + 1;
+ newstr = malloc(bufsize);
+ strlcpy(newstr, begin, bufsize);
*list = end;
*size = newsize;
return newstr;
}
+#endif
+
/*
* compress == compress escaped characters to one character
*/
-int stringLength(char *table, int compress)
+int stringLength(const char *table, int compress)
{
int ret = 0;
return ret;
}
-// looks in table for strings of format << "key" = "value"; >>
-// or << "key"; >>
-BOOL getValueForStringTableKey(char *table, char *key, char **val, int *size)
+BOOL getValueForConfigTableKey(const char *table, const char *key, const char **val, int *size)
{
int keyLength;
- char *tableKey;
-
- do
- {
- eatThru('\"',&table);
- tableKey = table;
- keyLength = strlen(key);
- if (keyLength &&
- (stringLength(table,1) == keyLength) &&
- (keyncmp(key, table, keyLength) == 0))
- {
- int c;
+ const char *tableKey;
+
+ if (gConfigDict != 0 ) {
+ /* Look up key in XML dictionary */
+ TagPtr value;
+ value = XMLGetProperty(gConfigDict, key);
+ if (value != 0) {
+ if (value->type != kTagTypeString) {
+ error("Non-string tag '%s' found in config file\n",
+ key);
+ return NO;
+ }
+ *val = value->string;
+ *size = strlen(value->string);
+ return YES;
+ }
+ } else {
+ /* Legacy plist-style table */
+ do
+ {
+ eatThru('\"',&table);
+ tableKey = table;
+ keyLength = strlen(key);
+ if (keyLength &&
+ (stringLength(table,1) == keyLength) &&
+ (keyncmp(key, table, keyLength) == 0))
+ {
+ int c;
- /* found the key; now look for either
- * '=' or ';'
- */
- while (c = *table) {
- ++table;
- if (c == '\\') {
- ++table;
- continue;
- } else if (c == '=' || c == ';') {
- break;
- }
- }
- if (c == ';') {
- table = tableKey;
- } else {
- eatThru('\"',&table);
- }
- *val = table;
- *size = stringLength(table,0);
- return YES;
- }
-
- eatThru(';',&table);
-
- } while (*table);
+ /* found the key; now look for either
+ * '=' or ';'
+ */
+ while (c = *table) {
+ ++table;
+ if (c == '\\') {
+ ++table;
+ continue;
+ } else if (c == '=' || c == ';') {
+ break;
+ }
+ }
+ if (c == ';') {
+ table = tableKey;
+ } else {
+ eatThru('\"',&table);
+ }
+ *val = table;
+ *size = stringLength(table,0);
+ return YES;
+ }
+
+ eatThru(';',&table);
+
+ } while (*table);
+ }
return NO;
}
+#if UNUSED
/*
* Returns a new malloc'ed string if one is found
char *key
)
{
- char *val, *newstr, *p;
+ const char *val;
+ char *newstr, *p;
int size;
- if (getValueForStringTableKey(table, key, &val, &size)) {
- newstr = malloc(size+1);
+ if (getValueForConfigTableKey(table, key, &val, &size)) {
+ newstr = (char *)malloc(size+1);
for (p = newstr; size; size--, p++, val++) {
if ((*p = *val) == '\\') {
switch (*++val) {
}
}
+#endif
+
char *
newStringForKey(char *key)
{
- char *val, *newstr;
+ const char *val;
+ char *newstr;
int size;
if (getValueForKey(key, &val, &size) && size) {
- newstr = malloc(size + 1);
- strncpy(newstr, val, size);
+ newstr = (char *)malloc(size + 1);
+ strlcpy(newstr, val, size + 1);
return newstr;
} else {
return 0;
* non-whitespace characters, or enclosed in quotes.
*/
-static char *getToken(char *line, char **begin, int *len)
+static const char *getToken(const char *line, const char **begin, int *len)
{
if (*line == '\"') {
*begin = ++line;
return line;
}
-BOOL getValueForBootKey(char *line, char *match, char **matchval, int *len)
+BOOL getValueForBootKey(const char *line, const char *match, const char **matchval, int *len)
{
- char *key, *value;
+ const char *key, *value;
int key_len, value_len;
+ BOOL retval = NO;
while (*line) {
/* look for keyword or argument */
&& strncmp(match, key, key_len) == 0) {
*matchval = value;
*len = value_len;
- return YES;
+ retval = YES;
+ /* Continue to look for this key; last one wins. */
}
}
- return NO;
+ return retval;
}
+/* Returns TRUE if a value was found, FALSE otherwise.
+ * The boolean value of the key is stored in 'val'.
+ */
BOOL getBoolForKey(
- char *key
+ const char *key,
+ BOOL *result_val
)
{
- char *val;
+ const char *key_val;
int size;
- if (getValueForKey(key, &val, &size) && (size >= 1) &&
- val[0] == 'Y' || val[0] == 'y')
- return YES;
+ if (getValueForKey(key, &key_val, &size)) {
+ if ( (size >= 1) && (key_val[0] == 'Y' || key_val[0] == 'y') ) {
+ *result_val = YES;
+ } else {
+ *result_val = NO;
+ }
+ return YES;
+ }
return NO;
}
BOOL getIntForKey(
- char *key,
+ const char *key,
int *value
)
{
- char *val;
+ const char *val;
int size, sum;
if (getValueForKey(key, &val, &size)) {
}
BOOL getValueForKey(
- char *key,
- char **val,
+ const char *key,
+ const char **val,
int *size
)
{
- if (getValueForBootKey(kernBootStruct->bootString, key, val, size))
+ if (getValueForBootKey(bootArgs->bootString, key, val, size))
return YES;
- else if (getValueForStringTableKey(kernBootStruct->config, key, val, size))
+ else if (getValueForConfigTableKey(bootArgs->config, key, val, size))
return YES;
return NO;
}
-#if 0
-#define LOCALIZABLE_PATH \
- "%s/%s.config/%s.lproj/%s.strings"
-char *
-loadLocalizableStrings(
- char *name,
- char *tableName
-)
-{
- char buf[256], *config;
- register int count, fd = -1;
- char *device_dir = usrDevices();
-
- sprintf(buf, LOCALIZABLE_PATH, device_dir, name,
- Language, tableName);
- if ((fd = open(buf, 0)) < 0) {
- sprintf(buf, LOCALIZABLE_PATH, device_dir, name,
- "English", tableName);
- if ((fd = open(buf,0)) < 0) {
- return 0;
- }
- }
- count = file_size(fd);
- config = malloc(count);
- count = read(fd, config, count);
- close(fd);
- if (count <= 0) {
- free(config);
- return 0;
- }
- return config;
-}
-#endif
-
-#if 0 // XXX
-char *
-bundleLongName(
- char *bundleName,
- char *tableName
-)
-{
- char *table, *name, *version, *newName;
- char *path = malloc(256);
-
-#define LONG_NAME_FORMAT "%s (v%s)"
- sprintf(path, "%s/%s.config/%s.table",
- usrDevices(), bundleName, tableName ? tableName : "Default");
- if (loadConfigFile(path, &table, YES) == 0) {
- version = newStringForStringTableKey(table, "Version");
- free(table);
- } else {
- version = newString("0.0");
- }
- table = loadLocalizableStrings(bundleName,
- tableName ? tableName : "Localizable");
- if (table) {
- name = newStringForStringTableKey(table, "Long Name");
- free(table);
- } else {
- name = newString(bundleName);
- }
- newName = malloc(strlen(name)+strlen(version)+strlen(LONG_NAME_FORMAT));
- sprintf(newName, LONG_NAME_FORMAT, name, version);
- free(name); free(version);
- return newName;
-}
-#endif
-
int sysConfigValid;
-void
-addConfig(
- char *config
-)
-{
- char *configPtr = kernBootStruct->configEnd;
- int len = strlen(config);
-
- if ((configPtr - kernBootStruct->config) > CONFIG_SIZE) {
- error("No room in memory for config files\n");
- return;
- }
- strcpy(configPtr, config);
- configPtr += (len + 1);
- *configPtr = 0;
- kernBootStruct->configEnd = configPtr;
-}
-
#define TABLE_EXPAND_SIZE 192
/*
* Allocates an extra number of bytes for table expansion.
*/
int
-loadConfigFile( char *configFile, char **table, BOOL allocTable)
+loadConfigFile(const char *configFile)
{
- char *configPtr = kernBootStruct->configEnd;
+ char *configPtr = bootArgs->config;
int fd, count;
/* Read config file into memory */
if ((fd = open(configFile, 0)) >= 0)
{
- if (allocTable) {
- configPtr = malloc(file_size(fd)+2+TABLE_EXPAND_SIZE);
- } else {
- if ((configPtr - kernBootStruct->config) > CONFIG_SIZE) {
- error("No room in memory for config files\n");
- close(fd);
- return -1;
- }
- verbose("Reading configuration file '%s'.\n",configFile);
- }
- if (table) *table = configPtr;
+ if ((configPtr - bootArgs->config) > CONFIG_SIZE) {
+ error("No room in memory for config files\n");
+ close(fd);
+ return -1;
+ }
+ verbose("Reading configuration file '%s'.\n",configFile);
+
count = read(fd, configPtr, IO_CONFIG_DATA_SIZE);
close(fd);
configPtr += count;
*configPtr++ = 0;
*configPtr = 0;
- if (!allocTable)
- kernBootStruct->configEnd = configPtr;
+
+ bootArgs->configEnd = configPtr;
return 0;
} else {
}
}
-/* Returns 0 if requested config files were loaded,
- * 1 if default files were loaded,
- * -1 if no files were loaded.
- * Prints error message if files cannot be loaded.
- */
-
-int
-loadConfigDir(
- char *bundleName, // bundle directory name (e.g. "System")
- BOOL useDefault, // use Default.table instead of instance tables
- char **table, // returns pointer to config table
- BOOL allocTable // malloc the table and return in *table
-)
+#define LP '('
+#define RP ')'
+
+#define SYSTEM_CONFIG_DIR "/Library/Preferences/SystemConfiguration"
+#define SYSTEM_CONFIG_FILE "/com.apple.Boot.plist"
+#define LRE_CONFIG_FILE "/com.apple.lre.Boot.plist"
+#define SYSTEM_CONFIG_PATH SYSTEM_CONFIG_DIR SYSTEM_CONFIG_FILE
+#define CONFIG_EXT ".plist"
+
+#if UNUSED
+void
+printSystemConfig(void)
{
- char *buf;
- int i, max, ret;
- char *device_dir = usrDevices();
+ char *p1 = bootArgs->config;
+ char *p2 = p1, tmp;
+
+ while (*p1 != '\0') {
+ while (*p2 != '\0' && *p2 != '\n') p2++;
+ tmp = *p2;
+ *p2 = '\0';
+ printf("%s\n", p1);
+ *p2 = tmp;
+ if (tmp == '\0') break;
+ p1 = ++p2;
+ }
+}
+#endif
+
+//==========================================================================
+// ParseXMLFile
+// Modifies the input buffer.
+// Expects to see one dictionary in the XML file.
+// Puts the first dictionary it finds in the
+// tag pointer and returns 0, or returns -1 if not found
+// (and does not modify dict pointer).
+// Prints an error message if there is a parsing error.
+//
+static long
+ParseXMLFile( char * buffer, TagPtr * dict )
+{
+ long length, pos;
+ TagPtr tag;
+ pos = 0;
+ char *configBuffer;
+
+ configBuffer = malloc(strlen(buffer)+1);
+ strcpy(configBuffer, buffer);
+
+ while (1)
+ {
+ length = XMLParseNextTag(configBuffer + pos, &tag);
+ if (length == -1) break;
- buf = malloc(256);
- ret = 0;
+ pos += length;
- // load up to 99 instance tables
- if (allocTable)
- max = 1;
- else
- max = 99;
- for (i=0; i < max; i++) {
- sprintf(buf, "%s/%s.config/Instance%d.table",
- device_dir,
- bundleName, i);
- if (useDefault || (loadConfigFile(buf, table, allocTable) != 0)) {
- if (i == 0) {
- // couldn't load first instance table;
- // try the default table
- sprintf(buf, "%s/%s.config/%s",
- device_dir,
- bundleName,
- IO_DEFAULT_TABLE_FILENAME);
- if (loadConfigFile(buf, table, allocTable) == 0) {
- ret = 1;
- } else {
- if (!allocTable)
- error("Config file \"%s\" not found\n", buf);
- ret = -1;
- }
- }
- // we must be done.
- break;
- }
+ if (tag == 0) continue;
+ if (tag->type == kTagTypeDict) break;
+
+ XMLFreeTag(tag);
}
- free(buf);
- return ret;
+ free(configBuffer);
+ if (length < 0) {
+ error ("Error parsing plist file");
+ return -1;
+ }
+ *dict = tag;
+ return 0;
}
-
-#define USR_SYSTEM_CONFIG \
- USR_DEVICES "/System.config"
-#define USR_SYSTEM_DEFAULT_FILE \
- USR_SYSTEM_CONFIG "/Default.table"
-#define ARCH_SYSTEM_CONFIG \
- ARCH_DEVICES "/System.config"
-#define ARCH_SYSTEM_DEFAULT_FILE \
- ARCH_SYSTEM_CONFIG "/Default.table"
-#define SYSTEM_CONFIG "System"
-#define LP '('
-#define RP ')'
-
-static int sysconfig_dev;
-
/* Returns 0 if requested config files were loaded,
* 1 if default files were loaded,
* -1 if no files were loaded.
*/
int
loadSystemConfig(
- char *which,
+ const char *which,
int size
)
{
- char *buf, *bp, *cp;
+ char *buf, *bp;
+ const char *cp;
int ret, len, doDefault=0;
- char *device_dir = usrDevices();
-
-#if 0
- printf("In Load system config which=%d ; size=%d\n", which, size);
- //sleep(1);
-#endif 1
- buf = bp = malloc(256);
- if (which && size)
- {
-#if 0
- printf("In Load system config alt\n");
- //sleep(1);
-#endif 1
- for(cp = which, len = size; len && *cp && *cp != LP; cp++, len--) ;
- if (*cp == LP) {
- while (len-- && *cp && *cp++ != RP) ;
- /* cp now points past device */
- strncpy(buf,which,cp - which);
- bp += cp - which;
- } else {
- cp = which;
- len = size;
- }
- if (*cp != '/') {
- strcpy(bp, device_dir);
- strcat(bp, "/System.config/");
- strncat(bp, cp, len);
- if (strncmp(cp + len - strlen(IO_TABLE_EXTENSION),
- IO_TABLE_EXTENSION, strlen(IO_TABLE_EXTENSION)) != 0)
- strcat(bp, IO_TABLE_EXTENSION);
- } else {
- strncpy(bp, cp, len);
- bp[size] = '\0';
- }
- if ((strcmp(bp, USR_SYSTEM_DEFAULT_FILE) == 0) ||
- (strcmp(bp, ARCH_SYSTEM_DEFAULT_FILE) == 0))
- doDefault = 1;
- ret = loadConfigFile(bp = buf, 0, 0);
+
+ buf = bp = malloc(512);
+ if (which && size) {
+ for(cp = which, len = size; len && *cp && *cp != LP; cp++, len--) ;
+ if (*cp == LP) {
+ while (len-- && *cp && *cp++ != RP) ;
+ /* cp now points past device */
+ strlcpy(buf,which,cp - which + 1);
+ bp += cp - which;
+ } else {
+ cp = which;
+ len = size;
+ }
+ if (*cp != '/') {
+ strcpy(bp, systemConfigDir());
+ strcat(bp, "/");
+ strncat(bp, cp, len);
+ if (strncmp(cp + len - strlen(CONFIG_EXT),
+ CONFIG_EXT, strlen(CONFIG_EXT)) != 0)
+ strcat(bp, CONFIG_EXT);
+ } else {
+ strlcpy(bp, cp, len + 1);
+ }
+ if ((strcmp(bp, SYSTEM_CONFIG_PATH) == 0)) {
+ doDefault = 1;
+ }
+ bp = buf;
+ ret = loadConfigFile(bp);
} else {
-#if 0
- printf("In default SYSTEM_CONFIG LOAD\n");
- //sleep(1);
-#endif 1
- ret = loadConfigDir((bp = SYSTEM_CONFIG), 0, 0, 0);
-#if 0
- printf("come back from SYSTEM_CONFIG loadConfigDir\n");
- //sleep(1);
-#endif 1
- }
- sysconfig_dev = currentdev();
+ /* First try LRE file */
+ strcpy(bp, systemConfigDir());
+ strcat(bp, LRE_CONFIG_FILE);
+ ret = loadConfigFile(bp);
+
+ if (ret < 0) {
+ /* If not found, try default file */
+ strcpy(bp, systemConfigDir());
+ strcat(bp, SYSTEM_CONFIG_FILE);
+ ret = loadConfigFile(bp);
+ }
+ }
if (ret < 0) {
error("System config file '%s' not found\n", bp);
- } else
+ sleep(1);
+ } else {
sysConfigValid = 1;
+ // Check for XML file;
+ // if not XML, gConfigDict will remain 0.
+ ParseXMLFile(bootArgs->config, &gConfigDict);
+ }
free(buf);
return (ret < 0 ? ret : doDefault);
}
-#ifdef DISABLED
-int
-loadOtherConfigs(
- int useDefault
-)
-{
- char *val, *table;
- char *path = malloc(256);
- char *hintTable;
- char *installVersion = NULL, *thisVersion;
- char *longName, *tableName;
- int count;
- char *string;
- int ret;
- int old_dev = currentdev();
-
- if (sysconfig_dev)
- switchdev(sysconfig_dev);
- if (getValueForKey( "Boot Drivers", &val, &count))
- {
-#if 0
- printf("Loading Boot Drivers\n");
- sleep(1);
-#endif 1
- while (string = newStringFromList(&val, &count)) {
- /* Check installation hints... */
- sprintf(path, "%s/System.config/" INSTALL_HINTS
- "/%s.table", usrDevices(), string);
-
- if (getBoolForKey("Ignore Hints") == NO &&
- loadConfigFile(path, &hintTable, YES) == 0) {
- installVersion = newStringForStringTableKey(
- hintTable, "Version");
- longName = newStringForStringTableKey(
- hintTable, "Long Name");
- tableName = newStringForStringTableKey(
- hintTable, "Default Table");
- free(hintTable);
- } else {
- installVersion = longName = tableName = NULL;
- }
-
- ret = loadConfigDir(string, useDefault, &table, YES);
- if (ret >= 0) {
- thisVersion = newStringForStringTableKey(
- table, "Version");
- if (installVersion && thisVersion &&
- (strcmp(thisVersion, installVersion) != 0)) {
- /* Versions do not match */
- driverIsMissing(string, installVersion, longName,
- tableName, DRIVER_VERSION_MISMATCH);
- } else {
- struct driver_load_data dl;
-
- dl.name = string;
- if ((openDriverReloc(&dl)) >= 0) {
- verbose("Loading binary for %s device driver.\n",string);
- if (loadDriver(&dl) < 0) /// need to stop if error
- error("Error loading %s device driver.\n",string);
-#if 0
- printf("Calling link driver for %s\n", string);
-#endif 1
- if (linkDriver(&dl) < 0)
- error("Error linking %s device Driver.\n",string);
- }
- loadConfigDir(string, useDefault, NULL, NO);
- driverWasLoaded(string, table, NULL);
- free(table);
- free(string);
- free(installVersion); free(longName);
- free(tableName);
- }
- free(thisVersion);
- } else {
- /* driver not found */
- driverIsMissing(string, installVersion, longName,
- tableName, DRIVER_NOT_FOUND);
- }
-#if 0
- if (ret == 1)
- useDefault = 1; // use defaults from now on
-#endif
- }
- } else {
- error("Warning: No Boot drivers specified in system config.\n");
- }
- kernBootStruct->first_addr0 =
- (int)kernBootStruct->configEnd + 1024;
- free(path);
- switchdev(old_dev);
- return 0;
+char * newString(const char * oldString)
+{
+ if ( oldString )
+ return strcpy(malloc(strlen(oldString)+1), oldString);
+ else
+ return NULL;
}
-#endif /* DISABLED */