X-Git-Url: https://git.saurik.com/apple/boot.git/blobdiff_plain/47b0a8bde7689760b67e872ba41bf4187ed315e5..57c72a9a9f2a263d364c2df1178760bd057c390f:/i386/libsaio/stringTable.c diff --git a/i386/libsaio/stringTable.c b/i386/libsaio/stringTable.c index 8fafe9b..65ef09e 100644 --- a/i386/libsaio/stringTable.c +++ b/i386/libsaio/stringTable.c @@ -1,12 +1,12 @@ /* - * 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. @@ -26,16 +26,18 @@ * 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) { @@ -46,7 +48,7 @@ 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--) { @@ -76,9 +78,9 @@ keyncmp(char *str, char *key, int 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) @@ -93,6 +95,8 @@ static void eatThru(char val, char **table_p) *table_p = table; } +#if UNUSED + /* Remove key and its associated value from the table. */ BOOL @@ -148,6 +152,7 @@ newStringFromList( char *begin = *list, *end; char *newstr; int newsize = *size; + int bufsize; while (*begin && newsize && isspace(*begin)) { begin++; @@ -160,17 +165,20 @@ newStringFromList( } 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; @@ -191,53 +199,69 @@ int stringLength(char *table, int compress) 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 @@ -249,11 +273,12 @@ char *newStringForStringTableKey( 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) { @@ -280,15 +305,18 @@ char *newStringForStringTableKey( } } +#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; @@ -301,7 +329,7 @@ newStringForKey(char *key) * 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; @@ -317,10 +345,11 @@ static char *getToken(char *line, char **begin, int *len) 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 */ @@ -339,31 +368,41 @@ BOOL getValueForBootKey(char *line, char *match, char **matchval, int *len) && 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)) { @@ -377,107 +416,21 @@ BOOL getIntForKey( } 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 /* @@ -488,33 +441,29 @@ addConfig( * 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 { @@ -522,75 +471,75 @@ loadConfigFile( char *configFile, char **table, BOOL allocTable) } } -/* 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. @@ -598,161 +547,72 @@ static int sysconfig_dev; */ 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 */