]> git.saurik.com Git - apple/boot.git/blob - i386/libsaio/old/stringTableNew.c
boot-83.2.tar.gz
[apple/boot.git] / i386 / libsaio / old / stringTableNew.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 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 1.1 (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 #import "libsaio.h"
30 #import "kernBootStruct.h"
31 #import "stringConstants.h"
32 #import <driverkit/configTablePrivate.h>
33
34 extern KERNBOOTSTRUCT *kernBootStruct;
35 extern char *Language;
36 extern char *LoadableFamilies;
37
38
39 static char_ret
40 getachar(
41 char **string_p
42 )
43 {
44 register char *str = *string_p;
45 register int c;
46 char_ret r;
47
48 c = *str++;
49 if (c == '\\') {
50 r.quoted = YES;
51 c = *str++;
52 switch(c) {
53 case 'n':
54 c = '\n';
55 break;
56 case 'r':
57 c = '\r';
58 break;
59 case 't':
60 c = '\t';
61 break;
62 default:
63 break;
64 }
65 } else {
66 r.quoted = NO;
67 }
68 *string_p = str;
69 r.c = c;
70 return r;
71 }
72
73 /*
74 * A token is:
75 * <non_space_non_semicolon>*
76 * "<non_quote>*"
77 * <semicolon>
78 */
79 char *
80 get_token(
81 char **string_p
82 )
83 {
84 char *begin;
85 char *newstr;
86 char_ret r;
87 int len;
88
89 do {
90 r = getachar(string_p);
91 } while (r.c && isspace(r.c));
92
93 if (!r.quoted && r.c == '\"') {
94 begin = *string_p;
95 do {
96 r = getachar(string_p);
97 } while (r.c && !r.quoted && r.c != '\"');
98 } else {
99 begin = *string_p - 1;
100 do {
101 r = getachar(string_p);
102 } while (r.c && !r.quoted && r.c != ';' && !isspace(r.c));
103 }
104 len = *string_p - begin - 1;
105 newstr = (char *)malloc(len + 1);
106 strncpy(newstr, begin, len);
107 newstr[len] = '\0';
108 return newstr;
109 }
110
111
112 char *
113 stringFromList(
114 char **list,
115 int *size
116 )
117 {
118 char *begin = *list, *end;
119 char *newstr;
120 int newsize = *size;
121
122 while (*begin && newsize && isspace(*begin)) {
123 begin++;
124 newsize--;
125 }
126 end = begin;
127 while (*end && newsize && !isspace(*end)) {
128 end++;
129 newsize--;
130 }
131 if (begin == end)
132 return 0;
133 newstr = malloc(end - begin + 1);
134 strncpy(newstr, begin, end - begin);
135 *list = end;
136 *size = newsize;
137 return newstr;
138 }
139
140 char *
141 valueForStringTableKey(
142 char *table,
143 char *key
144 )
145 {
146 char *token;
147 enum {
148 KEY,
149 EQUALS,
150 VALUE,
151 SEMICOLON,
152 BEGINCOMMENT,
153 ENDCOMMENT
154 } state;
155 BOOL foundKey;
156 int len;
157
158 state = KEY;
159 foundKey = NO;
160 while (*table) {
161 token = get_token(&table);
162 switch(state) {
163 case KEY:
164 if (strcmp(token, key) == 0)
165 foundKey = YES;
166 if (strncmp(token, "/*", 2) == 0)
167 state = ENDCOMMENT;
168 else
169 state = EQUALS;
170 break;
171 case EQUALS:
172 if (strcmp(token, "=") == 0) {
173 state = VALUE;
174 }
175 break;
176 case VALUE:
177 if (foundKey) {
178 return token;
179 }
180 state = SEMICOLON;
181 break;
182 case SEMICOLON:
183 if (strcmp(token, ";") == 0) {
184 state = KEY;
185 }
186 break;
187 case ENDCOMMENT:
188 len = strlen(token);
189 if (len >= 2 && strncmp(token + len - 2, "*/", 2) == 0)
190 state = KEY;
191 break;
192 }
193 free(token);
194 }
195 return 0;
196 }
197
198 char *
199 valueForBootKey(
200 char *line,
201 char *match
202 )
203 {
204 char *token;
205 enum {
206 KEY,
207 EQUALS,
208 VALUE,
209 WHITESPACE
210 } state;
211 BOOL foundKey;
212 int len;
213
214 state = KEY;
215 while (*line) {
216 token = get_token(&line);
217 }
218 }
219
220 BOOL
221 boolForKey(
222 char *key
223 )
224 {
225 char *str = valueForKey(key);
226 BOOL ret;
227
228 if (str && (str[0] == 'Y' || str[1] == 'y'))
229 ret = YES;
230 else
231 ret = NO;
232 free(str);
233 return ret;
234 }
235
236 BOOL
237 getIntForKey(
238 char *key,
239 int *value
240 )
241 {
242 char *str = valueForKey(key), *ptr = str;
243 int sum;
244 BOOL ret;
245
246 if (str) {
247 for (sum = 0; size > 0; size--) {
248 sum = (sum * 10) + (*ptr++ - '0');
249 }
250 *value = sum;
251 ret = YES;
252 } else {
253 ret = NO;
254 }
255 free(str);
256 return ret;
257 }
258
259 char *
260 valueForKey(
261 char *key
262 )
263 {
264 char *str = valueForBootKey(kernBootStruct->bootString, key);;
265
266 if (str)
267 return str;
268 else
269 return valueForStringTableKey(kernBootStruct->config, key);
270 }
271
272 #define LOCALIZABLE_PATH \
273 "%s/%s.config/%s.lproj/%s.strings"
274 char *
275 loadLocalizableStrings(
276 char *name,
277 char *tableName
278 )
279 {
280 char buf[256], *config;
281 register int i, count, fd = -1;
282 char * paths[] = {
283 ARCH_DEVICES,
284 USR_DEVICES,
285 "/",
286 NULL
287 }, **path;
288
289 for (i=0; i<2; i++) {
290 for (path = paths; *path; path++) {
291 sprintf(buf, LOCALIZABLE_PATH, *path, name,
292 (i == 0) ? Language : "English", tableName);
293 if ((fd = open(buf, 0)) >= 0) {
294 i = 2;
295 break;
296 }
297 }
298 }
299 if (fd < 0)
300 return 0;
301 count = file_size(fd);
302 config = malloc(count);
303 count = read(fd, config, count);
304 close(fd);
305 if (count <= 0) {
306 free(config);
307 return 0;
308 }
309 return config;
310 }
311
312 char *
313 bundleLongName(
314 char *bundleName,
315 char *tableName
316 )
317 {
318 char *table, *name, *val;
319 int size;
320
321 table = loadLocalizableStrings(bundleName,
322 tableName ? tableName : "Localizable");
323 if ( table != 0 &&
324 getValueForStringTableKey(table,"Long Name", &val, &size) == YES) {
325 name = malloc(size+1);
326 strncpy(name, val, size);
327 free(table);
328 } else {
329 name = newString(bundleName);
330 }
331 return name;
332 }
333
334 int sysConfigValid;
335
336 void
337 addConfig(
338 char *config
339 )
340 {
341 char *configPtr = kernBootStruct->configEnd;
342 int len = strlen(config);
343
344 if ((configPtr - kernBootStruct->config) > CONFIG_SIZE) {
345 error("No room in memory for config files\n");
346 return;
347 }
348 strcpy(configPtr, config);
349 configPtr += (len + 1);
350 *configPtr = 0;
351 kernBootStruct->configEnd = configPtr;
352 }
353
354 /*
355 * Returns 0 if file loaded OK,
356 * -1 if file was not loaded
357 * Does not print error messages.
358 * Returns pointer to table in memory in *table.
359 */
360 int
361 loadConfigFile( char *configFile, char **table, BOOL allocTable)
362 {
363 char *configPtr = kernBootStruct->configEnd;
364 int fd, count;
365
366 /* Read config file into memory */
367 if ((fd = open(configFile, 0)) >= 0)
368 {
369 if (allocTable) {
370 configPtr = malloc(file_size(fd)+2);
371 } else {
372 if ((configPtr - kernBootStruct->config) > CONFIG_SIZE) {
373 error("No room in memory for config files\n");
374 close(fd);
375 return -1;
376 }
377 verbose("Reading configuration file '%s'.\n",configFile);
378 }
379 if (table) *table = configPtr;
380 count = read(fd, configPtr, IO_CONFIG_DATA_SIZE);
381 close(fd);
382
383 configPtr += count;
384 *configPtr++ = 0;
385 *configPtr = 0;
386 if (!allocTable)
387 kernBootStruct->configEnd = configPtr;
388
389 return 0;
390 } else {
391 return -1;
392 }
393 }
394
395 /* Returns 0 if requested config files were loaded,
396 * 1 if default files were loaded,
397 * -1 if no files were loaded.
398 * Prints error message if files cannot be loaded.
399 */
400
401 int
402 loadConfigDir(
403 char *bundleName, // bundle directory name (e.g. "System")
404 BOOL useDefault, // use Default.table instead of instance tables
405 char **table, // returns pointer to config table
406 BOOL allocTable // malloc the table and return in *table
407 )
408 {
409 char *buf;
410 int i, ret;
411 BOOL archConfig = dirExists(ARCH_DEVICES);
412
413 buf = malloc(256);
414 ret = 0;
415
416 // load up to 99 instance tables
417 for (i=0; i < 99; i++) {
418 sprintf(buf, "%s/%s.config/Instance%d.table",
419 archConfig ? ARCH_DEVICES : USR_DEVICES,
420 bundleName, i);
421 if (useDefault || (loadConfigFile(buf, table, allocTable) != 0)) {
422 if (i == 0) {
423 // couldn't load first instance table;
424 // try the default table
425 sprintf(buf, "%s/%s.config/%s",
426 archConfig ? ARCH_DEVICES : USR_DEVICES,
427 bundleName,
428 IO_DEFAULT_TABLE_FILENAME);
429 if (loadConfigFile(buf, table, allocTable) == 0) {
430 ret = 1;
431 } else {
432 if (!allocTable)
433 error("Config file \"%s\" not found\n", buf);
434 ret = -1;
435 }
436 }
437 // we must be done.
438 break;
439 }
440 }
441 free(buf);
442 return ret;
443 }
444
445
446 #define USR_SYSTEM_CONFIG \
447 USR_DEVICES "/System.config"
448 #define USR_SYSTEM_DEFAULT_FILE \
449 USR_SYSTEM_CONFIG "/Default.table"
450 #define ARCH_SYSTEM_CONFIG \
451 ARCH_DEVICES "/System.config"
452 #define ARCH_SYSTEM_DEFAULT_FILE \
453 ARCH_SYSTEM_CONFIG "/Default.table"
454 #define SYSTEM_CONFIG "System"
455 #define LP '('
456 #define RP ')'
457
458 /* Returns 0 if requested config files were loaded,
459 * 1 if default files were loaded,
460 * -1 if no files were loaded.
461 * Prints error message if files cannot be loaded.
462 */
463 int
464 loadSystemConfig(
465 char *which,
466 int size
467 )
468 {
469 char *buf, *bp, *cp;
470 int ret, len, doDefault=0;
471 BOOL archConfig = dirExists(ARCH_DEVICES);
472
473 buf = bp = malloc(256);
474 if (which && size)
475 {
476 for(cp = which, len = size; len && *cp && *cp != LP; cp++, len--) ;
477 if (*cp == LP) {
478 while (len-- && *cp && *cp++ != RP) ;
479 /* cp now points past device */
480 strncpy(buf,which,cp - which);
481 bp += cp - which;
482 } else {
483 cp = which;
484 len = size;
485 }
486 if (*cp != '/') {
487 strcpy(bp, archConfig ?
488 ARCH_SYSTEM_CONFIG : USR_SYSTEM_CONFIG);
489 strcat(bp, "/");
490 strncat(bp, cp, len);
491 if (strncmp(cp + len - strlen(IO_TABLE_EXTENSION),
492 IO_TABLE_EXTENSION, strlen(IO_TABLE_EXTENSION)) != 0)
493 strcat(bp, IO_TABLE_EXTENSION);
494 } else {
495 strncpy(bp, cp, len);
496 bp[size] = '\0';
497 }
498 if ((strcmp(bp, USR_SYSTEM_DEFAULT_FILE) == 0) ||
499 (strcmp(bp, ARCH_SYSTEM_DEFAULT_FILE) == 0))
500 doDefault = 1;
501 ret = loadConfigFile(bp = buf, 0, 0);
502 } else {
503 ret = loadConfigDir((bp = SYSTEM_CONFIG), 0, 0, 0);
504 }
505 if (ret < 0) {
506 error("System config file '%s' not found\n", bp);
507 } else
508 sysConfigValid = 1;
509 free(buf);
510 return (ret < 0 ? ret : doDefault);
511 }
512
513
514 int
515 loadOtherConfigs(
516 int useDefault
517 )
518 {
519 char *val, *table;
520 int count;
521 char *string;
522 int fd, ret;
523
524 if (getValueForKey( "Boot Drivers", &val, &count))
525 {
526 while (string = stringFromList(&val, &count)) {
527 ret = loadConfigDir(string, useDefault, &table, 0);
528 if (ret >= 0) {
529 if ((fd = openDriverReloc(string)) >= 0) {
530 verbose("Loading binary for %s device driver.\n",string);
531 if (loadDriver(string, fd) < 0)
532 error("Error loading %s device driver.\n",string);
533 close(fd);
534 }
535 driverWasLoaded(string, table, NULL);
536 free(string);
537 } else {
538 driverIsMissing(string);
539 }
540 }
541 } else {
542 error("Warning: No active drivers specified in system config.\n");
543 }
544
545 kernBootStruct->first_addr0 =
546 (int)kernBootStruct->configEnd + 1024;
547 return 0;
548 }
549
550 static BOOL
551 dirExists(char *path)
552 {
553 int fd;
554
555 if ((fd = open(path, 0)) < 0) {
556 return NO;
557 } else {
558 close(fd);
559 return YES;
560 }
561 }
562
563
564