]> jfr.im git - solanum.git/blob - bandb/bandb.c
switch "KDX-Line active for" snote to L_NETWIDE and include which mask
[solanum.git] / bandb / bandb.c
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 #include "setup.h"
31 #include <rb_lib.h>
32 #include <stdio.h>
33 #include "rsdb.h"
34 #include "ircd_defs.h"
35
36
37 #define MAXPARA 10
38
39 #define COMMIT_INTERVAL 3 /* seconds */
40
41 typedef enum
42 {
43 BANDB_KLINE,
44 BANDB_DLINE,
45 BANDB_XLINE,
46 BANDB_RESV,
47 LAST_BANDB_TYPE
48 } bandb_type;
49
50 static char bandb_letter[LAST_BANDB_TYPE] = {
51 'K', 'D', 'X', 'R'
52 };
53
54 static const char *bandb_table[LAST_BANDB_TYPE] = {
55 "kline", "dline", "xline", "resv"
56 };
57
58
59 static rb_helper *bandb_helper;
60 static int in_transaction;
61
62 static void check_schema(void);
63
64 static void
65 bandb_commit(void *unused)
66 {
67 rsdb_transaction(RSDB_TRANS_END);
68 in_transaction = 0;
69 }
70
71 static void
72 parse_ban(bandb_type type, char *parv[], int parc)
73 {
74 const char *mask1 = NULL;
75 const char *mask2 = NULL;
76 const char *oper = NULL;
77 const char *curtime = NULL;
78 const char *reason = NULL;
79 const char *perm = NULL;
80 int para = 1;
81
82 if(type == BANDB_KLINE)
83 {
84 if(parc != 7)
85 return;
86 }
87 else if(parc != 6)
88 return;
89
90 mask1 = parv[para++];
91
92 if(type == BANDB_KLINE)
93 mask2 = parv[para++];
94
95 oper = parv[para++];
96 curtime = parv[para++];
97 perm = parv[para++];
98 reason = parv[para++];
99
100 if(!in_transaction)
101 {
102 rsdb_transaction(RSDB_TRANS_START);
103 in_transaction = 1;
104 rb_event_addonce("bandb_commit", bandb_commit, NULL,
105 COMMIT_INTERVAL);
106 }
107
108 rsdb_exec(NULL,
109 "INSERT INTO %s (mask1, mask2, oper, time, perm, reason) VALUES('%Q', '%Q', '%Q', %s, %s, '%Q')",
110 bandb_table[type], mask1, mask2 ? mask2 : "", oper, curtime, perm, reason);
111 }
112
113 static void
114 parse_unban(bandb_type type, char *parv[], int parc)
115 {
116 const char *mask1 = NULL;
117 const char *mask2 = NULL;
118
119 if(type == BANDB_KLINE)
120 {
121 if(parc != 3)
122 return;
123 }
124 else if(parc != 2)
125 return;
126
127 mask1 = parv[1];
128
129 if(type == BANDB_KLINE)
130 mask2 = parv[2];
131
132 if(!in_transaction)
133 {
134 rsdb_transaction(RSDB_TRANS_START);
135 in_transaction = 1;
136 rb_event_addonce("bandb_commit", bandb_commit, NULL,
137 COMMIT_INTERVAL);
138 }
139
140 rsdb_exec(NULL, "DELETE FROM %s WHERE mask1='%Q' AND mask2='%Q'",
141 bandb_table[type], mask1, mask2 ? mask2 : "");
142 }
143
144 static void
145 list_bans(void)
146 {
147 static char buf[512];
148 struct rsdb_table table;
149 int i, j;
150
151 /* schedule a clear of anything already pending */
152 rb_helper_write_queue(bandb_helper, "C");
153
154 for(i = 0; i < LAST_BANDB_TYPE; i++)
155 {
156 rsdb_exec_fetch(&table, "SELECT mask1,mask2,oper,reason FROM %s WHERE 1",
157 bandb_table[i]);
158
159 for(j = 0; j < table.row_count; j++)
160 {
161 if(i == BANDB_KLINE)
162 snprintf(buf, sizeof(buf), "%c %s %s %s :%s",
163 bandb_letter[i], table.row[j][0],
164 table.row[j][1], table.row[j][2], table.row[j][3]);
165 else
166 snprintf(buf, sizeof(buf), "%c %s %s :%s",
167 bandb_letter[i], table.row[j][0],
168 table.row[j][2], table.row[j][3]);
169
170 rb_helper_write_queue(bandb_helper, "%s", buf);
171 }
172
173 rsdb_exec_fetch_end(&table);
174 }
175
176 rb_helper_write(bandb_helper, "F");
177 }
178
179 static void
180 parse_request(rb_helper *helper)
181 {
182 static char *parv[MAXPARA + 1];
183 static char readbuf[READBUF_SIZE];
184 int parc;
185 int len;
186
187
188 while((len = rb_helper_read(helper, readbuf, sizeof(readbuf))) > 0)
189 {
190 parc = rb_string_to_array(readbuf, parv, MAXPARA);
191
192 if(parc < 1)
193 continue;
194
195 switch (parv[0][0])
196 {
197 case 'K':
198 parse_ban(BANDB_KLINE, parv, parc);
199 break;
200
201 case 'D':
202 parse_ban(BANDB_DLINE, parv, parc);
203 break;
204
205 case 'X':
206 parse_ban(BANDB_XLINE, parv, parc);
207 break;
208
209 case 'R':
210 parse_ban(BANDB_RESV, parv, parc);
211 break;
212
213 case 'k':
214 parse_unban(BANDB_KLINE, parv, parc);
215 break;
216
217 case 'd':
218 parse_unban(BANDB_DLINE, parv, parc);
219 break;
220
221 case 'x':
222 parse_unban(BANDB_XLINE, parv, parc);
223 break;
224
225 case 'r':
226 parse_unban(BANDB_RESV, parv, parc);
227 break;
228
229 case 'L':
230 list_bans();
231 break;
232 default:
233 break;
234 }
235 }
236 }
237
238
239 static void
240 error_cb(rb_helper *helper) __attribute__((noreturn));
241
242 static void
243 error_cb(rb_helper *helper)
244 {
245 if(in_transaction)
246 rsdb_transaction(RSDB_TRANS_END);
247 exit(1);
248 }
249
250 #ifndef WINDOWS
251 static void
252 dummy_handler(int sig)
253 {
254 return;
255 }
256 #endif
257
258 static void
259 setup_signals(void)
260 {
261 #ifndef _WIN32
262 struct sigaction act;
263
264 act.sa_flags = 0;
265 act.sa_handler = SIG_IGN;
266 sigemptyset(&act.sa_mask);
267 sigaddset(&act.sa_mask, SIGPIPE);
268 sigaddset(&act.sa_mask, SIGALRM);
269 #ifdef SIGTRAP
270 sigaddset(&act.sa_mask, SIGTRAP);
271 #endif
272
273 #ifdef SIGWINCH
274 sigaddset(&act.sa_mask, SIGWINCH);
275 sigaction(SIGWINCH, &act, 0);
276 #endif
277 sigaction(SIGPIPE, &act, 0);
278 #ifdef SIGTRAP
279 sigaction(SIGTRAP, &act, 0);
280 #endif
281
282 act.sa_handler = dummy_handler;
283 sigaction(SIGALRM, &act, 0);
284 #endif
285 }
286
287
288 static void
289 db_error_cb(const char *errstr) __attribute__((noreturn));
290
291 static void
292 db_error_cb(const char *errstr)
293 {
294 char buf[256];
295 snprintf(buf, sizeof(buf), "! :%s", errstr);
296 rb_helper_write(bandb_helper, "%s", buf);
297 rb_sleep(1 << 30, 0);
298 exit(1);
299 }
300
301 int
302 main(int argc, char *argv[])
303 {
304 setup_signals();
305 bandb_helper = rb_helper_child(parse_request, error_cb, NULL, NULL, NULL, 256, 256, 256); /* XXX fix me */
306 if(bandb_helper == NULL)
307 {
308 fprintf(stderr,
309 "This is the solanum bandb for internal ircd use.\n");
310 fprintf(stderr,
311 "You aren't supposed to run me directly (did you want solanum-bantool?). Exiting.\n");
312 exit(1);
313 }
314 rsdb_init(db_error_cb);
315 check_schema();
316 rb_helper_loop(bandb_helper, 0);
317
318 return 0;
319 }
320
321 static void
322 check_schema(void)
323 {
324 struct rsdb_table table;
325 int i;
326
327 for(i = 0; i < LAST_BANDB_TYPE; i++)
328 {
329 rsdb_exec_fetch(&table,
330 "SELECT name FROM sqlite_master WHERE type='table' AND name='%s'",
331 bandb_table[i]);
332
333 rsdb_exec_fetch_end(&table);
334
335 if(!table.row_count)
336 rsdb_exec(NULL,
337 "CREATE TABLE %s (mask1 TEXT, mask2 TEXT, oper TEXT, time INTEGER, perm INTEGER, reason TEXT)",
338 bandb_table[i]);
339 }
340 }