ircu2.10.12 pk910 fork
[ircu2.10.12-pk.git] / ircd / ircd_lexer.l
1 /*
2  * ircd_lexer.l: A lexical scanner for ircd config files.
3  * This is part of ircu, an Internet Relay Chat server.
4  * The contents of this file are Copyright(C) 2001 by Andrew Miller, the
5  * ircd-hybrid team and the ircu team.
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19  *  USA.
20  * $Id: ircd_lexer.l 1851 2007-11-30 22:10:04Z klmitch $
21  */
22
23 %{
24 #include <unistd.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include "config.h"
29 #include "fileio.h"
30 #include "ircd.h"
31 #include "ircd_alloc.h"
32 #include "ircd_string.h"
33 #include "s_debug.h"
34 #include "y.tab.h"
35
36 extern int lineno;
37
38 static struct lexer_token {
39   const char *string;
40   int value;
41 } tokens[] = {
42 #define TOKEN(NAME) { #NAME, NAME }
43   TOKEN(ADMIN),
44   TOKEN(GENERAL),
45   TOKEN(LOCATION),
46   TOKEN(CONTACT),
47   TOKEN(CLASS),
48   TOKEN(PINGFREQ),
49   TOKEN(CONNECT),
50   TOKEN(CONNECTFREQ),
51   TOKEN(MAXLINKS),
52   TOKEN(MAXHOPS),
53   TOKEN(SENDQ),
54   TOKEN(NAME),
55   TOKEN(HOST),
56   TOKEN(IP),
57   TOKEN(USERNAME),
58   TOKEN(PASS),
59   TOKEN(SECONDS),
60   TOKEN(MINUTES),
61   TOKEN(HOURS),
62   TOKEN(DAYS),
63   TOKEN(WEEKS),
64   TOKEN(MONTHS),
65   TOKEN(YEARS),
66   TOKEN(DECADES),
67   TOKEN(BYTES),
68   TOKEN(KBYTES),
69   TOKEN(MBYTES),
70   TOKEN(GBYTES),
71   TOKEN(TBYTES),
72   TOKEN(PORT),
73   TOKEN(SERVER),
74   TOKEN(YES),
75   TOKEN(NO),
76   TOKEN(HUB),
77   TOKEN(LEAF),
78   TOKEN(UWORLD),
79   TOKEN(OPER),
80   TOKEN(LOCAL),
81   TOKEN(VHOST),
82   TOKEN(MASK),
83   TOKEN(HIDDEN),
84   TOKEN(MOTD),
85   TOKEN(NUMERIC),
86   TOKEN(NICK),
87   TOKEN(JUPE),
88   TOKEN(DESCRIPTION),
89   TOKEN(CLIENT),
90   TOKEN(REAL),
91   TOKEN(REASON),
92   TOKEN(RULE),
93   TOKEN(ALL),
94   TOKEN(CRULE),
95   TOKEN(KILL),
96   TOKEN(QUARANTINE),
97   TOKEN(IAUTH),
98   TOKEN(TIMEOUT),
99   TOKEN(FEATURES),
100   TOKEN(CHANNEL),
101   TOKEN(PSEUDO),
102   TOKEN(PREPEND),
103   TOKEN(USERMODE),
104   TOKEN(FAST),
105   TOKEN(AUTOCONNECT),
106   TOKEN(PROGRAM),
107   TOKEN(DNS),
108   TOKEN(FORWARDS),
109   TOKEN(SECURE),
110   TOKEN(WEBIRC),
111   TOKEN(SPOOF),
112   TOKEN(REQUIRED),
113   TOKEN(SSL),
114   TOKEN(CERT),
115   TOKEN(CACERT),
116 #undef TOKEN
117   { "administrator", ADMIN },
118   { "apass_opmode", TPRIV_APASS_OPMODE },
119   { "auto", AUTOCONNECT },
120   { "b", BYTES },
121   { "badchan", TPRIV_BADCHAN },
122   { "chan_limit", TPRIV_CHAN_LIMIT },
123   { "deop_lchan", TPRIV_DEOP_LCHAN },
124   { "die", TPRIV_DIE },
125   { "display", TPRIV_DISPLAY },
126   { "file", TFILE },
127   { "force_local_opmode", TPRIV_FORCE_LOCAL_OPMODE },
128   { "force_opmode", TPRIV_FORCE_OPMODE },
129   { "gb", GBYTES },
130   { "gigabytes", GBYTES },
131   { "gline", TPRIV_GLINE },
132 #ifdef OLD_OGN_IRCU_COMPAT
133   { "hide_channels", TPRIV_UMODE_NOCHAN },
134   { "hide_idletime", TPRIV_UMODE_NOIDLE },
135 #endif
136   { "umode_nochan", TPRIV_UMODE_NOCHAN },
137   { "umode_noidle", TPRIV_UMODE_NOIDLE },
138   { "extra_hide_idletime", TPRIV_HIDE_IDLETIME },
139 #ifndef OLD_OGN_IRCU_COMPAT
140   { "hide_idletime", TPRIV_HIDE_IDLETIME },
141 #endif
142   { "ipv4", TOK_IPV4 },
143   { "ipv6", TOK_IPV6 },
144   { "kb", KBYTES },
145   { "kilobytes", KBYTES },
146   { "list_chan", TPRIV_LIST_CHAN },
147   { "local_badchan", TPRIV_LOCAL_BADCHAN },
148   { "local_gline", TPRIV_LOCAL_GLINE },
149   { "local_jupe", TPRIV_LOCAL_JUPE },
150   { "local_kill", TPRIV_LOCAL_KILL },
151   { "local_opmode", TPRIV_LOCAL_OPMODE },
152   { "maxchans", MAXCHANS },
153   { "mb", MBYTES },
154   { "megabytes", MBYTES },
155   { "mode_lchan", TPRIV_MODE_LCHAN },
156   { "more_flood", TPRIV_HALFFLOOD },
157   { "noamsg_override", TPRIV_NOAMSG_OVERRIDE },
158   { "operator", OPER },
159   { "opmode", TPRIV_OPMODE },
160   { "password", PASS },
161   { "propagate", TPRIV_PROPAGATE },
162   { "realname", REAL },
163   { "rehash", TPRIV_REHASH },
164   { "restart", TPRIV_RESTART },
165   { "see_chan", TPRIV_SEE_CHAN },
166   { "see_idletime", TPRIV_SEE_IDLETIME },
167   { "see_opers", TPRIV_SEE_OPERS },
168   { "set", TPRIV_SET },
169   { "show_all_invis", TPRIV_SHOW_ALL_INVIS },
170   { "show_invis", TPRIV_SHOW_INVIS },
171 #ifdef OLD_OGN_IRCU_COMPAT
172   { "targetchange", TPRIV_UNLIMITED_TARGET },
173 #endif
174   { "unlimited_targets", TPRIV_UNLIMITED_TARGET },
175   { "tb", TBYTES },
176   { "terabytes", TBYTES },
177   { "umode_chserv", TPRIV_UMODE_CHSERV },
178   { "umode_xtraop", TPRIV_UMODE_XTRAOP },
179   { "umode_netserv", TPRIV_UMODE_NETSERV },
180   { "umode_overridecc", TPRIV_UMODE_OVERRIDECC },
181   { "unlimit_query", TPRIV_UNLIMIT_QUERY },
182   { "unlimited_flood", TPRIV_FLOOD },
183   { "walk_lchan", TPRIV_WALK_LCHAN },
184   { "wide_gline", TPRIV_WIDE_GLINE },
185   { "whox", TPRIV_WHOX },
186   { NULL, 0 }
187 };
188 static int ntokens;
189
190 static int
191 token_compare(const void *pa, const void *pb)
192 {
193   const struct lexer_token *ta = pa;
194   const struct lexer_token *tb = pb;
195   unsigned int ii = 0;
196   int res;
197   while (ta->string[ii] && (ToLower(ta->string[ii]) == ToLower(tb->string[ii])))
198     ii++;
199   res = ToLower(tb->string[ii]) - ToLower(ta->string[ii]);
200   return res;
201 }
202
203 static void
204 init_ntokens(void)
205 {
206   for (ntokens = 0; tokens[ntokens].string; ++ntokens) ;
207   qsort(tokens, ntokens, sizeof(tokens[0]), token_compare);
208 }
209
210 static int
211 find_token(char *token)
212 {
213   struct lexer_token *tok;
214   if (!ntokens)
215     init_ntokens();
216   tok = bsearch(&token, tokens, ntokens, sizeof(tokens[0]), token_compare);
217   return tok ? tok->value : 0;
218 }
219
220 static FBFILE *lexer_input;
221
222 #undef YY_INPUT
223 #define YY_INPUT(buf, res, size) res = (fbgets(buf, size, lexer_input) ? strlen(buf) : 0)
224
225 int
226 init_lexer(void)
227 {
228   lexer_input = fbopen(configfile, "r");
229   if (lexer_input == NULL)
230   {
231 #ifdef YY_FATAL_ERROR
232     YY_FATAL_ERROR("Could not open the configuration file.");
233 #else
234     fprintf(stderr, "Could not open the configuration file.");
235 #endif
236     return 0;
237   }
238 #ifdef YY_NEW_FILE
239   YY_NEW_FILE;
240 #endif
241   lineno = 1;
242   return 1;
243 }
244
245 void deinit_lexer(void)
246 {
247   if (lexer_input != NULL)
248   {
249     fbclose(lexer_input);
250     lexer_input = NULL;
251   }
252 }
253
254 int
255 yywrap(void)
256 {
257   return 1;
258 }
259
260 %}
261
262 WHITE [ \t\r]+
263 SHCOMMENT #[^\n]*
264 NUMBER [0-9]+
265 QSTRING \"[^"\n]+[\"\n]
266 %%
267
268 {QSTRING} {yytext[yyleng-1] = 0; DupString(yylval.text, yytext+1); return QSTRING;}
269 {NUMBER} {yylval.num = strtoul(yytext, NULL, 10); return NUMBER;}
270 {WHITE} ;
271 {SHCOMMENT} ;
272
273 [a-zA-Z_][a-zA-Z_0-9]* { int res = find_token(yytext); if (res) return res; else REJECT; }
274 \n lineno++;
275 . return yytext[0];