]>
Commit | Line | Data |
---|---|---|
189935b1 | 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 2005/04/26 03:56:50 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 | #undef TOKEN | |
106 | { "administrator", ADMIN }, | |
107 | { "apass_opmode", TPRIV_APASS_OPMODE }, | |
108 | { "auto", AUTOCONNECT }, | |
109 | { "b", BYTES }, | |
110 | { "badchan", TPRIV_BADCHAN }, | |
111 | { "chan_limit", TPRIV_CHAN_LIMIT }, | |
112 | { "deop_lchan", TPRIV_DEOP_LCHAN }, | |
113 | { "die", TPRIV_DIE }, | |
114 | { "display", TPRIV_DISPLAY }, | |
115 | { "file", TFILE }, | |
116 | { "force_local_opmode", TPRIV_FORCE_LOCAL_OPMODE }, | |
117 | { "force_opmode", TPRIV_FORCE_OPMODE }, | |
118 | { "gline", TPRIV_GLINE }, | |
119 | { "kb", KBYTES }, | |
120 | { "kilobytes", KBYTES }, | |
121 | { "local_badchan", TPRIV_LOCAL_BADCHAN }, | |
122 | { "local_gline", TPRIV_LOCAL_GLINE }, | |
123 | { "local_jupe", TPRIV_LOCAL_JUPE }, | |
124 | { "local_kill", TPRIV_LOCAL_KILL }, | |
125 | { "local_opmode", TPRIV_LOCAL_OPMODE }, | |
126 | { "mb", MBYTES }, | |
127 | { "megabytes", MBYTES }, | |
128 | { "mode_lchan", TPRIV_MODE_LCHAN }, | |
129 | { "gb", GBYTES }, | |
130 | { "gigabytes", GBYTES }, | |
131 | { "operator", OPER }, | |
132 | { "opmode", TPRIV_OPMODE }, | |
133 | { "password", PASS }, | |
134 | { "propagate", TPRIV_PROPAGATE }, | |
135 | { "realname", REAL }, | |
136 | { "rehash", TPRIV_REHASH }, | |
137 | { "restart", TPRIV_RESTART }, | |
138 | { "see_chan", TPRIV_SEE_CHAN }, | |
139 | { "see_opers", TPRIV_SEE_OPERS }, | |
140 | { "set", TPRIV_SET }, | |
141 | { "show_all_invis", TPRIV_SHOW_ALL_INVIS }, | |
142 | { "show_invis", TPRIV_SHOW_INVIS }, | |
143 | { "tb", TBYTES }, | |
144 | { "terabytes", TBYTES }, | |
145 | { "unlimit_query", TPRIV_UNLIMIT_QUERY }, | |
146 | { "walk_lchan", TPRIV_WALK_LCHAN }, | |
147 | { "wide_gline", TPRIV_WIDE_GLINE }, | |
148 | { "whox", TPRIV_WHOX }, | |
149 | { NULL, 0 } | |
150 | }; | |
151 | static int ntokens; | |
152 | ||
153 | static int | |
154 | token_compare(const void *pa, const void *pb) | |
155 | { | |
156 | const struct lexer_token *ta = pa; | |
157 | const struct lexer_token *tb = pb; | |
158 | unsigned int ii = 0; | |
159 | int res; | |
160 | while (ta->string[ii] && (ToLower(ta->string[ii]) == ToLower(tb->string[ii]))) | |
161 | ii++; | |
162 | res = ToLower(tb->string[ii]) - ToLower(ta->string[ii]); | |
163 | return res; | |
164 | } | |
165 | ||
166 | static void | |
167 | init_ntokens(void) | |
168 | { | |
169 | for (ntokens = 0; tokens[ntokens].string; ++ntokens) ; | |
170 | qsort(tokens, ntokens, sizeof(tokens[0]), token_compare); | |
171 | } | |
172 | ||
173 | static int | |
174 | find_token(char *token) | |
175 | { | |
176 | struct lexer_token *tok; | |
177 | if (!ntokens) | |
178 | init_ntokens(); | |
179 | tok = bsearch(&token, tokens, ntokens, sizeof(tokens[0]), token_compare); | |
180 | return tok ? tok->value : 0; | |
181 | } | |
182 | ||
183 | void | |
184 | init_lexer(void) | |
185 | { | |
186 | yyin = fopen(configfile, "r"); | |
187 | if (yyin == NULL) | |
188 | { | |
189 | #ifdef YY_FATAL_ERROR | |
190 | YY_FATAL_ERROR("Could not open the configuration file."); | |
191 | #else | |
192 | fprintf(stderr, "Could not open the configuration file."); | |
193 | #endif | |
194 | } | |
195 | #ifdef YY_NEW_FILE | |
196 | YY_NEW_FILE; | |
197 | #endif | |
198 | lineno = 1; | |
199 | } | |
200 | ||
201 | %} | |
202 | ||
203 | WHITE [ \t\r]+ | |
204 | SHCOMMENT #[^\n]* | |
205 | NUMBER [0-9]+ | |
206 | QSTRING \"[^"\n]+[\"\n] | |
207 | %% | |
208 | ||
209 | {QSTRING} {yytext[yyleng-1] = 0; DupString(yylval.text, yytext+1); return QSTRING;} | |
210 | {NUMBER} {yylval.num = strtoul(yytext, NULL, 10); return NUMBER;} | |
211 | {WHITE} ; | |
212 | {SHCOMMENT} ; | |
213 | ||
214 | [a-zA-Z_]+ { int res = find_token(yytext); if (res) return res; else REJECT; } | |
215 | \n lineno++; | |
216 | . return yytext[0]; |