ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/modules/m_resv.c
Revision: 766
Committed: Sun Aug 20 11:18:36 2006 UTC (19 years ago) by michael
Content type: text/x-csrc
File size: 14033 byte(s)
Log Message:
- Fixed src/Makefile.in
- Have KLINE and friends deal properly with write_csv_line().  It's currently
  kinda ugly, but the whole csvlib crap will have to be rewritten to use some
  proper database anyways.

  /UN*LINE may core for now.


File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * m_resv.c: Reserves(jupes) a nickname or channel.
4 *
5 * Copyright (C) 2001-2002 Hybrid Development Team
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 *
22 * $Id$
23 */
24
25 #include "stdinc.h"
26 #include "conf/conf.h"
27 #include "handlers.h"
28 #include "client.h"
29 #include "channel.h"
30 #include "ircd.h"
31 #include "numeric.h"
32 #include "s_serv.h"
33 #include "send.h"
34 #include "msg.h"
35 #include "parse.h"
36 #include "parse_aline.h"
37 #include "hash.h"
38 #include "s_user.h"
39
40 static void mo_resv(struct Client *, struct Client *, int, char *[]);
41 static void me_resv(struct Client *, struct Client *, int, char *[]);
42 static void ms_resv(struct Client *, struct Client *, int, char *[]);
43 static void mo_unresv(struct Client *, struct Client *, int, char *[]);
44 static void ms_unresv(struct Client *, struct Client *, int, char *[]);
45
46 static void parse_resv(struct Client *, char *, int, char *);
47 static void remove_resv(struct Client *, const char *);
48
49 struct Message resv_msgtab = {
50 "RESV", 0, 0, 3, 0, MFLG_SLOW, 0,
51 { m_ignore, m_not_oper, ms_resv, me_resv, mo_resv, m_ignore }
52 };
53
54 struct Message unresv_msgtab = {
55 "UNRESV", 0, 0, 2, 0, MFLG_SLOW, 0,
56 { m_ignore, m_not_oper, ms_unresv, m_ignore, mo_unresv, m_ignore }
57 };
58
59 INIT_MODULE(m_resv, "$Revision$")
60 {
61 mod_add_cmd(&resv_msgtab);
62 mod_add_cmd(&unresv_msgtab);
63 }
64
65 CLEANUP_MODULE
66 {
67 mod_del_cmd(&unresv_msgtab);
68 mod_del_cmd(&resv_msgtab);
69 }
70
71 /* mo_resv()
72 * parv[0] = sender prefix
73 * parv[1] = channel/nick to forbid
74 */
75 static void
76 mo_resv(struct Client *client_p, struct Client *source_p,
77 int parc, char *parv[])
78 {
79 char *resv = NULL;
80 char *reason = NULL;
81 char *target_server = NULL;
82 time_t tkline_time = 0;
83
84 /* RESV #channel ON irc.server.com :abuse
85 * RESV kiddie ON irc.server.com :abuse
86 */
87 if (parse_aline("RESV", source_p, parc, parv,
88 AWILD, &resv, NULL, &tkline_time, &target_server, &reason) < 0)
89 return;
90
91 if (target_server != NULL)
92 {
93 // if a given expire time is given, ENCAP it
94 if (tkline_time != 0)
95 sendto_match_servs(source_p, target_server, CAP_ENCAP,
96 "ENCAP %s RESV %d %s 0 :%s",
97 target_server, (int)tkline_time, resv, reason);
98 else
99 sendto_match_servs(source_p, target_server, CAP_CLUSTER,
100 "RESV %s %s :%s",
101 target_server, resv, reason);
102 // Allow ON to apply local resv as well if it matches
103 if (!match(target_server, me.name))
104 return;
105 }
106 else
107 {
108 /* RESV #channel :abuse
109 * RESV kiddie :abuse
110 */
111 if (tkline_time != 0)
112 cluster_a_line(source_p, "ENCAP", CAP_ENCAP, SHARED_RESV,
113 "RESV %d %s 0 : %s", (int)tkline_time, resv, reason);
114 else
115 cluster_a_line(source_p, "RESV", CAP_KLN, SHARED_RESV,
116 "%s : %s", resv, reason);
117 }
118
119 parse_resv(source_p, resv, (int)tkline_time, reason);
120 }
121
122 /* me_resv()
123 *
124 * inputs - server
125 * - client (oper)
126 * - parc number of arguments
127 * - parv list of arguments
128 * via parv[]
129 * parv[0] = client name applying resv
130 * parv[1] = tkline_time
131 * parv[2] = name
132 * parv[3] = 0
133 * parv[4] = reason
134 * parc should be 5
135 *
136 * outputs - NONE
137 * side effects -
138 */
139 static void
140 me_resv(struct Client *client_p, struct Client *source_p,
141 int parc, char *parv[])
142 {
143 if (parc != 5 || !IsClient(source_p))
144 return;
145
146 parse_resv(source_p, parv[2], atoi(parv[1]), parv[4]);
147 }
148
149 /* ms_resv()
150 * parv[0] = sender prefix
151 * parv[1] = target server
152 * parv[2] = channel/nick to resv
153 * parv[3] = reason
154 */
155 static void
156 ms_resv(struct Client *client_p, struct Client *source_p,
157 int parc, char *parv[])
158 {
159 if ((parc != 4) || EmptyString(parv[3]))
160 return;
161
162 sendto_match_servs(source_p, parv[1], CAP_CLUSTER,
163 "RESV %s %s :%s",
164 parv[1], parv[2], parv[3]);
165
166 if (!IsClient(source_p) || !match(parv[1], me.name))
167 return;
168
169 if (find_shared(source_p->servptr->name, source_p->username, source_p->host,
170 source_p->sockhost, SHARED_RESV))
171 parse_resv(source_p, parv[2], 0, parv[3]);
172 }
173
174 /* mo_unresv()
175 * parv[0] = sender prefix
176 * parv[1] = channel/nick to unforbid
177 */
178 static void
179 mo_unresv(struct Client *client_p, struct Client *source_p,
180 int parc, char *parv[])
181 {
182 char *resv = NULL;
183 char *reason = NULL;
184 char *target_server = NULL;
185
186 // UNRESV #channel ON irc.server.com
187 // UNRESV kiddie ON irc.server.com
188 if (parse_aline("UNRESV", source_p, parc, parv,
189 0, &resv, NULL, NULL, &target_server, &reason) < 0)
190 return;
191
192 if (target_server != NULL)
193 {
194 sendto_match_servs(source_p, target_server, CAP_CLUSTER,
195 "UNRESV %s %s",
196 target_server, resv);
197
198 // Allow ON to apply local unresv as well if it matches
199 if (!match(target_server, me.name))
200 return;
201 }
202 else
203 cluster_a_line(source_p, "UNRESV", CAP_KLN, SHARED_UNRESV, resv);
204
205 remove_resv(source_p, resv);
206 }
207
208 /* ms_unresv()
209 * parv[0] = sender prefix
210 * parv[1] = target server
211 * parv[2] = resv to remove
212 */
213 static void
214 ms_unresv(struct Client *client_p, struct Client *source_p,
215 int parc, char *parv[])
216 {
217 if ((parc != 3) || EmptyString(parv[2]))
218 return;
219
220 sendto_match_servs(source_p, parv[1], CAP_CLUSTER,
221 "UNRESV %s %s",
222 parv[1], parv[2]);
223
224 if (!IsClient(source_p) || !match(parv[1], me.name))
225 return;
226
227 if (find_shared(source_p->servptr->name, source_p->username, source_p->host,
228 source_p->sockhost, SHARED_UNRESV))
229 remove_resv(source_p, parv[2]);
230 }
231
232 /* parse_resv()
233 *
234 * inputs - source_p, NULL supported
235 * - thing to resv
236 * - time_t if tkline
237 * - reason
238 * outputs - none
239 * side effects - parse resv, create if valid
240 */
241 static void
242 parse_resv(struct Client *source_p, char *name, int tkline_time, char *reason)
243 {
244 struct ResvConf *conf = NULL;
245 FBFILE *out = NULL;
246
247 if (!IsAdmin(source_p) && has_wildcards(name, IsChanPrefix(*name)))
248 {
249 sendto_one(source_p, ":%s NOTICE %s :You must be an admin to perform a "
250 "wildcard RESV", me.name, source_p->name);
251 return;
252 }
253
254 if (IsChanPrefix(*name))
255 {
256 if (find_channel_resv(name))
257 {
258 sendto_one(source_p,
259 ":%s NOTICE %s :A RESV has already been placed on channel: %s",
260 me.name, source_p->name, name);
261 return;
262 }
263
264 conf = MyMalloc(sizeof(*conf));
265 DupString(conf->mask, name);
266 DupString(conf->reason, reason);
267 if (has_wildcards(name, YES))
268 {
269 unsigned int hashv = hash_text(name, RHSIZE);
270 conf->hnext = cresv_hash[hashv];
271 cresv_hash[hashv] = conf;
272 num_hashed_resvs++;
273 }
274 else
275 dlinkAdd(conf, &conf->node, &cresv_confs);
276
277 if (tkline_time != 0)
278 {
279 sendto_one(source_p,
280 ":%s NOTICE %s :A %d minute %s RESV has been placed on "
281 "channel: %s", me.name, source_p->name, tkline_time/60,
282 (MyClient(source_p) ? "local" : "remote"), name);
283 sendto_realops_flags(UMODE_ALL, L_ALL,
284 "%s has placed a %d minute %s RESV on "
285 "channel: %s [%s]", get_oper_name(source_p),
286 tkline_time/60, (MyClient(source_p) ?
287 "local" : "remote"), conf->mask, conf->reason);
288 ilog(L_TRACE, "%s added temporary %d min. RESV for [%s] [%s]",
289 get_oper_name(source_p), (int)tkline_time/60,
290 conf->mask, conf->reason);
291 conf->expires = CurrentTime + tkline_time;
292 }
293 else
294 {
295 sendto_one(source_p,
296 ":%s NOTICE %s :A %s RESV has been placed on channel %s",
297 me.name, source_p->name,
298 (MyClient(source_p) ? "local" : "remote"), name);
299 sendto_realops_flags(UMODE_ALL, L_ALL,
300 "%s has placed a %s RESV on channel %s : [%s]",
301 get_oper_name(source_p), (MyClient(source_p) ?
302 "local" : "remote"), conf->mask, conf->reason);
303 // TBD - don't keep the *line in memory if we cannot open the conf file
304 if ((out = fbopen(ServerState.cresvfile, "a")) == NULL)
305 sendto_realops_flags(UMODE_ALL, L_ALL,
306 "*** Problem opening %s", ServerState.cresvfile);
307 else
308 write_csv_line(out, "%s%s",
309 conf->mask, conf->reason);
310 }
311 }
312 else
313 {
314 if (!valid_wild_card_simple(name))
315 {
316 sendto_one(source_p, ":%s NOTICE %s :Please include at least %d non-wildcard characters with the resv",
317 me.name, source_p->name, General.min_nonwildcard_simple);
318 return;
319 }
320
321 if (find_nick_resv(name))
322 {
323 sendto_one(source_p,
324 ":%s NOTICE %s :A RESV has already been placed on nick %s",
325 me.name, source_p->name, name);
326 return;
327 }
328
329 conf = MyMalloc(sizeof(*conf));
330 DupString(conf->mask, name);
331 DupString(conf->reason, reason);
332 if (has_wildcards(name, NO))
333 {
334 unsigned int hashv = hash_text(name, RHSIZE);
335 conf->hnext = nresv_hash[hashv];
336 nresv_hash[hashv] = conf;
337 num_hashed_resvs++;
338 }
339 else
340 dlinkAdd(conf, &conf->node, &nresv_confs);
341
342 if (tkline_time != 0)
343 {
344 sendto_one(source_p,
345 ":%s NOTICE %s :A %d minute %s RESV has been placed on nick "
346 "%s : [%s]", me.name, source_p->name, tkline_time/60,
347 (MyClient(source_p) ? "local" : "remote"),
348 conf->mask, conf->reason);
349 sendto_realops_flags(UMODE_ALL, L_ALL,
350 "%s has placed a %d minute %s RESV on nick %s : "
351 "[%s]", get_oper_name(source_p), tkline_time/60,
352 (MyClient(source_p) ? "local" : "remote"),
353 conf->mask, conf->reason);
354 ilog(L_TRACE, "%s added temporary %d min. RESV for [%s] [%s]",
355 get_oper_name(source_p), (int)tkline_time/60,
356 conf->mask, conf->reason);
357 conf->expires = CurrentTime + tkline_time;
358 }
359 else
360 {
361 sendto_one(source_p,
362 ":%s NOTICE %s :A %s RESV has been placed on nick %s : [%s]",
363 me.name, source_p->name,
364 (MyClient(source_p) ? "local" : "remote"),
365 conf->mask, conf->reason);
366 sendto_realops_flags(UMODE_ALL, L_ALL,
367 "%s has placed a %s RESV on nick %s : [%s]",
368 get_oper_name(source_p), (MyClient(source_p) ?
369 "local" : "remote"), conf->mask, conf->reason);
370 if ((out = fbopen(ServerState.nresvfile, "a")) == NULL)
371 sendto_realops_flags(UMODE_ALL, L_ALL,
372 "*** Problem opening %s", ServerState.nresvfile);
373 else
374 write_csv_line(out, "%s%s",
375 conf->mask, conf->reason);
376 }
377 }
378 }
379
380 static void
381 remove_resv(struct Client *source_p, const char *name)
382 {
383 struct ResvConf *conf, *prev;
384
385 if (IsChanPrefix(*name))
386 {
387 if (!(conf = do_find_resv(&cresv_confs, cresv_hash, name, irccmp)))
388 {
389 sendto_one(source_p,
390 ":%s NOTICE %s :A RESV does not exist for channel: %s",
391 me.name, source_p->name, name);
392 return;
393 }
394
395 if (has_wildcards(conf->mask, YES))
396 {
397 unsigned int hashv = hash_text(conf->mask, RHSIZE);
398 if (cresv_hash[hashv] == conf)
399 cresv_hash[hashv] = conf->hnext;
400 else
401 {
402 // make it core if not found
403 for (prev = cresv_hash[hashv]; prev->hnext != conf; prev = prev->hnext)
404 ;
405 prev->hnext = conf->hnext;
406 }
407 num_hashed_resvs--;
408 }
409 else
410 dlinkDelete(&conf->node, &cresv_confs);
411
412 if (!conf->expires)
413 remove_conf_line(123, source_p, name, NULL);
414
415 MyFree(conf->mask);
416 MyFree(conf->reason);
417 MyFree(conf);
418
419 sendto_one(source_p,
420 ":%s NOTICE %s :The RESV has been removed on channel: %s",
421 me.name, source_p->name, name);
422 sendto_realops_flags(UMODE_ALL, L_ALL,
423 "%s has removed the RESV for channel: %s",
424 get_oper_name(source_p), name);
425 }
426 else
427 {
428 if (!(conf = do_find_resv(&nresv_confs, nresv_hash, name, irccmp)))
429 {
430 sendto_one(source_p, ":%s NOTICE %s :A RESV does not exist for nick: %s",
431 me.name, source_p->name, name);
432 return;
433 }
434
435 if (has_wildcards(conf->mask, NO))
436 {
437 unsigned int hashv = hash_text(conf->mask, RHSIZE);
438 if (nresv_hash[hashv] == conf)
439 nresv_hash[hashv] = conf->hnext;
440 else
441 {
442 // make it core if not found
443 for (prev = nresv_hash[hashv]; prev->hnext != conf; prev = prev->hnext)
444 ;
445 prev->hnext = conf->hnext;
446 }
447 num_hashed_resvs--;
448 }
449 else
450 dlinkDelete(&conf->node, &nresv_confs);
451
452 if (!conf->expires)
453 remove_conf_line(456, source_p, name, NULL);
454
455 MyFree(conf->mask);
456 MyFree(conf->reason);
457 MyFree(conf);
458
459 sendto_one(source_p, ":%s NOTICE %s :The RESV has been removed on nick: %s",
460 me.name, source_p->name, name);
461 sendto_realops_flags(UMODE_ALL, L_ALL,
462 "%s has removed the RESV for nick: %s",
463 get_oper_name(source_p), name);
464 }
465 }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision