#include "mit-copyright.h"
#include "krb.h"
#include <stdio.h>
#include <ctype.h>
#include <kparse.h>
#include <string.h>
#include "autoconf.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifndef FALSE
#define FALSE 0
#define TRUE 1
#endif
#define MAXKEY 80
#define MAXVALUE 80
static char *strutol (char *);
#ifndef HAVE_STRDUP
static char *strdup();
#endif
#ifndef HAVE_STDLIB_H
extern char *malloc();
#endif
static int sLineNbr=1;
static char ErrorMsg[80];
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:
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 = strdup(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;
}
}
}
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';
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);
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 );
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 );
return 0;
}
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);
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);
}
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);
}
}
if (ch==EOF) {
return(GTOK_EOF);
}
if (!ISWHITESPACE(ch)) {
*p++ = ch;
*p='\0';
} else {
*p++ = ' ';
*p='\0';
while (ISWHITESPACE(ch) && ((ch=fGetChar(fp)) != EOF))
;
if (ch!=EOF) {
fUngetChar(ch,fp);
}
return(GTOK_WHITE);
}
return(GTOK_PUNK);
}
int fGetLiteral(fp)
FILE *fp;
{
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);
}
}
if (ch!='0') {
base=10;
} else {
ch = fGetChar(fp);
if ((ch!='x') && (ch!='X')) {
base=010;
} else {
ch = fGetChar(fp);
base=0x10;
}
}
switch (base) {
case 010:
while (ISOCTAL(ch)) {
n = (n*base) + ch - '0';
ch = fGetChar(fp);
}
break;
case 10:
while (isdigit(ch)) {
n = (n*base) + ch - '0';
ch = fGetChar(fp);
}
break;
case 0x10:
while (isxdigit(ch)) {
if (isdigit(ch)) {
n = (n*base) + ch - '0';
} else {
n = (n*base) + toupper(ch) - 'A' + 0xA ;
}
ch = fGetChar(fp);
}
break;
default:
#ifdef DEBUG
fprintf(stderr,"fGetLiteral() died real bad. Fix kparse.c.");
#endif
break;
}
fUngetChar(ch,fp);
return(n);
}
int fUngetChar(ch,fp)
int ch;
FILE *fp;
{
if (ch=='\n') sLineNbr--;
return(ungetc(ch,fp));
}
int fGetChar(fp)
FILE *fp;
{
int ch = fgetc(fp);
if (ch=='\n') sLineNbr++;
return(ch);
}
static char * strutol( start )
char *start;
{
char *q;
for (q=start; *q; q++)
if (isupper((unsigned char) *q))
*q=tolower((unsigned char) *q);
return(start);
}
#ifdef GTOK_TEST
#define MAXTOKEN 100
char *pgm = "gettoken";
main(argc,argv)
int argc;
char **argv;
{
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
main(argc,argv)
int argc;
char **argv;
{
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,sLineNbr-1);
break;
case KV_SYNTAX:
printf("%s, line %d: syntax error: %s\n",
filename,sLineNbr,ErrorMsg);
while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
break;
case KV_OKAY:
printf("%s, line %d: okay, %s=\"%s\"\n",
filename,sLineNbr,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[] = {
{ "user", "", (char *)NULL },
{ "realm", "Athena", (char *)NULL },
{ "instance", "", (char *)NULL }
};
main(argc,argv)
int argc;
char **argv;
{
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,sLineNbr,ErrorMsg);
while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
break;
case PS_SYNTAX:
printf("%s, line %d: syntax error: %s\n",
filename,sLineNbr,ErrorMsg);
while ( ((ch=fGetChar(fp))!=EOF) && (ch!='\n') );
break;
case PS_OKAY:
printf("%s, line %d: valid parameter set found:\n",
filename,sLineNbr-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
#ifndef HAVE_STRDUP
static char *
strdup(str)
const char *str;
{
int len;
char *copy;
if (!str)
return((char *)0);
len = strlen(str) + 1;
if (!(copy = malloc((u_int)len)))
return((char *)0);
memcpy(copy, str, len);
return(copy);
}
#endif