From 774a362e87feab25f1be16fbca08269ddc7121a4 Mon Sep 17 00:00:00 2001
From: Rene Mayrhofer <rene@mayrhofer.eu.org>
Date: Thu, 12 Apr 2007 20:41:31 +0000
Subject: Major new upstream release, just ran svn-upgrade for now (and wrote
 some debian/changelong entries).

---
 src/starter/parser.y | 283 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 283 insertions(+)
 create mode 100644 src/starter/parser.y

(limited to 'src/starter/parser.y')

diff --git a/src/starter/parser.y b/src/starter/parser.y
new file mode 100644
index 000000000..db984fae3
--- /dev/null
+++ b/src/starter/parser.y
@@ -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 FILE_VERSION
+%token <s> STRING
+
+%%
+
+/*
+ * Config file
+ */
+
+config_file:
+    config_file section_or_include
+    | /* NULL */		
+    ;
+
+section_or_include:
+    FILE_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);
+    }
+}
-- 
cgit v1.2.3