ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/modules/m_rxline.c
Revision: 69
Committed: Tue Oct 4 16:09:51 2005 UTC (20 years, 10 months ago) by adx
Content type: text/x-csrc
File size: 11217 byte(s)
Log Message:
- splitted ircd/libio, all headers connected with libio sources have been
  moved for internal use only. To use libio interface, include "libio.h"
  (which is already done in "stdinc.h")


File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * m_rxline.c: xlines a user with regular expression support.
4     *
5     * Copyright (C) 2005 by the past and present ircd coders, and others.
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 knight 31 * $Id$
23 adx 30 */
24    
25     #include "stdinc.h"
26     #include "channel.h"
27     #include "client.h"
28     #include "common.h"
29     #include "ircd.h"
30     #include "hostmask.h"
31     #include "numeric.h"
32     #include "s_conf.h"
33     #include "send.h"
34     #include "hash.h"
35     #include "handlers.h"
36     #include "s_serv.h"
37     #include "msg.h"
38     #include "parse.h"
39     #include "modules.h"
40     #include "resv.h"
41    
42     static void mo_rxline(struct Client *, struct Client *, int, char *[]);
43     static void ms_rxline(struct Client *, struct Client *, int, char *[]);
44     static void mo_unrxline(struct Client *, struct Client *, int, char *[]);
45     static void ms_unrxline(struct Client *, struct Client *, int, char *[]);
46    
47     static int valid_xline(struct Client *, char *, char *, int);
48     static void write_rxline(struct Client *, const char *, char *, time_t);
49     static void remove_xline(struct Client *, char *);
50     static int remove_txline(const char *);
51    
52     struct Message rxline_msgtab = {
53     "RXLINE", 0, 0, 2, 0, MFLG_SLOW, 0,
54     { m_unregistered, m_not_oper, ms_rxline, m_ignore, mo_rxline, m_ignore }
55     };
56    
57     struct Message unrxline_msgtab = {
58     "UNRXLINE", 0, 0, 2, 0, MFLG_SLOW, 0,
59     { m_unregistered, m_not_oper, ms_unrxline, m_ignore, mo_unrxline, m_ignore }
60     };
61    
62     #ifndef STATIC_MODULES
63     void
64     _modinit(void)
65     {
66     mod_add_cmd(&rxline_msgtab);
67     mod_add_cmd(&unrxline_msgtab);
68     }
69    
70     void
71     _moddeinit(void)
72     {
73     mod_del_cmd(&rxline_msgtab);
74     mod_del_cmd(&unrxline_msgtab);
75     }
76    
77 knight 31 const char *_version = "$Revision$";
78 adx 30 #endif
79    
80     static int
81     already_placed_rxline(struct Client *source_p, const char *gecos)
82     {
83     const dlink_node *ptr = NULL;
84    
85     DLINK_FOREACH(ptr, rxconf_items.head)
86     {
87     struct ConfItem *aptr = ptr->data;
88     const struct MatchItem *match_item = map_to_conf(aptr);
89    
90     if (!strcmp(gecos, aptr->name))
91     {
92     sendto_one(source_p, ":%s NOTICE %s :[%s] already RX-Lined by [%s] - %s",
93     me.name, source_p->name, gecos,
94     aptr->name, match_item->reason);
95     return 1;
96     }
97     }
98    
99     return 0;
100     }
101    
102     /* mo_rxline()
103     *
104     * inputs - pointer to server
105     * - pointer to client
106     * - parameter count
107     * - parameter list
108     * output -
109     * side effects - regular expression x line is added
110     *
111     */
112     static void
113     mo_rxline(struct Client *client_p, struct Client *source_p,
114     int parc, char *parv[])
115     {
116     char *reason = NULL;
117     char *gecos = NULL;
118     char *target_server = NULL;
119     time_t tkline_time = 0;
120    
121     if (!IsOperX(source_p))
122     {
123     sendto_one(source_p, form_str(ERR_NOPRIVS),
124     me.name, source_p->name, "rxline");
125     return;
126     }
127    
128     if (parse_aline("RXLINE", source_p, parc, parv, AWILD, &gecos,
129     NULL, &tkline_time, NULL, &reason) < 0)
130     return;
131    
132     if (target_server != NULL)
133     {
134     sendto_match_servs(source_p, target_server, CAP_CLUSTER,
135     "RXLINE %s %s %d :%s",
136     target_server, gecos, (int)tkline_time, reason);
137    
138     /* Allow ON to apply local rxline as well if it matches */
139     if (!match(target_server, me.name))
140     return;
141     }
142    
143     #if 0
144     cluster_a_line(source_p, "RXLINE", CAP_KLN, SHARED_XLINE,
145     "%s 0 :%s", gecos, reason);
146     #endif
147    
148     if (!valid_xline(source_p, gecos, reason, 0))
149     return;
150    
151     if (!already_placed_rxline(source_p, gecos))
152     write_rxline(source_p, gecos, reason, tkline_time);
153     }
154    
155     /* ms_rxline()
156     *
157     * inputs - oper, target server, rxline, {type}, reason
158     * deprecate {type} reserve for temp xlines later? XXX
159     *
160     * outputs - none
161     * side effects - propagates rxline, applies it if we are a target
162     */
163     static void
164     ms_rxline(struct Client *client_p, struct Client *source_p,
165     int parc, char *parv[])
166     {
167     int t_sec = 0;
168    
169     if (parc != 5 || EmptyString(parv[4]))
170     return;
171    
172     if (!IsClient(source_p))
173     return;
174    
175     if (!valid_xline(source_p, parv[2], parv[4], 0))
176     return;
177    
178     t_sec = atoi(parv[3]);
179     /* XXX kludge! */
180     if (t_sec < 3)
181     t_sec = 0;
182    
183     sendto_match_servs(source_p, parv[1], CAP_CLUSTER,
184     "RXLINE %s %s %s :%s",
185     parv[1], parv[2], parv[3], parv[4]);
186    
187     if (!match(parv[1], me.name))
188     return;
189    
190     if (find_matching_name_conf(ULINE_TYPE, source_p->servptr->name,
191     source_p->username, source_p->host,
192     SHARED_XLINE))
193     if (!already_placed_rxline(source_p, parv[2]))
194     write_rxline(source_p, parv[2], parv[4], t_sec);
195     }
196    
197     static void
198     mo_unrxline(struct Client *client_p, struct Client *source_p,
199     int parc, char *parv[])
200     {
201     char *gecos = NULL;
202     char *target_server = NULL;
203    
204     if (!IsOperX(source_p))
205     {
206     sendto_one(source_p, form_str(ERR_NOPRIVS),
207     me.name, source_p->name, "unrxline");
208     return;
209     }
210    
211     if (parse_aline("UNRXLINE", source_p, parc, parv, 0, &gecos,
212     NULL, NULL, &target_server, NULL) < 0)
213     return;
214    
215     if (target_server != NULL)
216     {
217    
218     sendto_match_servs(source_p, target_server, CAP_CLUSTER,
219     "UNRXLINE %s %s", target_server, gecos);
220    
221     /* Allow ON to apply local unrxline as well if it matches */
222     if (!match(target_server, me.name))
223     return;
224     }
225    
226     #if 0
227     cluster_a_line(source_p, "UNRXLINE", CAP_CLUSTER, SHARED_UNXLINE,
228     "%s", gecos);
229     #endif
230    
231     remove_xline(source_p, gecos);
232     }
233    
234     /* ms_unrxline()
235     *
236     * inputs - oper, target server, gecos
237     * outputs - none
238     * side effects - propagates unrxline, applies it if we are a target
239     */
240     static void
241     ms_unrxline(struct Client *client_p, struct Client *source_p,
242     int parc, char *parv[])
243     {
244     if (parc != 3 || EmptyString(parv[2]))
245     return;
246    
247     sendto_match_servs(source_p, parv[1], CAP_CLUSTER,
248     "UNRXLINE %s %s",
249     parv[1], parv[2]);
250    
251     if (!IsClient(source_p) || !match(parv[1], me.name))
252     return;
253    
254     if (find_matching_name_conf(ULINE_TYPE, source_p->servptr->name,
255     source_p->username, source_p->host,
256     SHARED_UNXLINE))
257     remove_xline(source_p, parv[2]);
258     }
259    
260     /* valid_xline()
261     *
262     * inputs - client to complain to, gecos, reason, whether to complain
263     * outputs - 1 for valid, else 0
264     * side effects - complains to client, when warn != 0
265     */
266     static int
267     valid_xline(struct Client *source_p, char *gecos, char *reason, int warn)
268     {
269     if (EmptyString(reason))
270     {
271     if (warn)
272     sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
273     me.name, source_p->name, "RXLINE");
274     return 0;
275     }
276    
277     if (strchr(gecos, '"'))
278     {
279     sendto_one(source_p, ":%s NOTICE %s :Invalid character '\"'",
280     me.name, source_p->name);
281     return 0;
282     }
283    
284     if (!valid_wild_card_simple(gecos))
285     {
286     if (warn)
287     sendto_one(source_p, ":%s NOTICE %s :Please include at least %d non-wildcard characters with the rxline",
288     me.name, source_p->name, ConfigFileEntry.min_nonwildcard_simple);
289    
290     return 0;
291     }
292    
293     return 1;
294     }
295    
296     /* write_rxline()
297     *
298     * inputs - client taking credit for rxline
299     * outputs - none
300     * side effects - when successful, adds an rxline to the conf
301     */
302     static void
303     write_rxline(struct Client *source_p, const char *gecos, char *reason,
304     time_t tkline_time)
305     {
306     struct ConfItem *conf = NULL;
307     struct MatchItem *match_item = NULL;
308     const char *current_date = NULL;
309     time_t cur_time = 0;
310     pcre *exp_gecos = NULL;
311     const char *errptr = NULL;
312    
313     if (!(exp_gecos = ircd_pcre_compile(gecos, &errptr)))
314     {
315     sendto_realops_flags(UMODE_ALL, L_ALL,
316     "Failed to add regular expression based X-Line: %s", errptr);
317     return;
318     }
319    
320     conf = make_conf_item(RXLINE_TYPE);
321     conf->regexpname = exp_gecos;
322    
323     match_item = map_to_conf(conf);
324    
325     DupString(conf->name, gecos);
326     DupString(match_item->reason, reason);
327     DupString(match_item->oper_reason, ""); /* XXX */
328    
329     cur_time = CurrentTime;
330     current_date = smalldate(cur_time);
331    
332     if (tkline_time)
333     {
334     sendto_realops_flags(UMODE_ALL, L_ALL,
335     "%s added temporary %d min. RX-Line for [%s] [%s]",
336     get_oper_name(source_p), (int)tkline_time/60,
337     conf->name, match_item->reason);
338     sendto_one(source_p, ":%s NOTICE %s :Added temporary %d min. RX-Line [%s]",
339     MyConnect(source_p) ? me.name : ID_or_name(&me, source_p->from),
340     source_p->name, (int)tkline_time/60, conf->name);
341     ilog(L_TRACE, "%s added temporary %d min. RX-Line for [%s] [%s]",
342     source_p->name, (int)tkline_time/60,
343     conf->name, match_item->reason);
344     match_item->hold = CurrentTime + tkline_time;
345     add_temp_line(conf);
346     }
347     else
348     write_conf_line(source_p, conf, current_date, cur_time);
349     rehashed_klines = 1;
350     }
351    
352     static void
353     remove_xline(struct Client *source_p, char *gecos)
354     {
355     /* XXX use common temporary un function later */
356     if (remove_txline(gecos))
357     {
358     sendto_one(source_p,
359     ":%s NOTICE %s :Un-rxlined [%s] from temporary RX-Lines",
360     me.name, source_p->name, gecos);
361     sendto_realops_flags(UMODE_ALL, L_ALL,
362     "%s has removed the temporary RX-Line for: [%s]",
363     get_oper_name(source_p), gecos);
364     ilog(L_NOTICE, "%s removed temporary RX-Line for [%s]",
365     source_p->name, gecos);
366     return;
367     }
368    
369     if (remove_conf_line(RXLINE_TYPE, source_p, gecos, NULL) > 0)
370     {
371     sendto_one(source_p, ":%s NOTICE %s :RX-Line for [%s] is removed",
372     me.name, source_p->name, gecos);
373     sendto_realops_flags(UMODE_ALL, L_ALL,
374     "%s has removed the RX-Line for: [%s]",
375     get_oper_name(source_p), gecos);
376     ilog(L_NOTICE, "%s removed RX-Line for [%s]",
377     get_oper_name(source_p), gecos);
378     }
379     else
380     sendto_one(source_p, ":%s NOTICE %s :No RX-Line for %s",
381     me.name, source_p->name, gecos);
382     }
383    
384     /* static int remove_tkline_match(const char *host, const char *user)
385     *
386     * Inputs: gecos
387     * Output: returns YES on success, NO if no tkline removed.
388     * Side effects: Any matching tklines are removed.
389     */
390     static int
391     remove_txline(const char *const gecos)
392     {
393     dlink_node *ptr = NULL;
394    
395     DLINK_FOREACH(ptr, temporary_rxlines.head)
396     {
397     struct ConfItem *conf = ptr->data;
398    
399     if (!strcmp(gecos, conf->name))
400     {
401     dlinkDelete(ptr, &temporary_rxlines);
402     free_dlink_node(ptr);
403     delete_conf_item(conf);
404     return 1;
405     }
406     }
407    
408     return 0;
409     }

Properties

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