Root/
Source at commit 214 created 13 years 5 months ago. By ifabio, update to chameleon trunk 630, and now the pakage folder is the same as blackosx branch, also add Icon "building" into buildpkg script, and add mint theme info into the English localizable.strings. | |
---|---|
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 | ␊ |
33 | extern char *Language;␊ |
34 | extern char *LoadableFamilies;␊ |
35 | ␊ |
36 | bool sysConfigValid;␊ |
37 | ␊ |
38 | /*␊ |
39 | * Compare a string to a key with quoted characters␊ |
40 | */␊ |
41 | static inline int␊ |
42 | keyncmp(const char *str, const char *key, int n)␊ |
43 | {␊ |
44 | int c;␊ |
45 | while (n--) {␊ |
46 | ␉c = *key++;␊ |
47 | ␉if (c == '\\') {␊ |
48 | ␉ switch(c = *key++) {␊ |
49 | ␉ case 'n':␊ |
50 | ␉␉c = '\n';␊ |
51 | ␉␉break;␊ |
52 | ␉ case 'r':␊ |
53 | ␉␉c = '\r';␊ |
54 | ␉␉break;␊ |
55 | ␉ case 't':␊ |
56 | ␉␉c = '\t';␊ |
57 | ␉␉break;␊ |
58 | ␉ default:␊ |
59 | ␉␉break;␊ |
60 | ␉ }␊ |
61 | ␉} else if (c == '\"') {␊ |
62 | ␉ /* Premature end of key */␊ |
63 | ␉ return 1;␊ |
64 | ␉}␊ |
65 | ␉if (c != *str++) {␊ |
66 | ␉ return 1;␊ |
67 | ␉}␊ |
68 | }␊ |
69 | return 0;␊ |
70 | }␊ |
71 | ␊ |
72 | #if UNUSED␊ |
73 | ␊ |
74 | static void eatThru(char val, const char **table_p)␊ |
75 | {␊ |
76 | ␉register const char *table = *table_p;␊ |
77 | ␉register bool found = false;␊ |
78 | ␊ |
79 | ␉while (*table && !found)␊ |
80 | ␉{␊ |
81 | ␉␉if (*table == '\\') table += 2;␊ |
82 | ␉␉else␊ |
83 | ␉␉{␊ |
84 | ␉␉␉if (*table == val) found = true;␊ |
85 | ␉␉␉table++;␊ |
86 | ␉␉}␊ |
87 | ␉}␊ |
88 | ␉*table_p = table;␊ |
89 | }␊ |
90 | ␊ |
91 | /* Remove key and its associated value from the table. */␊ |
92 | ␊ |
93 | bool␊ |
94 | removeKeyFromTable(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;␊ |
125 | out:␊ |
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 | ␊ |
137 | char *␊ |
138 | newStringFromList(␊ |
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)) {␊ |
149 | ␉begin++;␊ |
150 | ␉newsize--;␊ |
151 | }␊ |
152 | end = begin;␊ |
153 | while (*end && newsize && !isspace(*end)) {␊ |
154 | ␉end++;␊ |
155 | ␉newsize--;␊ |
156 | }␊ |
157 | if (begin == end)␊ |
158 | ␉return 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 | */␊ |
172 | int stringLength(const char *table, int compress)␊ |
173 | {␊ |
174 | ␉int ret = 0;␊ |
175 | ␊ |
176 | ␉while (*table)␊ |
177 | ␉{␊ |
178 | ␉␉if (*table == '\\')␊ |
179 | ␉␉{␊ |
180 | ␉␉␉table += 2;␊ |
181 | ␉␉␉ret += 1 + (compress ? 0 : 1);␊ |
182 | ␉␉}␊ |
183 | ␉␉else␊ |
184 | ␉␉{␊ |
185 | ␉␉␉if (*table == '\"') return ret;␊ |
186 | ␉␉␉ret++;␊ |
187 | ␉␉␉table++;␊ |
188 | ␉␉}␊ |
189 | ␉}␊ |
190 | ␉return ret;␊ |
191 | }␊ |
192 | ␊ |
193 | ␊ |
194 | bool getValueForConfigTableKey(config_file_t *config, const char *key, const char **val, int *size)␊ |
195 | {␊ |
196 | ␉if (config->dictionary != 0 ) {␊ |
197 | ␉␉// Look up key in XML dictionary␊ |
198 | ␉␉TagPtr value;␊ |
199 | ␉␉value = XMLGetProperty(config->dictionary, key);␊ |
200 | ␉␉if (value != 0) {␊ |
201 | ␉␉␉if (value->type != kTagTypeString) {␊ |
202 | ␉␉␉␉error("Non-string tag '%s' found in config file\n",␊ |
203 | ␉␉␉␉␉ key);␊ |
204 | ␉␉␉␉return false;␊ |
205 | ␉␉␉}␊ |
206 | ␉␉␉*val = value->string;␊ |
207 | ␉␉␉*size = strlen(value->string);␊ |
208 | ␉␉␉return true;␊ |
209 | ␉␉}␊ |
210 | ␉} else {␊ |
211 | ␉␊ |
212 | ␉␉// Legacy plist-style table␊ |
213 | ␊ |
214 | ␉}␊ |
215 | ␊ |
216 | ␉return 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 | */␊ |
226 | char *newStringForStringTableKey(␊ |
227 | ␉char *table,␊ |
228 | ␉char *key,␊ |
229 | ␉config_file_t *config␊ |
230 | )␊ |
231 | {␊ |
232 | const char *val;␊ |
233 | char *newstr, *p;␊ |
234 | int size;␊ |
235 | ␊ |
236 | if (getValueForConfigTableKey(config, key, &val, &size)) {␊ |
237 | ␉newstr = (char *)malloc(size+1);␊ |
238 | ␉for (p = newstr; size; size--, p++, val++) {␊ |
239 | ␉ if ((*p = *val) == '\\') {␊ |
240 | ␉␉switch (*++val) {␊ |
241 | ␉␉case 'r':␊ |
242 | ␉␉ *p = '\r';␊ |
243 | ␉␉ break;␊ |
244 | ␉␉case 'n':␊ |
245 | ␉␉ *p = '\n';␊ |
246 | ␉␉ break;␊ |
247 | ␉␉case 't':␊ |
248 | ␉␉ *p = '\t';␊ |
249 | ␉␉ break;␊ |
250 | ␉␉default:␊ |
251 | ␉␉ *p = *val;␊ |
252 | ␉␉ break;␊ |
253 | ␉␉}␊ |
254 | ␉␉size--;␊ |
255 | ␉ }␊ |
256 | ␉}␊ |
257 | ␉*p = '\0';␊ |
258 | ␉return newstr;␊ |
259 | } else {␊ |
260 | ␉return 0;␊ |
261 | }␊ |
262 | }␊ |
263 | ␊ |
264 | #endif␊ |
265 | ␊ |
266 | char *␊ |
267 | newStringForKey(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) {␊ |
274 | ␉newstr = (char *)malloc(size + 1);␊ |
275 | ␉strlcpy(newstr, val, size + 1);␊ |
276 | ␉return newstr;␊ |
277 | } else {␊ |
278 | ␉return 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 | ␊ |
288 | static const char *getToken(const char *line, const char **begin, int *len)␊ |
289 | {␊ |
290 | if (*line == '\"') {␊ |
291 | ␉*begin = ++line;␊ |
292 | ␉while (*line && *line != '\"')␊ |
293 | ␉ line++;␊ |
294 | ␉*len = line++ - *begin;␊ |
295 | } else {␊ |
296 | ␉*begin = line;␊ |
297 | ␉while (*line && !isspace(*line) && *line != '=')␊ |
298 | ␉ line++;␊ |
299 | ␉*len = line - *begin;␊ |
300 | }␊ |
301 | return line;␊ |
302 | }␊ |
303 | ␊ |
304 | bool 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 */␊ |
312 | ␉while (isspace(*line)) line++;␊ |
313 | ␊ |
314 | ␉/* now look for '=' or whitespace */␊ |
315 | ␉line = getToken(line, &key, &key_len);␊ |
316 | ␉/* line now points to '=' or space */␊ |
317 | ␉if (*line && !isspace(*line)) {␊ |
318 | ␉ line = getToken(++line, &value, &value_len);␊ |
319 | ␉} else {␊ |
320 | ␉ value = line;␊ |
321 | ␉ value_len = 0;␊ |
322 | ␉}␊ |
323 | ␉if ((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 */␊ |
335 | const 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 | ␊ |
348 | bool getBoolForKey( const char *key, bool *result_val, config_file_t *config )␊ |
349 | {␊ |
350 | const char *key_val;␊ |
351 | int size;␊ |
352 | ␊ |
353 | if (getValueForKey(key, &key_val, &size, config)) {␊ |
354 | if ( (size >= 1) && (key_val[0] == 'Y' || key_val[0] == 'y') ) {␊ |
355 | *result_val = true;␊ |
356 | } else {␊ |
357 | *result_val = false;␊ |
358 | }␊ |
359 | return true;␊ |
360 | }␊ |
361 | return false;␊ |
362 | }␊ |
363 | ␊ |
364 | bool getIntForKey( const char *key, int *value, config_file_t *config )␊ |
365 | {␊ |
366 | const char *val;␊ |
367 | int size, sum;␊ |
368 | bool negative = false;␊ |
369 | ␊ |
370 | if (getValueForKey(key, &val, &size, config))␊ |
371 | ␉{␊ |
372 | ␉␉if ( size )␊ |
373 | ␉␉{␊ |
374 | ␉␉␉if (*val == '-')␊ |
375 | ␉␉␉{␊ |
376 | ␉␉␉␉negative = true;␊ |
377 | ␉␉␉␉val++;␊ |
378 | ␉␉␉␉size--;␊ |
379 | ␉␉␉}␊ |
380 | ␉␉␉␊ |
381 | ␉␉␉for (sum = 0; size > 0; size--)␊ |
382 | ␉␉␉{␊ |
383 | ␉␉␉␉if (*val < '0' || *val > '9')␊ |
384 | ␉␉␉␉␉return false;␊ |
385 | ␉␉␉␉␊ |
386 | ␉␉␉␉sum = (sum * 10) + (*val++ - '0');␊ |
387 | ␉␉␉}␊ |
388 | ␉␉␉␊ |
389 | ␉␉␉if (negative)␊ |
390 | ␉␉␉␉sum = -sum;␊ |
391 | ␉␉␉␊ |
392 | ␉␉␉*value = sum;␊ |
393 | ␉␉␉return true;␊ |
394 | ␉␉}␊ |
395 | ␉}␊ |
396 | return false;␊ |
397 | }␊ |
398 | ␊ |
399 | /*␊ |
400 | *␊ |
401 | */␊ |
402 | ␊ |
403 | bool getDimensionForKey( const char *key, unsigned int *value, config_file_t *config, unsigned int dimension_max, unsigned int object_size )␊ |
404 | {␊ |
405 | ␉const char *val;␊ |
406 | ␉␊ |
407 | int size = 0;␊ |
408 | ␉int sum = 0;␊ |
409 | ␊ |
410 | ␉bool negative = false;␊ |
411 | ␉bool percentage = false;␊ |
412 | ␉␊ |
413 | if (getValueForKey(key, &val, &size, config))␊ |
414 | ␉{␊ |
415 | ␉␉if ( size )␊ |
416 | ␉␉{␊ |
417 | ␉␉␉if (*val == '-')␊ |
418 | ␉␉␉{␊ |
419 | ␉␉␉␉negative = true;␊ |
420 | ␉␉␉␉val++;␊ |
421 | ␉␉␉␉size--;␊ |
422 | ␉␉␉}␊ |
423 | ␉␉␉␊ |
424 | ␉␉␉if (val[size-1] == '%')␊ |
425 | ␉␉␉{␊ |
426 | ␉␉␉␉percentage = true;␊ |
427 | ␉␉␉␉size--;␊ |
428 | ␉␉␉}␊ |
429 | ␉␉␉␊ |
430 | ␉␉␉// convert string to integer␊ |
431 | ␉␉␉for (sum = 0; size > 0; size--)␊ |
432 | ␉␉␉{␊ |
433 | ␉␉␉␉if (*val < '0' || *val > '9')␊ |
434 | ␉␉␉␉␉return false;␊ |
435 | ␉␉␉␉␊ |
436 | ␉␉␉␉sum = (sum * 10) + (*val++ - '0');␊ |
437 | ␉␉␉}␊ |
438 | ␉␉␉␊ |
439 | ␉␉␉if (percentage)␊ |
440 | ␉␉␉␉sum = ( dimension_max * sum ) / 100;␊ |
441 | ␉␉␉␊ |
442 | ␉␉␉// calculate offset from opposite origin␊ |
443 | ␉␉␉if (negative)␊ |
444 | ␉␉␉␉sum = ( ( dimension_max - object_size ) - sum );␊ |
445 | ␉␉␉␊ |
446 | ␉␉} else {␊ |
447 | ␉␉␉␊ |
448 | ␉␉␉// null value calculate center␊ |
449 | ␉␉␉sum = ( dimension_max - object_size ) / 2;␊ |
450 | ␉␉␉␊ |
451 | ␉␉}␊ |
452 | ␉␉␊ |
453 | ␉␉*value = (uint16_t) sum;␊ |
454 | ␉␉return true;␊ |
455 | ␉}␊ |
456 | ␉␊ |
457 | ␉// key not found␊ |
458 | return false;␊ |
459 | }␊ |
460 | ␊ |
461 | /*␊ |
462 | *␉get color value from plist format #RRGGBB␊ |
463 | */␊ |
464 | ␊ |
465 | bool getColorForKey( const char *key, unsigned int *value, config_file_t *config )␊ |
466 | {␊ |
467 | const char *val;␊ |
468 | int size;␊ |
469 | ␊ |
470 | if (getValueForKey(key, &val, &size, config))␊ |
471 | ␉{␊ |
472 | ␉␉if (*val == '#')␊ |
473 | ␉␉{␊ |
474 | val++;␊ |
475 | ␉␉␉*value = strtol(val, NULL, 16);␊ |
476 | ␉␉␉return true;␊ |
477 | }␊ |
478 | }␊ |
479 | return false;␊ |
480 | }␊ |
481 | ␊ |
482 | bool getValueForKey( const char *key, const char **val, int *size, config_file_t *config )␊ |
483 | {␊ |
484 | const char *overrideVal;␊ |
485 | int overrideSize;␊ |
486 | bool override, ret;␊ |
487 | ␊ |
488 | if (getValueForBootKey(bootArgs->CommandLine, key, val, size))␊ |
489 | return true;␊ |
490 | ␊ |
491 | ret = getValueForConfigTableKey(config, key, val, size);␊ |
492 | ␊ |
493 | // Try to find alternate keys in bootInfo->overrideConfig␊ |
494 | // and prefer its values with the exceptions for␊ |
495 | // "Kernel"="mach_kernel" and "Kernel Flags"="".␊ |
496 | ␊ |
497 | if (config->canOverride)␊ |
498 | {␊ |
499 | if (getValueForConfigTableKey(&bootInfo->overrideConfig, key, &overrideVal, &overrideSize))␊ |
500 | {␊ |
501 | override = true;␊ |
502 | ␊ |
503 | if (ret && (strcmp(key, "Kernel") == 0) && (strcmp(overrideVal, "mach_kernel") == 0))␊ |
504 | override = false;␊ |
505 | ␊ |
506 | if (ret && (strcmp(key, "Kernel Flags") == 0) && (overrideSize == 0))␊ |
507 | override = false;␊ |
508 | ␊ |
509 | if (override)␊ |
510 | {␊ |
511 | *val = overrideVal;␊ |
512 | *size = overrideSize;␊ |
513 | return true;␊ |
514 | }␊ |
515 | }␊ |
516 | }␊ |
517 | ␊ |
518 | return ret;␊ |
519 | }␊ |
520 | ␊ |
521 | ␊ |
522 | #if UNUSED␊ |
523 | void␊ |
524 | printSystemConfig(char *p1)␊ |
525 | {␊ |
526 | char *p2 = p1, tmp;␊ |
527 | ␊ |
528 | while (*p1 != '\0') {␊ |
529 | ␉while (*p2 != '\0' && *p2 != '\n') p2++;␊ |
530 | ␉tmp = *p2;␊ |
531 | ␉*p2 = '\0';␊ |
532 | ␉printf("%s\n", p1);␊ |
533 | ␉*p2 = tmp;␊ |
534 | ␉if (tmp == '\0') break;␊ |
535 | ␉p1 = ++p2;␊ |
536 | }␊ |
537 | }␊ |
538 | #endif␊ |
539 | ␊ |
540 | //==========================================================================␊ |
541 | // ParseXMLFile␊ |
542 | // Modifies the input buffer.␊ |
543 | // Expects to see one dictionary in the XML file.␊ |
544 | // Puts the first dictionary it finds in the␊ |
545 | // tag pointer and returns 0, or returns -1 if not found␊ |
546 | // (and does not modify dict pointer).␊ |
547 | // Prints an error message if there is a parsing error.␊ |
548 | //␊ |
549 | int ParseXMLFile( char * buffer, TagPtr * dict )␊ |
550 | {␊ |
551 | long length, pos;␊ |
552 | TagPtr tag;␊ |
553 | pos = 0;␊ |
554 | char *configBuffer;␊ |
555 | ␊ |
556 | configBuffer = malloc(strlen(buffer)+1);␊ |
557 | strcpy(configBuffer, buffer);␊ |
558 | ␊ |
559 | while (1)␊ |
560 | {␊ |
561 | length = XMLParseNextTag(configBuffer + pos, &tag);␊ |
562 | if (length == -1) break;␊ |
563 | ␊ |
564 | pos += length;␊ |
565 | ␊ |
566 | if (tag == 0) continue;␊ |
567 | if (tag->type == kTagTypeDict) break;␊ |
568 | ␊ |
569 | XMLFreeTag(tag);␊ |
570 | }␊ |
571 | free(configBuffer);␊ |
572 | if (length < 0) {␊ |
573 | error ("Error parsing plist file\n");␊ |
574 | return -1;␊ |
575 | }␊ |
576 | *dict = tag;␊ |
577 | return 0;␊ |
578 | }␊ |
579 | ␊ |
580 | /* loadConfigFile␊ |
581 | *␊ |
582 | * Returns 0 - successful.␊ |
583 | *␉␉ -1 - unsuccesful.␊ |
584 | */␊ |
585 | int loadConfigFile (const char *configFile, config_file_t *config)␊ |
586 | {␊ |
587 | ␉int fd, count;␊ |
588 | ␊ |
589 | ␉if ((fd = open_bvdev("bt(0,0)", configFile, 0)) < 0) {␊ |
590 | ␉␉return -1;␊ |
591 | ␉}␊ |
592 | ␉// read file␊ |
593 | ␉count = read(fd, config->plist, IO_CONFIG_DATA_SIZE);␊ |
594 | ␉close(fd);␊ |
595 | ␉␊ |
596 | ␉// build xml dictionary␊ |
597 | ␉ParseXMLFile(config->plist, &config->dictionary);␊ |
598 | ␉return 0;␊ |
599 | }␊ |
600 | ␊ |
601 | ␊ |
602 | /* loadSystemConfig␊ |
603 | *␊ |
604 | * Returns 0 - successful.␊ |
605 | *␉␉ -1 - unsuccesful.␊ |
606 | */␊ |
607 | int loadSystemConfig(config_file_t *config)␊ |
608 | {␊ |
609 | ␉char *dirspec[] = {␊ |
610 | ␉␉"/Extra/com.apple.Boot.plist",␊ |
611 | ␉␉"bt(0,0)/Extra/com.apple.Boot.plist",␊ |
612 | ␉␉"/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",␊ |
613 | ␉␉"/com.apple.boot.P/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",␊ |
614 | ␉␉"/com.apple.boot.R/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",␊ |
615 | ␉␉"/com.apple.boot.S/Library/Preferences/SystemConfiguration/com.apple.Boot.plist"␊ |
616 | ␉};␊ |
617 | ␊ |
618 | ␉int i, fd, count, ret=-1;␊ |
619 | ␊ |
620 | ␉for(i = 0; i< sizeof(dirspec)/sizeof(dirspec[0]); i++)␊ |
621 | ␉{␊ |
622 | ␉␉if ((fd = open(dirspec[i], 0)) >= 0)␊ |
623 | ␉␉{␊ |
624 | ␉␉␉// read file␊ |
625 | ␉␉␉count = read(fd, config->plist, IO_CONFIG_DATA_SIZE);␊ |
626 | ␉␉␉close(fd);␊ |
627 | ␉␉␉␊ |
628 | ␉␉␉// build xml dictionary␊ |
629 | ␉␉␉ParseXMLFile(config->plist, &config->dictionary);␊ |
630 | ␉␉␉sysConfigValid = true;␉␊ |
631 | ␉␉␉ret=0;␊ |
632 | ␉␉␉␊ |
633 | ␉␉␉// enable canOverride flag␊ |
634 | ␉␉␉config->canOverride = true;␊ |
635 | ␊ |
636 | ␉␉␉break;␊ |
637 | ␉␉}␊ |
638 | ␉}␊ |
639 | ␉return ret;␊ |
640 | }␊ |
641 | ␊ |
642 | /* loadOverrideConfig␊ |
643 | *␊ |
644 | * Returns 0 - successful.␊ |
645 | *␉␉ -1 - unsuccesful.␊ |
646 | */␊ |
647 | int loadOverrideConfig(config_file_t *config)␊ |
648 | {␊ |
649 | ␉char *dirspec[] = {␊ |
650 | ␉␉"rd(0,0)/Extra/com.apple.Boot.plist",␊ |
651 | ␉␉"/Extra/com.apple.Boot.plist",␊ |
652 | ␉␉"/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",␊ |
653 | ␉␉"/com.apple.boot.P/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",␊ |
654 | ␉␉"/com.apple.boot.R/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",␊ |
655 | ␉␉"/com.apple.boot.S/Library/Preferences/SystemConfiguration/com.apple.Boot.plist"␊ |
656 | ␉};␊ |
657 | ␊ |
658 | ␉int i, fd, count, ret=-1;␊ |
659 | ␊ |
660 | ␉for(i = 0; i< sizeof(dirspec)/sizeof(dirspec[0]); i++)␊ |
661 | ␉{␊ |
662 | ␉␉if ((fd = open(dirspec[i], 0)) >= 0)␊ |
663 | ␉␉{␊ |
664 | ␉␉␉// read file␊ |
665 | ␉␉␉count = read(fd, config->plist, IO_CONFIG_DATA_SIZE);␊ |
666 | ␉␉␉close(fd);␊ |
667 | ␉␉␉␊ |
668 | ␉␉␉// build xml dictionary␊ |
669 | ␉␉␉ParseXMLFile(config->plist, &config->dictionary);␊ |
670 | ␉␉␉sysConfigValid = true;␉␊ |
671 | ␉␉␉ret=0;␊ |
672 | ␉␉␉break;␊ |
673 | ␉␉}␊ |
674 | ␉}␊ |
675 | ␉return ret;␊ |
676 | }␊ |
677 | ␊ |
678 | /* loadHelperConfig␊ |
679 | *␊ |
680 | * Returns 0 - successful.␊ |
681 | *␉␉ -1 - unsuccesful.␊ |
682 | */␊ |
683 | int loadHelperConfig(config_file_t *config)␊ |
684 | {␊ |
685 | ␉char *dirspec[] = {␊ |
686 | ␉␉"/com.apple.boot.P/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",␊ |
687 | ␉␉"/com.apple.boot.R/Library/Preferences/SystemConfiguration/com.apple.Boot.plist",␊ |
688 | ␉␉"/com.apple.boot.S/Library/Preferences/SystemConfiguration/com.apple.Boot.plist"␊ |
689 | ␉};␊ |
690 | ␊ |
691 | ␉int i, fd, count, ret=-1;␊ |
692 | ␊ |
693 | ␉for(i = 0; i< sizeof(dirspec)/sizeof(dirspec[0]); i++)␊ |
694 | ␉{␊ |
695 | ␉␉if ((fd = open(dirspec[i], 0)) >= 0)␊ |
696 | ␉␉{␊ |
697 | ␉␉␉// read file␊ |
698 | ␉␉␉count = read(fd, config->plist, IO_CONFIG_DATA_SIZE);␊ |
699 | ␉␉␉close(fd);␊ |
700 | ␉␉␉␊ |
701 | ␉␉␉// build xml dictionary␊ |
702 | ␉␉␉ParseXMLFile(config->plist, &config->dictionary);␊ |
703 | ␉␉␉sysConfigValid = true;␉␊ |
704 | ␉␉␉ret=0;␊ |
705 | ␉␉␉break;␊ |
706 | ␉␉}␊ |
707 | ␉}␊ |
708 | ␉return ret;␊ |
709 | }␊ |
710 | ␊ |
711 | char * newString(const char * oldString)␊ |
712 | {␊ |
713 | if ( oldString )␊ |
714 | return strcpy(malloc(strlen(oldString)+1), oldString);␊ |
715 | else␊ |
716 | return NULL;␊ |
717 | }␊ |
718 | ␊ |
719 | /*␊ |
720 | * Extracts the next argument from the command line, double quotes are allowed here.␊ |
721 | */␊ |
722 | char * getNextArg(char ** argPtr, char * val)␊ |
723 | {␊ |
724 | char * ptr = *argPtr;␊ |
725 | const char * strStart;␊ |
726 | int len = 0;␊ |
727 | bool isQuoted = false;␊ |
728 | ␊ |
729 | *val = '\0';␊ |
730 | ␊ |
731 | // Scan for the next non-whitespace character.␊ |
732 | while ( *ptr && (*ptr == ' ' || *ptr == '=') )␊ |
733 | {␊ |
734 | ptr++;␊ |
735 | }␊ |
736 | ␊ |
737 | strStart = ptr;␊ |
738 | ␊ |
739 | // Skip the leading double quote character.␊ |
740 | if (*ptr == '\"')␊ |
741 | {␊ |
742 | isQuoted = true;␊ |
743 | ptr++;␊ |
744 | strStart++;␊ |
745 | }␊ |
746 | ␊ |
747 | // Scan for the argument terminator character.␊ |
748 | // This can be either a NULL character - in case we reach the end of the string,␊ |
749 | // a double quote in case of quoted argument,␊ |
750 | // or a whitespace character (' ' or '=') for non-quoted argument.␊ |
751 | while (*ptr && !( (isQuoted && (*ptr == '\"')) ||␊ |
752 | (!isQuoted && (*ptr == ' ' || *ptr == '=')) )␊ |
753 | )␊ |
754 | {␊ |
755 | ptr++;␊ |
756 | }␊ |
757 | ␊ |
758 | len = ptr - strStart;␊ |
759 | ␊ |
760 | // Skip the closing double quote character and adjust␊ |
761 | // the starting pointer for the next getNextArg call.␊ |
762 | if (*ptr && isQuoted && *ptr == '\"')␊ |
763 | ptr++;␊ |
764 | ␊ |
765 | // Copy the extracted argument to val.␊ |
766 | strncat(val, strStart, len);␊ |
767 | ␊ |
768 | // Set command line pointer.␊ |
769 | *argPtr = ptr;␊ |
770 | ␊ |
771 | return ptr;␊ |
772 | }␊ |
773 |