|
|
1.1.1.6 root 1: /* config.c - config file parser by Peter Gutmann
2: Parses config file for PGP
1.1.1.8 ! root 3:
1.1.1.6 root 4: (c) Copyright 1990-1994 by Philip Zimmermann. All rights reserved.
5: The author assumes no liability for damages resulting from the use
6: of this software, even if the damage results from defects in this
7: software. No warranty is expressed or implied.
1.1.1.8 ! root 8:
1.1.1.6 root 9: Note that while most PGP source modules bear Philip Zimmermann's
10: copyright notice, many of them have been revised or entirely written
11: by contributors who frequently failed to put their names in their
12: code. Code that has been incorporated into PGP from other authors
13: was either originally published in the public domain or is used with
14: permission from the various authors.
1.1.1.8 ! root 15:
1.1.1.6 root 16: PGP is available for free to the public under certain restrictions.
17: See the PGP User's Guide (included in the release package) for
18: important information about licensing, patent restrictions on
19: certain algorithms, trademarks, copyrights, and export controls.
1.1.1.8 ! root 20:
1.1.1.6 root 21: Modified 24 Jun 92 - HAJK
1.1.1.8 ! root 22: Misc fixes for VAX C restrictions
! 23:
! 24: Updated by Peter Gutmann to only warn about unrecognized options,
! 25: so future additions to the config file will give old versions a
! 26: chance to still run. A number of code cleanups, too. */
1.1.1.6 root 27:
28: #include <ctype.h>
29: #include <string.h>
30: #include <stdio.h>
31: #include <stdlib.h>
1.1.1.8 ! root 32: #include <limits.h>
1.1.1.6 root 33: #include "usuals.h"
34: #include "fileio.h"
35: #include "pgp.h"
36: #include "config.h"
37: #include "charset.h"
38:
1.1.1.8 ! root 39: /* Various maximum/minimum allowable settings for config options */
! 40:
! 41: #define MIN_MARGINALS 1
! 42: #define MIN_COMPLETE 1
! 43: #define MAX_COMPLETE 4
! 44: #define MIN_CERT_DEPTH 0
! 45: #define MAX_CERT_DEPTH 8
! 46:
! 47: /* Prototypes for local functions */
! 48:
1.1.1.6 root 49: static int lookup( char *key, int keyLength, char *keyWords[], int range );
50: static int extractToken( char *buffer, int *endIndex, int *length );
51: static int getaString( char *buffer, int *endIndex );
1.1.1.8 ! root 52: static int getAssignment( char *buffer, int *endIndex, INPUT_TYPE settingType );
1.1.1.6 root 53: static void processAssignment( int intrinsicIndex );
54:
55: /* The external config variables we can set here are referenced in pgp.h */
56:
57: /* Return values */
58:
59: #define ERROR -1
60: #define OK 0
61:
62: /* The types of error we check for */
63:
64: enum { NO_ERROR, ILLEGAL_CHAR_ERROR, LINELENGTH_ERROR };
65:
1.1.1.8 ! root 66: #define CPM_EOF 0x1A /* ^Z = CPM EOF char */
1.1.1.6 root 67:
1.1.1.8 ! root 68: #define MAX_ERRORS 3 /* Max.no.errors before we give up */
1.1.1.6 root 69:
1.1.1.8 ! root 70: #define LINEBUF_SIZE 100 /* Size of input buffer */
1.1.1.6 root 71:
1.1.1.7 root 72: static int line; /* The line on which an error occurred */
1.1.1.8 ! root 73: static int errCount; /* Total error count */
1.1.1.7 root 74: static boolean hasError; /* Whether this line has an error in it */
1.1.1.6 root 75:
76: /* The settings parsed out by getAssignment() */
77:
78: static char str[ LINEBUF_SIZE ];
79: static int value;
1.1.1.8 ! root 80: static char *errtag; /* Prefix for printing error messages */
! 81: static char optstr[ 100 ]; /* Option being processed */
1.1.1.6 root 82:
83: /* A .CFG file roughly follows the format used in the world-famous HPACK
84: archiver and is as follows:
85:
86: - Leading spaces/tabs (whitespace) are ignored.
87:
1.1.1.7 root 88: - Lines with a '#' as the first non-whitespace character are treated
89: as comment lines.
1.1.1.6 root 90:
91: - All other lines are treated as config options for the program.
92:
93: - Lines may be terminated by either linefeeds, carriage returns, or
94: carriage return/linefeed pairs (the latter being the DOS default
95: method of storing text files).
96:
97: - Config options have the form:
98:
99: <option> '=' <setting>
100:
101: where <setting> may be 'on', 'off', a numeric value, or a string
102: value.
103:
104: - If strings have spaces or the '#' character inside them they must be
105: surrounded by quote marks '"' */
106:
107: /* Intrinsic variables */
108:
109: #define NO_INTRINSICS (sizeof(intrinsics) / sizeof(intrinsics[0]))
1.1.1.8 ! root 110: #define CONFIG_INTRINSICS BATCHMODE
1.1.1.6 root 111:
1.1.1.8 ! root 112: enum {
! 113: ARMOR, COMPRESS, SHOWPASS, KEEPBINARY, LANGUAGE,
1.1.1.6 root 114: MYNAME, TEXTMODE, TMP, TZFIX, VERBOSE, BAKRING,
115: ARMORLINES, COMPLETES_NEEDED, MARGINALS_NEEDED, PAGER,
116: CERT_DEPTH, CHARSET, CLEAR, SELF_ENCRYPT,
1.1.1.8 ! root 117: INTERACTIVE, PUBRING, SECRING, RANDSEED,
1.1.1.6 root 118: COMMENT,
119: /* options below this line can only be used as command line
120: * "long" options */
1.1.1.8 ! root 121: BATCHMODE, FORCE, NOMANUAL, MAKERANDOM
! 122: };
1.1.1.6 root 123:
1.1.1.8 ! root 124: static char *intrinsics[] = {
! 125: "ARMOR", "COMPRESS", "SHOWPASS", "KEEPBINARY", "LANGUAGE",
1.1.1.6 root 126: "MYNAME", "TEXTMODE", "TMP", "TZFIX", "VERBOSE", "BAKRING",
127: "ARMORLINES", "COMPLETES_NEEDED", "MARGINALS_NEEDED", "PAGER",
128: "CERT_DEPTH", "CHARSET", "CLEARSIG", "ENCRYPTTOSELF",
1.1.1.8 ! root 129: "INTERACTIVE", "PUBRING", "SECRING", "RANDSEED",
1.1.1.6 root 130: "COMMENT",
131: /* command line only */
1.1.1.8 ! root 132: "BATCHMODE", "FORCE", "NOMANUAL", "MAKERANDOM"
! 133: };
1.1.1.6 root 134:
1.1.1.8 ! root 135: static INPUT_TYPE intrinsicType[] = {
! 136: BOOL, BOOL, BOOL, BOOL, STRING,
1.1.1.6 root 137: STRING, BOOL, STRING, NUMERIC, NUMERIC, STRING,
138: NUMERIC, NUMERIC, NUMERIC, STRING,
139: NUMERIC, STRING, BOOL, BOOL,
1.1.1.8 ! root 140: BOOL, STRING, STRING, STRING,
1.1.1.6 root 141: STRING,
142: /* command line only */
1.1.1.8 ! root 143: BOOL, BOOL, BOOL, NUMERIC
! 144: };
1.1.1.6 root 145:
146: /* Possible settings for variables */
147:
148: #define NO_SETTINGS 2
149:
150: static char *settings[] = { "OFF", "ON" };
151:
152: /* Search a list of keywords for a match */
1.1.1.8 ! root 153:
1.1.1.6 root 154: static int lookup( char *key, int keyLength, char *keyWords[], int range )
155: {
1.1.1.8 ! root 156: int index, position = 0, noMatches = 0;
! 157:
! 158: strncpy( optstr, key, keyLength );
! 159: optstr[ keyLength ] = '\0';
1.1.1.6 root 160:
161: /* Make the search case insensitive */
1.1.1.8 ! root 162: for( index = 0; index < keyLength; index++ )
! 163: key[ index ] = to_upper( key[ index ] );
1.1.1.6 root 164:
1.1.1.8 ! root 165: for( index = 0; index < range; index++ )
! 166: if( !strncmp( key, keyWords[ index ], keyLength ) )
! 167: {
! 168: if( strlen( keyWords[ index ] ) == keyLength )
! 169: return index; /* exact match */
! 170: position = index;
! 171: noMatches++;
! 172: }
! 173:
! 174: switch( noMatches )
! 175: {
! 176: case 0:
! 177: fprintf( stderr, "%s: unknown keyword: \"%s\"\n",
! 178: errtag, optstr );
! 179: break;
! 180: case 1:
! 181: return( position ); /* Match succeeded */
! 182: default:
! 183: fprintf( stderr, "%s: \"%s\" is ambiguous\n",
! 184: errtag, optstr );
1.1.1.6 root 185: }
186: return ERROR;
187: }
188:
189: /* Extract a token from a buffer */
1.1.1.8 ! root 190:
1.1.1.6 root 191: static int extractToken( char *buffer, int *endIndex, int *length )
192: {
1.1.1.8 ! root 193: int index = 0, tokenStart;
1.1.1.6 root 194: char ch;
195:
196: /* Skip whitespace */
1.1.1.8 ! root 197: for( ch = buffer[ index ]; ch && ( ch == ' ' || ch == '\t' );
! 198: ch = buffer[ index ] )
! 199: index++;
! 200: tokenStart = index;
1.1.1.6 root 201:
202: /* Find end of setting */
1.1.1.8 ! root 203: while( index < LINEBUF_SIZE && ( ch = buffer[ index ] ) != '\0'
! 204: && ch != ' ' && ch != '\t' )
! 205: index++;
! 206: *endIndex += index;
! 207: *length = index - tokenStart;
1.1.1.6 root 208:
209: /* Return start position of token in buffer */
210: return tokenStart;
211: }
212:
213: /* Get a string constant */
1.1.1.8 ! root 214:
1.1.1.6 root 215: static int getaString( char *buffer, int *endIndex )
216: {
217: boolean noQuote = FALSE;
1.1.1.8 ! root 218: int stringIndex = 0, bufferIndex = 1;
1.1.1.6 root 219: char ch = *buffer;
220:
221: /* Skip whitespace */
222: while( ch && ( ch == ' ' || ch == '\t' ) )
1.1.1.8 ! root 223: ch = buffer[ bufferIndex++ ];
1.1.1.6 root 224:
225: /* Check for non-string */
1.1.1.8 ! root 226: if( ch != '\"' )
! 227: {
! 228: *endIndex += bufferIndex;
1.1.1.6 root 229:
230: /* Check for special case of null string */
1.1.1.8 ! root 231: if( !ch )
! 232: {
1.1.1.6 root 233: *str = '\0';
234: return OK;
1.1.1.8 ! root 235: }
1.1.1.6 root 236:
237: /* Use nasty non-rigorous string format */
238: noQuote = TRUE;
1.1.1.8 ! root 239: }
1.1.1.6 root 240:
241: /* Get first char of string */
242: if( !noQuote )
1.1.1.8 ! root 243: ch = buffer[ bufferIndex++ ];
1.1.1.6 root 244:
245: /* Get string into string */
1.1.1.8 ! root 246: while( ch && ch != '\"' )
! 247: {
1.1.1.6 root 248: /* Exit on '#' if using non-rigorous format */
249: if( noQuote && ch == '#' )
250: break;
251:
252: str[ stringIndex++ ] = ch;
1.1.1.8 ! root 253: ch = buffer[ bufferIndex++ ];
! 254: }
1.1.1.6 root 255:
256: /* If using the non-rigorous format, stomp trailing spaces */
257: if( noQuote )
258: while( stringIndex > 0 && str[ stringIndex - 1 ] == ' ' )
259: stringIndex--;
260:
261: str[ stringIndex++ ] = '\0';
1.1.1.8 ! root 262: *endIndex += bufferIndex;
1.1.1.6 root 263:
264: /* Check for missing string terminator */
1.1.1.8 ! root 265: if( ch != '\"' && !noQuote )
! 266: {
! 267: if( line )
! 268: fprintf( stderr, "%s: unterminated string in line %d\n",
! 269: errtag, line );
1.1.1.6 root 270: else
1.1.1.8 ! root 271: fprintf( stderr, "unterminated string: '\"%s'\n", str );
1.1.1.6 root 272: hasError = TRUE;
273: errCount++;
274: return ERROR;
1.1.1.8 ! root 275: }
1.1.1.6 root 276:
277: return OK;
278: }
279:
280: /* Get an assignment to an intrinsic */
1.1.1.8 ! root 281:
1.1.1.6 root 282: static int getAssignment( char *buffer, int *endIndex, INPUT_TYPE settingType )
283: {
284: int settingIndex = 0, length;
1.1.1.8 ! root 285: long longval;
! 286: char *p;
1.1.1.6 root 287:
288: buffer += extractToken( buffer, endIndex, &length );
289:
290: /* Check for an assignment operator */
1.1.1.8 ! root 291: if( *buffer != '=' )
! 292: {
! 293: if( line )
! 294: fprintf( stderr, "%s: expected '=' in line %d\n",
! 295: errtag, line );
1.1.1.6 root 296: else
1.1.1.8 ! root 297: fprintf( stderr, "%s: expected '=' after \"%s\"\n",
! 298: errtag, optstr);
1.1.1.6 root 299: hasError = TRUE;
300: errCount++;
301: return ERROR;
1.1.1.8 ! root 302: }
! 303: buffer++; /* Skip '=' */
1.1.1.6 root 304:
305: buffer += extractToken( buffer, endIndex, &length );
306:
1.1.1.8 ! root 307: switch( settingType )
1.1.1.6 root 308: {
1.1.1.8 ! root 309: case BOOL:
! 310: /* Check for known intrinsic - really more general
! 311: than just checking for TRUE or FALSE */
! 312: settingIndex = lookup( buffer, length, settings,
! 313: NO_SETTINGS );
! 314: if( settingIndex == ERROR )
! 315: {
! 316: hasError = TRUE;
! 317: errCount++;
! 318: return ERROR;
! 319: }
! 320:
! 321: value = ( settingIndex == 0 ) ? FALSE : TRUE;
! 322: break;
! 323:
! 324: case STRING:
! 325: /* Get a string */
! 326: getaString( buffer, &length );
! 327: break;
! 328:
! 329: case NUMERIC:
! 330: longval = strtol(buffer, &p, 0);
! 331: if (p == buffer+length &&
! 332: longval <= INT_MAX && longval >= INT_MIN) {
! 333: value = (int)longval;
! 334: break;
! 335: }
! 336: if( line )
! 337: fprintf( stderr,
! 338: "%s: numeric argument expected in line %d\n",
! 339: errtag, line );
! 340: else
! 341: fprintf( stderr,
! 342: "%s: numeric argument required for \"%s\"\n",
! 343: errtag, optstr);
1.1.1.6 root 344: hasError = TRUE;
345: errCount++;
346: return ERROR;
347: }
348:
349: return settingIndex;
350: }
351:
352: /* Process an assignment */
1.1.1.8 ! root 353:
1.1.1.6 root 354: static void processAssignment( int intrinsicIndex )
1.1.1.8 ! root 355: {
1.1.1.6 root 356: if( !hasError )
1.1.1.8 ! root 357: switch( intrinsicIndex )
! 358: {
! 359: case ARMOR:
! 360: emit_radix_64 = value;
! 361: break;
1.1.1.6 root 362:
1.1.1.8 ! root 363: case ARMORLINES:
! 364: pem_lines = value;
! 365: break;
1.1.1.6 root 366:
1.1.1.8 ! root 367: case BAKRING:
! 368: strcpy( floppyring, str );
! 369: break;
1.1.1.6 root 370:
1.1.1.8 ! root 371: case BATCHMODE:
! 372: batchmode = value;
! 373: break;
1.1.1.6 root 374:
1.1.1.8 ! root 375: case CERT_DEPTH:
! 376: max_cert_depth = value;
! 377: if( max_cert_depth < MIN_CERT_DEPTH )
! 378: max_cert_depth = MIN_CERT_DEPTH;
! 379: if( max_cert_depth > MAX_CERT_DEPTH )
! 380: max_cert_depth = MAX_CERT_DEPTH;
! 381: break;
1.1.1.6 root 382:
1.1.1.8 ! root 383: case CHARSET:
! 384: strcpy( charset, str );
! 385: break;
1.1.1.6 root 386:
1.1.1.8 ! root 387: case CLEAR:
! 388: clear_signatures = value;
! 389: break;
1.1.1.6 root 390:
1.1.1.8 ! root 391: case COMMENT:
! 392: strcpy( globalCommentString, str );
! 393: break;
1.1.1.6 root 394:
1.1.1.8 ! root 395: case COMPLETES_NEEDED:
! 396: compl_min = value;
! 397: /* Keep within range */
! 398: if( compl_min < MIN_COMPLETE )
! 399: compl_min = MIN_COMPLETE;
! 400: if( compl_min > MAX_COMPLETE )
! 401: compl_min = MAX_COMPLETE;
! 402: break;
1.1.1.6 root 403:
1.1.1.8 ! root 404: case COMPRESS:
! 405: compress_enabled = value;
! 406: break;
1.1.1.6 root 407:
1.1.1.8 ! root 408: case FORCE:
! 409: force_flag = value;
! 410: break;
1.1.1.6 root 411:
1.1.1.8 ! root 412: case INTERACTIVE:
! 413: interactive_add = value;
! 414: break;
1.1.1.6 root 415:
1.1.1.8 ! root 416: case KEEPBINARY:
! 417: keepctx = value;
! 418: break;
1.1.1.6 root 419:
1.1.1.8 ! root 420: case LANGUAGE:
! 421: strncpy( language, str, 15 );
! 422: break;
1.1.1.6 root 423:
1.1.1.8 ! root 424: case MAKERANDOM:
! 425: makerandom = value;
! 426: break;
1.1.1.6 root 427:
1.1.1.8 ! root 428: case MARGINALS_NEEDED:
! 429: marg_min = value;
! 430: /* Keep within range */
! 431: if( marg_min < MIN_MARGINALS )
! 432: marg_min = MIN_MARGINALS;
! 433: break;
1.1.1.6 root 434:
1.1.1.8 ! root 435: case MYNAME:
! 436: strcpy( my_name, str );
! 437: break;
1.1.1.6 root 438:
1.1.1.8 ! root 439: case NOMANUAL:
! 440: nomanual = value;
! 441: break;
1.1.1.6 root 442:
1.1.1.8 ! root 443: case PAGER:
! 444: strcpy( pager, str );
! 445: break;
1.1.1.6 root 446:
1.1.1.8 ! root 447: case PUBRING:
! 448: strcpy( globalPubringName, str );
! 449: break;
1.1.1.6 root 450:
1.1.1.8 ! root 451: case RANDSEED:
! 452: strcpy( globalRandseedName, str );
! 453: break;
1.1.1.6 root 454:
1.1.1.8 ! root 455: case SECRING:
! 456: strcpy( globalSecringName, str );
! 457: break;
1.1.1.6 root 458:
1.1.1.8 ! root 459: case SELF_ENCRYPT:
! 460: encrypt_to_self = value;
! 461: break;
! 462:
! 463: case SHOWPASS:
! 464: showpass = value;
! 465: break;
! 466:
! 467: case TEXTMODE:
! 468: if( value )
! 469: literal_mode = MODE_TEXT;
! 470: else
! 471: literal_mode = MODE_BINARY;
! 472: break;
! 473:
! 474: case TMP:
! 475: /* directory pathname to store temp files */
! 476: settmpdir( str );
! 477: break;
! 478:
! 479: case TZFIX:
! 480: /* How many hours to add to time() to get GMT.
! 481: We just compute the seconds from hours to
! 482: get the GMT shift */
! 483: timeshift = 3600L * ( long ) value;
! 484: break;
! 485:
! 486: case VERBOSE:
! 487: if( value < 1 )
! 488: {
! 489: quietmode = TRUE;
! 490: verbose = FALSE;
! 491: }
! 492: else
! 493: if( value == 1 )
! 494: {
! 495: quietmode = FALSE;
! 496: verbose = FALSE;
! 497: }
! 498: else
! 499: {
! 500: /* Value > 1 */
! 501: quietmode = FALSE;
! 502: verbose = TRUE;
! 503: }
! 504: break;
! 505:
! 506: }
1.1.1.6 root 507: }
508:
509: /* Process an option on a line by itself. This expects options which are
510: taken from the command-line, and is less finicky about errors than the
511: config-file version */
1.1.1.8 ! root 512:
1.1.1.6 root 513: int processConfigLine( char *option )
514: {
1.1.1.8 ! root 515: int index, intrinsicIndex;
1.1.1.6 root 516: char ch;
517:
518: /* Give it a pseudo-linenumber of 0 */
519: line = 0;
520:
521: errtag = "pgp";
522: errCount = 0;
1.1.1.8 ! root 523: for( index = 0;
! 524: index < LINEBUF_SIZE && ( ch = option[ index ] ) != '\0' &&
1.1.1.6 root 525: ch != ' ' && ch != '\t' && ch != '=';
1.1.1.8 ! root 526: index++ );
! 527: if( ( intrinsicIndex = lookup( ( char * ) option, index, intrinsics,
1.1.1.7 root 528: NO_INTRINSICS ) ) == ERROR )
1.1.1.6 root 529: return -1;
1.1.1.8 ! root 530: if( option[ index ] == '\0' && intrinsicType[ intrinsicIndex ] == BOOL)
! 531: {
! 532: /* Boolean option, no '=' means TRUE */
! 533: value = TRUE;
! 534: processAssignment( intrinsicIndex );
! 535: }
! 536: else
! 537: /* Get the value to set to, either as a string, a numeric
! 538: value, or a boolean flag */
! 539: if( getAssignment( ( char * ) option + index,
! 540: &index, intrinsicType[ intrinsicIndex ] ) != ERROR )
1.1.1.6 root 541: processAssignment( intrinsicIndex );
1.1.1.8 ! root 542:
1.1.1.6 root 543: return errCount ? -1 : 0;
544: }
545:
1.1.1.8 ! root 546: /* Process a configuration file */
! 547:
1.1.1.6 root 548: int processConfigFile( char *configFileName )
549: {
550: FILE *configFilePtr;
1.1.1.8 ! root 551: int ch = 0, theChar;
1.1.1.6 root 552: int errType, errPos = 0, lineBufCount, intrinsicIndex;
1.1.1.8 ! root 553: int index;
1.1.1.6 root 554: char inBuffer[ LINEBUF_SIZE ];
555:
556: line = 1;
557: errCount = 0;
1.1.1.8 ! root 558: errtag = file_tail( configFileName );
1.1.1.6 root 559:
1.1.1.8 ! root 560: if( ( configFilePtr = fopen( configFileName, FOPRTXT ) ) == NULL )
! 561: {
! 562: fprintf( stderr, "Cannot open configuration file %s\n",
! 563: configFileName );
! 564: return OK; /* Treat it as if it were an empty file */
! 565: }
1.1.1.6 root 566:
567: /* Process each line in the configFile */
1.1.1.8 ! root 568: while( ch != EOF )
! 569: {
1.1.1.6 root 570: /* Skip whitespace */
1.1.1.7 root 571: while( ( ( ch = getc( configFilePtr ) ) == ' ' || ch == '\t' )
572: && ch != EOF )
1.1.1.8 ! root 573: ;
1.1.1.6 root 574:
575: /* Get a line into the inBuffer */
576: hasError = FALSE;
577: lineBufCount = 0;
578: errType = NO_ERROR;
579: while( ch != '\r' && ch != '\n' && ch != CPM_EOF && ch != EOF )
1.1.1.8 ! root 580: {
1.1.1.6 root 581: /* Check for an illegal char in the data */
1.1.1.7 root 582: if( ( ch < ' ' || ch > '~' ) &&
1.1.1.8 ! root 583: ch != '\r' && ch != '\n' &&
! 584: ch != ' ' && ch != '\t' && ch != CPM_EOF &&
! 585: ch != EOF )
! 586: {
1.1.1.6 root 587: if( errType == NO_ERROR )
1.1.1.8 ! root 588: /* Save pos of first illegal char */
1.1.1.6 root 589: errPos = lineBufCount;
590: errType = ILLEGAL_CHAR_ERROR;
1.1.1.8 ! root 591: }
1.1.1.7 root 592:
1.1.1.8 ! root 593: /* Make sure the path is of the correct length. Note
! 594: that the code is ordered so that a LINELENGTH_ERROR
! 595: takes precedence over an ILLEGAL_CHAR_ERROR */
1.1.1.6 root 596: if( lineBufCount > LINEBUF_SIZE )
597: errType = LINELENGTH_ERROR;
598: else
599: inBuffer[ lineBufCount++ ] = ch;
600:
601: if( ( ch = getc( configFilePtr ) ) == '#' )
1.1.1.8 ! root 602: {
1.1.1.7 root 603: /* Skip comment section and trailing
604: whitespace */
1.1.1.8 ! root 605: while( ch != '\r' && ch != '\n' &&
! 606: ch != CPM_EOF && ch != EOF )
1.1.1.7 root 607: ch = getc( configFilePtr );
1.1.1.6 root 608: break;
1.1.1.8 ! root 609: }
1.1.1.6 root 610: }
611:
612: /* Skip trailing whitespace and add der terminador */
1.1.1.8 ! root 613: while( lineBufCount &&
! 614: ( ( theChar = inBuffer[ lineBufCount - 1 ] ) == ' ' ||
! 615: theChar == '\t' ) )
1.1.1.7 root 616: lineBufCount--;
1.1.1.6 root 617: inBuffer[ lineBufCount ] = '\0';
618:
619: /* Process the line unless its a blank or comment line */
620: if( lineBufCount && *inBuffer != '#' )
621: {
1.1.1.8 ! root 622: switch( errType )
! 623: {
! 624: case LINELENGTH_ERROR:
! 625: fprintf( stderr,
! 626: "%s: line '%.30s...' too long\n",
! 627: errtag, inBuffer );
! 628: errCount++;
! 629: break;
1.1.1.6 root 630:
1.1.1.8 ! root 631: case ILLEGAL_CHAR_ERROR:
! 632: fprintf( stderr, "> %s\n ", inBuffer );
! 633: fprintf( stderr, "%*s^\n", errPos, "" );
! 634: fprintf( stderr,
! 635: "%s: bad character in command on line %d\n",
! 636: errtag, line );
! 637: errCount++;
! 638: break;
1.1.1.6 root 639:
1.1.1.8 ! root 640: default:
! 641: for( index = 0;
! 642: index < LINEBUF_SIZE &&
! 643: ( ch = inBuffer[ index ] ) != '\0'
! 644: && ch != ' ' && ch != '\t'
! 645: && ch != '=';
! 646: index++ )
! 647: /*Do nothing*/ ;
! 648:
! 649: /* Try and find the intrinsic. We
! 650: don't treat unknown intrinsics as
! 651: an error to allow older versions to
! 652: be used with new config files */
! 653: intrinsicIndex = lookup(inBuffer,
! 654: index, intrinsics,
! 655: CONFIG_INTRINSICS );
1.1.1.7 root 656:
1.1.1.8 ! root 657: if( intrinsicIndex == ERROR )
! 658: break;
! 659:
! 660: /* Get the value to set to, either as
! 661: a string, a numeric value, or a
! 662: boolean flag */
! 663: getAssignment( inBuffer + index, &index,
! 664: intrinsicType[ intrinsicIndex ] );
! 665: processAssignment( intrinsicIndex );
! 666: break;
1.1.1.6 root 667: }
668: }
669:
1.1.1.8 ! root 670: /* Handle special-case of ^Z if configFile came off an
! 671: MSDOS system */
1.1.1.6 root 672: if( ch == CPM_EOF )
673: ch = EOF;
674:
675: /* Exit if there are too many errors */
676: if( errCount >= MAX_ERRORS )
677: break;
678:
679: line++;
1.1.1.8 ! root 680: }
1.1.1.6 root 681:
682: fclose( configFilePtr );
683:
684: /* Exit if there were errors */
1.1.1.8 ! root 685: if( errCount )
! 686: {
! 687: fprintf( stderr, "%s: %s%d error(s) detected\n\n",
! 688: configFileName, ( errCount >= MAX_ERRORS ) ?
! 689: "Maximum level of " : "", errCount );
1.1.1.6 root 690: return ERROR;
1.1.1.8 ! root 691: }
1.1.1.6 root 692:
693: return OK;
694: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.