summaryrefslogtreecommitdiff
path: root/src/conf_lexer.l
diff options
context:
space:
mode:
Diffstat (limited to 'src/conf_lexer.l')
-rw-r--r--src/conf_lexer.l489
1 files changed, 489 insertions, 0 deletions
diff --git a/src/conf_lexer.l b/src/conf_lexer.l
new file mode 100644
index 0000000..d089a57
--- /dev/null
+++ b/src/conf_lexer.l
@@ -0,0 +1,489 @@
+/*
+ * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
+ * conf_lexer.l: Scans the ircd configuration file for tokens.
+ *
+ * Copyright (C) 2002 by the past and present ircd coders, and others.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ * $Id$
+ */
+
+%option case-insensitive
+%option noyywrap
+%option nounput
+%option never-interactive
+
+%{
+#include "stdinc.h"
+#include "irc_string.h"
+#include "conf.h"
+#include "conf_parser.h" /* autogenerated header file */
+#include "memory.h"
+#include "hostmask.h"
+#include "log.h"
+
+#undef YY_INPUT
+#define YY_FATAL_ERROR(msg) conf_yy_fatal_error(msg)
+#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[IRCD_BUFSIZE];
+char conffilebuf[IRCD_BUFSIZE];
+
+static int include_stack_ptr = 0;
+static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
+static unsigned int lineno_stack[MAX_INCLUDE_DEPTH];
+static FILE *inc_fbfile_in[MAX_INCLUDE_DEPTH];
+static char conffile_stack[MAX_INCLUDE_DEPTH][IRCD_BUFSIZE];
+static void ccomment(void);
+static void cinclude(void);
+static int ieof(void);
+
+static int
+conf_yy_input(char *lbuf, unsigned int max_size)
+{
+ return !fgets(lbuf, max_size, conf_parser_ctx.conf_file) ? 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}(\<.*\>|\".*\")
+
+%%
+{include} { cinclude(); }
+"/*" { ccomment(); }
+
+\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] != '"')
+ ilog(LOG_TYPE_IRCD, "Unterminated character string");
+ else
+ {
+ int i,j;
+
+ yylval.string[yyleng-2] = '\0'; /* remove close
+ * quote
+ */
+
+ for (j=i=0 ;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
+ */
+ {
+ ilog(LOG_TYPE_IRCD,
+ "Unterminated character string");
+ break;
+ }
+ yylval.string[j] = yylval.string[i];
+ }
+ }
+ yylval.string[j] = '\0';
+ return QSTRING;
+ }
+ }
+ }
+
+accept_password { return ACCEPT_PASSWORD; }
+admin { return ADMIN; }
+administrator { return ADMIN; }
+aftype { return AFTYPE; }
+all { return T_ALL; }
+auth { return IRCD_AUTH; }
+autoconn { return AUTOCONN; }
+can_flood { return CAN_FLOOD; }
+caller_id_wait { return CALLER_ID_WAIT; }
+opers_bypass_callerid { return OPERS_BYPASS_CALLERID; }
+channel { return CHANNEL; }
+cidr_bitlen_ipv4 { return CIDR_BITLEN_IPV4; }
+cidr_bitlen_ipv6 { return CIDR_BITLEN_IPV6; }
+class { return CLASS; }
+cluster { return T_CLUSTER; }
+connect { return CONNECT; }
+connectfreq { return CONNECTFREQ; }
+default_floodcount { return DEFAULT_FLOODCOUNT; }
+default_split_server_count { return DEFAULT_SPLIT_SERVER_COUNT; }
+default_split_user_count { return DEFAULT_SPLIT_USER_COUNT; }
+deny { return DENY; }
+description { return DESCRIPTION; }
+die { return DIE; }
+disable_auth { return DISABLE_AUTH; }
+disable_fake_channels { return DISABLE_FAKE_CHANNELS; }
+disable_remote_commands { return DISABLE_REMOTE_COMMANDS; }
+dline { return T_DLINE; }
+dots_in_ident { return DOTS_IN_IDENT; }
+egdpool_path { return EGDPOOL_PATH; }
+email { return EMAIL; }
+encrypted { return ENCRYPTED; }
+exceed_limit { return EXCEED_LIMIT; }
+exempt { return EXEMPT; }
+file { return T_FILE; }
+flags { return IRCD_FLAGS; }
+flatten_links { return FLATTEN_LINKS; }
+gecos { return GECOS; }
+general { return GENERAL; }
+gline { return GLINE; }
+gline_enable { return GLINE_ENABLE; }
+gline_exempt { return GLINE_EXEMPT; }
+gline_duration { return GLINE_DURATION; }
+gline_request_duration { return GLINE_REQUEST_DURATION; }
+gline_min_cidr { return GLINE_MIN_CIDR; }
+gline_min_cidr6 { return GLINE_MIN_CIDR6; }
+globops { return T_GLOBOPS; }
+global_kill { return GLOBAL_KILL; }
+have_ident { return NEED_IDENT; }
+need_ident { return NEED_IDENT; }
+havent_read_conf { return HAVENT_READ_CONF; }
+hidden { return HIDDEN; }
+hidden_name { return HIDDEN_NAME; }
+hide_server_ips { return HIDE_SERVER_IPS; }
+hide_servers { return HIDE_SERVERS; }
+hide_spoof_ips { return HIDE_SPOOF_IPS; }
+host { return HOST; }
+hub { return HUB; }
+hub_mask { return HUB_MASK; }
+ignore_bogus_ts { return IGNORE_BOGUS_TS; }
+invisible_on_connect { return INVISIBLE_ON_CONNECT; }
+ip { return IP; }
+ipv4 { return T_IPV4; }
+ipv6 { return T_IPV6; }
+join_flood_count { return JOIN_FLOOD_COUNT; }
+join_flood_time { return JOIN_FLOOD_TIME; }
+kill { return KILL; }
+kill_chase_time_limit { return KILL_CHASE_TIME_LIMIT; }
+kline { return KLINE; }
+kline_exempt { return KLINE_EXEMPT; }
+leaf_mask { return LEAF_MASK; }
+listen { return LISTEN; }
+log { return T_LOG; }
+masked { return TMASKED; }
+max_clients { return T_MAX_CLIENTS; }
+max_ident { return MAX_IDENT; }
+max_local { return MAX_LOCAL; }
+max_global { return MAX_GLOBAL; }
+max_number { return MAX_NUMBER; }
+max_watch { return MAX_WATCH; }
+message_locale { return MESSAGE_LOCALE; }
+min_nonwildcard { return MIN_NONWILDCARD; }
+min_nonwildcard_simple { return MIN_NONWILDCARD_SIMPLE; }
+name { return NAME; }
+need_password { return NEED_PASSWORD; }
+network_desc { return NETWORK_DESC; }
+network_name { return NETWORK_NAME; }
+nick { return NICK; }
+nick_changes { return NICK_CHANGES; }
+no { yylval.number = 0; return TBOOL; }
+no_create_on_split { return NO_CREATE_ON_SPLIT; }
+no_join_on_split { return NO_JOIN_ON_SPLIT; }
+no_oper_flood { return NO_OPER_FLOOD; }
+no_tilde { return NO_TILDE; }
+number_per_cidr { return NUMBER_PER_CIDR; }
+number_per_ip { return NUMBER_PER_IP; }
+oper { return OPERATOR; }
+oper_pass_resv { return OPER_PASS_RESV; }
+operator { return OPERATOR; }
+passwd { return PASSWORD; }
+password { return PASSWORD; }
+ping_cookie { return PING_COOKIE; }
+ping_time { return PING_TIME; }
+ping_warning { return PING_WARNING; }
+port { return PORT; }
+quarantine { return RESV; }
+quiet_on_ban { return QUIET_ON_BAN; }
+reason { return REASON; }
+recvq { return T_RECVQ; }
+redirport { return REDIRPORT; }
+redirserv { return REDIRSERV; }
+regex { return REGEX_T; }
+rehash { return REHASH; }
+remote { return REMOTE; }
+remoteban { return REMOTEBAN; }
+restart { return T_RESTART; }
+restrict_channels { return RESTRICT_CHANNELS; }
+resv { return RESV; }
+resv_exempt { return RESV_EXEMPT; }
+rsa_private_key_file { return RSA_PRIVATE_KEY_FILE; }
+rsa_public_key_file { return RSA_PUBLIC_KEY_FILE; }
+ssl { return T_SSL; }
+ssl_certificate_file { return SSL_CERTIFICATE_FILE; }
+ssl_client_method { return T_SSL_CLIENT_METHOD; }
+ssl_server_method { return T_SSL_SERVER_METHOD; }
+ssl_dh_param_file { return SSL_DH_PARAM_FILE; }
+ssl_cipher_list { return T_SSL_CIPHER_LIST; }
+sslv3 { return T_SSLV3; }
+tlsv1 { return T_TLSV1; }
+send_password { return SEND_PASSWORD; }
+sendq { return SENDQ; }
+server { return T_SERVER; }
+serverhide { return SERVERHIDE; }
+serverinfo { return SERVERINFO; }
+service { return T_SERVICE; }
+services_name { return T_SERVICES_NAME; }
+set { return T_SET; }
+shared { return T_SHARED; }
+short_motd { return SHORT_MOTD; }
+sid { return IRCD_SID; }
+size { return T_SIZE; }
+spoof { return SPOOF; }
+spoof_notice { return SPOOF_NOTICE; }
+tkline_expire_notices { return TKLINE_EXPIRE_NOTICES; }
+type { return TYPE; }
+true_no_oper_flood { return TRUE_NO_OPER_FLOOD; }
+umodes { return T_UMODES; }
+unkline { return UNKLINE; }
+undline { return T_UNDLINE; }
+unlimited { return T_UNLIMITED; }
+use_egd { return USE_EGD; }
+use_logging { return USE_LOGGING; }
+throttle_time { return THROTTLE_TIME; }
+user { return USER; }
+vhost { return VHOST; }
+vhost6 { return VHOST6; }
+xline { return XLINE; }
+yes { yylval.number = 1; return TBOOL; }
+
+failed_oper_notice { return FAILED_OPER_NOTICE; }
+max_accept { return MAX_ACCEPT; }
+max_nick_changes { return MAX_NICK_CHANGES; }
+max_chans_per_oper { return MAX_CHANS_PER_OPER; }
+max_chans_per_user { return MAX_CHANS_PER_USER; }
+max_nick_time { return MAX_NICK_TIME; }
+anti_nick_flood { return ANTI_NICK_FLOOD; }
+anti_spam_exit_message_time { return ANTI_SPAM_EXIT_MESSAGE_TIME; }
+ts_max_delta { return TS_MAX_DELTA; }
+ts_warn_delta { return TS_WARN_DELTA; }
+links_delay { return LINKS_DELAY; }
+warn_no_nline { return WARN_NO_NLINE; }
+
+stats_e_disabled { return STATS_E_DISABLED; }
+stats_o_oper_only { return STATS_O_OPER_ONLY; }
+stats_k_oper_only { return STATS_K_OPER_ONLY; }
+stats_i_oper_only { return STATS_I_OPER_ONLY; }
+stats_P_oper_only { return STATS_P_OPER_ONLY; }
+pace_wait { return PACE_WAIT; }
+pace_wait_simple { return PACE_WAIT_SIMPLE; }
+knock_delay { return KNOCK_DELAY; }
+knock_delay_channel { return KNOCK_DELAY_CHANNEL; }
+max_bans { return MAX_BANS; }
+modules { return MODULES; }
+module { return MODULE; }
+path { return PATH; }
+max_targets { return MAX_TARGETS; }
+
+unxline { return T_UNXLINE; }
+unresv { return T_UNRESV; }
+
+oper_only_umodes { return OPER_ONLY_UMODES; }
+oper_umodes { return OPER_UMODES; }
+bots { return T_BOTS; }
+cconn { return T_CCONN; }
+cconn_full { return T_CCONN_FULL; }
+deaf { return T_DEAF; }
+debug { return T_DEBUG; }
+full { return T_FULL; }
+skill { return T_SKILL; }
+nchange { return T_NCHANGE; }
+rej { return T_REJ; }
+unauth { return T_UNAUTH; }
+spy { return T_SPY; }
+external { return T_EXTERNAL; }
+operwall { return T_OPERWALL; }
+servnotice { return T_SERVNOTICE; }
+invisible { return T_INVISIBLE; }
+wallop { return T_WALLOP; }
+callerid { return T_CALLERID; }
+softcallerid { return T_SOFTCALLERID; }
+locops { return T_LOCOPS; }
+
+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; }
+\.\. { return TWODOTS; }
+
+. { return yytext[0]; }
+<<EOF>> { if (ieof()) yyterminate(); }
+
+%%
+
+/* C-comment ignoring routine -kre*/
+static void
+ccomment(void)
+{
+ int c = 0;
+
+ /* log(L_NOTICE, "got comment"); */
+ while (1)
+ {
+ while ((c = input()) != '*' && c != EOF)
+ if (c == '\n')
+ ++lineno;
+
+ if (c == '*')
+ {
+ while ((c = input()) == '*')
+ /* Nothing */ ;
+ if (c == '/')
+ break;
+ else if (c == '\n')
+ ++lineno;
+ }
+
+ if (c == EOF)
+ {
+ YY_FATAL_ERROR("EOF in comment");
+ /* XXX hack alert this disables
+ * the stupid unused function warning
+ * gcc generates
+ */
+ if (1 == 0)
+ yy_fatal_error("EOF in comment");
+ break;
+ }
+ }
+}
+
+/* C-style .includes. This function will properly swap input conf buffers,
+ * and lineno -kre */
+static void
+cinclude(void)
+{
+ char *p = NULL;
+
+ if ((p = strchr(yytext, '<')) == NULL)
+ *strchr(p = strchr(yytext, '"') + 1, '"') = '\0';
+ else
+ *strchr(++p, '>') = '\0';
+
+ /* log(L_NOTICE, "got include %s!", c); */
+
+ /* do stacking and co. */
+ if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
+ ilog(LOG_TYPE_IRCD, "Includes nested too deep in %s", p);
+ else
+ {
+ FILE *tmp_fbfile_in = NULL;
+ char filenamebuf[IRCD_BUFSIZE];
+
+ if (*p == '/') /* if it is an absolute path */
+ snprintf(filenamebuf, sizeof(filenamebuf), "%s", p);
+ else
+ snprintf(filenamebuf, sizeof(filenamebuf), "%s/%s", ETCPATH, p);
+
+ tmp_fbfile_in = fopen(filenamebuf, "r");
+
+ if (tmp_fbfile_in == NULL)
+ {
+ ilog(LOG_TYPE_IRCD, "Unable to read configuration file '%s': %s",
+ filenamebuf, strerror(errno));
+ return;
+ }
+
+ lineno_stack[include_stack_ptr] = lineno;
+ lineno = 1;
+ inc_fbfile_in[include_stack_ptr] = conf_parser_ctx.conf_file;
+ strlcpy(conffile_stack[include_stack_ptr], conffilebuf, IRCD_BUFSIZE);
+ include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
+ conf_parser_ctx.conf_file = tmp_fbfile_in;
+ snprintf(conffilebuf, sizeof(conffilebuf), "%s", filenamebuf);
+ yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
+ }
+}
+
+/* This is function that will be called on EOF in conf file. It will
+ * apropriately close conf if it not main conf and swap input buffers -kre
+ * */
+static int
+ieof(void)
+{
+ /* log(L_NOTICE, "return from include stack!"); */
+ if (include_stack_ptr)
+ fclose(conf_parser_ctx.conf_file);
+ if (--include_stack_ptr < 0)
+ {
+ /* log(L_NOTICE, "terminating lexer"); */
+ /* We will now exit the lexer - restore init values if we get /rehash
+ * later and reenter lexer -kre */
+ include_stack_ptr = 0;
+ lineno = 1;
+ return 1;
+ }
+
+ /* switch buffer */
+ /* log(L_NOTICE, "deleting include_stack_ptr=%d", include_stack_ptr); */
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ lineno = lineno_stack[include_stack_ptr];
+ conf_parser_ctx.conf_file = inc_fbfile_in[include_stack_ptr];
+ strlcpy(conffilebuf, conffile_stack[include_stack_ptr], sizeof(conffilebuf));
+ yy_switch_to_buffer(include_stack[include_stack_ptr]);
+
+ return 0;
+}