]> jfr.im git - irc/rqf/shadowircd.git/blob - bandb/bandb.c
libratbox: Clean up uses of strcpy().
[irc/rqf/shadowircd.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 * $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
41 #define COMMIT_INTERVAL 3 /* seconds */
42
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;
62 static int in_transaction;
63
64 static void check_schema(void);
65
66 static void
67 bandb_commit(void *unused)
68 {
69 rsdb_transaction(RSDB_TRANS_END);
70 in_transaction = 0;
71 }
72
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
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
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
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
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 {
244 if(in_transaction)
245 rsdb_transaction(RSDB_TRANS_END);
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 }