Blame usr/lib/common/parser.y

Packit Service 8aa27d
/*
Packit Service 8aa27d
 * COPYRIGHT (c) International Business Machines Corp. 2013-2017
Packit Service 8aa27d
 *
Packit Service 8aa27d
 * This program is provided under the terms of the Common Public License,
Packit Service 8aa27d
 * version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
Packit Service 8aa27d
 * software constitutes recipient's acceptance of CPL-1.0 terms which can be
Packit Service 8aa27d
 * found in the file LICENSE file or at
Packit Service 8aa27d
 * https://opensource.org/licenses/cpl1.0.php
Packit Service 8aa27d
 */
Packit Service 8aa27d
Packit Service 8aa27d
%{
Packit Service 8aa27d
/*
Packit Service 8aa27d
 * Parse openCryptoki's config file.
Packit Service 8aa27d
 */
Packit Service 8aa27d
Packit Service 8aa27d
#include <stddef.h>
Packit Service 8aa27d
#include <stdio.h>
Packit Service 8aa27d
#include <stdlib.h>
Packit Service 8aa27d
#include <errno.h>
Packit Service 8aa27d
#include <string.h>
Packit Service 8aa27d
Packit Service 8aa27d
#include "slotmgr.h"
Packit Service 8aa27d
#include "configparser.h"
Packit Service 8aa27d
Packit Service 8aa27d
static struct strholder {
Packit Service 8aa27d
    struct strholder *prev;
Packit Service 8aa27d
    char *str;
Packit Service 8aa27d
} *strroot;
Packit Service 8aa27d
Packit Service 8aa27d
struct parsefuncs *parsefuncs;
Packit Service 8aa27d
void *parsedata;
Packit Service 8aa27d
Packit Service 8aa27d
extern FILE *yyin;
Packit Service 8aa27d
extern int yyparse();
Packit Service 8aa27d
extern void yyerror(const char *s);
Packit Service 8aa27d
extern int line_num;
Packit Service 8aa27d
extern int yylex();
Packit Service 8aa27d
Packit Service 8aa27d
static void configparse_freestrings(void);
Packit Service 8aa27d
static void configparse_freestringsfrom(char *str);
Packit Service 8aa27d
Packit Service 8aa27d
struct ock_key {
Packit Service 8aa27d
	char *name;
Packit Service 8aa27d
	keyword_token token;
Packit Service 8aa27d
};
Packit Service 8aa27d
Packit Service 8aa27d
static const struct ock_key ock_keywords[] = {
Packit Service 8aa27d
	{"stdll",       	KW_STDLL},
Packit Service 8aa27d
	{"description", 	KW_SLOTDESC},
Packit Service 8aa27d
	{"manufacturer",	KW_MANUFID},
Packit Service 8aa27d
	{"hwversion",		KW_HWVERSION},
Packit Service 8aa27d
	{"firmwareversion",	KW_FWVERSION},
Packit Service 8aa27d
	{"confname",		KW_CONFNAME},
Packit Service 8aa27d
	{"tokname",		KW_TOKNAME},
Packit Service 8aa27d
	{"tokversion",		KW_TOKVERSION}
Packit Service 8aa27d
};
Packit Service 8aa27d
Packit Service 8aa27d
int lookup_keyword(const char *key);
Packit Service 8aa27d
Packit Service 8aa27d
%}
Packit Service 8aa27d
Packit Service 8aa27d
%union {
Packit Service 8aa27d
	char *str;
Packit Service 8aa27d
	unsigned int num;
Packit Service 8aa27d
    int err;
Packit Service 8aa27d
}
Packit Service 8aa27d
Packit Service 8aa27d
%token EQUAL DOT SLOT EOL OCKVERSION BEGIN_DEF END_DEF
Packit Service 8aa27d
%token <str> STRING
Packit Service 8aa27d
%token <str> KEYWORD
Packit Service 8aa27d
%token <num> INTEGER
Packit Service 8aa27d
%token <num> TOKVERSION
Packit Service 8aa27d
%token <str> COMMENT
Packit Service 8aa27d
Packit Service 8aa27d
%%
Packit Service 8aa27d
Packit Service 8aa27d
config_file:
Packit Service 8aa27d
	config_file sections
