This commit is contained in:
@@ -0,0 +1,283 @@
|
||||
%{
|
||||
/* strongSwan config file parser (parser.y)
|
||||
* Copyright (C) 2001 Mathieu Lafon - Arkoon Network Security
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* RCSID $Id: parser.y,v 1.6 2006/01/17 23:43:36 as Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <freeswan.h>
|
||||
|
||||
#include "../pluto/constants.h"
|
||||
#include "../pluto/defs.h"
|
||||
#include "../pluto/log.h"
|
||||
#include "parser.h"
|
||||
|
||||
#define YYERROR_VERBOSE
|
||||
#define ERRSTRING_LEN 256
|
||||
|
||||
/**
|
||||
* Bison
|
||||
*/
|
||||
static char parser_errstring[ERRSTRING_LEN+1];
|
||||
|
||||
extern void yyerror(const char *s);
|
||||
extern int yylex (void);
|
||||
extern void _parser_y_error(char *b, int size, const char *s);
|
||||
|
||||
/**
|
||||
* Static Globals
|
||||
*/
|
||||
static int _save_errors_;
|
||||
static config_parsed_t *_parser_cfg;
|
||||
static kw_list_t **_parser_kw, *_parser_kw_last;
|
||||
static char errbuf[ERRSTRING_LEN+1];
|
||||
|
||||
/**
|
||||
* Gperf
|
||||
*/
|
||||
extern kw_entry_t *in_word_set (char *str, unsigned int len);
|
||||
|
||||
%}
|
||||
|
||||
%union { char *s; };
|
||||
%token EQUAL FIRST_SPACES EOL CONFIG SETUP CONN CA INCLUDE VERSION
|
||||
%token <s> STRING
|
||||
|
||||
%%
|
||||
|
||||
/*
|
||||
* Config file
|
||||
*/
|
||||
|
||||
config_file:
|
||||
config_file section_or_include
|
||||
| /* NULL */
|
||||
;
|
||||
|
||||
section_or_include:
|
||||
VERSION STRING EOL
|
||||
{
|
||||
free($2);
|
||||
}
|
||||
| CONFIG SETUP EOL
|
||||
{
|
||||
_parser_kw = &(_parser_cfg->config_setup);
|
||||
_parser_kw_last = NULL;
|
||||
} kw_section
|
||||
| CONN STRING EOL
|
||||
{
|
||||
section_list_t *section = (section_list_t *)alloc_thing(section_list_t
|
||||
, "section_list_t");
|
||||
|
||||
section->name = clone_str($2, "conn section name");
|
||||
section->kw = NULL;
|
||||
section->next = NULL;
|
||||
_parser_kw = &(section->kw);
|
||||
if (!_parser_cfg->conn_first)
|
||||
_parser_cfg->conn_first = section;
|
||||
if (_parser_cfg->conn_last)
|
||||
_parser_cfg->conn_last->next = section;
|
||||
_parser_cfg->conn_last = section;
|
||||
_parser_kw_last = NULL;
|
||||
free($2);
|
||||
} kw_section
|
||||
| CA STRING EOL
|
||||
{
|
||||
section_list_t *section = (section_list_t *)alloc_thing(section_list_t
|
||||
, "section_list_t");
|
||||
section->name = clone_str($2, "ca section name");
|
||||
section->kw = NULL;
|
||||
section->next = NULL;
|
||||
_parser_kw = &(section->kw);
|
||||
if (!_parser_cfg->ca_first)
|
||||
_parser_cfg->ca_first = section;
|
||||
if (_parser_cfg->ca_last)
|
||||
_parser_cfg->ca_last->next = section;
|
||||
_parser_cfg->ca_last = section;
|
||||
_parser_kw_last = NULL;
|
||||
free($2);
|
||||
} kw_section
|
||||
| INCLUDE STRING
|
||||
{
|
||||
extern void _parser_y_include (const char *f);
|
||||
_parser_y_include($2);
|
||||
free($2);
|
||||
} EOL
|
||||
| EOL
|
||||
;
|
||||
|
||||
kw_section:
|
||||
FIRST_SPACES statement_kw EOL kw_section
|
||||
|
|
||||
;
|
||||
|
||||
statement_kw:
|
||||
STRING EQUAL STRING
|
||||
{
|
||||
kw_list_t *new;
|
||||
kw_entry_t *entry = in_word_set($1, strlen($1));
|
||||
|
||||
if (entry == NULL)
|
||||
{
|
||||
snprintf(errbuf, ERRSTRING_LEN, "unknown keyword '%s'", $1);
|
||||
yyerror(errbuf);
|
||||
}
|
||||
else if (_parser_kw)
|
||||
{
|
||||
new = (kw_list_t *)alloc_thing(kw_list_t, "kw_list_t");
|
||||
new->entry = entry;
|
||||
new->value = clone_str($3, "kw_list value");
|
||||
new->next = NULL;
|
||||
if (_parser_kw_last)
|
||||
_parser_kw_last->next = new;
|
||||
_parser_kw_last = new;
|
||||
if (!*_parser_kw)
|
||||
*_parser_kw = new;
|
||||
}
|
||||
free($1);
|
||||
free($3);
|
||||
}
|
||||
| STRING EQUAL
|
||||
{
|
||||
free($1);
|
||||
}
|
||||
|
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void
|
||||
yyerror(const char *s)
|
||||
{
|
||||
if (_save_errors_)
|
||||
_parser_y_error(parser_errstring, ERRSTRING_LEN, s);
|
||||
}
|
||||
|
||||
config_parsed_t *
|
||||
parser_load_conf(const char *file)
|
||||
{
|
||||
config_parsed_t *cfg = NULL;
|
||||
int err = 0;
|
||||
FILE *f;
|
||||
|
||||
extern void _parser_y_init (const char *f);
|
||||
extern FILE *yyin;
|
||||
|
||||
memset(parser_errstring, 0, ERRSTRING_LEN+1);
|
||||
|
||||
cfg = (config_parsed_t *)alloc_thing(config_parsed_t, "config_parsed_t");
|
||||
if (cfg)
|
||||
{
|
||||
memset(cfg, 0, sizeof(config_parsed_t));
|
||||
f = fopen(file, "r");
|
||||
if (f)
|
||||
{
|
||||
yyin = f;
|
||||
_parser_y_init(file);
|
||||
_save_errors_ = 1;
|
||||
_parser_cfg = cfg;
|
||||
|
||||
if (yyparse() !=0 )
|
||||
{
|
||||
if (parser_errstring[0] == '\0')
|
||||
{
|
||||
snprintf(parser_errstring, ERRSTRING_LEN, "Unknown error...");
|
||||
}
|
||||
_save_errors_ = 0;
|
||||
while (yyparse() != 0);
|
||||
err++;
|
||||
}
|
||||
else if (parser_errstring[0] != '\0')
|
||||
{
|
||||
err++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* Config valid
|
||||
*/
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(parser_errstring, ERRSTRING_LEN, "can't load file '%s'", file);
|
||||
err++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(parser_errstring, ERRSTRING_LEN, "can't allocate memory");
|
||||
err++;
|
||||
}
|
||||
|
||||
if (err)
|
||||
{
|
||||
plog("%s", parser_errstring);
|
||||
|
||||
if (cfg)
|
||||
parser_free_conf(cfg);
|
||||
cfg = NULL;
|
||||
}
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
static void
|
||||
parser_free_kwlist(kw_list_t *list)
|
||||
{
|
||||
kw_list_t *elt;
|
||||
|
||||
while (list)
|
||||
{
|
||||
elt = list;
|
||||
list = list->next;
|
||||
if (elt->value)
|
||||
pfree(elt->value);
|
||||
pfree(elt);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
parser_free_conf(config_parsed_t *cfg)
|
||||
{
|
||||
section_list_t *sec;
|
||||
if (cfg)
|
||||
{
|
||||
parser_free_kwlist(cfg->config_setup);
|
||||
while (cfg->conn_first)
|
||||
{
|
||||
sec = cfg->conn_first;
|
||||
cfg->conn_first = cfg->conn_first->next;
|
||||
if (sec->name)
|
||||
pfree(sec->name);
|
||||
parser_free_kwlist(sec->kw);
|
||||
pfree(sec);
|
||||
}
|
||||
while (cfg->ca_first)
|
||||
{
|
||||
sec = cfg->ca_first;
|
||||
cfg->ca_first = cfg->ca_first->next;
|
||||
if (sec->name)
|
||||
pfree(sec->name);
|
||||
parser_free_kwlist(sec->kw);
|
||||
pfree(sec);
|
||||
}
|
||||
pfree(cfg);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user