]>
Commit | Line | Data |
---|---|---|
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,v 1.21.2.2 2006/06/08 02:11:21 entrope Exp $ | |
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 "ircd.h" | |
30 | #include "ircd_alloc.h" | |
31 | #include "ircd_string.h" | |
32 | #include "s_debug.h" | |
33 | #include "y.tab.h" | |
34 | ||
35 | extern int lineno; | |
36 | ||
37 | static struct lexer_token { | |
38 | const char *string; | |
39 | int value; | |
40 | } tokens[] = { | |
41 | #define TOKEN(NAME) { #NAME, NAME } | |
42 | TOKEN(ADMIN), | |
43 | TOKEN(GENERAL), | |
44 | TOKEN(LOCATION), | |
45 | TOKEN(CONTACT), | |
46 | TOKEN(CLASS), | |
47 | TOKEN(PINGFREQ), | |
48 | TOKEN(CONNECT), | |
49 | TOKEN(CONNECTFREQ), | |
50 | TOKEN(MAXLINKS), | |
51 | TOKEN(MAXHOPS), | |
52 | TOKEN(SENDQ), | |
53 | TOKEN(NAME), | |
54 | TOKEN(HOST), | |
55 | TOKEN(IP), | |
56 | TOKEN(USERNAME), | |
57 | TOKEN(PASS), | |
58 | TOKEN(SECONDS), | |
59 | TOKEN(MINUTES), | |
60 | TOKEN(HOURS), | |
61 | TOKEN(DAYS), | |
62 | TOKEN(WEEKS), | |
63 | TOKEN(MONTHS), | |
64 | TOKEN(YEARS), | |
65 | TOKEN(DECADES), | |
66 | TOKEN(BYTES), | |
67 | TOKEN(KBYTES), | |
68 | TOKEN(MBYTES), | |
69 | TOKEN(GBYTES), | |
70 | TOKEN(TBYTES), | |
71 | TOKEN(PORT), | |
72 | TOKEN(SERVER), | |
73 | TOKEN(YES), | |
74 | TOKEN(NO), | |
75 | TOKEN(HUB), | |
76 | TOKEN(LEAF), | |
77 | TOKEN(UWORLD), | |
78 | TOKEN(OPER), | |
79 | TOKEN(LOCAL), | |
80 | TOKEN(VHOST), | |
81 | TOKEN(MASK), | |
82 | TOKEN(HIDDEN), | |
83 | TOKEN(MOTD), | |
84 | TOKEN(NUMERIC), | |
85 | TOKEN(NICK), | |
86 | TOKEN(JUPE), | |
87 | TOKEN(DESCRIPTION), | |
88 | TOKEN(CLIENT), | |
89 | TOKEN(REAL), | |
90 | TOKEN(REASON), | |
91 | TOKEN(RULE), | |
92 | TOKEN(ALL), | |
93 | TOKEN(CRULE), | |
94 | TOKEN(KILL), | |
95 | TOKEN(QUARANTINE), | |
96 | TOKEN(IAUTH), | |
97 | TOKEN(TIMEOUT), | |
98 | TOKEN(FEATURES), | |
99 | TOKEN(CHANNEL), | |
100 | TOKEN(PSEUDO), | |
101 | TOKEN(PREPEND), | |
102 | TOKEN(USERMODE), | |
103 | TOKEN(FAST), | |
104 | TOKEN(AUTOCONNECT), | |
105 | TOKEN(SPOOFHOST), | |
106 | TOKEN(PROGRAM), | |
107 | #undef TOKEN | |
108 | { "administrator", ADMIN }, | |
109 | { "apass_opmode", TPRIV_APASS_OPMODE }, | |
110 | { "auto", AUTOCONNECT }, | |
111 | { "b", BYTES }, | |
112 | { "badchan", TPRIV_BADCHAN }, | |
113 | { "chan_limit", TPRIV_CHAN_LIMIT }, | |
114 | { "deop_lchan", TPRIV_DEOP_LCHAN }, | |
115 | { "die", TPRIV_DIE }, | |
116 | { "display", TPRIV_DISPLAY }, | |
117 | { "file", TFILE }, | |
118 | { "force_local_opmode", TPRIV_FORCE_LOCAL_OPMODE }, | |
119 | { "force_opmode", TPRIV_FORCE_OPMODE }, | |
120 | { "gline", TPRIV_GLINE }, | |
121 | { "kb", KBYTES }, | |
122 | { "kilobytes", KBYTES }, | |
123 | { "list_chan", TPRIV_LIST_CHAN }, | |
124 | { "local_badchan", TPRIV_LOCAL_BADCHAN }, | |
125 | { "local_gline", TPRIV_LOCAL_GLINE }, | |
126 | { "local_jupe", TPRIV_LOCAL_JUPE }, | |
127 | { "local_kill", TPRIV_LOCAL_KILL }, | |
128 | { "local_opmode", TPRIV_LOCAL_OPMODE }, | |
129 | { "mb", MBYTES }, | |
130 | { "megabytes", MBYTES }, | |
131 | { "mode_lchan", TPRIV_MODE_LCHAN }, | |
132 | { "gb", GBYTES }, | |
133 | { "gigabytes", GBYTES }, | |
134 | { "operator", OPER }, | |
135 | { "opmode", TPRIV_OPMODE }, | |
136 | { "password", PASS }, | |
137 | { "propagate", TPRIV_PROPAGATE }, | |
138 | { "realname", REAL }, | |
139 | { "rehash", TPRIV_REHASH }, | |
140 | { "restart", TPRIV_RESTART }, | |
141 | { "see_chan", TPRIV_SEE_CHAN }, | |
142 | { "see_opers", TPRIV_SEE_OPERS }, | |
143 | { "set", TPRIV_SET }, | |
144 | { "show_all_invis", TPRIV_SHOW_ALL_INVIS }, | |
145 | { "show_invis", TPRIV_SHOW_INVIS }, | |
146 | { "tb", TBYTES }, | |
147 | { "terabytes", TBYTES }, | |
148 | { "unlimit_query", TPRIV_UNLIMIT_QUERY }, | |
149 | { "walk_lchan", TPRIV_WALK_LCHAN }, | |
150 | { "wide_gline", TPRIV_WIDE_GLINE }, | |
151 | { "whox", TPRIV_WHOX }, | |
152 | { NULL, 0 } | |
153 | }; | |
154 | static int ntokens; | |
155 | ||
156 | static int | |
157 | token_compare(const void *pa, const void *pb) | |
158 | { | |
159 | const struct lexer_token *ta = pa; | |
160 | const struct lexer_token *tb = pb; | |
161 | unsigned int ii = 0; | |
162 | int res; | |
163 | while (ta->string[ii] && (ToLower(ta->string[ii]) == ToLower(tb->string[ii]))) | |
164 | ii++; | |
165 | res = ToLower(tb->string[ii]) - ToLower(ta->string[ii]); | |
166 | return res; | |
167 | } | |
168 | ||
169 | static void | |
170 | init_ntokens(void) | |
171 | { | |
172 | for (ntokens = 0; tokens[ntokens].string; ++ntokens) ; | |
173 | qsort(tokens, ntokens, sizeof(tokens[0]), token_compare); | |
174 | } | |
175 | ||
176 | static int | |
177 | find_token(char *token) | |
178 | { | |
179 | struct lexer_token *tok; | |
180 | if (!ntokens) | |
181 | init_ntokens(); | |
182 | tok = bsearch(&token, tokens, ntokens, sizeof(tokens[0]), token_compare); | |
183 | return tok ? tok->value : 0; | |
184 | } | |
185 | ||
186 | void | |
187 | init_lexer(void) | |
188 | { | |
189 | yyin = fopen(configfile, "r"); | |
190 | if (yyin == NULL) | |
191 | { | |
192 | #ifdef YY_FATAL_ERROR | |
193 | YY_FATAL_ERROR("Could not open the configuration file."); | |
194 | #else | |
195 | fprintf(stderr, "Could not open the configuration file."); | |
196 | #endif | |
197 | } | |
198 | #ifdef YY_NEW_FILE | |
199 | YY_NEW_FILE; | |
200 | #endif | |
201 | lineno = 1; | |
202 | } | |
203 | ||
204 | %} | |
205 | ||
206 | WHITE [ \t\r]+ | |
207 | SHCOMMENT #[^\n]* | |
208 | NUMBER [0-9]+ | |
209 | QSTRING \"[^"\n]+[\"\n] | |
210 | %% | |
211 | ||
212 | {QSTRING} {yytext[yyleng-1] = 0; DupString(yylval.text, yytext+1); return QSTRING;} | |
213 | {NUMBER} {yylval.num = strtoul(yytext, NULL, 10); return NUMBER;} | |
214 | {WHITE} ; | |
215 | {SHCOMMENT} ; | |
216 | ||
217 | [a-zA-Z_]+ { int res = find_token(yytext); if (res) return res; else REJECT; } | |
218 | \n lineno++; | |
219 | . return yytext[0]; |