Packit Service 8aa27d
	|
Packit Service 8aa27d
	;
Packit Service 8aa27d
Packit Service 8aa27d
sections:
Packit Service 8aa27d
	version_def eolcomment
Packit Service 8aa27d
	| SLOT INTEGER BEGIN_DEF
Packit Service 8aa27d
	{
Packit Service 8aa27d
        if (parsefuncs->begin_slot && parsefuncs->begin_slot(parsedata, $2, 0)) {
Packit Service 8aa27d
            if (parsefuncs->parseerror)
Packit Service 8aa27d
                parsefuncs->parseerror(parsedata, line_num, NULL);
Packit Service 8aa27d
            YYERROR;
Packit Service 8aa27d
        }
Packit Service 8aa27d
	} eolcomment keyword_defs END_DEF
Packit Service 8aa27d
	{
Packit Service 8aa27d
        if (parsefuncs->end_slot && parsefuncs->end_slot(parsedata)) {
Packit Service 8aa27d
            if (parsefuncs->parseerror)
Packit Service 8aa27d
                parsefuncs->parseerror(parsedata, line_num, NULL);
Packit Service 8aa27d
            YYERROR;
Packit Service 8aa27d
        }
Packit Service 8aa27d
	}
Packit Service 8aa27d
	| SLOT INTEGER EOL BEGIN_DEF
Packit Service 8aa27d
	{
Packit Service 8aa27d
        if (parsefuncs->begin_slot && parsefuncs->begin_slot(parsedata, $2, 1)) {
Packit Service 8aa27d
            if (parsefuncs->parseerror)
Packit Service 8aa27d
                parsefuncs->parseerror(parsedata, line_num, NULL);
Packit Service 8aa27d
            YYERROR;
Packit Service 8aa27d
        }
Packit Service 8aa27d
    } eolcomment keyword_defs END_DEF
Packit Service 8aa27d
	{
Packit Service 8aa27d
        if (parsefuncs->end_slot && parsefuncs->end_slot(parsedata)) {
Packit Service 8aa27d
            if (parsefuncs->parseerror)
Packit Service 8aa27d
                parsefuncs->parseerror(parsedata, line_num, NULL);
Packit Service 8aa27d
            YYERROR;
Packit Service 8aa27d
        }
Packit Service 8aa27d
	}
Packit Service 8aa27d
	| eolcomment
Packit Service 8aa27d
	;
Packit Service 8aa27d
Packit Service 8aa27d
version_def:
Packit Service 8aa27d
    OCKVERSION STRING
Packit Service 8aa27d
    {
Packit Service 8aa27d
        if (parsefuncs->version && parsefuncs->version(parsedata, $2)) {
Packit Service 8aa27d
            if (parsefuncs->parseerror)
Packit Service 8aa27d
                parsefuncs->parseerror(parsedata, line_num, NULL);
Packit Service 8aa27d
            configparse_freestringsfrom($2);
Packit Service 8aa27d
            YYERROR;
Packit Service 8aa27d
        }
Packit Service 8aa27d
        configparse_freestringsfrom($2);
Packit Service 8aa27d
    }
Packit Service 8aa27d
Packit Service 8aa27d
line_def:
Packit Service 8aa27d
    STRING EQUAL TOKVERSION
Packit Service 8aa27d
    {
Packit Service 8aa27d
        int kw;
Packit Service 8aa27d
        char errbuf[256];
Packit Service 8aa27d
Packit Service 8aa27d
        kw = lookup_keyword($1);
Packit Service 8aa27d
        if (kw == -1) {
Packit Service 8aa27d
            if (parsefuncs->parseerror) {
Packit Service 8aa27d
                snprintf(errbuf, sizeof(errbuf), "Unknown keyword: \"%s\"", $1);
Packit Service 8aa27d
                parsefuncs->parseerror(parsedata, line_num, errbuf);
Packit Service 8aa27d
            }
Packit Service 8aa27d
            configparse_freestringsfrom($1);
Packit Service 8aa27d
            YYERROR;
Packit Service 8aa27d
        }
Packit Service 8aa27d
        configparse_freestringsfrom($1);
Packit Service 8aa27d
        if (parsefuncs->key_vers) {
Packit Service 8aa27d
            if(parsefuncs->key_vers(parsedata, kw, $3)) {
Packit Service 8aa27d
                if (parsefuncs->parseerror)
Packit Service 8aa27d
                    parsefuncs->parseerror(parsedata, line_num, NULL);
Packit Service 8aa27d
                YYERROR;
Packit Service 8aa27d
            }
Packit Service 8aa27d
        }
Packit Service 8aa27d
    }
