Chameleon

Chameleon Svn Source Tree

Root/branches/meklortOld/i386/libsaio/stringTable.c

Source at commit 1146 created 12 years 10 months ago.
By azimutz, Sync with trunk (r1145). Add nVidia dev id's, 0DF4 for "GeForce GT 450M" (issue 99) and 1251 for "GeForce GTX 560M" (thanks to oSxFr33k for testing).
1/*
2 * Copyright (c) 1999-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
12 * this file.
13 *
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
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/*
25 * Copyright 1993 NeXT, Inc.
26 * All rights reserved.
27 */
28
29#include "bootstruct.h"
30#include "libsaio.h"
31#include "xml.h"
32
33extern char *Language;
34extern char *LoadableFamilies;
35
36bool sysConfigValid;
37
38/*
39 * Compare a string to a key with quoted characters
40 */
41static inline int
42keyncmp(const char *str, const char *key, int n)
43{
44 int c;
45 while (n--) {
46c = *key++;
47if (c == '\\') {
48 switch(c = *key++) {
49 case 'n':
50c = '\n';
51break;
52 case 'r':
53c = '\r';
54break;
55 case 't':
56c = '\t';
57break;
58 default:
59break;
60 }
61} else if (c == '\"') {
62 /* Premature end of key */
63 return 1;
64}
65if (c != *str++) {
66 return 1;
67}
68 }
69 return 0;
70}
71
72#if UNUSED
73
74static void eatThru(char val, const char **table_p)
75{
76register const char *table = *table_p;
77register bool found = false;
78
79while (*table && !found)
80{
81if (*table == '\\') table += 2;
82else
83{
84if (*table == val) found = true;
85table++;
86}
87}
88*table_p = table;
89}
90
91/* Remove key and its associated value from the table. */
92
93bool
94removeKeyFromTable(const char *key, char *table)
95{
96 register int len;
97 register char *tab;
98 char *buf;
99
100 len = strlen(key);
101 tab = (char *)table;
102 buf = (char *)malloc(len + 3);
103
104 sprintf(buf, "\"%s\"", key);
105 len = strlen(buf);
106
107 while(*tab) {
108 if(strncmp(buf, tab, len) == 0) {
109 char c;
110
111 while((c = *(tab + len)) != ';') {
112 if(c == 0) {
113 len = -1;
114 goto out;
115 }
116 len++;
117 }
118 len++;
119 if(*(tab + len) == '\n') len++;
120 goto out;
121 }
122 tab++;
123 }
124 len = -1;
125out:
126 free(buf);
127
128 if(len == -1) return false;
129
130 while((*tab = *(tab + len))) {
131 tab++;
132 }
133
134 return true;
135}
136
137char *
138newStringFromList(
139 char **list,
140 int *size
141)
142{
143 char *begin = *list, *end;
144 char *newstr;
145 int newsize = *size;
146 int bufsize;
147
148 while (*begin && newsize && isspace(*begin)) {
149begin++;
150newsize--;
151 }
152 end = begin;
153 while (*end && newsize && !isspace(*end)) {
154end++;
155newsize--;
156 }
157 if (begin == end)
158return 0;
159 bufsize = end - begin + 1;
160 newstr = malloc(bufsize);
161 strlcpy(newstr, begin, bufsize);
162 *list = end;
163 *size = newsize;
164 return newstr;
165}
166
167#endif
168
169/*
170 * compress == compress escaped characters to one character
171 */
172int stringLength(const char *table, int compress)
173{
174int ret = 0;
175
176while (*table)
177{
178if (*table == '\\')
179{
180table += 2;
181ret += 1 + (compress ? 0 : 1);
182}
183else
184{
185if (*table == '\"') return ret;
186ret++;
187table++;
188}
189}
190return ret;
191}
192
193
194bool getValueForConfigTableKey(config_file_t *config, const char *key, const char **val, int *size)
195{
196if (config->dictionary != 0 ) {
197// Look up key in XML dictionary
198TagPtr value;
199value = XMLGetProperty(config->dictionary, key);
200if (value != 0) {
201if (value->type != kTagTypeString) {
202error("Non-string tag '%s' found in config file\n",
203 key);
204return false;
205}
206*val = value->string;
207*size = strlen(value->string);
208return true;
209}
210} else {
211
212// Legacy plist-style table
213
214}
215
216return false;
217}
218
219#if UNUSED
220
221/*
222 * Returns a new malloc'ed string if one is found
223 * in the string table matching 'key'. Also translates
224 * \n escapes in the string.
225 */
226char *newStringForStringTableKey(
227char *table,
228char *key,
229config_file_t *config
230)
231{
232 const char *val;
233 char *newstr, *p;
234 int size;
235
236 if (getValueForConfigTableKey(config, key, &val, &size)) {
237newstr = (char *)malloc(size+1);
238for (p = newstr; size; size--, p++, val++) {
239 if ((*p = *val) == '\\') {
240switch (*++val) {
241case 'r':
242 *p = '\r';
243 break;
244case 'n':
245 *p = '\n';
246 break;
247case 't':
248 *p = '\t';
249 break;
250default:
251 *p = *val;
252 break;
253}
254size--;
255 }
256}
257*p = '\0';
258return newstr;
259 } else {
260return 0;
261 }
262}
263
264#endif
265
266char *
267newStringForKey(char *key, config_file_t *config)
268{
269 const char *val;
270 char *newstr;
271 int size;
272
273 if (getValueForKey(key, &val, &size, config) && size) {
274newstr = (char *)malloc(size + 1);
275strlcpy(newstr, val, size + 1);
276return newstr;
277 } else {
278return 0;
279 }
280}
281
282/* parse a command line
283 * in the form: [<argument> ...] [<option>=<value> ...]
284 * both <option> and <value> must be either composed of
285 * non-whitespace characters, or enclosed in quotes.
286 */
287
288static const char *getToken(const char *line, const char **begin, int *len)
289{
290 if (*line == '\"') {
291*begin = ++line;
292while (*line && *line != '\"')
293 line++;
294*len = line++ - *begin;
295 } else {
296*begin = line;
297while (*line && !isspace(*line) && *line != '=')
298 line++;
299*len = line - *begin;
300 }
301 return line;
302}
303
304bool getValueForBootKey(const char *line, const char *match, const char **matchval, int *len)
305{
306 const char *key, *value;
307 int key_len, value_len;
308 bool retval = false;
309
310 while (*line) {
311/* look for keyword or argument */
312while (isspace(*line)) line++;
313
314/* now look for '=' or whitespace */
315line = getToken(line, &key, &key_len);
316/* line now points to '=' or space */
317if (*line && !isspace(*line)) {
318 line = getToken(++line, &value, &value_len);
319} else {
320 value = line;
321 value_len = 0;
322}
323if ((strlen(match) == key_len)
324 && strncmp(match, key, key_len) == 0) {
325 *matchval = value;
326 *len = value_len;
327 retval = true;
328 /* Continue to look for this key; last one wins. */
329}
330 }
331 return retval;
332}
333
334/* Return NULL if no option has been successfully retrieved, or the string otherwise */
335const char * getStringForKey(const char * key, config_file_t *config)
336{
337 static const char* value =0;
338 int len=0;
339 if(!getValueForKey(key, &value, &len, config)) value = 0;
340 return value;
341}
342
343
344/* Returns TRUE if a value was found, FALSE otherwise.
345 * The boolean value of the key is stored in 'val'.
346 */
347
348bool getBoolForKey( const char *key, bool *result_val, config_file_t *config )
349{
350 const char *key_val;
351 int size;
352 if (getValueForKey(key, &key_val, &size, config))
353{
354 if ( (size >= 1) && (key_val[0] == 'Y' || key_val[0] == 'y') )
355{
356 *result_val = true;
357 } else
358{
359 *result_val = false;
360 }
361 return true;
362 }
363 return false;
364}
365
366bool getIntForKey( const char *key, int *value, config_file_t *config )
367{
368 const char *val;
369 int size, sum;
370 bool negative = false;
371
372 if (getValueForKey(key, &val, &size, config))
373{
374if ( size )
375{
376if (*val == '-')
377{
378negative = true;
379val++;
380size--;
381}
382
383for (sum = 0; size > 0; size--)
384{
385if (*val < '0' || *val > '9')
386return false;
387
388sum = (sum * 10) + (*val++ - '0');
389}
390
391if (negative)
392sum = -sum;
393
394*value = sum;
395return true;
396}
397}
398 return false;
399}
400
401/*
402 *
403 */
404
405bool getDimensionForKey( const char *key, unsigned int *value, config_file_t *config, unsigned int dimension_max, unsigned int object_size )
406{
407const char *val;
408
409 int size = 0;
410int sum = 0;
411
412bool negative = false;
413bool percentage = false;
414
415 if (getValueForKey(key, &val, &size, config))
416{
417if ( size )
418{
419if (*val == '-')
420{
421negative = true;
422val++;
423size--;
424}
425
426if (val[size-1] == '%')
427{
428percentage = true;
429size--;
430}
431
432// convert string to integer
433for (sum = 0; size > 0; size--)
434{
435if (*val < '0' || *val > '9')
436return false;
437
438sum = (sum * 10) + (*val++ - '0');
439}
440
441if (percentage)
442sum = ( dimension_max * sum ) / 100;
443
444// calculate offset from opposite origin
445if (negative)
446sum = ( ( dimension_max - object_size ) - sum );
447
448} else {
449
450// null value calculate center
451sum = ( dimension_max - object_size ) / 2;
452
453}
454
455*value = (uint16_t) sum;
456return true;
457}
458
459// key not found
460 return false;
461}
462
463/*
464 *get color value from plist format #RRGGBB
465 */
466
467bool getColorForKey( const char *key, unsigned int *value, config_file_t *config )
468{
469 const char *val;
470 int size;
471
472 if (getValueForKey(key, &val, &size, config))
473{
474if (*val == '#')
475{
476 val++;
477*value = strtol(val, NULL, 16);
478return true;
479 }
480 }
481 return false;
482}
483
484bool getValueForKey( const char *key, const char **val, int *size, config_file_t *config )
485{
486 const char *overrideVal;
487 int overrideSize;
488 bool override, ret;
489
490 if (getValueForBootKey(bootArgs->CommandLine, key, val, size))
491 return true;
492
493 ret = getValueForConfigTableKey(config, key, val, size);
494
495 // Try to find alternate keys in bootInfo->overrideConfig
496 // and prefer its values with the exceptions for
497 // "Kernel"="mach_kernel" and "Kernel Flags"="".
498
499 if (config->canOverride)
500 {
501 if (getValueForConfigTableKey(&bootInfo->overrideConfig, key, &overrideVal, &overrideSize))
502 {
503 override = true;
504
505 if (ret && (strcmp(key, "Kernel") == 0) && (strcmp(overrideVal, "mach_kernel") == 0))
506 override = false;
507
508 if (ret && (strcmp(key, "Kernel Flags") == 0) && (overrideSize == 0))
509 override = false;
510
511 if (override)
512 {
513 *val = overrideVal;
514 *size = overrideSize;
515 return true;
516 }
517 }
518 }
519
520 return ret;
521}
522
523
524#if UNUSED
525void
526printSystemConfig(char *p1)
527{
528 char *p2 = p1, tmp;
529
530 while (*p1 != '\0') {
531while (*p2 != '\0' && *p2 != '\n') p2++;
532tmp = *p2;
533*p2 = '\0';
534printf("%s\n", p1);
535*p2 = tmp;
536if (tmp == '\0') break;
537p1 = ++p2;
538 }
539}
540#endif
541
542//==========================================================================
543// ParseXMLFile
544// Modifies the input buffer.
545// Expects to see one dictionary in the XML file.
546// Puts the first dictionary it finds in the
547// tag pointer and returns 0, or returns -1 if not found
548// (and does not modify dict pointer).
549// Prints an error message if there is a parsing error.
550//
551int ParseXMLFile( char * buffer, TagPtr * dict )
552{
553 long length, pos;
554 TagPtr tag;
555 pos = 0;
556 char *configBuffer;
557
558 configBuffer = malloc(strlen(buffer)+1);
559 strcpy(configBuffer, buffer);
560
561 while (1)
562 {
563 length = XMLParseNextTag(configBuffer + pos, &tag);
564 if (length == -1) break;
565
566 pos += length;
567
568 if (tag == 0) continue;
569 if (tag->type == kTagTypeDict) break;
570
571 XMLFreeTag(tag);
572 }
573 free(configBuffer);
574 if (length < 0) {
575 error ("Error parsing plist file\n");
576 return -1;
577 }
578 *dict = tag;
579 return 0;
580}
581
582/* loadConfigFile
583 *
584 * Returns 0 - successful.
585 * -1 - unsuccesful.
586 */
587int loadConfigFile (const char *configFile, config_file_t *config)
588{
589int fd, count;
590
591/*if ((fd = open_bvdev("bt(0,0)", configFile, 0)) < 0) {
592return -1;
593}*/
594
595if ((fd = open(configFile, 0)) < 0) {
596return -1;
597}
598
599// read file
600count = read(fd, config->plist, IO_CONFIG_DATA_SIZE);
601close(fd);
602
603// build xml dictionary
604ParseXMLFile(config->plist, &config->dictionary);
605return 0;
606}
607
608
609/* loadSystemConfig
610 *
611 * Returns 0 - successful.
612 * -1 - unsuccesful.
613 */
614int loadSystemConfig(config_file_t *config)
615{
616char *dirspec[] = {
617"/Extra/com.apple.Boot.plist",
618"bt(0,0)/Extra/com.apple.Boot.plist",
619"/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",
620};
621
622int i, fd, count, ret=-1;
623
624for(i = 0; i< sizeof(dirspec)/sizeof(dirspec[0]); i++)
625{
626if ((fd = open(dirspec[i], 0)) >= 0)
627{
628// read file
629count = read(fd, config->plist, IO_CONFIG_DATA_SIZE);
630close(fd);
631
632// build xml dictionary
633ParseXMLFile(config->plist, &config->dictionary);
634sysConfigValid = true;
635ret=0;
636
637// enable canOverride flag
638config->canOverride = true;
639
640break;
641}
642}
643if(ret == -1)
644{
645ret = loadHelperConfig(config);
646}
647
648return ret;
649}
650
651/* loadOverrideConfig
652 *
653 * Returns 0 - successful.
654 * -1 - unsuccesful.
655 */
656int loadOverrideConfig(config_file_t *config)
657{
658char *dirspec[] = {
659"rd(0,0)/Extra/com.apple.Boot.plist",
660"/Extra/com.apple.Boot.plist",
661"/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",
662};
663
664int i, fd, count, ret=-1;
665
666for(i = 0; i< sizeof(dirspec)/sizeof(dirspec[0]); i++)
667{
668if ((fd = open(dirspec[i], 0)) >= 0)
669{
670// read file
671count = read(fd, config->plist, IO_CONFIG_DATA_SIZE);
672close(fd);
673
674// build xml dictionary
675ParseXMLFile(config->plist, &config->dictionary);
676sysConfigValid = true;
677ret=0;
678break;
679}
680}
681
682if(ret == -1)
683{
684ret = loadHelperConfig(config);
685}
686return ret;
687}
688
689/* loadHelperConfig
690 *
691 * Returns 0 - successful.
692 * -1 - unsuccesful.
693 */
694int loadHelperConfig(config_file_t *config)
695{
696int rfd, pfd, sfd, count, ret=-1;
697
698char *dirspec[] = {
699"/com.apple.boot.P/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",
700"/com.apple.boot.R/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",
701"/com.apple.boot.S/Library/Preferences/SystemConfiguration/com.apple.Boot.plist"
702};
703
704// This is a simple rock - paper scissors algo. R beats S, P beats R, S beats P
705// If all three, S is used for now. This should be change dto something else (say, timestamp?)
706
707pfd = open(dirspec[0], 0);
708if(pfd >= 0)// com.apple.boot.P exists
709{
710sfd = open(dirspec[2], 0); // com.apple.boot.S takes precidence if it also exists
711if(sfd >= 0)
712{
713// Use sfd
714count = read(sfd, config->plist, IO_CONFIG_DATA_SIZE);
715close(sfd);
716close(pfd);
717
718// build xml dictionary
719ParseXMLFile(config->plist, &config->dictionary);
720sysConfigValid = true;
721ret=0;
722
723}
724else
725{
726// used pfd
727count = read(pfd, config->plist, IO_CONFIG_DATA_SIZE);
728close(pfd);
729
730// build xml dictionary
731ParseXMLFile(config->plist, &config->dictionary);
732sysConfigValid = true;
733ret=0;
734}
735
736}
737else
738{
739rfd = open(dirspec[1], 0); // com.apple.boot.R exists
740if(rfd >= 0)
741{
742pfd = open(dirspec[2], 0); // com.apple.boot.P takes recidence if it exists
743if(pfd >= 0)
744{
745// use sfd
746count = read(pfd, config->plist, IO_CONFIG_DATA_SIZE);
747close(pfd);
748close(rfd);
749
750// build xml dictionary
751ParseXMLFile(config->plist, &config->dictionary);
752sysConfigValid = true;
753ret=0;
754
755}
756else
757{
758// use rfd
759count = read(rfd, config->plist, IO_CONFIG_DATA_SIZE);
760close(rfd);
761
762// build xml dictionary
763ParseXMLFile(config->plist, &config->dictionary);
764sysConfigValid = true;
765ret=0;
766
767}
768
769}
770else
771{
772sfd = open(dirspec[2], 0); // com.apple.boot.S exists, but nothing else does
773if(sfd >= 0)
774{
775// use sfd
776count = read(sfd, config->plist, IO_CONFIG_DATA_SIZE);
777close(sfd);
778
779// build xml dictionary
780ParseXMLFile(config->plist, &config->dictionary);
781sysConfigValid = true;
782ret=0;
783
784}
785}
786
787}
788
789return ret;
790}
791
792char * newString(const char * oldString)
793{
794 if ( oldString )
795 return strcpy(malloc(strlen(oldString)+1), oldString);
796 else
797 return NULL;
798}
799
800/*
801 * Extracts the next argument from the command line, double quotes are allowed here.
802 */
803char * getNextArg(char ** argPtr, char * val)
804{
805 char * ptr = *argPtr;
806 const char * strStart;
807 int len = 0;
808 bool isQuoted = false;
809
810 *val = '\0';
811
812 // Scan for the next non-whitespace character.
813 while ( *ptr && (*ptr == ' ' || *ptr == '=') )
814 {
815 ptr++;
816 }
817
818 strStart = ptr;
819
820 // Skip the leading double quote character.
821 if (*ptr == '\"')
822 {
823 isQuoted = true;
824 ptr++;
825 strStart++;
826 }
827
828 // Scan for the argument terminator character.
829 // This can be either a NULL character - in case we reach the end of the string,
830 // a double quote in case of quoted argument,
831 // or a whitespace character (' ' or '=') for non-quoted argument.
832 while (*ptr && !( (isQuoted && (*ptr == '\"')) ||
833 (!isQuoted && (*ptr == ' ' || *ptr == '=')) )
834 )
835 {
836 ptr++;
837 }
838
839 len = ptr - strStart;
840
841 // Skip the closing double quote character and adjust
842 // the starting pointer for the next getNextArg call.
843 if (*ptr && isQuoted && *ptr == '\"')
844 ptr++;
845
846 // Copy the extracted argument to val.
847 strncat(val, strStart, len);
848
849 // Set command line pointer.
850 *argPtr = ptr;
851
852 return ptr;
853}
854

Archive Download this file

Revision: 1146