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

1.1     ! root        1: /*     config.c  - config file parser by Peter Gutmann
        !             2:        Parses config file for PGP
        !             3: 
        !             4:        Modified 24 Jun 92 - HAJK
        !             5:        Misc fixes for VAX C restrictions.
        !             6: 
        !             7: */
        !             8: 
        !             9: #include <ctype.h>
        !            10: #include <string.h>
        !            11: #include <stdio.h>
        !            12: #include <stdlib.h>
        !            13: #include "usuals.h"
        !            14: #include "pgp.h"
        !            15: /* The external config variables we can set here are referenced in pgp.h */
        !            16: 
        !            17: /* Return values */
        !            18: 
        !            19: #define ERROR  -1
        !            20: #define OK             0
        !            21: 
        !            22: /* The types of error we check for */
        !            23: 
        !            24: enum { NO_ERROR, ILLEGAL_CHAR_ERROR, LINELENGTH_ERROR };
        !            25: 
        !            26: #define CPM_EOF                        0x1A    /* ^Z = CPM EOF char */
        !            27: 
        !            28: #define MAX_ERRORS             3               /* Max.no.errors before we give up */
        !            29: 
        !            30: #define LINEBUF_SIZE   100             /* Size of input buffer */
        !            31: 
        !            32: int line;                                              /* The line on which an error occurred */
        !            33: int errCount;                                  /* Total error count */
        !            34: boolean hasError;                              /* Whether this line has an error in it */
        !            35: 
        !            36: /* The settings parsed out by getAssignment() */
        !            37: 
        !            38: char str[ LINEBUF_SIZE ];
        !            39: int value;
        !            40: boolean flag;
        !            41: 
        !            42: /* A .CFG file roughly follows the format used in the world-famous HPACK
        !            43:    archiver and is as follows:
        !            44: 
        !            45:        - Leading spaces/tabs (whitespace) are ignored.
        !            46: 
        !            47:        - Lines with a '#' as the first non-whitespace character are treated as
        !            48:          comment lines.
        !            49: 
        !            50:        - All other lines are treated as config options for the program.
        !            51: 
        !            52:        - Lines may be terminated by either linefeeds, carriage returns, or
        !            53:          carriage return/linefeed pairs (the latter being the DOS default method
        !            54:          of storing text files).
        !            55: 
        !            56:        - Config options have the form:
        !            57: 
        !            58:          <option> '=' <setting>
        !            59: 
        !            60:          where <setting> may be 'on', 'off', a numeric value, or a string
        !            61:          value.
        !            62: 
        !            63:        - If strings have spaces or the '#' character inside them they must be
        !            64:          surrounded by quote marks '"' */
        !            65: 
        !            66: /* The types of input we can expect */
        !            67: 
        !            68: typedef enum { BOOL, NUMERIC, STRING } INPUT_TYPE;
        !            69: 
        !            70: /* Intrinsic variables */
        !            71: 
        !            72: #define NO_INTRINSICS          17
        !            73: 
        !            74: enum
        !            75: {      ARMOR, COMPRESS, SHOWPASS, KEEPBINARY, LANGUAGE,
        !            76:        MYNAME, TEXTMODE, TMP, TZFIX, VERBOSE, BAKRING,
        !            77:        ARMORLINES, COMPLETES_NEEDED, MARGINALS_NEEDED, PAGER,
        !            78:        CERT_DEPTH, CHARSET
        !            79: };
        !            80: 
        !            81: char *intrinsics[] =
        !            82: {      "ARMOR", "COMPRESS", "SHOWPASS", "KEEPBINARY", "LANGUAGE",
        !            83:        "MYNAME", "TEXTMODE", "TMP", "TZFIX", "VERBOSE", "BAKRING",
        !            84:        "ARMORLINES", "COMPLETES_NEEDED", "MARGINALS_NEEDED", "PAGER",
        !            85:        "CERT_DEPTH", "CHARSET"
        !            86: };
        !            87: 
        !            88: INPUT_TYPE intrinsicType[] =
        !            89: {      BOOL, BOOL, BOOL, BOOL, STRING,
        !            90:        STRING, BOOL, STRING, NUMERIC, BOOL, STRING,
        !            91:        NUMERIC, NUMERIC, NUMERIC, STRING,
        !            92:        NUMERIC, STRING
        !            93: };
        !            94: 
        !            95: /* Possible settings for variables */
        !            96: 
        !            97: #define NO_SETTINGS                    2
        !            98: 
        !            99: char *settings[] = { "OFF", "ON" };
        !           100: 
        !           101: 
        !           102: /* Search a list of keywords for a match */
        !           103: 
        !           104: int lookup( char *key, int keyLength, char *keyWords[], int range )
        !           105:        {
        !           106:        int index;
        !           107: 
        !           108:        /* Make the search case insensitive */
        !           109:        for( index = 0; index < keyLength; index++ )
        !           110:                key[ index ] = toupper( key[ index ] );
        !           111: 
        !           112:        for( index = 0; index < range; index++ )
        !           113:                if( !strncmp( key, keyWords[ index ], keyLength ) )
        !           114:                        return( index );
        !           115: 
        !           116:        /* Key not found */
        !           117:        return( ERROR );
        !           118:        }
        !           119: 
        !           120: /* Extract a token from a buffer */
        !           121: int extractToken( char *buffer, int *endIndex, int *length )
        !           122: {
        !           123:        int index = 0, tokenStart;
        !           124:        char ch;
        !           125: 
        !           126:        /* Skip whitespace */
        !           127:        for( ch = buffer[ index ]; ch && ( ch == ' ' || ch == '\t' ); ch = buffer[ index ] )
        !           128:                index++;
        !           129:        tokenStart = index;
        !           130: 
        !           131:        /* Find end of setting */
        !           132:        while( index < LINEBUF_SIZE && ( ch = buffer[ index ] ) != '\0' && ch != ' ' && ch != '\t' )
        !           133:                index++;
        !           134:        *endIndex += index;
        !           135:        *length = index - tokenStart;
        !           136: 
        !           137:        /* Return start position of token in buffer */
        !           138:        return( tokenStart );
        !           139: }
        !           140: 
        !           141: 
        !           142: /* Get a string constant */
        !           143: int getaString( char *buffer, int *endIndex )
        !           144:        {
        !           145:        boolean noQuote = FALSE;
        !           146:        int stringIndex = 0, bufIndex = 1;
        !           147:        char ch = *buffer;
        !           148: 
        !           149:        /* Skip whitespace */
        !           150:        while( ch && ( ch == ' ' || ch == '\t' ) )
        !           151:                ch = buffer[ bufIndex++ ];
        !           152: 
        !           153:        /* Check for non-string */
        !           154:        if( ch != '\"' )
        !           155:                {
        !           156:                *endIndex += bufIndex;
        !           157: 
        !           158:                /* Check for special case of null string */
        !           159:                if( !ch )
        !           160:                        {
        !           161:                        *str = '\0';
        !           162:                        return( OK );
        !           163:                        }
        !           164: 
        !           165:                /* Use nasty non-rigorous string format */
        !           166:                noQuote = TRUE;
        !           167:                }
        !           168: 
        !           169:        /* Get first char of string */
        !           170:        if( !noQuote )
        !           171:                ch = buffer[ bufIndex++ ];
        !           172: 
        !           173:        /* Get string into string */
        !           174:        while( ch && ch != '\"' )
        !           175:                {
        !           176:                /* Exit on '#' if using non-rigorous format */
        !           177:                if( noQuote && ch == '#' )
        !           178:                        break;
        !           179: 
        !           180:                str[ stringIndex++ ] = ch;
        !           181:                ch = buffer[ bufIndex++ ];
        !           182:                }
        !           183: 
        !           184:        /* If using the non-rigorous format, stomp trailing spaces */
        !           185:        if( noQuote )
        !           186:                while( stringIndex > 0 && str[ stringIndex - 1 ] == ' ' )
        !           187:                        stringIndex--;
        !           188: 
        !           189:        str[ stringIndex++ ] = '\0';
        !           190:        *endIndex += bufIndex;
        !           191: 
        !           192:        /* Check for missing string terminator */
        !           193:        if( ch != '\"' && !noQuote )
        !           194:                {
        !           195:                printf( "Unterminated string in line %d\n", line );
        !           196:                hasError = TRUE;
        !           197:                errCount++;
        !           198:                return( ERROR );
        !           199:                }
        !           200: 
        !           201:        return( OK );
        !           202:        }
        !           203: 
        !           204: /* Get an assignment to an intrinsic */
        !           205: int getAssignment( char *buffer, int *endIndex, INPUT_TYPE settingType )
        !           206: {
        !           207:        int settingIndex = 0, length;
        !           208: 
        !           209:        buffer += extractToken( buffer, endIndex, &length );
        !           210: 
        !           211:        /* Check for an assignment operator */
        !           212:        if ( *buffer != '=' )
        !           213:        {
        !           214:                printf( "Expected '=' in line %d\n", line );
        !           215:                hasError = TRUE;
        !           216:                errCount++;
        !           217:                return( ERROR );
        !           218:        }
        !           219:        buffer++;               /* Skip '=' */
        !           220: 
        !           221:        buffer += extractToken( buffer, endIndex, &length );
        !           222: 
        !           223:        switch( settingType )
        !           224:        {
        !           225:                case BOOL:
        !           226:                        /* Check for known intrinsic - really more general than just
        !           227:                           checking for TRUE or FALSE */
        !           228:                        if( ( settingIndex = lookup( buffer, length, settings, NO_SETTINGS ) ) == ERROR )
        !           229:                        {
        !           230:                                printf( "Unknown setting '%s' in line %d\n", buffer, line );
        !           231:                                hasError = TRUE;
        !           232:                                errCount++;
        !           233:                                return( ERROR );
        !           234:                        }
        !           235: 
        !           236:                        flag = ( settingIndex == 0 ) ? FALSE : TRUE;
        !           237:                        break;
        !           238: 
        !           239:                case STRING:
        !           240:                        /* Get a string */
        !           241:                        getaString( buffer, &length );
        !           242:                        break;
        !           243: 
        !           244:                case NUMERIC:
        !           245:                        /* Get numeric input.  Error checking is a pain since atoi()
        !           246:                                has no real equivalent of NAN */
        !           247:                        value = atoi( buffer );
        !           248:                        break;
        !           249:        }
        !           250: 
        !           251:        return( settingIndex );
        !           252: }
        !           253: 
        !           254: 
        !           255: /* Process a config file */
        !           256: int processConfigFile( char *configFileName )
        !           257: {
        !           258:        FILE *configFilePtr;
        !           259:        int ch = 0, theCh;
        !           260:        int errType, errPos = 0, lineBufCount, intrinsicIndex;
        !           261:        int index;
        !           262:        char inBuffer[ LINEBUF_SIZE ];
        !           263: 
        !           264:        line = 1;
        !           265:        errCount = 0;
        !           266: 
        !           267:        if( ( configFilePtr = fopen( configFileName, "r" ) ) == NULL )
        !           268:        {
        !           269:                printf( "Cannot open configuration file %s\n", configFileName );
        !           270:                return( OK );   /* treat like empty config file */
        !           271:        }
        !           272: 
        !           273:        /* Process each line in the configFile */
        !           274:        while( ch != EOF )
        !           275:        {
        !           276:                /* Skip whitespace */
        !           277:                while( ( ( ch = getc( configFilePtr ) ) == ' ' || ch == '\t' ) && ch != EOF );
        !           278: 
        !           279:                /* Get a line into the inBuffer */
        !           280:                hasError = FALSE;
        !           281:                lineBufCount = 0;
        !           282:                errType = NO_ERROR;
        !           283:                while( ch != '\r' && ch != '\n' && ch != CPM_EOF && ch != EOF )
        !           284:                {
        !           285:                        /* Check for an illegal char in the data */
        !           286:                        if( ( ch < ' ' || ch > '~' ) && ch != '\r' && ch != '\n' &&
        !           287:                                ch != ' ' && ch != '\t' && ch != CPM_EOF && ch != EOF )
        !           288:                        {
        !           289:                                if( errType == NO_ERROR )
        !           290:                                        /* Save position of first illegal char */
        !           291:                                        errPos = lineBufCount;
        !           292:                                errType = ILLEGAL_CHAR_ERROR;
        !           293:                        }
        !           294: 
        !           295:                        /* Make sure the path is of the correct length.  Note that the
        !           296:                           code is ordered so that a LINELENGTH_ERROR takes precedence over
        !           297:                           an ILLEGAL_CHAR_ERROR */
        !           298:                        if( lineBufCount > LINEBUF_SIZE )
        !           299:                                errType = LINELENGTH_ERROR;
        !           300:                        else
        !           301:                                inBuffer[ lineBufCount++ ] = ch;
        !           302: 
        !           303:                        if( ( ch = getc( configFilePtr ) ) == '#' )
        !           304:                        {
        !           305:                                /* Skip comment section and trailing whitespace */
        !           306:                                while( ch != '\r' && ch != '\n' && ch != CPM_EOF && ch != EOF )
        !           307:                                        ch = getc( configFilePtr );
        !           308:                                break;
        !           309:                        }
        !           310:                }
        !           311: 
        !           312:                /* Skip trailing whitespace and add der terminador */
        !           313:                while( ( theCh = inBuffer[ lineBufCount - 1 ] ) == ' ' || theCh == '\t' )
        !           314:                        lineBufCount--;
        !           315:                inBuffer[ lineBufCount ] = '\0';
        !           316: 
        !           317:                /* Process the line unless its a blank or comment line */
        !           318:                if( lineBufCount && *inBuffer != '#' )
        !           319:                {
        !           320:                        switch( errType )
        !           321:                        {
        !           322:                                case LINELENGTH_ERROR:
        !           323:                                        inBuffer[ 80 - strlen( "Line '%s...' too long\n" ) - 3 ] = '\0';
        !           324:                                                                /* Truncate to fit screen size (3 = '%s' + 1) */
        !           325:                                        printf( "Line '%s...' too long\n", inBuffer );
        !           326:                                        errCount++;
        !           327:                                        break;
        !           328: 
        !           329:                                case ILLEGAL_CHAR_ERROR:
        !           330:                                        printf( "> %s\n  ", inBuffer );
        !           331:                                        while( errPos-- )
        !           332:                                                putchar( ' ' );
        !           333:                                        printf( "^ Bad character in command on line %d\n", line );
        !           334:                                        errCount++;
        !           335:                                        break;
        !           336: 
        !           337:                                default:
        !           338:                                        for( index = 0;
        !           339:                                                 index < LINEBUF_SIZE && ( ch = inBuffer[ index ] ) != '\0' && ch != ' ' && ch != '\t';
        !           340:                                                 index++ );
        !           341:                                        if( ( intrinsicIndex = lookup( inBuffer, index, intrinsics, NO_INTRINSICS ) ) == ERROR )
        !           342:                                        {
        !           343:                                                printf( "Unknown command '%s' in line %d\n", inBuffer, line );
        !           344:                                                errCount++;
        !           345:                                        }
        !           346:                                        else
        !           347:                                        {
        !           348:                                                /* Get the value to set to, either as a string, a
        !           349:                                                   numeric value, or a boolean flag */
        !           350:                                                getAssignment( inBuffer + index, &index, intrinsicType[ intrinsicIndex ] );
        !           351: 
        !           352:                                                if( !hasError )
        !           353:                                                        switch( intrinsicIndex )
        !           354:                                                        {
        !           355:                                                                case ARMOR:
        !           356:                                                                        emit_radix_64 = flag;
        !           357:                                                                        break;
        !           358: 
        !           359:                                                                case COMPRESS:
        !           360:                                                                        compress_enabled = flag;
        !           361:                                                                        break;
        !           362: 
        !           363:                                                                case SHOWPASS:
        !           364:                                                                        showpass = flag;
        !           365:                                                                        break;
        !           366: 
        !           367:                                                                case KEEPBINARY:
        !           368:                                                                        keepctx = flag;
        !           369:                                                                        break;
        !           370: 
        !           371:                                                                case LANGUAGE:
        !           372:                                                                        strncpy(language, str, 15);
        !           373:                                                                        break;
        !           374: 
        !           375:                                                                case BAKRING:
        !           376:                                                                        strcpy(floppyring, str);
        !           377:                                                                        break;
        !           378: 
        !           379:                                                                case MYNAME:
        !           380:                                                                        strcpy(my_name, str);
        !           381:                                                                        break;
        !           382: 
        !           383:                                                                case TEXTMODE:
        !           384:                                                                        if( flag )
        !           385:                                                                                lit_mode = MODE_TEXT;
        !           386:                                                                        break;
        !           387: 
        !           388:                                                                case TMP:
        !           389:                                                                        /* directory pathname to store temp files */
        !           390:                                                                        strcpy(tmpdir, str);
        !           391:                                                                        break;
        !           392: 
        !           393:                                                                case TZFIX:
        !           394:                                                                        /* How many hours to add to time() to get GMT. */
        !           395:                                                                        /* Compute seconds from hours to shift to GMT: */
        !           396:                                                                        timeshift = 3600L * (long) value;
        !           397:                                                                        break;
        !           398: 
        !           399:                                                                case VERBOSE:
        !           400:                                                                        verbose = flag;
        !           401:                                                                        break;
        !           402:                                                                
        !           403:                                                                case ARMORLINES:
        !           404:                                                                        pem_lines = value;
        !           405:                                                                        break;
        !           406: 
        !           407:                                                                case MARGINALS_NEEDED:
        !           408:                                                                        marg_min = value;
        !           409:                                                                        if (marg_min < 1) 
        !           410:                                                                                marg_min = 1;
        !           411:                                                                        break;
        !           412: 
        !           413:                                                                case COMPLETES_NEEDED:
        !           414:                                                                        compl_min = value;
        !           415:                                                                        if (compl_min < 1) 
        !           416:                                                                                compl_min = 1;
        !           417:                                                                        if (compl_min > 4) 
        !           418:                                                                                compl_min = 4;
        !           419:                                                                        break;
        !           420: 
        !           421:                                                                case CERT_DEPTH:
        !           422:                                                                        max_cert_depth = value;
        !           423:                                                                        if (max_cert_depth < 0) 
        !           424:                                                                                max_cert_depth = 0;
        !           425:                                                                        if (max_cert_depth > 8) 
        !           426:                                                                                max_cert_depth = 8;
        !           427:                                                                        break;
        !           428: 
        !           429:                                                                case PAGER:
        !           430:                                                                        strcpy(pager, str);
        !           431:                                                                        break;
        !           432:                                                                
        !           433:                                                                case CHARSET:
        !           434:                                                                        strcpy(charset, str);
        !           435:                                                                        break;
        !           436: 
        !           437:                                                        }
        !           438:                                        }
        !           439:                        }
        !           440:                }
        !           441: 
        !           442:                /* Handle special-case of ^Z if configFile came off an MSDOS system */
        !           443:                if( ch == CPM_EOF )
        !           444:                        ch = EOF;
        !           445: 
        !           446:                /* Exit if there are too many errors */
        !           447:                if( errCount >= MAX_ERRORS )
        !           448:                        break;
        !           449: 
        !           450:                line++;
        !           451:        }
        !           452: 
        !           453:        fclose( configFilePtr );
        !           454: 
        !           455:        /* Exit if there were errors */
        !           456:        if( errCount )
        !           457:        {
        !           458:                printf( "%s%d errors detected\n", ( errCount >= MAX_ERRORS ) ?
        !           459:                                "Maximum level of " : "", errCount );
        !           460:                return( ERROR );
        !           461:        }
        !           462: 
        !           463:        return( OK );
        !           464: }

unix.superglobalmegacorp.com

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