Packit Service 8aa27d
    |
Packit Service 8aa27d
    STRING EQUAL STRING
Packit Service 8aa27d
    {
Packit Service 8aa27d
        int kw;
Packit Service 8aa27d
        char errbuf[256];
Packit Service 8aa27d
Packit Service 8aa27d
        kw = lookup_keyword($1);
Packit Service 8aa27d
        if (kw == -1) {
Packit Service 8aa27d
            if (parsefuncs->parseerror) {
Packit Service 8aa27d
                snprintf(errbuf, sizeof(errbuf), "Unknown keyword: \"%s\"", $1);
Packit Service 8aa27d
                parsefuncs->parseerror(parsedata, line_num, errbuf);
Packit Service 8aa27d
            }
Packit Service 8aa27d
            configparse_freestringsfrom($3);
Packit Service 8aa27d
            YYERROR;
Packit Service 8aa27d
        }
Packit Service 8aa27d
        if (parsefuncs->key_str && parsefuncs->key_str(parsedata, kw, $3)) {
Packit Service 8aa27d
            if (parsefuncs->parseerror)
Packit Service 8aa27d
                parsefuncs->parseerror(parsedata, line_num, NULL);
Packit Service 8aa27d
            configparse_freestringsfrom($3);
Packit Service 8aa27d
            YYERROR;
Packit Service 8aa27d
        }
Packit Service 8aa27d
        configparse_freestringsfrom($3); // Will also free $1
Packit Service 8aa27d
    }
Packit Service 8aa27d
Packit Service 8aa27d
keyword_defs:
Packit Service 8aa27d
    line_def eolcomment keyword_defs
Packit Service 8aa27d
    |
Packit Service 8aa27d
    eolcomment keyword_defs
Packit Service 8aa27d
    |
Packit Service 8aa27d
    /* empty */
Packit Service 8aa27d
Packit Service 8aa27d
eolcomment:
Packit Service 8aa27d
    COMMENT EOL
Packit Service 8aa27d
    {
Packit Service 8aa27d
        if (parsefuncs->eolcomment)
Packit Service 8aa27d
            parsefuncs->eolcomment(parsedata, $1);
Packit Service 8aa27d
        if (parsefuncs->eol)
Packit Service 8aa27d
            parsefuncs->eol(parsedata);
Packit Service 8aa27d
        configparse_freestringsfrom($1);
Packit Service 8aa27d
    }
Packit Service 8aa27d
    |
Packit Service 8aa27d
    EOL
Packit Service 8aa27d
    {
Packit Service 8aa27d
        if (parsefuncs->eol)
Packit Service 8aa27d
            parsefuncs->eol(parsedata);
Packit Service 8aa27d
    }
