/* * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * 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 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. * * The Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * Copyright 1993 NeXT, Inc. * All rights reserved. */ #include "bootstruct.h" #include "libsaio.h" #include "stringConstants.h" #include "legacy/configTablePrivate.h" #include "xml.h" extern char *Language; extern char *LoadableFamilies; static TagPtr gConfigDict; static void eatThru(char val, const char **table_p); static inline int isspace(char c) { return (c == ' ' || c == '\t'); } /* * Compare a string to a key with quoted characters */ static inline int keyncmp(const char *str, const char *key, int n) { int c; while (n--) { c = *key++; if (c == '\\') { switch(c = *key++) { case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; default: break; } } else if (c == '\"') { /* Premature end of key */ return 1; } if (c != *str++) { return 1; } } return 0; } static void eatThru(char val, const char **table_p) { register const char *table = *table_p; register BOOL found = NO; while (*table && !found) { if (*table == '\\') table += 2; else { if (*table == val) found = YES; table++; } } *table_p = table; } #if UNUSED /* Remove key and its associated value from the table. */ BOOL removeKeyFromTable(const char *key, char *table) { register int len; register char *tab; char *buf; len = strlen(key); tab = (char *)table; buf = (char *)malloc(len + 3); sprintf(buf, "\"%s\"", key); len = strlen(buf); while(*tab) { if(strncmp(buf, tab, len) == 0) { char c; while((c = *(tab + len)) != ';') { if(c == 0) { len = -1; goto out; } len++; } len++; if(*(tab + len) == '\n') len++; goto out; } tab++; } len = -1; out: free(buf); if(len == -1) return NO; while((*tab = *(tab + len))) { tab++; } return YES; } char * newStringFromList( char **list, int *size ) { char *begin = *list, *end; char *newstr; int newsize = *size; int bufsize; while (*begin && newsize && isspace(*begin)) { begin++; newsize--; } end = begin; while (*end && newsize && !isspace(*end)) { end++; newsize--; } if (begin == end) return 0; 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(const char *table, int compress) { int ret = 0; while (*table) { if (*table == '\\') { table += 2; ret += 1 + (compress ? 0 : 1); } else { if (*table == '\"') return ret; ret++; table++; } } return ret; } BOOL getValueForConfigTableKey(const char *table, const char *key, const char **val, int *size) { int keyLength; 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) != 0) { ++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 * in the string table matching 'key'. Also translates * \n escapes in the string. */ char *newStringForStringTableKey( char *table, char *key ) { const char *val; char *newstr, *p; int size; if (getValueForConfigTableKey(table, key, &val, &size)) { newstr = (char *)malloc(size+1); for (p = newstr; size; size--, p++, val++) { if ((*p = *val) == '\\') { switch (*++val) { case 'r': *p = '\r'; break; case 'n': *p = '\n'; break; case 't': *p = '\t'; break; default: *p = *val; break; } size--; } } *p = '\0'; return newstr; } else { return 0; } } #endif char * newStringForKey(char *key) { const char *val; char *newstr; int size; if (getValueForKey(key, &val, &size) && size) { newstr = (char *)malloc(size + 1); strlcpy(newstr, val, size + 1); return newstr; } else { return 0; } } /* parse a command line * in the form: [ ...] [