ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/modules/m_resv.c
Revision: 33
Committed: Sun Oct 2 20:50:00 2005 UTC (18 years, 5 months ago) by knight
Content type: text/x-csrc
File size: 12472 byte(s)
Log Message:
- svn:keywords

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 "handlers.h"
27 #include "client.h"
28 #include "channel.h"
29 #include "ircd.h"
30 #include "irc_string.h"
31 #include "numeric.h"
32 #include "s_serv.h"
33 #include "send.h"
34 #include "msg.h"
35 #include "parse.h"
36 #include "modules.h"
37 #include "s_conf.h"
38 #include "s_log.h"
39 #include "resv.h"
40 #include "hash.h"
41
42 static void mo_resv(struct Client *, struct Client *, int, char *[]);
43 static void me_resv(struct Client *, struct Client *, int, char *[]);
44 static void ms_resv(struct Client *, struct Client *, int, char *[]);
45 static void mo_unresv(struct Client *, struct Client *, int, char *[]);
46 static void ms_unresv(struct Client *, struct Client *, int, char *[]);
47
48 static void parse_resv(struct Client *, char *, int, char *);
49 static void remove_resv(struct Client *, const char *);
50
51 struct Message resv_msgtab = {
52 "RESV", 0, 0, 3, 0, MFLG_SLOW, 0,
53 { m_ignore, m_not_oper, ms_resv, me_resv, mo_resv, m_ignore }
54 };
55
56 struct Message unresv_msgtab = {
57 "UNRESV", 0, 0, 2, 0, MFLG_SLOW, 0,
58 { m_ignore, m_not_oper, ms_unresv, m_ignore, mo_unresv, m_ignore }
59 };
60
61 #ifndef STATIC_MODULES
62 void
63 _modinit(void)
64 {
65 mod_add_cmd(&resv_msgtab);
66 mod_add_cmd(&unresv_msgtab);
67 }
68
69 void
70 _moddeinit(void)
71 {
72 mod_del_cmd(&resv_msgtab);
73 mod_del_cmd(&unresv_msgtab);
74 }
75
76 const char *_version = "$Revision$";
77 #endif
78
79 /* mo_resv()
80 * parv[0] = sender prefix
81 * parv[1] = channel/nick to forbid
82 */
83 static void
84 mo_resv(struct Client *client_p, struct Client *source_p,
85 int parc, char *parv[])
86 {
87 char *resv = NULL;
88 char *reason = NULL;
89 char *target_server = NULL;
90 time_t tkline_time = 0;
91
92 /* RESV #channel ON irc.server.com :abuse
93 * RESV kiddie ON irc.server.com :abuse
94 */
95 if (parse_aline("RESV", source_p, parc, parv,
96 AWILD, &resv, NULL, &tkline_time, &target_server, &reason) < 0)
97 return;
98
99 if (target_server != NULL)
100 {
101 /* if a given expire time is given, ENCAP it */
102 if (tkline_time != 0)
103 sendto_match_servs(source_p, target_server, CAP_ENCAP,
104 "ENCAP %s RESV %d %s 0 :%s",
105 target_server, (int)tkline_time, resv, reason);
106 else
107 sendto_match_servs(source_p, target_server, CAP_CLUSTER,
108 "RESV %s %s :%s",
109 target_server, resv, reason);
110 /* Allow ON to apply local resv as well if it matches */
111 if (!match(target_server, me.name))
112 return;
113 }
114 else
115 {
116 /* RESV #channel :abuse
117 * RESV kiddie :abuse
118 */
119 if (tkline_time != 0)
120 cluster_a_line(source_p, "ENCAP", CAP_ENCAP, SHARED_RESV,
121 "RESV %d %s 0 : %s", (int)tkline_time, resv, reason);
122 else
123 cluster_a_line(source_p, "RESV", CAP_KLN, SHARED_RESV,
124 "%s : %s", resv, reason);
125 }
126
127 parse_resv(source_p, resv, (int)tkline_time, reason);
128 }
129
130 /* me_resv()
131 *
132 * inputs - server
133 * - client (oper)
134 * - parc number of arguments
135 * - parv list of arguments
136 * via parv[]
137 * parv[0] = client name applying resv
138 * parv[1] = tkline_time
139 * parv[2] = name
140 * parv[3] = 0
141 * parv[4] = reason
142 * parc should be 5
143 *
144 * outputs - NONE
145 * side effects -
146 */
147 static void
148 me_resv(struct Client *client_p, struct Client *source_p,
149 int parc, char *parv[])
150 {
151 if (parc != 5 || !IsClient(source_p))
152 return;
153
154 parse_resv(source_p, parv[2], atoi(parv[1]), parv[4]);
155 }
156
157 /* ms_resv()
158 * parv[0] = sender prefix
159 * parv[1] = target server
160 * parv[2] = channel/nick to resv
161 * parv[3] = reason
162 */
163 static void
164 ms_resv(struct Client *client_p, struct Client *source_p,
165 int parc, char *parv[])
166 {
167 if ((parc != 4) || EmptyString(parv[3]))
168 return;
169
170 sendto_match_servs(source_p, parv[1], CAP_CLUSTER,
171 "RESV %s %s :%s",
172 parv[1], parv[2], parv[3]);
173
174 if (!IsClient(source_p) || !match(parv[1], me.name))
175 return;
176
177 if (find_matching_name_conf(ULINE_TYPE, source_p->servptr->name,
178 source_p->username, source_p->host,
179 SHARED_RESV))
180 parse_resv(source_p, parv[2], 0, parv[3]);
181 }
182
183 /* mo_unresv()
184 * parv[0] = sender prefix
185 * parv[1] = channel/nick to unforbid
186 */
187 static void
188 mo_unresv(struct Client *client_p, struct Client *source_p,
189 int parc, char *parv[])
190 {
191 char *resv = NULL;
192 char *reason = NULL;
193 char *target_server = NULL;
194
195 /* UNRESV #channel ON irc.server.com */
196 /* UNRESV kiddie ON irc.server.com */
197 if (parse_aline("UNRESV", source_p, parc, parv,
198 0, &resv, NULL, NULL, &target_server, &reason) < 0)
199 return;
200
201 if (target_server != NULL)
202 {
203 sendto_match_servs(source_p, target_server, CAP_CLUSTER,
204 "UNRESV %s %s",
205 target_server, resv);
206
207 /* Allow ON to apply local unresv as well if it matches */
208 if (!match(target_server, me.name))
209 return;
210 }
211 else
212 cluster_a_line(source_p, "UNRESV", CAP_KLN, SHARED_UNRESV, resv);
213
214 remove_resv(source_p, resv);
215 }
216
217 /* ms_unresv()
218 * parv[0] = sender prefix
219 * parv[1] = target server
220 * parv[2] = resv to remove
221 */
222 static void
223 ms_unresv(struct Client *client_p, struct Client *source_p,
224 int parc, char *parv[])
225 {
226 if ((parc != 3) || EmptyString(parv[2]))
227 return;
228
229 sendto_match_servs(source_p, parv[1], CAP_CLUSTER,
230 "UNRESV %s %s",
231 parv[1], parv[2]);
232
233 if (!IsClient(source_p) || !match(parv[1], me.name))
234 return;
235
236 if (find_matching_name_conf(ULINE_TYPE, source_p->servptr->name,
237 source_p->username, source_p->host,
238 SHARED_UNRESV))
239 remove_resv(source_p, parv[2]);
240 }
241
242 /* parse_resv()
243 *
244 * inputs - source_p, NULL supported
245 * - thing to resv
246 * - time_t if tkline
247 * - reason
248 * outputs - none
249 * side effects - parse resv, create if valid
250 */
251 static void
252 parse_resv(struct Client *source_p, char *name, int tkline_time, char *reason)
253 {
254 struct ConfItem *conf = NULL;
255
256 if (IsChanPrefix(*name))
257 {
258 struct ResvChannel *resv_p;
259
260 if ((conf = create_channel_resv(name, reason, 0)) == NULL)
261 {
262 sendto_one(source_p,
263 ":%s NOTICE %s :A RESV has already been placed on channel: %s",
264 me.name, source_p->name, name);
265 return;
266 }
267
268 resv_p = map_to_conf(conf);
269
270 if (tkline_time != 0)
271 {
272 sendto_one(source_p,
273 ":%s NOTICE %s :A %d minute %s RESV has been placed on channel: %s",
274 me.name, source_p->name,
275 tkline_time/60,
276 (MyClient(source_p) ? "local" : "remote"), name);
277 sendto_realops_flags(UMODE_ALL, L_ALL,
278 "%s has placed a %d minute %s RESV on channel: %s [%s]",
279 get_oper_name(source_p),
280 tkline_time/60,
281 (MyClient(source_p) ? "local" : "remote"),
282 resv_p->name, resv_p->reason);
283 ilog(L_TRACE, "%s added temporary %d min. RESV for [%s] [%s]",
284 source_p->name, (int)tkline_time/60,
285 conf->name, resv_p->reason);
286 resv_p->hold = CurrentTime + tkline_time;
287 add_temp_line(conf);
288 }
289 else
290 {
291 sendto_one(source_p,
292 ":%s NOTICE %s :A %s RESV has been placed on channel %s",
293 me.name, source_p->name,
294 (MyClient(source_p) ? "local" : "remote"), name);
295 sendto_realops_flags(UMODE_ALL, L_ALL,
296 "%s has placed a %s RESV on channel %s : [%s]",
297 get_oper_name(source_p),
298 (MyClient(source_p) ? "local" : "remote"),
299 resv_p->name, resv_p->reason);
300 write_conf_line(source_p, conf, NULL /* not used */, 0 /* not used */);
301 }
302 }
303 else
304 {
305 struct MatchItem *resv_p = NULL;
306
307 if (!valid_wild_card_simple(name))
308 {
309 sendto_one(source_p, ":%s NOTICE %s :Please include at least %d non-wildcard characters with the resv",
310 me.name, source_p->name, ConfigFileEntry.min_nonwildcard_simple);
311 return;
312 }
313
314 if (!IsAdmin(source_p) && strpbrk(name, "*?#"))
315 {
316 sendto_one(source_p, ":%s NOTICE %s :You must be an admin to perform a "
317 "wildcard RESV", me.name, source_p->name);
318 return;
319 }
320
321 if ((conf = create_nick_resv(name, reason, 0)) == NULL)
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 resv_p = map_to_conf(conf);
330
331 if (tkline_time != 0)
332 {
333 sendto_one(source_p,
334 ":%s NOTICE %s :A %d minute %s RESV has been placed on nick %s : [%s]",
335 me.name, source_p->name,
336 tkline_time/60,
337 (MyClient(source_p) ? "local" : "remote"),
338 conf->name, resv_p->reason);
339 sendto_realops_flags(UMODE_ALL, L_ALL,
340 "%s has placed a %d minute %s RESV on nick %s : [%s]",
341 get_oper_name(source_p),
342 tkline_time/60,
343 (MyClient(source_p) ? "local" : "remote"),
344 conf->name, resv_p->reason);
345 ilog(L_TRACE, "%s added temporary %d min. RESV for [%s] [%s]",
346 source_p->name, (int)tkline_time/60,
347 conf->name, resv_p->reason);
348 resv_p->hold = CurrentTime + tkline_time;
349 add_temp_line(conf);
350 }
351 else
352 {
353 sendto_one(source_p,
354 ":%s NOTICE %s :A %s RESV has been placed on nick %s : [%s]",
355 me.name, source_p->name,
356 (MyClient(source_p) ? "local" : "remote"),
357 conf->name, resv_p->reason);
358 sendto_realops_flags(UMODE_ALL, L_ALL,
359 "%s has placed a %s RESV on nick %s : [%s]",
360 get_oper_name(source_p),
361 (MyClient(source_p) ? "local" : "remote"),
362 conf->name, resv_p->reason);
363 write_conf_line(source_p, conf, NULL /* not used */, 0 /* not used */);
364 }
365 }
366 }
367
368 static void
369 remove_resv(struct Client *source_p, const char *name)
370 {
371 struct ConfItem *conf = NULL;
372
373 if (IsChanPrefix(*name))
374 {
375 struct ResvChannel *resv_p;
376
377 if (resv_channel_list.head == NULL ||
378 !(resv_p = hash_find_resv(name)))
379 {
380 sendto_one(source_p,
381 ":%s NOTICE %s :A RESV does not exist for channel: %s",
382 me.name, source_p->name, name);
383 return;
384 }
385
386 if (resv_p->conf)
387 {
388 sendto_one(source_p,
389 ":%s NOTICE %s :The RESV for channel: %s is in ircd.conf and must be removed by hand.",
390 me.name, source_p->name, name);
391 return;
392 }
393
394 delete_channel_resv(resv_p);
395 remove_conf_line(CRESV_TYPE, source_p, name, NULL);
396
397 sendto_one(source_p,
398 ":%s NOTICE %s :The RESV has been removed on channel: %s",
399 me.name, source_p->name, name);
400 sendto_realops_flags(UMODE_ALL, L_ALL,
401 "%s has removed the RESV for channel: %s",
402 get_oper_name(source_p), name);
403 }
404 else
405 {
406 struct MatchItem *resv_p = NULL;
407
408 if ((conf = find_exact_name_conf(NRESV_TYPE, name, NULL, NULL)) == NULL)
409 {
410 sendto_one(source_p, ":%s NOTICE %s :A RESV does not exist for nick: %s",
411 me.name, source_p->name, name);
412 return;
413 }
414
415 resv_p = map_to_conf(conf);
416
417 if (resv_p->action)
418 {
419 sendto_one(source_p,
420 ":%s NOTICE %s :The RESV for nick: %s is in ircd.conf and must be removed by hand.",
421 me.name, source_p->name, name);
422 return;
423 }
424
425 delete_conf_item(conf);
426 remove_conf_line(NRESV_TYPE, source_p, name, NULL);
427
428 sendto_one(source_p, ":%s NOTICE %s :The RESV has been removed on nick: %s",
429 me.name, source_p->name, name);
430 sendto_realops_flags(UMODE_ALL, L_ALL,
431 "%s has removed the RESV for nick: %s",
432 get_oper_name(source_p), name);
433 }
434 }

Properties

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