1994-09-30 14:50:09 +00:00
|
|
|
|
/*
|
|
|
|
|
* Copyright 1988 by the Massachusetts Institute of Technology.
|
|
|
|
|
* For copying and distribution information, please see the file
|
|
|
|
|
* <Copyright.MIT>.
|
|
|
|
|
*
|
|
|
|
|
* 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
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* from: kparse.c,v 4.5 89/01/21 17:20:39 jtkohl Exp $
|
1995-08-25 22:52:32 +00:00
|
|
|
|
* $Id: kparse.c,v 1.3 1995/07/18 16:38:58 mark Exp $
|
1994-09-30 14:50:09 +00:00
|
|
|
|
*/
|
|
|
|
|
|
1995-08-25 22:52:32 +00:00
|
|
|
|
#if 0
|
1994-09-30 14:50:09 +00:00
|
|
|
|
#ifndef lint
|
|
|
|
|
static char rcsid[] =
|
1995-08-25 22:52:32 +00:00
|
|
|
|
"$Id: kparse.c,v 1.3 1995/07/18 16:38:58 mark Exp $";
|
1994-09-30 14:50:09 +00:00
|
|
|
|
#endif lint
|
1995-08-25 22:52:32 +00:00
|
|
|
|
#endif
|
1994-09-30 14:50:09 +00:00
|
|
|
|
|
1995-08-25 22:52:32 +00:00
|
|
|
|
#include <stdlib.h>
|
1995-09-07 21:39:00 +00:00
|
|
|
|
#include <stdio.h>
|
1994-09-30 14:50:09 +00:00
|
|
|
|
#include <ctype.h>
|
|
|
|
|
#include <kparse.h>
|
|
|
|
|
|
|
|
|
|
#ifndef FALSE
|
|
|
|
|
#define FALSE 0
|
|
|
|
|
#define TRUE 1
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#define MAXKEY 80
|
|
|
|
|
#define MAXVALUE 80
|
|
|
|
|
|
1995-09-07 21:39:00 +00:00
|
|
|
|
int fUngetChar(int ch, FILE *fp);
|
1995-08-25 22:52:32 +00:00
|
|
|
|
int fGetChar(FILE *fp);
|
1995-09-07 21:39:00 +00:00
|
|
|
|
int fGetLiteral(FILE *fp);
|
1994-09-30 14:50:09 +00:00
|
|
|
|
|
|
|
|
|
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 */
|
|
|
|
|
|
1995-09-07 21:39:00 +00:00
|
|
|
|
int
|
|
|
|
|
fGetParameterSet( fp,parm,parmcount )
|
|
|
|
|
FILE *fp;
|
|
|
|
|
parmtable parm[];
|
|
|
|
|
int parmcount;
|
1994-09-30 14:50:09 +00:00
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
*/
|
1995-09-07 21:39:00 +00:00
|
|
|
|
int
|
|
|
|
|
ParmCompare( parm, parmcount, keyword, value )
|
|
|
|
|
parmtable parm[];
|
|
|
|
|
int parmcount;
|
|
|
|
|
char *keyword;
|
|
|
|
|
char *value;
|
1994-09-30 14:50:09 +00:00
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
1995-09-07 21:39:00 +00:00
|
|
|
|
void
|
|
|
|
|
FreeParameterSet(parm,parmcount)
|
|
|
|
|
parmtable parm[];
|
|
|
|
|
int parmcount;
|
1994-09-30 14:50:09 +00:00
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i=0; i<parmcount; i++) {
|
|
|
|
|
if (parm[i].value) {
|
|
|
|
|
free(parm[i].value);
|
|
|
|
|
parm[i].value = (char *)NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1995-09-07 21:39:00 +00:00
|
|
|
|
int
|
|
|
|
|
fGetKeywordValue( fp, keyword, klen, value, vlen )
|
|
|
|
|
FILE *fp;
|
|
|
|
|
char *keyword;
|
|
|
|
|
int klen;
|
|
|
|
|
char *value;
|
|
|
|
|
int vlen;
|
1994-09-30 14:50:09 +00:00
|
|
|
|
{
|
|
|
|
|
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*/
|
1995-09-07 21:39:00 +00:00
|
|
|
|
return(0); /*just to shut up -Wall MRVM*/
|
1994-09-30 14:50:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
1995-09-07 21:39:00 +00:00
|
|
|
|
int
|
|
|
|
|
fGetToken(fp, dest, maxlen)
|
|
|
|
|
FILE *fp;
|
|
|
|
|
char *dest;
|
|
|
|
|
int maxlen;
|
1994-09-30 14:50:09 +00:00
|
|
|
|
{
|
|
|
|
|
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))
|
|
|
|
|
fUngetChar(ch,fp);
|
|
|
|
|
} while (!done);
|
|
|
|
|
*p = '\0';
|
|
|
|
|
if (ISLINEFEED(ch)) return(GTOK_BAD_QSTRING);
|
|
|
|
|
return(GTOK_QSTRING);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Not a quoted string. If its a token character (rules are
|
|
|
|
|
* defined via the ISTOKENCHAR macro, in kparse.h) take it and all
|
|
|
|
|
* token chars following it until we run out of space.
|
|
|
|
|
*/
|
|
|
|
|
digits=TRUE;
|
|
|
|
|
if (ISTOKENCHAR(ch)) {
|
|
|
|
|
while ( (ISTOKENCHAR(ch)) && len<maxlen-1 ) {
|
|
|
|
|
if (!isdigit(ch)) digits=FALSE;
|
|
|
|
|
*p++ = ch;
|
|
|
|
|
len++;
|
|
|
|
|
ch = fGetChar(fp);
|
|
|
|
|
};
|
|
|
|
|
*p = '\0';
|
|
|
|
|
|
|
|
|
|
if (ch!=EOF) {
|
|
|
|
|
fUngetChar(ch,fp);
|
|
|
|
|
}
|
|
|
|
|
if (digits) {
|
|
|
|
|
return(GTOK_NUMBER);
|
|
|
|
|
} else {
|
|
|
|
|
return(GTOK_STRING);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Neither a quoted string nor a token character. Return a string
|
|
|
|
|
* with just that one character in it.
|
|
|
|
|
*/
|
|
|
|
|
if (ch==EOF) {
|
|
|
|
|
return(GTOK_EOF);
|
|
|
|
|
}
|
|
|
|
|
if (!ISWHITESPACE(ch)) {
|
|
|
|
|
*p++ = ch;
|
|
|
|
|
*p='\0';
|
|
|
|
|
} else {
|
|
|
|
|
*p++ = ' '; /* white space is always the
|
|
|
|
|
* blank character */
|
|
|
|
|
*p='\0';
|
|
|
|
|
/*
|
|
|
|
|
* The character is a white space. Flush all additional white
|
|
|
|
|
* space.
|
|
|
|
|
*/
|
|
|
|
|
while (ISWHITESPACE(ch) && ((ch=fGetChar(fp)) != EOF))
|
|
|
|
|
;
|
|
|
|
|
if (ch!=EOF) {
|
|
|
|
|
fUngetChar(ch,fp);
|
|
|
|
|
}
|
|
|
|
|
return(GTOK_WHITE);
|
|
|
|
|
}
|
|
|
|
|
return(GTOK_PUNK);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* fGetLiteral is called after we find a '\' in the input stream. A
|
|
|
|
|
* string of numbers following the backslash are converted to the
|
|
|
|
|
* appropriate value; hex (0xn), octal (0n), and decimal (otherwise)
|
|
|
|
|
* are all supported. If the char after the \ is not a number, we
|
|
|
|
|
* special case certain values (\n, \f, \r, \b) or return a literal
|
|
|
|
|
* otherwise (useful for \", for example).
|
|
|
|
|
*/
|
1995-09-07 21:39:00 +00:00
|
|
|
|
int
|
|
|
|
|
fGetLiteral(fp)
|
|
|
|
|
FILE *fp;
|
1994-09-30 14:50:09 +00:00
|
|
|
|
{
|
|
|
|
|
int ch;
|
|
|
|
|
int n=0;
|
|
|
|
|
int base;
|
|
|
|
|
|
|
|
|
|
ch = fGetChar(fp);
|
|
|
|
|
|
|
|
|
|
if (!isdigit(ch)) {
|
|
|
|
|
switch (ch) {
|
|
|
|
|
case 'n': return('\n');
|
|
|
|
|
case 'f': return('\f');
|
|
|
|
|
case 'r': return('\r');
|
|
|
|
|
case 'b': return('\b');
|
|
|
|
|
default: return(ch);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* got a number. might be decimal (no prefix), octal (prefix 0),
|
|
|
|
|
* or hexadecimal (prefix 0x). Set the base appropriately.
|
|
|
|
|
*/
|
|
|
|
|
if (ch!='0') {
|
|
|
|
|
base=10; /* its a decimal number */
|
|
|
|
|
} else {
|
|
|
|
|
/*
|
|
|
|
|
* found a zero, its either hex or octal
|
|
|
|
|
*/
|
|
|
|
|
ch = fGetChar(fp);
|
|
|
|
|
if ((ch!='x') && (ch!='X')) {
|
|
|
|
|
base=010;
|
|
|
|
|
} else {
|
|
|
|
|
ch = fGetChar(fp);
|
|
|
|
|
base=0x10;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (base) {
|
|
|
|
|
|
|
|
|
|
case 010: /* octal */
|
|
|
|
|
while (ISOCTAL(ch)) {
|
|
|
|
|
n = (n*base) + ch - '0';
|
|
|
|
|
ch = fGetChar(fp);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 10: /* decimal */
|
|
|
|
|
while (isdigit(ch)) {
|
|
|
|
|
n = (n*base) + ch - '0';
|
|
|
|
|
ch = fGetChar(fp);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 0x10: /* hexadecimal */
|
|
|
|
|
while (isxdigit(ch)) {
|
|
|
|
|
if (isdigit(ch)) {
|
|
|
|
|
n = (n*base) + ch - '0';
|
|
|
|
|
} else {
|
|
|
|
|
n = (n*base) + toupper(ch) - 'A' + 0xA ;
|
|
|
|
|
}
|
|
|
|
|
ch = fGetChar(fp);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
fprintf(stderr,"fGetLiteral() died real bad. Fix gettoken.c.");
|
|
|
|
|
exit(1);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
fUngetChar(ch,fp);
|
|
|
|
|
return(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* exactly the same as ungetc(3) except that the line number of the
|
|
|
|
|
* input file is maintained.
|
|
|
|
|
*/
|
1995-09-07 21:39:00 +00:00
|
|
|
|
int
|
|
|
|
|
fUngetChar(ch,fp)
|
|
|
|
|
int ch;
|
|
|
|
|
FILE *fp;
|
1994-09-30 14:50:09 +00:00
|
|
|
|
{
|
|
|
|
|
if (ch=='\n') LineNbr--;
|
|
|
|
|
return(ungetc(ch,fp));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* exactly the same as fgetc(3) except that the line number of the
|
|
|
|
|
* input file is maintained.
|
|
|
|
|
*/
|
1995-09-07 21:39:00 +00:00
|
|
|
|
int
|
|
|
|
|
fGetChar(fp)
|
|
|
|
|
FILE *fp;
|
1994-09-30 14:50:09 +00:00
|
|
|
|
{
|
|
|
|
|
int ch = fgetc(fp);
|
|
|
|
|
if (ch=='\n') LineNbr++;
|
|
|
|
|
return(ch);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Routine Name: strsave
|
|
|
|
|
*
|
|
|
|
|
* Function: return a pointer to a saved copy of the
|
|
|
|
|
* input string. the copy will be allocated
|
|
|
|
|
* as large as necessary.
|
|
|
|
|
*
|
|
|
|
|
* Explicit Parameters: pointer to string to save
|
|
|
|
|
*
|
|
|
|
|
* Implicit Parameters: None
|
|
|
|
|
*
|
|
|
|
|
* External Procedures: malloc,strcpy,strlen
|
|
|
|
|
*
|
|
|
|
|
* Side Effects: None
|
|
|
|
|
*
|
|
|
|
|
* Return Value: pointer to copied string
|
|
|
|
|
*
|
|
|
|
|
*/
|
1995-09-07 21:39:00 +00:00
|
|
|
|
char *
|
|
|
|
|
strsave(p)
|
|
|
|
|
char *p;
|
1994-09-30 14:50:09 +00:00
|
|
|
|
{
|
|
|
|
|
return(strcpy(malloc(strlen(p)+1),p));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* strutol changes all characters in a string to lower case, in place.
|
|
|
|
|
* the pointer to the beginning of the string is returned.
|
|
|
|
|
*/
|
|
|
|
|
|
1995-09-07 21:39:00 +00:00
|
|
|
|
char *
|
|
|
|
|
strutol( start )
|
|
|
|
|
char *start;
|
1994-09-30 14:50:09 +00:00
|
|
|
|
{
|
|
|
|
|
char *q;
|
|
|
|
|
for (q=start; *q; q++)
|
|
|
|
|
if (isupper(*q))
|
|
|
|
|
*q=tolower(*q);
|
|
|
|
|
return(start);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef GTOK_TEST /* mainline test routine for fGetToken() */
|
|
|
|
|
|
|
|
|
|
#define MAXTOKEN 100
|
|
|
|
|
|
|
|
|
|
char *pgm = "gettoken";
|
|
|
|
|
|
1995-09-07 21:39:00 +00:00
|
|
|
|
main(argc,argv)
|
|
|
|
|
int argc;
|
|
|
|
|
char **argv;
|
1994-09-30 14:50:09 +00:00
|
|
|
|
{
|
|
|
|
|
char *p;
|
|
|
|
|
int type;
|
|
|
|
|
FILE *fp;
|
|
|
|
|
|
|
|
|
|
if (--argc) {
|
|
|
|
|
fp = fopen(*++argv,"ra");
|
|
|
|
|
if (fp == (FILE *)NULL) {
|
|
|
|
|
fprintf(stderr,"can\'t open \"%s\"\n",*argv);
|
|
|
|
|
}
|
|
|
|
|
} else
|
|
|
|
|
fp = stdin;
|
|
|
|
|
|
|
|
|
|
p = malloc(MAXTOKEN);
|
|
|
|
|
while (type = fGetToken(fp,p,MAXTOKEN)) {
|
|
|
|
|
switch(type) {
|
|
|
|
|
case GTOK_BAD_QSTRING:
|
|
|
|
|
printf("BAD QSTRING!\t");
|
|
|
|
|
break;
|
|
|
|
|
case GTOK_EOF:
|
|
|
|
|
printf("EOF!\t");
|
|
|
|
|
break;
|
|
|
|
|
case GTOK_QSTRING:
|
|
|
|
|
printf("QSTRING\t");
|
|
|
|
|
break;
|
|
|
|
|
case GTOK_STRING:
|
|
|
|
|
printf("STRING\t");
|
|
|
|
|
break;
|
|
|
|
|
case GTOK_NUMBER:
|
|
|
|
|
printf("NUMBER\t");
|
|
|
|
|
break;
|
|
|
|
|
case GTOK_PUNK:
|
|
|
|
|
printf("PUNK\t");
|
|
|
|
|
break;
|
|
|
|
|
case GTOK_WHITE:
|
|
|
|
|
printf("WHITE\t");
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
printf("HUH?\t");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (*p=='\n')
|
|
|
|
|
printf("\\n\n");
|
|
|
|
|
else
|
|
|
|
|
printf("%s\n",p);
|
|
|
|
|
}
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef KVTEST
|
|
|
|
|
|
1995-09-07 21:39:00 +00:00
|
|
|
|
main(argc,argv)
|
|
|
|
|
int argc;
|
|
|
|
|
char **argv;
|
1994-09-30 14:50:09 +00:00
|
|
|
|
{
|
|
|
|
|
int rc,ch;
|
|
|
|
|
FILE *fp;
|
|
|
|
|
char key[MAXKEY],valu[MAXVALUE];
|
|
|
|
|
char *filename;
|
|
|
|
|
|
|
|
|
|
if (argc != 2) {
|
|
|
|
|
fprintf(stderr,"usage: test <filename>\n");
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!(fp=fopen(*++argv,"r"))) {
|
|
|
|
|
fprintf(stderr,"can\'t open input file \"%s\"\n",filename);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
filename = *argv;
|
|
|
|
|
|
|
|
|
|
while ((rc=fGetKeywordValue(fp,key,MAXKEY,valu,MAXVALUE))!=KV_EOF){
|
|
|
|
|
|
|
|
|
|
switch (rc) {
|
|
|
|
|
|
|
|
|
|
case KV_EOL:
|
|
|
|
|
printf("%s, line %d: nada mas.\n",filename,LineNbr-1);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case KV_SYNTAX:
|
|
|
|
|
printf("%s, line %d: syntax error: %s\n",
|
|
|
|
|
filename,LineNbr,ErrorMsg);
|
|
|
|
|
while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case KV_OKAY:
|
|
|
|
|
printf("%s, line %d: okay, %s=\"%s\"\n",
|
|
|
|
|
filename,LineNbr,key,valu);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
printf("panic: bad return (%d) from fGetKeywordValue\n",rc);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
printf("EOF");
|
|
|
|
|
fclose(fp);
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef PSTEST
|
|
|
|
|
|
|
|
|
|
parmtable kparm[] = {
|
|
|
|
|
/* keyword, default, found value */
|
|
|
|
|
{ "user", "", (char *)NULL },
|
|
|
|
|
{ "realm", "Athena", (char *)NULL },
|
|
|
|
|
{ "instance", "", (char *)NULL }
|
|
|
|
|
};
|
|
|
|
|
|
1995-09-07 21:39:00 +00:00
|
|
|
|
main(argc,argv)
|
|
|
|
|
int argc;
|
|
|
|
|
char **argv;
|
1994-09-30 14:50:09 +00:00
|
|
|
|
{
|
|
|
|
|
int rc,i,ch;
|
|
|
|
|
FILE *fp;
|
|
|
|
|
char *filename;
|
|
|
|
|
|
|
|
|
|
if (argc != 2) {
|
|
|
|
|
fprintf(stderr,"usage: test <filename>\n");
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!(fp=fopen(*++argv,"r"))) {
|
|
|
|
|
fprintf(stderr,"can\'t open input file \"%s\"\n",filename);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
filename = *argv;
|
|
|
|
|
|
|
|
|
|
while ((rc=fGetParameterSet(fp,kparm,PARMCOUNT(kparm))) != PS_EOF) {
|
|
|
|
|
|
|
|
|
|
switch (rc) {
|
|
|
|
|
|
|
|
|
|
case PS_BAD_KEYWORD:
|
|
|
|
|
printf("%s, line %d: %s\n",filename,LineNbr,ErrorMsg);
|
|
|
|
|
while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PS_SYNTAX:
|
|
|
|
|
printf("%s, line %d: syntax error: %s\n",
|
|
|
|
|
filename,LineNbr,ErrorMsg);
|
|
|
|
|
while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PS_OKAY:
|
|
|
|
|
printf("%s, line %d: valid parameter set found:\n",
|
|
|
|
|
filename,LineNbr-1);
|
|
|
|
|
for (i=0; i<PARMCOUNT(kparm); i++) {
|
|
|
|
|
printf("\t%s = \"%s\"\n",kparm[i].keyword,
|
|
|
|
|
(kparm[i].value ? kparm[i].value
|
|
|
|
|
: kparm[i].defvalue));
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
printf("panic: bad return (%d) from fGetParameterSet\n",rc);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
FreeParameterSet(kparm,PARMCOUNT(kparm));
|
|
|
|
|
}
|
|
|
|
|
printf("EOF");
|
|
|
|
|
fclose(fp);
|
|
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
#endif
|