]>
git.saurik.com Git - apple/boot.git/blob - i386/libsaio/stringTable.c
2 * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 1999-2003 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 2.0 (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.
29 #include "bootstruct.h"
31 #include "stringConstants.h"
32 #include "legacy/configTablePrivate.h"
35 extern char *Language
;
36 extern char *LoadableFamilies
;
38 static TagPtr gConfigDict
;
40 static void eatThru(char val
, const char **table_p
);
42 static inline int isspace(char c
)
44 return (c
== ' ' || c
== '\t');
48 * Compare a string to a key with quoted characters
51 keyncmp(const char *str
, const char *key
, int n
)
70 } else if (c
== '\"') {
71 /* Premature end of key */
81 static void eatThru(char val
, const char **table_p
)
83 register const char *table
= *table_p
;
84 register BOOL found
= NO
;
86 while (*table
&& !found
)
88 if (*table
== '\\') table
+= 2;
91 if (*table
== val
) found
= YES
;
100 /* Remove key and its associated value from the table. */
103 removeKeyFromTable(const char *key
, char *table
)
111 buf
= (char *)malloc(len
+ 3);
113 sprintf(buf
, "\"%s\"", key
);
117 if(strncmp(buf
, tab
, len
) == 0) {
120 while((c
= *(tab
+ len
)) != ';') {
128 if(*(tab
+ len
) == '\n') len
++;
137 if(len
== -1) return NO
;
139 while((*tab
= *(tab
+ len
))) {
152 char *begin
= *list
, *end
;
157 while (*begin
&& newsize
&& isspace(*begin
)) {
162 while (*end
&& newsize
&& !isspace(*end
)) {
168 bufsize
= end
- begin
+ 1;
169 newstr
= malloc(bufsize
);
170 strlcpy(newstr
, begin
, bufsize
);
179 * compress == compress escaped characters to one character
181 int stringLength(const char *table
, int compress
)
190 ret
+= 1 + (compress
? 0 : 1);
194 if (*table
== '\"') return ret
;
202 BOOL
getValueForConfigTableKey(const char *table
, const char *key
, const char **val
, int *size
)
205 const char *tableKey
;
207 if (gConfigDict
!= 0 ) {
208 /* Look up key in XML dictionary */
210 value
= XMLGetProperty(gConfigDict
, key
);
212 if (value
->type
!= kTagTypeString
) {
213 error("Non-string tag '%s' found in config file\n",
217 *val
= value
->string
;
218 *size
= strlen(value
->string
);
222 /* Legacy plist-style table */
225 eatThru('\"',&table
);
227 keyLength
= strlen(key
);
229 (stringLength(table
,1) == keyLength
) &&
230 (keyncmp(key
, table
, keyLength
) == 0))
234 /* found the key; now look for either
242 } else if (c
== '=' || c
== ';') {
249 eatThru('\"',&table
);
252 *size
= stringLength(table
,0);
267 * Returns a new malloc'ed string if one is found
268 * in the string table matching 'key'. Also translates
269 * \n escapes in the string.
271 char *newStringForStringTableKey(
280 if (getValueForConfigTableKey(table
, key
, &val
, &size
)) {
281 newstr
= (char *)malloc(size
+1);
282 for (p
= newstr
; size
; size
--, p
++, val
++) {
283 if ((*p
= *val
) == '\\') {
311 newStringForKey(char *key
)
317 if (getValueForKey(key
, &val
, &size
) && size
) {
318 newstr
= (char *)malloc(size
+ 1);
319 strlcpy(newstr
, val
, size
+ 1);
326 /* parse a command line
327 * in the form: [<argument> ...] [<option>=<value> ...]
328 * both <option> and <value> must be either composed of
329 * non-whitespace characters, or enclosed in quotes.
332 static const char *getToken(const char *line
, const char **begin
, int *len
)
336 while (*line
&& *line
!= '\"')
338 *len
= line
++ - *begin
;
341 while (*line
&& !isspace(*line
) && *line
!= '=')
343 *len
= line
- *begin
;
348 BOOL
getValueForBootKey(const char *line
, const char *match
, const char **matchval
, int *len
)
350 const char *key
, *value
;
351 int key_len
, value_len
;
355 /* look for keyword or argument */
356 while (isspace(*line
)) line
++;
358 /* now look for '=' or whitespace */
359 line
= getToken(line
, &key
, &key_len
);
360 /* line now points to '=' or space */
361 if (*line
&& !isspace(*line
)) {
362 line
= getToken(++line
, &value
, &value_len
);
367 if ((strlen(match
) == key_len
)
368 && strncmp(match
, key
, key_len
) == 0) {
372 /* Continue to look for this key; last one wins. */
378 /* Returns TRUE if a value was found, FALSE otherwise.
379 * The boolean value of the key is stored in 'val'.
389 if (getValueForKey(key
, &key_val
, &size
)) {
390 if ( (size
>= 1) && (key_val
[0] == 'Y' || key_val
[0] == 'y') ) {
409 if (getValueForKey(key
, &val
, &size
)) {
414 for (sum
= 0; size
> 0; size
--) {
415 if (*val
< '0' || *val
> '9') return NO
;
416 sum
= (sum
* 10) + (*val
++ - '0');
418 if (negative
) sum
= -sum
;
431 if (getValueForBootKey(bootArgs
->CommandLine
, key
, val
, size
))
433 else if (getValueForConfigTableKey(bootInfo
->config
, key
, val
, size
))
441 #define TABLE_EXPAND_SIZE 192
444 * Returns 0 if file loaded OK,
445 * -1 if file was not loaded
446 * Does not print error messages.
447 * Returns pointer to table in memory in *table.
448 * Allocates an extra number of bytes for table expansion.
451 loadConfigFile(const char *configFile
)
453 char *configPtr
= bootInfo
->config
;
456 /* Read config file into memory */
457 if ((fd
= open(configFile
, 0)) >= 0)
459 if ((configPtr
- bootInfo
->config
) > CONFIG_SIZE
) {
460 error("No room in memory for config files\n");
464 verbose("Reading configuration file '%s'.\n",configFile
);
466 count
= read(fd
, configPtr
, IO_CONFIG_DATA_SIZE
);
473 bootInfo
->configEnd
= configPtr
;
484 #define SYSTEM_CONFIG_DIR "/Library/Preferences/SystemConfiguration"
485 #define SYSTEM_CONFIG_FILE "/com.apple.Boot.plist"
486 #define LRE_CONFIG_FILE "/com.apple.lre.Boot.plist"
487 #define SYSTEM_CONFIG_PATH SYSTEM_CONFIG_DIR SYSTEM_CONFIG_FILE
488 #define CONFIG_EXT ".plist"
492 printSystemConfig(void)
494 char *p1
= bootInfo
->config
;
497 while (*p1
!= '\0') {
498 while (*p2
!= '\0' && *p2
!= '\n') p2
++;
503 if (tmp
== '\0') break;
509 //==========================================================================
511 // Modifies the input buffer.
512 // Expects to see one dictionary in the XML file.
513 // Puts the first dictionary it finds in the
514 // tag pointer and returns 0, or returns -1 if not found
515 // (and does not modify dict pointer).
516 // Prints an error message if there is a parsing error.
519 ParseXMLFile( char * buffer
, TagPtr
* dict
)
526 configBuffer
= malloc(strlen(buffer
)+1);
527 strcpy(configBuffer
, buffer
);
531 length
= XMLParseNextTag(configBuffer
+ pos
, &tag
);
532 if (length
== -1) break;
536 if (tag
== 0) continue;
537 if (tag
->type
== kTagTypeDict
) break;
543 error ("Error parsing plist file");
550 /* Returns 0 if requested config files were loaded,
551 * 1 if default files were loaded,
552 * -1 if no files were loaded.
553 * Prints error message if files cannot be loaded.
563 int ret
, len
, doDefault
=0;
565 buf
= bp
= malloc(512);
567 for(cp
= which
, len
= size
; len
&& *cp
&& *cp
!= LP
; cp
++, len
--) ;
569 while (len
-- && *cp
&& *cp
++ != RP
) ;
570 /* cp now points past device */
571 strlcpy(buf
,which
,cp
- which
+ 1);
578 strcpy(bp
, systemConfigDir());
580 strncat(bp
, cp
, len
);
581 if (strncmp(cp
+ len
- strlen(CONFIG_EXT
),
582 CONFIG_EXT
, strlen(CONFIG_EXT
)) != 0)
583 strcat(bp
, CONFIG_EXT
);
585 strlcpy(bp
, cp
, len
+ 1);
587 if ((strcmp(bp
, SYSTEM_CONFIG_PATH
) == 0)) {
591 ret
= loadConfigFile(bp
);
593 /* First try LRE file */
594 strcpy(bp
, systemConfigDir());
595 strcat(bp
, LRE_CONFIG_FILE
);
596 ret
= loadConfigFile(bp
);
599 /* If not found, try default file */
600 strcpy(bp
, systemConfigDir());
601 strcat(bp
, SYSTEM_CONFIG_FILE
);
602 ret
= loadConfigFile(bp
);
606 error("System config file '%s' not found\n", bp
);
610 // Check for XML file;
611 // if not XML, gConfigDict will remain 0.
612 ParseXMLFile(bootInfo
->config
, &gConfigDict
);
615 return (ret
< 0 ? ret
: doDefault
);
619 char * newString(const char * oldString
)
622 return strcpy(malloc(strlen(oldString
)+1), oldString
);