summaryrefslogtreecommitdiff
path: root/src/starter/lexer.l
diff options
context:
space:
mode:
Diffstat (limited to 'src/starter/lexer.l')
-rw-r--r--src/starter/lexer.l215
1 files changed, 215 insertions, 0 deletions
diff --git a/src/starter/lexer.l b/src/starter/lexer.l
new file mode 100644
index 000000000..734776a74
--- /dev/null
+++ b/src/starter/lexer.l
@@ -0,0 +1,215 @@
+%option noinput
+%option nounput
+%{
+/* FreeS/WAN config file parser (parser.l)
+ * 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.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef HAVE_GLOB_H
+#include <glob.h>
+#endif
+
+#include "parser.h"
+
+#define MAX_INCLUDE_DEPTH 20
+
+extern void yyerror(const char *);
+extern int yylex(void);
+extern int yylex_destroy(void);
+
+static struct {
+ int stack_ptr;
+ YY_BUFFER_STATE stack[MAX_INCLUDE_DEPTH];
+ FILE *file[MAX_INCLUDE_DEPTH];
+ unsigned int line[MAX_INCLUDE_DEPTH];
+ char *filename[MAX_INCLUDE_DEPTH];
+} __parser_y_private;
+
+void _parser_y_error(char *b, int size, const char *s);
+void _parser_y_init (const char *f);
+void _parser_y_fini (void);
+int _parser_y_include (const char *filename);
+
+void _parser_y_error(char *b, int size, const char *s)
+{
+ extern char *yytext; // was: char yytext[];
+
+ snprintf(b, size, "%s:%d: %s [%s]",
+ __parser_y_private.filename[__parser_y_private.stack_ptr],
+ __parser_y_private.line[__parser_y_private.stack_ptr],
+ s, yytext);
+}
+
+void _parser_y_init (const char *f)
+{
+ memset(&__parser_y_private, 0, sizeof(__parser_y_private));
+ __parser_y_private.line[0] = 1;
+ __parser_y_private.filename[0] = strdup(f);
+}
+
+void _parser_y_fini (void)
+{
+ unsigned int i;
+
+ for (i = 0; i < MAX_INCLUDE_DEPTH; i++)
+ {
+ if (__parser_y_private.filename[i])
+ free(__parser_y_private.filename[i]);
+ if (__parser_y_private.file[i])
+ fclose(__parser_y_private.file[i]);
+ }
+ memset(&__parser_y_private, 0, sizeof(__parser_y_private));
+ yylex_destroy();
+}
+
+/**
+ * parse the file located at filename
+ */
+int include_file(char *filename)
+{
+ unsigned int p = __parser_y_private.stack_ptr + 1;
+ FILE *f;
+
+ if (p >= MAX_INCLUDE_DEPTH)
+ {
+ yyerror("max inclusion depth reached");
+ return 1;
+ }
+
+ f = fopen(filename, "r");
+ if (!f)
+ {
+ yyerror("can't open include filename");
+ return 0; /* ignore this error */
+ }
+
+ __parser_y_private.stack_ptr++;
+ __parser_y_private.file[p] = f;
+ __parser_y_private.stack[p] = YY_CURRENT_BUFFER;
+ __parser_y_private.line[p] = 1;
+ __parser_y_private.filename[p] = strdup(filename);
+
+ yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
+ return 0;
+}
+
+int _parser_y_include (const char *filename)
+{
+ int ret = 0;
+#ifdef HAVE_GLOB_H
+ {
+ glob_t files;
+ int i;
+
+ ret = glob(filename, GLOB_ERR, NULL, &files);
+ if (ret)
+ {
+ const char *err;
+
+ switch (ret)
+ {
+ case GLOB_NOSPACE:
+ err = "include files ran out of memory";
+ break;
+ case GLOB_ABORTED:
+ err = "include files aborted due to read error";
+ break;
+ case GLOB_NOMATCH:
+ err = "include files found no matches";
+ break;
+ default:
+ err = "unknown include files error";
+ }
+ globfree(&files);
+ yyerror(err);
+ return 1;
+ }
+
+ for (i = 0; i < files.gl_pathc; i++)
+ {
+ if ((ret = include_file(files.gl_pathv[i])))
+ {
+ break;
+ }
+ }
+ globfree(&files);
+ }
+#else /* HAVE_GLOB_H */
+ /* if glob(3) is not available, try to load pattern directly */
+ ret = include_file(filename);
+#endif /* HAVE_GLOB_H */
+ return ret;
+}
+
+%}
+
+%%
+
+<<EOF>> {
+ if (__parser_y_private.filename[__parser_y_private.stack_ptr]) {
+ free(__parser_y_private.filename[__parser_y_private.stack_ptr]);
+ __parser_y_private.filename[__parser_y_private.stack_ptr] = NULL;
+ }
+ if (__parser_y_private.file[__parser_y_private.stack_ptr]) {
+ fclose(__parser_y_private.file[__parser_y_private.stack_ptr]);
+ __parser_y_private.file[__parser_y_private.stack_ptr] = NULL;
+ yy_delete_buffer (YY_CURRENT_BUFFER);
+ yy_switch_to_buffer
+ (__parser_y_private.stack[__parser_y_private.stack_ptr]);
+ }
+ if (--__parser_y_private.stack_ptr < 0) {
+ yyterminate();
+ }
+}
+
+^[\t ]+ return FIRST_SPACES;
+
+[\t ]+ /* ignore spaces in line */ ;
+
+= return EQUAL;
+
+\n|#.*\n {
+ __parser_y_private.line[__parser_y_private.stack_ptr]++;
+ return EOL;
+ }
+
+config return CONFIG;
+setup return SETUP;
+conn return CONN;
+ca return CA;
+include return INCLUDE;
+version return FILE_VERSION;
+
+[^\"= \t\n]+ {
+ yylval.s = strdup(yytext);
+ return STRING;
+ }
+
+\"[^\"\n]*\" {
+ yylval.s = strdup(yytext+1);
+ if (yylval.s) yylval.s[strlen(yylval.s)-1]='\0';
+ return STRING;
+ }
+
+. yyerror(yytext);
+
+%%
+
+int yywrap(void)
+{
+ return 1;
+}
+