]>
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 | ||
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 | ||
61 | static void check_schema(void); | |
62 | ||
63 | static void | |
64 | parse_ban(bandb_type type, char *parv[], int parc) | |
65 | { | |
66 | const char *mask1 = NULL; | |
67 | const char *mask2 = NULL; | |
68 | const char *oper = NULL; | |
69 | const char *curtime = NULL; | |
70 | const char *reason = NULL; | |
71 | const char *perm = NULL; | |
72 | int para = 1; | |
73 | ||
74 | if(type == BANDB_KLINE) | |
75 | { | |
76 | if(parc != 7) | |
77 | return; | |
78 | } | |
79 | else if(parc != 6) | |
80 | return; | |
81 | ||
82 | mask1 = parv[para++]; | |
83 | ||
84 | if(type == BANDB_KLINE) | |
85 | mask2 = parv[para++]; | |
86 | ||
87 | oper = parv[para++]; | |
88 | curtime = parv[para++]; | |
89 | perm = parv[para++]; | |
90 | reason = parv[para++]; | |
91 | ||
92 | rsdb_exec(NULL, | |
93 | "INSERT INTO %s (mask1, mask2, oper, time, perm, reason) VALUES('%Q', '%Q', '%Q', %s, %s, '%Q')", | |
94 | bandb_table[type], mask1, mask2 ? mask2 : "", oper, curtime, perm, reason); | |
95 | } | |
96 | ||
97 | static void | |
98 | parse_unban(bandb_type type, char *parv[], int parc) | |
99 | { | |
100 | const char *mask1 = NULL; | |
101 | const char *mask2 = NULL; | |
102 | ||
103 | if(type == BANDB_KLINE) | |
104 | { | |
105 | if(parc != 3) | |
106 | return; | |
107 | } | |
108 | else if(parc != 2) | |
109 | return; | |
110 | ||
111 | mask1 = parv[1]; | |
112 | ||
113 | if(type == BANDB_KLINE) | |
114 | mask2 = parv[2]; | |
115 | ||
116 | rsdb_exec(NULL, "DELETE FROM %s WHERE mask1='%Q' AND mask2='%Q'", | |
117 | bandb_table[type], mask1, mask2 ? mask2 : ""); | |
118 | } | |
119 | ||
120 | static void | |
121 | list_bans(void) | |
122 | { | |
123 | static char buf[512]; | |
124 | struct rsdb_table table; | |
125 | int i, j; | |
126 | ||
127 | /* schedule a clear of anything already pending */ | |
128 | rb_helper_write_queue(bandb_helper, "C"); | |
129 | ||
130 | for(i = 0; i < LAST_BANDB_TYPE; i++) | |
131 | { | |
132 | rsdb_exec_fetch(&table, "SELECT mask1,mask2,oper,reason FROM %s WHERE 1", | |
133 | bandb_table[i]); | |
134 | ||
135 | for(j = 0; j < table.row_count; j++) | |
136 | { | |
137 | if(i == BANDB_KLINE) | |
138 | rb_snprintf(buf, sizeof(buf), "%c %s %s %s :%s", | |
139 | bandb_letter[i], table.row[j][0], | |
140 | table.row[j][1], table.row[j][2], table.row[j][3]); | |
141 | else | |
142 | rb_snprintf(buf, sizeof(buf), "%c %s %s :%s", | |
143 | bandb_letter[i], table.row[j][0], | |
144 | table.row[j][2], table.row[j][3]); | |
145 | ||
146 | rb_helper_write_queue(bandb_helper, "%s", buf); | |
147 | } | |
148 | ||
149 | rsdb_exec_fetch_end(&table); | |
150 | } | |
151 | ||
152 | rb_helper_write(bandb_helper, "F"); | |
153 | } | |
154 | ||
155 | static void | |
156 | parse_request(rb_helper *helper) | |
157 | { | |
158 | static char *parv[MAXPARA + 1]; | |
159 | static char readbuf[READBUF_SIZE]; | |
160 | int parc; | |
161 | int len; | |
162 | ||
163 | ||
164 | while((len = rb_helper_read(helper, readbuf, sizeof(readbuf))) > 0) | |
165 | { | |
166 | parc = rb_string_to_array(readbuf, parv, MAXPARA); | |
167 | ||
168 | if(parc < 1) | |
169 | continue; | |
170 | ||
171 | switch (parv[0][0]) | |
172 | { | |
173 | case 'K': | |
174 | parse_ban(BANDB_KLINE, parv, parc); | |
175 | break; | |
176 | ||
177 | case 'D': | |
178 | parse_ban(BANDB_DLINE, parv, parc); | |
179 | break; | |
180 | ||
181 | case 'X': | |
182 | parse_ban(BANDB_XLINE, parv, parc); | |
183 | break; | |
184 | ||
185 | case 'R': | |
186 | parse_ban(BANDB_RESV, parv, parc); | |
187 | break; | |
188 | ||
189 | case 'k': | |
190 | parse_unban(BANDB_KLINE, parv, parc); | |
191 | break; | |
192 | ||
193 | case 'd': | |
194 | parse_unban(BANDB_DLINE, parv, parc); | |
195 | break; | |
196 | ||
197 | case 'x': | |
198 | parse_unban(BANDB_XLINE, parv, parc); | |
199 | break; | |
200 | ||
201 | case 'r': | |
202 | parse_unban(BANDB_RESV, parv, parc); | |
203 | break; | |
204 | ||
205 | case 'L': | |
206 | list_bans(); | |
207 | break; | |
208 | default: | |
209 | break; | |
210 | } | |
211 | } | |
212 | } | |
213 | ||
214 | ||
215 | static void | |
216 | error_cb(rb_helper *helper) | |
217 | { | |
218 | exit(1); | |
219 | } | |
220 | ||
221 | #ifndef WINDOWS | |
222 | static void | |
223 | dummy_handler(int sig) | |
224 | { | |
225 | return; | |
226 | } | |
227 | #endif | |
228 | ||
229 | static void | |
230 | setup_signals() | |
231 | { | |
232 | #ifndef WINDOWS | |
233 | struct sigaction act; | |
234 | ||
235 | act.sa_flags = 0; | |
236 | act.sa_handler = SIG_IGN; | |
237 | sigemptyset(&act.sa_mask); | |
238 | sigaddset(&act.sa_mask, SIGPIPE); | |
239 | sigaddset(&act.sa_mask, SIGALRM); | |
240 | #ifdef SIGTRAP | |
241 | sigaddset(&act.sa_mask, SIGTRAP); | |
242 | #endif | |
243 | ||
244 | #ifdef SIGWINCH | |
245 | sigaddset(&act.sa_mask, SIGWINCH); | |
246 | sigaction(SIGWINCH, &act, 0); | |
247 | #endif | |
248 | sigaction(SIGPIPE, &act, 0); | |
249 | #ifdef SIGTRAP | |
250 | sigaction(SIGTRAP, &act, 0); | |
251 | #endif | |
252 | ||
253 | act.sa_handler = dummy_handler; | |
254 | sigaction(SIGALRM, &act, 0); | |
255 | #endif | |
256 | } | |
257 | ||
258 | ||
259 | static void | |
260 | db_error_cb(const char *errstr) | |
261 | { | |
262 | char buf[256]; | |
263 | rb_snprintf(buf, sizeof(buf), "! :%s", errstr); | |
264 | rb_helper_write(bandb_helper, buf); | |
265 | rb_sleep(2 << 30, 0); | |
266 | exit(1); | |
267 | } | |
268 | ||
269 | int | |
270 | main(int argc, char *argv[]) | |
271 | { | |
272 | setup_signals(); | |
273 | bandb_helper = rb_helper_child(parse_request, error_cb, NULL, NULL, NULL, 256, 256, 256, 256); /* XXX fix me */ | |
274 | if(bandb_helper == NULL) | |
275 | { | |
276 | fprintf(stderr, | |
277 | "This is ircd-ratbox bandb. You aren't supposed to run me directly. Maybe you want bantool?\n"); | |
278 | fprintf(stderr, | |
279 | "However I will print my Id tag $Id: bandb.c 26094 2008-09-19 15:33:46Z androsyn $\n"); | |
280 | fprintf(stderr, "Have a nice day\n"); | |
281 | exit(1); | |
282 | } | |
283 | rsdb_init(db_error_cb); | |
284 | check_schema(); | |
285 | rb_helper_loop(bandb_helper, 0); | |
286 | ||
287 | return 0; | |
288 | } | |
289 | ||
290 | static void | |
291 | check_schema(void) | |
292 | { | |
293 | struct rsdb_table table; | |
294 | int i; | |
295 | ||
296 | for(i = 0; i < LAST_BANDB_TYPE; i++) | |
297 | { | |
298 | rsdb_exec_fetch(&table, | |
299 | "SELECT name FROM sqlite_master WHERE type='table' AND name='%s'", | |
300 | bandb_table[i]); | |
301 | ||
302 | rsdb_exec_fetch_end(&table); | |
303 | ||
304 | if(!table.row_count) | |
305 | rsdb_exec(NULL, | |
306 | "CREATE TABLE %s (mask1 TEXT, mask2 TEXT, oper TEXT, time INTEGER, perm INTEGER, reason TEXT)", | |
307 | bandb_table[i]); | |
308 | } | |
309 | } |