]>
Commit | Line | Data |
---|---|---|
832ed81a AC |
1 | /* bandb/bandb.c |
2 | * | |
3 | * Copyright (C) 2006 Lee Hardy <lee -at- leeh.co.uk> | |
4 | * Copyright (C) 2006-2008 ircd-ratbox development team | |
5 | * | |
6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions are | |
8 | * met: | |
9 | * | |
10 | * 1.Redistributions of source code must retain the above copyright notice, | |
11 | * this list of conditions and the following disclaimer. | |
12 | * 2.Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | |
15 | * 3.The name of the author may not be used to endorse or promote products | |
16 | * derived from this software without specific prior written permission. | |
17 | * | |
18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
20 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
21 | * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, | |
22 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
23 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
24 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
26 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | |
27 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
28 | * POSSIBILITY OF SUCH DAMAGE. | |
29 | * | |
30 | * $Id: bandb.c 26094 2008-09-19 15:33:46Z androsyn $ | |
31 | */ | |
32 | #include "setup.h" | |
33 | #include <ratbox_lib.h> | |
34 | #include <stdio.h> | |
35 | #include "rsdb.h" | |
36 | #include "common.h" | |
37 | ||
38 | ||
39 | #define MAXPARA 10 | |
40 | ||
9fca38c8 JT |
41 | #define COMMIT_INTERVAL 3 /* seconds */ |
42 | ||
832ed81a AC |
43 | typedef enum |
44 | { | |
45 | BANDB_KLINE, | |
46 | BANDB_DLINE, | |
47 | BANDB_XLINE, | |
48 | BANDB_RESV, | |
49 | LAST_BANDB_TYPE | |
50 | } bandb_type; | |
51 | ||
52 | static char bandb_letter[LAST_BANDB_TYPE] = { | |
53 | 'K', 'D', 'X', 'R' | |
54 | }; | |
55 | ||
56 | static const char *bandb_table[LAST_BANDB_TYPE] = { | |
57 | "kline", "dline", "xline", "resv" | |
58 | }; | |
59 | ||
60 | ||
61 | static rb_helper *bandb_helper; | |
9fca38c8 | 62 | static int in_transaction; |
832ed81a AC |
63 | |
64 | static void check_schema(void); | |
65 | ||
9fca38c8 JT |
66 | static void |
67 | bandb_commit(void *unused) | |
68 | { | |
69 | rsdb_transaction(RSDB_TRANS_END); | |
70 | in_transaction = 0; | |
71 | } | |
72 | ||
832ed81a AC |
73 | static void |
74 | parse_ban(bandb_type type, char *parv[], int parc) | |
75 | { | |
76 | const char *mask1 = NULL; | |
77 | const char *mask2 = NULL; | |
78 | const char *oper = NULL; | |
79 | const char *curtime = NULL; | |
80 | const char *reason = NULL; | |
81 | const char *perm = NULL; | |
82 | int para = 1; | |
83 | ||
84 | if(type == BANDB_KLINE) | |
85 | { | |
86 | if(parc != 7) | |
87 | return; | |
88 | } | |
89 | else if(parc != 6) | |
90 | return; | |
91 | ||
92 | mask1 = parv[para++]; | |
93 | ||
94 | if(type == BANDB_KLINE) | |
95 | mask2 = parv[para++]; | |
96 | ||
97 | oper = parv[para++]; | |
98 | curtime = parv[para++]; | |
99 | perm = parv[para++]; | |
100 | reason = parv[para++]; | |
101 | ||
9fca38c8 JT |
102 | if(!in_transaction) |
103 | { | |
104 | rsdb_transaction(RSDB_TRANS_START); | |
105 | in_transaction = 1; | |
106 | rb_event_addonce("bandb_commit", bandb_commit, NULL, | |
107 | COMMIT_INTERVAL); | |
108 | } | |
109 | ||
832ed81a AC |
110 | rsdb_exec(NULL, |
111 | "INSERT INTO %s (mask1, mask2, oper, time, perm, reason) VALUES('%Q', '%Q', '%Q', %s, %s, '%Q')", | |
112 | bandb_table[type], mask1, mask2 ? mask2 : "", oper, curtime, perm, reason); | |
113 | } | |
114 | ||
115 | static void | |
116 | parse_unban(bandb_type type, char *parv[], int parc) | |
117 | { | |
118 | const char *mask1 = NULL; | |
119 | const char *mask2 = NULL; | |
120 | ||
121 | if(type == BANDB_KLINE) | |
122 | { | |
123 | if(parc != 3) | |
124 | return; | |
125 | } | |
126 | else if(parc != 2) | |
127 | return; | |
128 | ||
129 | mask1 = parv[1]; | |
130 | ||
131 | if(type == BANDB_KLINE) | |
132 | mask2 = parv[2]; | |
133 | ||
9fca38c8 JT |
134 | if(!in_transaction) |
135 | { | |
136 | rsdb_transaction(RSDB_TRANS_START); | |
137 | in_transaction = 1; | |
138 | rb_event_addonce("bandb_commit", bandb_commit, NULL, | |
139 | COMMIT_INTERVAL); | |
140 | } | |
141 | ||
832ed81a AC |
142 | rsdb_exec(NULL, "DELETE FROM %s WHERE mask1='%Q' AND mask2='%Q'", |
143 | bandb_table[type], mask1, mask2 ? mask2 : ""); | |
144 | } | |
145 | ||
146 | static void | |
147 | list_bans(void) | |
148 | { | |
149 | static char buf[512]; | |
150 | struct rsdb_table table; | |
151 | int i, j; | |
152 | ||
153 | /* schedule a clear of anything already pending */ | |
154 | rb_helper_write_queue(bandb_helper, "C"); | |
155 | ||
156 | for(i = 0; i < LAST_BANDB_TYPE; i++) | |
157 | { | |
158 | rsdb_exec_fetch(&table, "SELECT mask1,mask2,oper,reason FROM %s WHERE 1", | |
159 | bandb_table[i]); | |
160 | ||
161 | for(j = 0; j < table.row_count; j++) | |
162 | { | |
163 | if(i == BANDB_KLINE) | |
164 | rb_snprintf(buf, sizeof(buf), "%c %s %s %s :%s", | |
165 | bandb_letter[i], table.row[j][0], | |
166 | table.row[j][1], table.row[j][2], table.row[j][3]); | |
167 | else | |
168 | rb_snprintf(buf, sizeof(buf), "%c %s %s :%s", | |
169 | bandb_letter[i], table.row[j][0], | |
170 | table.row[j][2], table.row[j][3]); | |
171 | ||
172 | rb_helper_write_queue(bandb_helper, "%s", buf); | |
173 | } | |
174 | ||
175 | rsdb_exec_fetch_end(&table); | |
176 | } | |
177 | ||
178 | rb_helper_write(bandb_helper, "F"); | |
179 | } | |
180 | ||
181 | static void | |
182 | parse_request(rb_helper *helper) | |
183 | { | |
184 | static char *parv[MAXPARA + 1]; | |
185 | static char readbuf[READBUF_SIZE]; | |
186 | int parc; | |
187 | int len; | |
188 | ||
189 | ||
190 | while((len = rb_helper_read(helper, readbuf, sizeof(readbuf))) > 0) | |
191 | { | |
192 | parc = rb_string_to_array(readbuf, parv, MAXPARA); | |
193 | ||
194 | if(parc < 1) | |
195 | continue; | |
196 | ||
197 | switch (parv[0][0]) | |
198 | { | |
199 | case 'K': | |
200 | parse_ban(BANDB_KLINE, parv, parc); | |
201 | break; | |
202 | ||
203 | case 'D': | |
204 | parse_ban(BANDB_DLINE, parv, parc); | |
205 | break; | |
206 | ||
207 | case 'X': | |
208 | parse_ban(BANDB_XLINE, parv, parc); | |
209 | break; | |
210 | ||
211 | case 'R': | |
212 | parse_ban(BANDB_RESV, parv, parc); | |
213 | break; | |
214 | ||
215 | case 'k': | |
216 | parse_unban(BANDB_KLINE, parv, parc); | |
217 | break; | |
218 | ||
219 | case 'd': | |
220 | parse_unban(BANDB_DLINE, parv, parc); | |
221 | break; | |
222 | ||
223 | case 'x': | |
224 | parse_unban(BANDB_XLINE, parv, parc); | |
225 | break; | |
226 | ||
227 | case 'r': | |
228 | parse_unban(BANDB_RESV, parv, parc); | |
229 | break; | |
230 | ||
231 | case 'L': | |
232 | list_bans(); | |
233 | break; | |
234 | default: | |
235 | break; | |
236 | } | |
237 | } | |
238 | } | |
239 | ||
240 | ||
241 | static void | |
242 | error_cb(rb_helper *helper) | |
243 | { | |
9fca38c8 JT |
244 | if(in_transaction) |
245 | rsdb_transaction(RSDB_TRANS_END); | |
832ed81a AC |
246 | exit(1); |
247 | } | |
248 | ||
249 | #ifndef WINDOWS | |
250 | static void | |
251 | dummy_handler(int sig) | |
252 | { | |
253 | return; | |
254 | } | |
255 | #endif | |
256 | ||
257 | static void | |
258 | setup_signals() | |
259 | { | |
260 | #ifndef WINDOWS | |
261 | struct sigaction act; | |
262 | ||
263 | act.sa_flags = 0; | |
264 | act.sa_handler = SIG_IGN; | |
265 | sigemptyset(&act.sa_mask); | |
266 | sigaddset(&act.sa_mask, SIGPIPE); | |
267 | sigaddset(&act.sa_mask, SIGALRM); | |
268 | #ifdef SIGTRAP | |
269 | sigaddset(&act.sa_mask, SIGTRAP); | |
270 | #endif | |
271 | ||
272 | #ifdef SIGWINCH | |
273 | sigaddset(&act.sa_mask, SIGWINCH); | |
274 | sigaction(SIGWINCH, &act, 0); | |
275 | #endif | |
276 | sigaction(SIGPIPE, &act, 0); | |
277 | #ifdef SIGTRAP | |
278 | sigaction(SIGTRAP, &act, 0); | |
279 | #endif | |
280 | ||
281 | act.sa_handler = dummy_handler; | |
282 | sigaction(SIGALRM, &act, 0); | |
283 | #endif | |
284 | } | |
285 | ||
286 | ||
287 | static void | |
288 | db_error_cb(const char *errstr) | |
289 | { | |
290 | char buf[256]; | |
291 | rb_snprintf(buf, sizeof(buf), "! :%s", errstr); | |
292 | rb_helper_write(bandb_helper, buf); | |
293 | rb_sleep(2 << 30, 0); | |
294 | exit(1); | |
295 | } | |
296 | ||
297 | int | |
298 | main(int argc, char *argv[]) | |
299 | { | |
300 | setup_signals(); | |
301 | bandb_helper = rb_helper_child(parse_request, error_cb, NULL, NULL, NULL, 256, 256, 256, 256); /* XXX fix me */ | |
302 | if(bandb_helper == NULL) | |
303 | { | |
304 | fprintf(stderr, | |
305 | "This is ircd-ratbox bandb. You aren't supposed to run me directly. Maybe you want bantool?\n"); | |
306 | fprintf(stderr, | |
307 | "However I will print my Id tag $Id: bandb.c 26094 2008-09-19 15:33:46Z androsyn $\n"); | |
308 | fprintf(stderr, "Have a nice day\n"); | |
309 | exit(1); | |
310 | } | |
311 | rsdb_init(db_error_cb); | |
312 | check_schema(); | |
313 | rb_helper_loop(bandb_helper, 0); | |
314 | ||
315 | return 0; | |
316 | } | |
317 | ||
318 | static void | |
319 | check_schema(void) | |
320 | { | |
321 | struct rsdb_table table; | |
322 | int i; | |
323 | ||
324 | for(i = 0; i < LAST_BANDB_TYPE; i++) | |
325 | { | |
326 | rsdb_exec_fetch(&table, | |
327 | "SELECT name FROM sqlite_master WHERE type='table' AND name='%s'", | |
328 | bandb_table[i]); | |
329 | ||
330 | rsdb_exec_fetch_end(&table); | |
331 | ||
332 | if(!table.row_count) | |
333 | rsdb_exec(NULL, | |
334 | "CREATE TABLE %s (mask1 TEXT, mask2 TEXT, oper TEXT, time INTEGER, perm INTEGER, reason TEXT)", | |
335 | bandb_table[i]); | |
336 | } | |
337 | } |