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