📄 kparse.c
字号:
/* * $Source: /mit/kerberos/src/lib/krb/RCS/kparse.c,v $ * $Author: jtkohl $ * * Copyright 1988 by the Massachusetts Institute of Technology. * * For copying and distribution information, please see the file * <mit-copyright.h>. * * Purpose: * This module was developed to parse the "~/.klogin" files for * Kerberos-authenticated rlogin/rcp/rsh services. However, it is * general purpose and can be used to parse any such parameter file. * * The parameter file should consist of one or more entries, with each * entry on a separate line and consisting of zero or more * "keyword=value" combinations. The keyword is case insensitive, but * the value is not. Any string may be enclosed in quotes, and * c-style "\" literals are supported. A comma may be used to * separate the k/v combinations, and multiple commas are ignored. * Whitespace (blank or tab) may be used freely and is ignored. * * Full error processing is available. When PS_BAD_KEYWORD or * PS_SYNTAX is returned from fGetParameterSet(), the string ErrorMsg * contains a meaningful error message. * * Keywords and their default values are programmed by an external * table. * * Routines: * fGetParameterSet() parse one line of the parameter file * fGetKeywordValue() parse one "keyword=value" combo * fGetToken() parse one token */#ifndef lintstatic char rcsid_kparse_c[] ="$Header: kparse.c,v 4.5 89/01/21 17:20:39 jtkohl Exp $";#endif lint#include <mit-copyright.h>#include <stdio.h>#include <ctype.h>#include <kparse.h>#ifndef FALSE#define FALSE 0#define TRUE 1#endif#define void int#define MAXKEY 80#define MAXVALUE 80char *malloc();char *strcpy();int LineNbr=1; /* current line nbr in parameter file */char ErrorMsg[80]; /* meaningful only when KV_SYNTAX, PS_SYNTAX, * or PS_BAD_KEYWORD is returned by * fGetKeywordValue or fGetParameterSet */int fGetParameterSet( fp,parm,parmcount ) FILE *fp; parmtable parm[]; int parmcount;{ int rc,i; char keyword[MAXKEY]; char value[MAXVALUE]; while (TRUE) { rc=fGetKeywordValue(fp,keyword,MAXKEY,value,MAXVALUE); switch (rc) { case KV_EOF: return(PS_EOF); case KV_EOL: return(PS_OKAY); case KV_SYNTAX: return(PS_SYNTAX); case KV_OKAY: /* * got a reasonable keyword/value pair. Search the * parameter table to see if we recognize the keyword; if * not, return an error. If we DO recognize it, make sure * it has not already been given. If not already given, * save the value. */ for (i=0; i<parmcount; i++) { if (strcmp(strutol(keyword),parm[i].keyword)==0) { if (parm[i].value) { sprintf(ErrorMsg,"duplicate keyword \"%s\" found", keyword); return(PS_BAD_KEYWORD); } parm[i].value = strsave( value ); break; } } if (i >= parmcount) { sprintf(ErrorMsg, "unrecognized keyword \"%s\" found", keyword); return(PS_BAD_KEYWORD); } break; default: sprintf(ErrorMsg, "panic: bad return (%d) from fGetToken()",rc); break; } }}/* * Routine: ParmCompare * * Purpose: * ParmCompare checks a specified value for a particular keyword. * fails if keyword not found or keyword found but the value was * different. Like strcmp, ParmCompare returns 0 for a match found, -1 * otherwise */int ParmCompare( parm, parmcount, keyword, value ) parmtable parm[]; int parmcount; char *keyword; char *value;{ int i; for (i=0; i<parmcount; i++) { if (strcmp(parm[i].keyword,keyword)==0) { if (parm[i].value) { return(strcmp(parm[i].value,value)); } else { return(strcmp(parm[i].defvalue,value)); } } } return(-1);}void FreeParameterSet(parm,parmcount) parmtable parm[]; int parmcount;{ int i; for (i=0; i<parmcount; i++) { if (parm[i].value) { free(parm[i].value); parm[i].value = (char *)NULL; } }}int fGetKeywordValue( fp, keyword, klen, value, vlen ) FILE *fp; char *keyword; int klen; char *value; int vlen;{ int rc; int gotit; *keyword = *value = '\0'; /* preset strings to NULL */ /* * Looking for a keyword. * return an exception for EOF or BAD_QSTRING * ignore leading WHITEspace * ignore any number of leading commas * newline means we have all the parms for this * statement; give an indication that there is * nothing more on this line. * stop looking if we find QSTRING, STRING, or NUMBER * return syntax error for any other PUNKtuation */ gotit = FALSE; do { rc = fGetToken(fp,keyword,klen); switch (rc) { case GTOK_WHITE: break; case GTOK_EOF: return(KV_EOF); case GTOK_BAD_QSTRING: sprintf(ErrorMsg,"unterminated string \"%s found",keyword); return(KV_SYNTAX); case GTOK_PUNK: if (strcmp("\n",keyword)==0) { return(KV_EOL); } else if (strcmp(",",keyword)!=0) { sprintf(ErrorMsg,"expecting rvalue, found \'%s\'",keyword); } break; case GTOK_STRING: case GTOK_QSTRING: case GTOK_NUMBER: gotit = TRUE; break; default: sprintf(ErrorMsg,"panic: bad return (%d) from fGetToken()",rc); return(KV_SYNTAX); } } while (!gotit); /* * now we expect an equal sign. * skip any whitespace * stop looking if we find an equal sign * anything else causes a syntax error */ gotit = FALSE; do { rc = fGetToken(fp,value,vlen); switch (rc) { case GTOK_WHITE: break; case GTOK_BAD_QSTRING: sprintf(ErrorMsg, "expecting \'=\', found unterminated string \"%s", value); return(KV_SYNTAX); case GTOK_PUNK: if (strcmp("=",value)==0) { gotit = TRUE; } else { if (strcmp("\n",value)==0) { sprintf(ErrorMsg,"expecting \"=\", found newline"); fUngetChar('\n',fp); } else { sprintf(ErrorMsg, "expecting rvalue, found \'%s\'",keyword); } return(KV_SYNTAX); } break; case GTOK_STRING: case GTOK_QSTRING: case GTOK_NUMBER: sprintf(ErrorMsg,"expecting \'=\', found \"%s\"",value); return(KV_SYNTAX); case GTOK_EOF: sprintf(ErrorMsg,"expecting \'=\', found EOF"); return(KV_SYNTAX); default: sprintf(ErrorMsg, "panic: bad return (%d) from fGetToken()",rc); return(KV_SYNTAX); } } while ( !gotit ); /* * got the keyword and equal sign, now get a value. * ignore any whitespace * any punctuation is a syntax error */ gotit = FALSE; do { rc = fGetToken(fp,value,vlen); switch (rc) { case GTOK_WHITE: break; case GTOK_EOF: sprintf(ErrorMsg,"expecting rvalue, found EOF"); return(KV_SYNTAX); case GTOK_BAD_QSTRING: sprintf(ErrorMsg,"unterminated quoted string \"%s",value); return(KV_SYNTAX); case GTOK_PUNK: if (strcmp("\n",value)==0) { sprintf(ErrorMsg,"expecting rvalue, found newline"); fUngetChar('\n',fp); } else { sprintf(ErrorMsg, "expecting rvalue, found \'%s\'",value); } return(KV_SYNTAX); break; case GTOK_STRING: case GTOK_QSTRING: case GTOK_NUMBER: gotit = TRUE; return(KV_OKAY); default: sprintf(ErrorMsg, "panic: bad return (%d) from fGetToken()",rc); return(KV_SYNTAX); } } while ( !gotit ); /*NOTREACHED*/}/* * Routine Name: fGetToken * * Function: read the next token from the specified file. * A token is defined as a group of characters * terminated by a white space char (SPACE, CR, * LF, FF, TAB). The token returned is stripped of * both leading and trailing white space, and is * terminated by a NULL terminator. An alternate * definition of a token is a string enclosed in * single or double quotes. * * Explicit Parameters: * fp pointer to the input FILE * dest pointer to destination buffer * maxlen length of the destination buffer. The buffer * length INCLUDES the NULL terminator. * * Implicit Parameters: stderr where the "token too long" message goes * * External Procedures: fgetc * * Side Effects: None * * Return Value: A token classification value, as * defined in kparse.h. Note that the * classification for end of file is * always zero. */int fGetToken(fp, dest, maxlen) FILE *fp; char *dest; int maxlen;{ int ch='\0'; int len=0; char *p = dest; int digits; ch=fGetChar(fp); /* * check for a quoted string. If found, take all characters * that fit until a closing quote is found. Note that this * algorithm will not behave well for a string which is too long. */ if (ISQUOTE(ch)) { int done = FALSE; do { ch = fGetChar(fp); done = ((maxlen<++len)||ISLINEFEED(ch)||(ch==EOF) ||ISQUOTE(ch)); if (ch=='\\') ch = fGetLiteral(fp); if (!done) *p++ = ch; else if ((ch!=EOF) && !ISQUOTE(ch))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -