]> git.saurik.com Git - apple/boot.git/blame - i386/libsaio/old/stringTableNew.c
boot-80.1.tar.gz
[apple/boot.git] / i386 / libsaio / old / stringTableNew.c
CommitLineData
14c7c974
A
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
34extern KERNBOOTSTRUCT *kernBootStruct;
35extern char *Language;
36extern char *LoadableFamilies;
37
38
39static char_ret
40getachar(
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 */
79char *
80get_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
112char *
113stringFromList(
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
140char *
141valueForStringTableKey(
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
198char *
199valueForBootKey(
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
220BOOL
221boolForKey(
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
236BOOL
237getIntForKey(
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
259char *
260valueForKey(
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"
274char *
275loadLocalizableStrings(
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
312char *
313bundleLongName(
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
334int sysConfigValid;
335
336void
337addConfig(
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 */
360int
361loadConfigFile( 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
401int
402loadConfigDir(
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 */
463int
464loadSystemConfig(
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
514int
515loadOtherConfigs(
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
550static BOOL
551dirExists(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