aboutsummaryrefslogtreecommitdiffstats
path: root/src/config-lexer.l
diff options
context:
space:
mode:
Diffstat (limited to 'src/config-lexer.l')
-rw-r--r--src/config-lexer.l379
1 files changed, 379 insertions, 0 deletions
diff --git a/src/config-lexer.l b/src/config-lexer.l
new file mode 100644
index 0000000..bea9365
--- /dev/null
+++ b/src/config-lexer.l
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 2002 Erik Fears
+ * Copyright (c) 2014-2018 ircd-hybrid development team
+ *
+ * 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.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ * USA
+ */
+
+%option case-insensitive
+%option noyywrap
+%option noinput
+%option nounput
+%option never-interactive
+
+%x IN_COMMENT
+
+%{
+#include <stdio.h>
+#include <string.h>
+
+#include "compat.h"
+#include "config.h"
+#include "config-parser.h" /* autogenerated header file */
+#include "log.h"
+
+/* libopm includes */
+#include "libopm/src/opm_types.h"
+
+#undef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) conf_yy_fatal_error(msg)
+
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if (!(result = conf_yy_input(buf, max_size))) \
+ YY_FATAL_ERROR("input in flex scanner failed");
+#define MAX_INCLUDE_DEPTH 10
+
+
+unsigned int lineno = 1;
+char linebuf[512];
+char conffilebuf[512];
+
+static struct included_file
+{
+ YY_BUFFER_STATE state;
+ unsigned int lineno;
+ FILE *file;
+ char conffile[512];
+} include_stack[MAX_INCLUDE_DEPTH];
+
+static unsigned int include_stack_ptr;
+
+
+static void conf_include(void);
+static int conf_eof(void);
+
+static int
+conf_yy_input(char *lbuf, unsigned int max_size)
+{
+ return fgets(lbuf, max_size, conf_file) == NULL ? 0 : strlen(lbuf);
+}
+
+static int
+conf_yy_fatal_error(const char *msg)
+{
+ return 0;
+}
+%}
+
+WS [[:blank:]]*
+DIGIT [[:digit:]]+
+COMMENT ("//"|"#").*
+qstring \"[^\"\n]*[\"\n]
+include \.include{WS}(\<.*\>|\".*\")
+
+%%
+
+"/*" { BEGIN IN_COMMENT; }
+<IN_COMMENT>"*/" { BEGIN INITIAL; }
+<IN_COMMENT>. ; /* Eat everything but a newline */
+<IN_COMMENT>\n { ++lineno; }
+<IN_COMMENT><<EOF>> { BEGIN INITIAL; if (conf_eof()) yyterminate(); }
+
+{include} { conf_include(); }
+\n.* { strlcpy(linebuf, yytext + 1, sizeof(linebuf)); ++lineno; yyless(1); }
+{WS} ;
+{COMMENT} ;
+{DIGIT} { yylval.number = atoi(yytext); return NUMBER; }
+{qstring} { if (yytext[yyleng - 2] == '\\')
+ {
+ yyless(yyleng - 1); /* Return last quote */
+ yymore(); /* Append next string */
+ }
+ else
+ {
+ yylval.string = yytext + 1;
+
+ if (yylval.string[yyleng - 2] != '"')
+ log_printf("CONFIG ->Unterminated character string");
+ else
+ {
+ unsigned int i = 0, j = 0;
+
+ yylval.string[yyleng - 2] = '\0'; /* Remove close quote */
+
+ for (; yylval.string[i] != '\0'; ++i, ++j)
+ {
+ if (yylval.string[i] != '\\')
+ yylval.string[j] = yylval.string[i];
+ else
+ {
+ ++i;
+
+ if (yylval.string[i] == '\0') /* XXX: should not happen */
+ {
+ log_printf("CONFIG -> Unterminated character string");
+ break;
+ }
+
+ yylval.string[j] = yylval.string[i];
+ }
+ }
+
+ yylval.string[j] = '\0';
+ return STRING;
+ }
+ }
+ }
+
+ADDRESS_FAMILY { return ADDRESS_FAMILY; }
+AWAY { return AWAY; }
+BAN_UNKNOWN { return BAN_UNKNOWN; }
+BLACKLIST { return BLACKLIST; }
+CHANNEL { return CHANNEL; }
+COMMAND_INTERVAL { return COMMAND_INTERVAL; }
+COMMAND_QUEUE_SIZE { return COMMAND_QUEUE_SIZE; }
+COMMAND_TIMEOUT { return COMMAND_TIMEOUT; }
+CONNREGEX { return CONNREGEX; }
+DNS_FDLIMIT { return DNS_FDLIMIT; }
+DNS_TIMEOUT { return DNS_TIMEOUT; }
+DNSBL_FROM { return DNSBL_FROM; }
+DNSBL_TO { return DNSBL_TO; }
+EXEMPT { return EXEMPT; }
+FD { return FD; }
+INVITE { return INVITE; }
+IPV4 { return IPV4; }
+IPV6 { return IPV6; }
+IRC { return IRC; }
+KLINE { return KLINE; }
+KEY { return KEY; }
+MASK { return MASK; }
+MAX_READ { return MAX_READ; }
+MODE { return MODE; }
+NAME { return NAME; }
+NEGCACHE { return NEGCACHE; }
+NEGCACHE_REBUILD { return NEGCACHE_REBUILD; }
+NICK { return NICK; }
+NICKSERV { return NICKSERV; }
+NOTICE { return NOTICE; }
+OPER { return OPER; }
+OPM { return OPM; }
+OPTIONS { return OPTIONS; }
+PASSWORD { return PASSWORD; }
+PERFORM { return PERFORM; }
+PIDFILE { return PIDFILE; }
+PORT { return PORT; }
+PROTOCOL { return PROTOCOL; }
+READTIMEOUT { return READTIMEOUT; }
+REALNAME { return REALNAME; }
+RECONNECTINTERVAL { return RECONNECTINTERVAL; }
+REPLY { return REPLY; }
+SCANLOG { return SCANLOG; }
+SCANNER { return SCANNER; }
+SENDMAIL { return SENDMAIL; }
+SERVER { return SERVER; }
+TARGET_IP { return TARGET_IP; }
+TARGET_PORT { return TARGET_PORT; }
+TARGET_STRING { return TARGET_STRING;}
+TIMEOUT { return TIMEOUT; }
+TYPE { return TYPE; }
+USER { return USER; }
+USERNAME { return USERNAME; }
+VHOST { return VHOST; }
+
+years { return YEARS; }
+year { return YEARS; }
+months { return MONTHS; }
+month { return MONTHS; }
+weeks { return WEEKS; }
+week { return WEEKS; }
+days { return DAYS; }
+day { return DAYS; }
+hours { return HOURS; }
+hour { return HOURS; }
+minutes { return MINUTES; }
+minute { return MINUTES; }
+seconds { return SECONDS; }
+second { return SECONDS; }
+
+bytes { return BYTES; }
+byte { return BYTES; }
+kilobytes { return KBYTES; }
+kilobyte { return KBYTES; }
+kbytes { return KBYTES; }
+kbyte { return KBYTES; }
+kb { return KBYTES; }
+megabytes { return MBYTES; }
+megabyte { return MBYTES; }
+mbytes { return MBYTES; }
+mbyte { return MBYTES; }
+mb { return MBYTES; }
+
+HTTP {
+ yylval.number = OPM_TYPE_HTTP;
+ return PROTOCOLTYPE;
+ }
+
+HTTPPOST {
+ yylval.number = OPM_TYPE_HTTPPOST;
+ return PROTOCOLTYPE;
+ }
+
+HTTPS {
+ yylval.number = OPM_TYPE_HTTPS;
+ return PROTOCOLTYPE;
+ }
+
+HTTPSPOST {
+ yylval.number = OPM_TYPE_HTTPSPOST;
+ return PROTOCOLTYPE;
+ }
+
+SOCKS4 {
+ yylval.number = OPM_TYPE_SOCKS4;
+ return PROTOCOLTYPE;
+ }
+
+SOCKS5 {
+ yylval.number = OPM_TYPE_SOCKS5;
+ return PROTOCOLTYPE;
+ }
+
+WINGATE {
+ yylval.number = OPM_TYPE_WINGATE;
+ return PROTOCOLTYPE;
+ }
+
+ROUTER {
+ yylval.number = OPM_TYPE_ROUTER;
+ return PROTOCOLTYPE;
+ }
+
+DREAMBOX {
+ yylval.number = OPM_TYPE_DREAMBOX;
+ return PROTOCOLTYPE;
+ }
+
+
+SSH {
+ yylval.number = OPM_TYPE_SSH;
+ return PROTOCOLTYPE;
+ }
+
+TRUE {
+ yylval.number=1;
+ return NUMBER;
+ }
+YES {
+ yylval.number=1;
+ return NUMBER;
+ }
+ON {
+ yylval.number=1;
+ return NUMBER;
+ }
+
+
+
+FALSE {
+ yylval.number=0;
+ return NUMBER;
+ }
+
+NO {
+ yylval.number=0;
+ return NUMBER;
+ }
+
+OFF {
+ yylval.number=0;
+ return NUMBER;
+ }
+
+. { return yytext[0]; }
+<<EOF>> { if (conf_eof()) yyterminate(); }
+
+%%
+
+static void
+conf_include(void)
+{
+ char *p = NULL;
+ char filenamebuf[512];
+
+ if ((p = strchr(yytext, '<')) == NULL)
+ *strchr(p = strchr(yytext, '"') + 1, '"') = '\0';
+ else
+ *strchr(++p, '>') = '\0';
+
+ /* do stacking and co. */
+ if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
+ {
+ log_printf("CONFIG -> Includes nested too deep in %s", p);
+ return;
+ }
+
+ if (*p == '/') /* if it is an absolute path */
+ snprintf(filenamebuf, sizeof(filenamebuf), "%s", p);
+ else
+ snprintf(filenamebuf, sizeof(filenamebuf), "%s/%s", HOPM_ETCDIR, p);
+
+ FILE *tmp_fbfile_in = fopen(filenamebuf, "r");
+ if (!tmp_fbfile_in)
+ {
+ log_printf("CONFIG -> Unable to read configuration file '%s': %s",
+ filenamebuf, strerror(errno));
+ return;
+ }
+
+ struct included_file *file = &include_stack[include_stack_ptr++];
+ file->lineno = lineno;
+ file->file = conf_file;
+ file->state = YY_CURRENT_BUFFER;
+ strlcpy(file->conffile, conffilebuf, sizeof(file->conffile));
+
+ lineno = 1;
+ conf_file = tmp_fbfile_in;
+ strlcpy(conffilebuf, filenamebuf, sizeof(conffilebuf));
+
+ yy_switch_to_buffer(yy_create_buffer(NULL, YY_BUF_SIZE));
+}
+
+static int
+conf_eof(void)
+{
+ if (include_stack_ptr == 0)
+ return 1;
+
+ /* switch buffer */
+ struct included_file *file = &include_stack[--include_stack_ptr];
+
+ /* close current file */
+ fclose(conf_file);
+
+ /* switch buffers */
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ yy_switch_to_buffer(file->state);
+
+ /* switch lineno */
+ lineno = file->lineno;
+
+ /* switch file */
+ conf_file = file->file;
+
+ strlcpy(conffilebuf, file->conffile, sizeof(conffilebuf));
+ return 0;
+}