Annotation of pgp/src/config.c, revision 1.1.1.9

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.