Packit Service 8aa27d
Packit Service 8aa27d
%%
Packit Service 8aa27d
Packit Service 8aa27d
char *configparse_strdup(char *val)
Packit Service 8aa27d
{
Packit Service 8aa27d
    struct strholder *holder;
Packit Service 8aa27d
    char *res = NULL;
Packit Service 8aa27d
Packit Service 8aa27d
    holder = (struct strholder *)malloc(sizeof(struct strholder));
Packit Service 8aa27d
    if (holder) {
Packit Service 8aa27d
        holder->prev = strroot;
Packit Service 8aa27d
        strroot = holder;
Packit Service 8aa27d
        holder->str = res = strdup(val);
Packit Service 8aa27d
    }
Packit Service 8aa27d
    return res;
Packit Service 8aa27d
}
Packit Service 8aa27d
Packit Service 8aa27d
static void configparse_freestrings()
Packit Service 8aa27d
{
Packit Service 8aa27d
    struct strholder *cur, *next;
Packit Service 8aa27d
Packit Service 8aa27d
    cur = strroot;
Packit Service 8aa27d
    while (cur) {
Packit Service 8aa27d
        next = cur->prev;
Packit Service 8aa27d
        free(cur->str);
Packit Service 8aa27d
        free(cur);
Packit Service 8aa27d
        cur = next;
Packit Service 8aa27d
    }
Packit Service 8aa27d
    strroot = NULL;
Packit Service 8aa27d
}
Packit Service 8aa27d
Packit Service 8aa27d
static void configparse_freestringsfrom(char *str)
Packit Service 8aa27d
{
Packit Service 8aa27d
    struct strholder *cur, *next, **anchor;
Packit Service 8aa27d
Packit Service 8aa27d
    anchor = &strroot;
Packit Service 8aa27d
    cur = strroot;
Packit Service 8aa27d
    while (cur && cur->str != str) {
Packit Service 8aa27d
        anchor = &cur->prev;
Packit Service 8aa27d
        cur = cur->prev;
Packit Service 8aa27d
    }
Packit Service 8aa27d
    while (cur) {
Packit Service 8aa27d
        next = cur->prev;
Packit Service 8aa27d
        free(cur->str);
Packit Service 8aa27d
        free(cur);
Packit Service 8aa27d
        cur = next;
Packit Service 8aa27d
    }
Packit Service 8aa27d
    *anchor = NULL;
Packit Service 8aa27d
}
Packit Service 8aa27d
Packit Service 8aa27d
void
Packit Service 8aa27d
yyerror(const char *s)
Packit Service 8aa27d
{
Packit Service 8aa27d
    if (parsefuncs->parseerror)
Packit Service 8aa27d
        parsefuncs->parseerror(parsedata, line_num, s);
Packit Service 8aa27d
}
Packit Service 8aa27d
Packit Service 8aa27d
int
Packit Service 8aa27d
lookup_keyword(const char *key)
Packit Service 8aa27d
{
Packit Service 8aa27d
	int i;
Packit Service 8aa27d
Packit Service 8aa27d
	for (i = 0; i < KW_MAX ; i++ ) {
Packit Service 8aa27d
		if (strncmp(key, ock_keywords[i].name, strlen(key)) == 0)
Packit Service 8aa27d
			return ock_keywords[i].token;
Packit Service 8aa27d
	}
Packit Service 8aa27d
	/* if we get here that means did not find a match... */
Packit Service 8aa27d
	return -1;
Packit Service 8aa27d
}
Packit Service 8aa27d
Packit Service 8aa27d
const char *keyword_token_to_str(int tok)
Packit Service 8aa27d
{
Packit Service 8aa27d
	return tok < KW_MAX ? ock_keywords[tok].name : "<UNKNWON>";
Packit Service 8aa27d
}
Packit Service 8aa27d
Packit Service 8aa27d
int
Packit Service 8aa27d
load_and_parse(const char *configfile, struct parsefuncs *funcs, void *private)
Packit Service 8aa27d
{
Packit Service 8aa27d
Packit Service 8aa27d
	FILE *conf;
Packit Service 8aa27d
	int res;
Packit Service 8aa27d
Packit Service 8aa27d
	extern FILE *yyin;
Packit Service 8aa27d
Packit Service 8aa27d
	conf = fopen(configfile, "r");
Packit Service 8aa27d
Packit Service 8aa27d
	if (!conf) {
Packit Service 8aa27d
		fprintf(stderr, "Failed to open %s: %s\n", configfile, strerror(errno));
Packit Service 8aa27d
		return -1;
Packit Service 8aa27d
	}
Packit Service 8aa27d
Packit Service 8aa27d
    line_num = 1;
Packit Service 8aa27d
	yyin = conf;
Packit Service 8aa27d
	parsefuncs = funcs;
Packit Service 8aa27d
	parsedata = private;
Packit Service 8aa27d
    strroot = NULL;
Packit Service 8aa27d
    
Packit Service 8aa27d
	res = yyparse();
Packit Service 8aa27d
Packit Service 8aa27d
	fclose(conf);
Packit Service 8aa27d
	parsefuncs = NULL;
Packit Service 8aa27d
	parsedata = NULL;
Packit Service 8aa27d
    configparse_freestrings();
Packit Service 8aa27d
Packit Service 8aa27d
	return res;
Packit Service 8aa27d
}