]>
git.saurik.com Git - apple/boot.git/blob - i386/libsaio/stringTable.c
65ef09ec8a1f73cd6422e1055a5f1c87ec48d017
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') ) {
408 if (getValueForKey(key
, &val
, &size
)) {
409 for (sum
= 0; size
> 0; size
--) {
410 sum
= (sum
* 10) + (*val
++ - '0');
424 if (getValueForBootKey(bootArgs
->bootString
, key
, val
, size
))
426 else if (getValueForConfigTableKey(bootArgs
->config
, key
, val
, size
))
434 #define TABLE_EXPAND_SIZE 192
437 * Returns 0 if file loaded OK,
438 * -1 if file was not loaded
439 * Does not print error messages.
440 * Returns pointer to table in memory in *table.
441 * Allocates an extra number of bytes for table expansion.
444 loadConfigFile(const char *configFile
)
446 char *configPtr
= bootArgs
->config
;
449 /* Read config file into memory */
450 if ((fd
= open(configFile
, 0)) >= 0)
452 if ((configPtr
- bootArgs
->config
) > CONFIG_SIZE
) {
453 error("No room in memory for config files\n");
457 verbose("Reading configuration file '%s'.\n",configFile
);
459 count
= read(fd
, configPtr
, IO_CONFIG_DATA_SIZE
);
466 bootArgs
->configEnd
= configPtr
;
477 #define SYSTEM_CONFIG_DIR "/Library/Preferences/SystemConfiguration"
478 #define SYSTEM_CONFIG_FILE "/com.apple.Boot.plist"
479 #define LRE_CONFIG_FILE "/com.apple.lre.Boot.plist"
480 #define SYSTEM_CONFIG_PATH SYSTEM_CONFIG_DIR SYSTEM_CONFIG_FILE
481 #define CONFIG_EXT ".plist"
485 printSystemConfig(void)
487 char *p1
= bootArgs
->config
;
490 while (*p1
!= '\0') {
491 while (*p2
!= '\0' && *p2
!= '\n') p2
++;
496 if (tmp
== '\0') break;
502 //==========================================================================
504 // Modifies the input buffer.
505 // Expects to see one dictionary in the XML file.
506 // Puts the first dictionary it finds in the
507 // tag pointer and returns 0, or returns -1 if not found
508 // (and does not modify dict pointer).
509 // Prints an error message if there is a parsing error.
512 ParseXMLFile( char * buffer
, TagPtr
* dict
)
519 configBuffer
= malloc(strlen(buffer
)+1);
520 strcpy(configBuffer
, buffer
);
524 length
= XMLParseNextTag(configBuffer
+ pos
, &tag
);
525 if (length
== -1) break;
529 if (tag
== 0) continue;
530 if (tag
->type
== kTagTypeDict
) break;
536 error ("Error parsing plist file");
543 /* Returns 0 if requested config files were loaded,
544 * 1 if default files were loaded,
545 * -1 if no files were loaded.
546 * Prints error message if files cannot be loaded.
556 int ret
, len
, doDefault
=0;
558 buf
= bp
= malloc(512);
560 for(cp
= which
, len
= size
; len
&& *cp
&& *cp
!= LP
; cp
++, len
--) ;
562 while (len
-- && *cp
&& *cp
++ != RP
) ;
563 /* cp now points past device */
564 strlcpy(buf
,which
,cp
- which
+ 1);
571 strcpy(bp
, systemConfigDir());
573 strncat(bp
, cp
, len
);
574 if (strncmp(cp
+ len
- strlen(CONFIG_EXT
),
575 CONFIG_EXT
, strlen(CONFIG_EXT
)) != 0)
576 strcat(bp
, CONFIG_EXT
);
578 strlcpy(bp
, cp
, len
+ 1);
580 if ((strcmp(bp
, SYSTEM_CONFIG_PATH
) == 0)) {
584 ret
= loadConfigFile(bp
);
586 /* First try LRE file */
587 strcpy(bp
, systemConfigDir());
588 strcat(bp
, LRE_CONFIG_FILE
);
589 ret
= loadConfigFile(bp
);
592 /* If not found, try default file */
593 strcpy(bp
, systemConfigDir());
594 strcat(bp
, SYSTEM_CONFIG_FILE
);
595 ret
= loadConfigFile(bp
);
599 error("System config file '%s' not found\n", bp
);
603 // Check for XML file;
604 // if not XML, gConfigDict will remain 0.
605 ParseXMLFile(bootArgs
->config
, &gConfigDict
);
608 return (ret
< 0 ? ret
: doDefault
);
612 char * newString(const char * oldString
)
615 return strcpy(malloc(strlen(oldString
)+1), oldString
);