Annotation of 43BSDReno/kerberosIV/krb/kparse.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * $Source: /mit/kerberos/src/lib/krb/RCS/kparse.c,v $
                      3:  * $Author: jtkohl $
                      4:  *
                      5:  * Copyright 1988 by the Massachusetts Institute of Technology.
                      6:  *
                      7:  * For copying and distribution information, please see the file
                      8:  * <mit-copyright.h>.
                      9:  *
                     10:  * Purpose:
                     11:  * This module was developed to parse the "~/.klogin" files for
                     12:  * Kerberos-authenticated rlogin/rcp/rsh services.  However, it is
                     13:  * general purpose and can be used to parse any such parameter file.
                     14:  *
                     15:  * The parameter file should consist of one or more entries, with each
                     16:  * entry on a separate line and consisting of zero or more
                     17:  * "keyword=value" combinations.  The keyword is case insensitive, but
                     18:  * the value is not.  Any string may be enclosed in quotes, and
                     19:  * c-style "\" literals are supported.  A comma may be used to
                     20:  * separate the k/v combinations, and multiple commas are ignored.
                     21:  * Whitespace (blank or tab) may be used freely and is ignored.
                     22:  *
                     23:  * Full error processing is available.  When PS_BAD_KEYWORD or
                     24:  * PS_SYNTAX is returned from fGetParameterSet(), the string ErrorMsg
                     25:  * contains a meaningful error message.
                     26:  *
                     27:  * Keywords and their default values are programmed by an external
                     28:  * table.
                     29:  *
                     30:  * Routines:
                     31:  * fGetParameterSet()      parse one line of the parameter file
                     32:  * fGetKeywordValue()      parse one "keyword=value" combo
                     33:  * fGetToken()             parse one token
                     34:  */
                     35: 
                     36: #ifndef        lint
                     37: static char rcsid_kparse_c[] =
                     38: "$Header: kparse.c,v 4.5 89/01/21 17:20:39 jtkohl Exp $";
                     39: #endif lint
                     40: 
                     41: #include <mit-copyright.h>
                     42: #include <stdio.h>
                     43: #include <ctype.h>
                     44: #include <kparse.h>
                     45: 
                     46: #ifndef FALSE
                     47: #define FALSE 0
                     48: #define TRUE 1
                     49: #endif
                     50: 
                     51: #define void int
                     52: 
                     53: #define MAXKEY          80
                     54: #define MAXVALUE        80
                     55: 
                     56: char *malloc();
                     57: char *strcpy();
                     58: 
                     59: int LineNbr=1;         /* current line nbr in parameter file */
                     60: char ErrorMsg[80];     /* meaningful only when KV_SYNTAX, PS_SYNTAX,
                     61:                          * or PS_BAD_KEYWORD is returned by
                     62:                          * fGetKeywordValue or fGetParameterSet */
                     63: 
                     64: int fGetParameterSet( fp,parm,parmcount )
                     65:     FILE *fp;
                     66:     parmtable parm[];
                     67:     int parmcount;
                     68: {
                     69:     int rc,i;
                     70:     char keyword[MAXKEY];
                     71:     char value[MAXVALUE];
                     72: 
                     73:     while (TRUE) {
                     74:         rc=fGetKeywordValue(fp,keyword,MAXKEY,value,MAXVALUE);
                     75: 
                     76:         switch (rc) {
                     77: 
                     78:         case KV_EOF:
                     79:             return(PS_EOF);
                     80: 
                     81:         case KV_EOL:
                     82:             return(PS_OKAY);
                     83: 
                     84:         case KV_SYNTAX:
                     85:             return(PS_SYNTAX);
                     86: 
                     87:         case KV_OKAY:
                     88:             /*
                     89:              * got a reasonable keyword/value pair.  Search the
                     90:              * parameter table to see if we recognize the keyword; if
                     91:              * not, return an error.  If we DO recognize it, make sure
                     92:              * it has not already been given.  If not already given,
                     93:              * save the value.
                     94:              */
                     95:             for (i=0; i<parmcount; i++) {
                     96:                 if (strcmp(strutol(keyword),parm[i].keyword)==0) {
                     97:                     if (parm[i].value) {
                     98:                         sprintf(ErrorMsg,"duplicate keyword \"%s\" found",
                     99:                                 keyword);
                    100:                         return(PS_BAD_KEYWORD);
                    101:                     }
                    102:                     parm[i].value = strsave( value );
                    103:                     break;
                    104:                 }
                    105:             }
                    106:             if (i >= parmcount) {
                    107:                 sprintf(ErrorMsg, "unrecognized keyword \"%s\" found",
                    108:                        keyword);
                    109:                 return(PS_BAD_KEYWORD);
                    110:             }
                    111:             break;
                    112: 
                    113:         default:
                    114:             sprintf(ErrorMsg,
                    115:                    "panic: bad return (%d) from fGetToken()",rc);
                    116:             break;
                    117:         }
                    118:     }
                    119: }
                    120: 
                    121: /*
                    122:  * Routine: ParmCompare
                    123:  *
                    124:  * Purpose:
                    125:  * ParmCompare checks a specified value for a particular keyword.
                    126:  * fails if keyword not found or keyword found but the value was
                    127:  * different. Like strcmp, ParmCompare returns 0 for a match found, -1
                    128:  * otherwise
                    129:  */
                    130: int ParmCompare( parm, parmcount, keyword, value )
                    131:     parmtable parm[];
                    132:     int parmcount;
                    133:     char *keyword;
                    134:     char *value;
                    135: {
                    136:     int i;
                    137: 
                    138:     for (i=0; i<parmcount; i++) {
                    139:         if (strcmp(parm[i].keyword,keyword)==0) {
                    140:             if (parm[i].value) {
                    141:                 return(strcmp(parm[i].value,value));
                    142:             } else {
                    143:                 return(strcmp(parm[i].defvalue,value));
                    144:             }
                    145:         }
                    146:     }
                    147:     return(-1);
                    148: }
                    149: 
                    150: void FreeParameterSet(parm,parmcount)
                    151:     parmtable parm[];
                    152:     int parmcount;
                    153: {
                    154:     int i;
                    155: 
                    156:     for (i=0; i<parmcount; i++) {
                    157:         if (parm[i].value) {
                    158:             free(parm[i].value);
                    159:             parm[i].value = (char *)NULL;
                    160:         }
                    161:     }
                    162: }
                    163: 
                    164: int fGetKeywordValue( fp, keyword, klen, value, vlen )
                    165:     FILE *fp;
                    166:     char *keyword;
                    167:     int klen;
                    168:     char *value;
                    169:     int vlen;
                    170: {
                    171:     int rc;
                    172:     int gotit;
                    173: 
                    174:     *keyword = *value = '\0';   /* preset strings to NULL */
                    175: 
                    176:     /*
                    177:      * Looking for a keyword.
                    178:      *          return an exception for EOF or BAD_QSTRING
                    179:      *          ignore leading WHITEspace
                    180:      *          ignore any number of leading commas
                    181:      *          newline means we have all the parms for this
                    182:      *                 statement; give an indication that there is
                    183:      *                 nothing more on this line.
                    184:      *          stop looking if we find QSTRING, STRING, or NUMBER
                    185:      *          return syntax error for any other PUNKtuation
                    186:      */
                    187:     gotit = FALSE;
                    188:     do {
                    189:         rc = fGetToken(fp,keyword,klen);
                    190: 
                    191:         switch (rc) {
                    192: 
                    193:         case GTOK_WHITE:
                    194:             break;
                    195: 
                    196:         case GTOK_EOF:
                    197:             return(KV_EOF);
                    198: 
                    199:         case GTOK_BAD_QSTRING:
                    200:             sprintf(ErrorMsg,"unterminated string \"%s found",keyword);
                    201:             return(KV_SYNTAX);
                    202: 
                    203:         case GTOK_PUNK:
                    204:             if (strcmp("\n",keyword)==0) {
                    205:                 return(KV_EOL);
                    206:             } else if (strcmp(",",keyword)!=0) {
                    207:                 sprintf(ErrorMsg,"expecting rvalue, found \'%s\'",keyword);
                    208:             }
                    209:             break;
                    210: 
                    211:         case GTOK_STRING:
                    212:         case GTOK_QSTRING:
                    213:         case GTOK_NUMBER:
                    214:             gotit = TRUE;
                    215:             break;
                    216: 
                    217:         default:
                    218:             sprintf(ErrorMsg,"panic: bad return (%d) from fGetToken()",rc);
                    219:             return(KV_SYNTAX);
                    220:         }
                    221: 
                    222:     } while (!gotit);
                    223: 
                    224:     /*
                    225:      * now we expect an equal sign.
                    226:      *          skip any whitespace
                    227:      *          stop looking if we find an equal sign
                    228:      *          anything else causes a syntax error
                    229:      */
                    230:     gotit = FALSE;
                    231:     do {
                    232:         rc = fGetToken(fp,value,vlen);
                    233: 
                    234:         switch (rc) {
                    235: 
                    236:         case GTOK_WHITE:
                    237:             break;
                    238: 
                    239:         case GTOK_BAD_QSTRING:
                    240:             sprintf(ErrorMsg,
                    241:                    "expecting \'=\', found unterminated string \"%s",
                    242:                     value);
                    243:             return(KV_SYNTAX);
                    244: 
                    245:         case GTOK_PUNK:
                    246:             if (strcmp("=",value)==0) {
                    247:                 gotit = TRUE;
                    248:             } else {
                    249:                 if (strcmp("\n",value)==0) {
                    250:                     sprintf(ErrorMsg,"expecting \"=\", found newline");
                    251:                     fUngetChar('\n',fp);
                    252:                 } else {
                    253:                     sprintf(ErrorMsg,
                    254:                            "expecting rvalue, found \'%s\'",keyword);
                    255:                 }
                    256:                 return(KV_SYNTAX);
                    257:             }
                    258:             break;
                    259: 
                    260:         case GTOK_STRING:
                    261:         case GTOK_QSTRING:
                    262:         case GTOK_NUMBER:
                    263:             sprintf(ErrorMsg,"expecting \'=\', found \"%s\"",value);
                    264:             return(KV_SYNTAX);
                    265: 
                    266:         case GTOK_EOF:
                    267:             sprintf(ErrorMsg,"expecting \'=\', found EOF");
                    268:             return(KV_SYNTAX);
                    269: 
                    270:         default:
                    271:             sprintf(ErrorMsg,
                    272:                    "panic: bad return (%d) from fGetToken()",rc);
                    273:             return(KV_SYNTAX);
                    274:         }
                    275: 
                    276:     } while ( !gotit );
                    277: 
                    278:     /*
                    279:      * got the keyword and equal sign, now get a value.
                    280:      *          ignore any whitespace
                    281:      *          any punctuation is a syntax error
                    282:      */
                    283:     gotit = FALSE;
                    284:     do {
                    285:         rc = fGetToken(fp,value,vlen);
                    286: 
                    287:         switch (rc) {
                    288: 
                    289:         case GTOK_WHITE:
                    290:             break;
                    291: 
                    292:         case GTOK_EOF:
                    293:             sprintf(ErrorMsg,"expecting rvalue, found EOF");
                    294:             return(KV_SYNTAX);
                    295: 
                    296:         case GTOK_BAD_QSTRING:
                    297:             sprintf(ErrorMsg,"unterminated quoted string \"%s",value);
                    298:             return(KV_SYNTAX);
                    299: 
                    300:         case GTOK_PUNK:
                    301:             if (strcmp("\n",value)==0) {
                    302:                 sprintf(ErrorMsg,"expecting rvalue, found newline");
                    303:                 fUngetChar('\n',fp);
                    304:             } else {
                    305:                 sprintf(ErrorMsg,
                    306:                        "expecting rvalue, found \'%s\'",value);
                    307:             }
                    308:             return(KV_SYNTAX);
                    309:             break;
                    310: 
                    311:         case GTOK_STRING:
                    312:         case GTOK_QSTRING:
                    313:         case GTOK_NUMBER:
                    314:             gotit = TRUE;
                    315:             return(KV_OKAY);
                    316: 
                    317:         default:
                    318:             sprintf(ErrorMsg,
                    319:                    "panic: bad return (%d) from fGetToken()",rc);
                    320:             return(KV_SYNTAX);
                    321:         }
                    322: 
                    323:     } while ( !gotit );
                    324:     /*NOTREACHED*/
                    325: }
                    326: 
                    327: /*
                    328:  * Routine Name: fGetToken
                    329:  *
                    330:  * Function: read the next token from the specified file.
                    331:  * A token is defined as a group of characters
                    332:  * terminated by a white space char (SPACE, CR,
                    333:  * LF, FF, TAB). The token returned is stripped of
                    334:  * both leading and trailing white space, and is
                    335:  * terminated by a NULL terminator.  An alternate
                    336:  * definition of a token is a string enclosed in
                    337:  * single or double quotes.
                    338:  *
                    339:  * Explicit Parameters:
                    340:  * fp              pointer to the input FILE
                    341:  * dest    pointer to destination buffer
                    342:  * maxlen  length of the destination buffer. The buffer
                    343:  * length INCLUDES the NULL terminator.
                    344:  *
                    345:  * Implicit Parameters: stderr  where the "token too long" message goes
                    346:  *
                    347:  * External Procedures: fgetc
                    348:  *
                    349:  * Side Effects:                None
                    350:  *
                    351:  * Return Value:                A token classification value, as
                    352:  *                             defined in kparse.h. Note that the
                    353:  *                             classification for end of file is
                    354:  *                             always zero.
                    355:  */
                    356: int fGetToken(fp, dest, maxlen)
                    357:     FILE *fp;
                    358:     char *dest;
                    359:     int  maxlen;
                    360: {
                    361:     int ch='\0';
                    362:     int len=0;
                    363:     char *p = dest;
                    364:     int digits;
                    365: 
                    366:     ch=fGetChar(fp);
                    367: 
                    368:     /*
                    369:      * check for a quoted string.  If found, take all characters
                    370:      * that fit until a closing quote is found.  Note that this
                    371:      * algorithm will not behave well for a string which is too long.
                    372:      */
                    373:     if (ISQUOTE(ch)) {
                    374:         int done = FALSE;
                    375:         do {
                    376:             ch = fGetChar(fp);
                    377:             done = ((maxlen<++len)||ISLINEFEED(ch)||(ch==EOF)
                    378:                    ||ISQUOTE(ch));
                    379:             if (ch=='\\')
                    380:                 ch = fGetLiteral(fp);
                    381:             if (!done)
                    382:                 *p++ = ch;
                    383:             else if ((ch!=EOF) && !ISQUOTE(ch))
                    384:                 fUngetChar(ch,fp);
                    385:         } while (!done);
                    386:         *p = '\0';
                    387:         if (ISLINEFEED(ch)) return(GTOK_BAD_QSTRING);
                    388:         return(GTOK_QSTRING);
                    389:     }
                    390: 
                    391:     /*
                    392:      * Not a quoted string.  If its a token character (rules are
                    393:      * defined via the ISTOKENCHAR macro, in kparse.h) take it and all
                    394:      * token chars following it until we run out of space.
                    395:      */
                    396:     digits=TRUE;
                    397:     if (ISTOKENCHAR(ch)) {
                    398:         while ( (ISTOKENCHAR(ch)) && len<maxlen-1 ) {
                    399:             if (!isdigit(ch)) digits=FALSE;
                    400:             *p++ = ch;
                    401:             len++;
                    402:             ch = fGetChar(fp);
                    403:         };
                    404:         *p = '\0';
                    405: 
                    406:         if (ch!=EOF) {
                    407:             fUngetChar(ch,fp);
                    408:         }
                    409:         if (digits) {
                    410:             return(GTOK_NUMBER);
                    411:         } else {
                    412:             return(GTOK_STRING);
                    413:         }
                    414:     }
                    415: 
                    416:     /*
                    417:      * Neither a quoted string nor a token character.  Return a string
                    418:      * with just that one character in it.
                    419:      */
                    420:     if (ch==EOF) {
                    421:         return(GTOK_EOF);
                    422:     }
                    423:     if (!ISWHITESPACE(ch)) {
                    424:         *p++ = ch;
                    425:         *p='\0';
                    426:     } else {
                    427:         *p++ = ' ';            /* white space is always the
                    428:                                 * blank character */
                    429:         *p='\0';
                    430:         /*
                    431:          * The character is a white space. Flush all additional white
                    432:          * space.
                    433:          */
                    434:         while (ISWHITESPACE(ch) && ((ch=fGetChar(fp)) != EOF))
                    435:             ;
                    436:         if (ch!=EOF) {
                    437:             fUngetChar(ch,fp);
                    438:         }
                    439:         return(GTOK_WHITE);
                    440:     }
                    441:     return(GTOK_PUNK);
                    442: }
                    443: 
                    444: /*
                    445:  * fGetLiteral is called after we find a '\' in the input stream.  A
                    446:  * string of numbers following the backslash are converted to the
                    447:  * appropriate value; hex (0xn), octal (0n), and decimal (otherwise)
                    448:  * are all supported.  If the char after the \ is not a number, we
                    449:  * special case certain values (\n, \f, \r, \b) or return a literal
                    450:  * otherwise (useful for \", for example).
                    451:  */
                    452: fGetLiteral(fp)
                    453:     FILE *fp;
                    454: {
                    455:     int ch;
                    456:     int n=0;
                    457:     int base;
                    458: 
                    459:     ch = fGetChar(fp);
                    460: 
                    461:     if (!isdigit(ch)) {
                    462:         switch (ch) {
                    463:         case 'n':       return('\n');
                    464:         case 'f':       return('\f');
                    465:         case 'r':       return('\r');
                    466:         case 'b':       return('\b');
                    467:         default:        return(ch);
                    468:         }
                    469:     }
                    470: 
                    471:     /*
                    472:      * got a number.  might be decimal (no prefix), octal (prefix 0),
                    473:      * or hexadecimal (prefix 0x).  Set the base appropriately.
                    474:      */
                    475:     if (ch!='0') {
                    476:         base=10;                /* its a decimal number */
                    477:     } else {
                    478:         /*
                    479:          * found a zero, its either hex or octal
                    480:          */
                    481:         ch = fGetChar(fp);
                    482:         if ((ch!='x') && (ch!='X')) {
                    483:             base=010;
                    484:         } else {
                    485:             ch = fGetChar(fp);
                    486:             base=0x10;
                    487:         }
                    488:     }
                    489: 
                    490:     switch (base) {
                    491: 
                    492:     case 010:                   /* octal */
                    493:         while (ISOCTAL(ch)) {
                    494:             n = (n*base) + ch - '0';
                    495:             ch = fGetChar(fp);
                    496:         }
                    497:         break;
                    498: 
                    499:     case 10:                    /* decimal */
                    500:         while (isdigit(ch)) {
                    501:             n = (n*base) + ch - '0';
                    502:             ch = fGetChar(fp);
                    503:         }
                    504:         break;
                    505:     case 0x10:                  /* hexadecimal */
                    506:         while (isxdigit(ch)) {
                    507:             if (isdigit(ch)) {
                    508:                 n = (n*base) + ch - '0';
                    509:             } else {
                    510:                 n = (n*base) + toupper(ch) - 'A' + 0xA ;
                    511:             }
                    512:             ch = fGetChar(fp);
                    513:         }
                    514:         break;
                    515:     default:
                    516:         fprintf(stderr,"fGetLiteral() died real bad. Fix gettoken.c.");
                    517:         exit(1);
                    518:         break;
                    519:     }
                    520:     fUngetChar(ch,fp);
                    521:     return(n);
                    522: }
                    523: 
                    524: /*
                    525:  * exactly the same as ungetc(3) except that the line number of the
                    526:  * input file is maintained.
                    527:  */
                    528: fUngetChar(ch,fp)
                    529:     int ch;
                    530:     FILE *fp;
                    531: {
                    532:     if (ch=='\n') LineNbr--;
                    533:     return(ungetc(ch,fp));
                    534: }
                    535: 
                    536: 
                    537: /*
                    538:  * exactly the same as fgetc(3) except that the line number of the
                    539:  * input file is maintained.
                    540:  */
                    541: fGetChar(fp)
                    542:     FILE *fp;
                    543: {
                    544:     int ch = fgetc(fp);
                    545:     if (ch=='\n') LineNbr++;
                    546:     return(ch);
                    547: }
                    548: 
                    549: 
                    550: /*
                    551:  * Routine Name: strsave
                    552:  *
                    553:  * Function: return a pointer to a saved copy of the
                    554:  * input string. the copy will be allocated
                    555:  * as large as necessary.
                    556:  *
                    557:  * Explicit Parameters: pointer to string to save
                    558:  *
                    559:  * Implicit Parameters: None
                    560:  *
                    561:  * External Procedures: malloc,strcpy,strlen
                    562:  *
                    563:  * Side Effects: None
                    564:  *
                    565:  * Return Value: pointer to copied string
                    566:  *
                    567:  */
                    568: char * strsave(p)
                    569:     char *p;
                    570: {
                    571:     return(strcpy(malloc(strlen(p)+1),p));
                    572: }
                    573: 
                    574: 
                    575: /*
                    576:  * strutol changes all characters in a string to lower case, in place.
                    577:  * the pointer to the beginning of the string is returned.
                    578:  */
                    579: 
                    580: char * strutol( start )
                    581:     char *start;
                    582: {
                    583:     char *q;
                    584:     for (q=start; *q; q++)
                    585:         if (isupper(*q))
                    586:            *q=tolower(*q);
                    587:     return(start);
                    588: }
                    589: 
                    590: #ifdef GTOK_TEST            /* mainline test routine for fGetToken() */
                    591: 
                    592: #define MAXTOKEN 100
                    593: 
                    594: char *pgm = "gettoken";
                    595: 
                    596: main(argc,argv)
                    597:     int argc;
                    598:     char **argv;
                    599: {
                    600:     char *p;
                    601:     int type;
                    602:     FILE *fp;
                    603: 
                    604:     if (--argc) {
                    605:         fp = fopen(*++argv,"ra");
                    606:         if (fp == (FILE *)NULL) {
                    607:             fprintf(stderr,"can\'t open \"%s\"\n",*argv);
                    608:         }
                    609:     } else
                    610:         fp = stdin;
                    611: 
                    612:     p = malloc(MAXTOKEN);
                    613:     while (type = fGetToken(fp,p,MAXTOKEN)) {
                    614:         switch(type) {
                    615:         case GTOK_BAD_QSTRING:
                    616:            printf("BAD QSTRING!\t");
                    617:            break;
                    618:         case GTOK_EOF:
                    619:            printf("EOF!\t");
                    620:            break;
                    621:         case GTOK_QSTRING:
                    622:            printf("QSTRING\t");
                    623:            break;
                    624:         case GTOK_STRING:
                    625:            printf("STRING\t");
                    626:            break;
                    627:         case GTOK_NUMBER:
                    628:            printf("NUMBER\t");
                    629:            break;
                    630:         case GTOK_PUNK:
                    631:            printf("PUNK\t");
                    632:            break;
                    633:         case GTOK_WHITE:
                    634:            printf("WHITE\t");
                    635:            break;
                    636:         default:
                    637:            printf("HUH?\t");
                    638:            break;
                    639:         }
                    640:         if (*p=='\n')
                    641:             printf("\\n\n");
                    642:        else
                    643:             printf("%s\n",p);
                    644:     }
                    645:     exit(0);
                    646: }
                    647: #endif
                    648: 
                    649: #ifdef KVTEST
                    650: 
                    651: main(argc,argv)
                    652:     int argc;
                    653:     char **argv;
                    654: {
                    655:     int rc,ch;
                    656:     FILE *fp;
                    657:     char key[MAXKEY],valu[MAXVALUE];
                    658:     char *filename;
                    659: 
                    660:     if (argc != 2) {
                    661:         fprintf(stderr,"usage: test <filename>\n");
                    662:         exit(1);
                    663:     }
                    664: 
                    665:     if (!(fp=fopen(*++argv,"r"))) {
                    666:         fprintf(stderr,"can\'t open input file \"%s\"\n",filename);
                    667:         exit(1);
                    668:     }
                    669:     filename = *argv;
                    670: 
                    671:     while ((rc=fGetKeywordValue(fp,key,MAXKEY,valu,MAXVALUE))!=KV_EOF){
                    672: 
                    673:         switch (rc) {
                    674: 
                    675:         case KV_EOL:
                    676:             printf("%s, line %d: nada mas.\n",filename,LineNbr-1);
                    677:             break;
                    678: 
                    679:         case KV_SYNTAX:
                    680:             printf("%s, line %d: syntax error: %s\n",
                    681:                    filename,LineNbr,ErrorMsg);
                    682:             while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
                    683:             break;
                    684: 
                    685:         case KV_OKAY:
                    686:             printf("%s, line %d: okay, %s=\"%s\"\n",
                    687:                    filename,LineNbr,key,valu);
                    688:             break;
                    689: 
                    690:         default:
                    691:             printf("panic: bad return (%d) from fGetKeywordValue\n",rc);
                    692:             break;
                    693:         }
                    694:     }
                    695:     printf("EOF");
                    696:     fclose(fp);
                    697:     exit(0);
                    698: }
                    699: #endif
                    700: 
                    701: #ifdef PSTEST
                    702: 
                    703: parmtable kparm[] = {
                    704:     /*  keyword, default, found value */
                    705:     { "user",       "",    (char *)NULL },
                    706:     { "realm",   "Athena", (char *)NULL },
                    707:     { "instance",   "",    (char *)NULL }
                    708: };
                    709: 
                    710: main(argc,argv)
                    711:     int argc;
                    712:     char **argv;
                    713: {
                    714:     int rc,i,ch;
                    715:     FILE *fp;
                    716:     char *filename;
                    717: 
                    718:     if (argc != 2) {
                    719:         fprintf(stderr,"usage: test <filename>\n");
                    720:         exit(1);
                    721:     }
                    722: 
                    723:     if (!(fp=fopen(*++argv,"r"))) {
                    724:         fprintf(stderr,"can\'t open input file \"%s\"\n",filename);
                    725:         exit(1);
                    726:     }
                    727:     filename = *argv;
                    728: 
                    729:     while ((rc=fGetParameterSet(fp,kparm,PARMCOUNT(kparm))) != PS_EOF) {
                    730: 
                    731:         switch (rc) {
                    732: 
                    733:         case PS_BAD_KEYWORD:
                    734:             printf("%s, line %d: %s\n",filename,LineNbr,ErrorMsg);
                    735:             while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
                    736:             break;
                    737: 
                    738:         case PS_SYNTAX:
                    739:             printf("%s, line %d: syntax error: %s\n",
                    740:                    filename,LineNbr,ErrorMsg);
                    741:             while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
                    742:             break;
                    743: 
                    744:         case PS_OKAY:
                    745:             printf("%s, line %d: valid parameter set found:\n",
                    746:                    filename,LineNbr-1);
                    747:             for (i=0; i<PARMCOUNT(kparm); i++) {
                    748:                 printf("\t%s = \"%s\"\n",kparm[i].keyword,
                    749:                        (kparm[i].value ? kparm[i].value
                    750:                        : kparm[i].defvalue));
                    751:             }
                    752:             break;
                    753: 
                    754:         default:
                    755:             printf("panic: bad return (%d) from fGetParameterSet\n",rc);
                    756:             break;
                    757:         }
                    758:         FreeParameterSet(kparm,PARMCOUNT(kparm));
                    759:     }
                    760:     printf("EOF");
                    761:     fclose(fp);
                    762:     exit(0);
                    763: }
                    764: #endif

unix.superglobalmegacorp.com

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