ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/modules/m_xline.c
Revision: 7208
Committed: Wed Feb 3 15:06:47 2016 UTC (9 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 7646 byte(s)
Log Message:
- Clustering has been broken in -r7158. Rewrote most of the shared/cluster implementation to be less obscure.
  This introduces a little bit of code duplication, but increases readability, is less error prone, and
  reduces memory consumption a bit. 

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 *
4 * Copyright (c) 2003-2016 ircd-hybrid development team
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 * USA
20 */
21
22 /*! \file m_xline.c
23 * \brief Includes required functions for processing the XLINE command.
24 * \version $Id$
25 */
26
27 #include "stdinc.h"
28 #include "list.h"
29 #include "client.h"
30 #include "irc_string.h"
31 #include "ircd.h"
32 #include "conf.h"
33 #include "conf_cluster.h"
34 #include "conf_shared.h"
35 #include "numeric.h"
36 #include "log.h"
37 #include "misc.h"
38 #include "send.h"
39 #include "server.h"
40 #include "parse.h"
41 #include "modules.h"
42 #include "memory.h"
43
44
45 static void
46 xline_check(struct MaskItem *conf)
47 {
48 dlink_node *node = NULL, *node_next = NULL;
49
50 DLINK_FOREACH_SAFE(node, node_next, local_client_list.head)
51 {
52 struct Client *client_p = node->data;
53
54 if (IsDead(client_p))
55 continue;
56
57 if (!match(conf->name, client_p->info))
58 conf_try_ban(client_p, conf);
59 }
60 }
61
62 /* valid_xline()
63 *
64 * inputs - client to complain to, gecos, reason, whether to complain
65 * outputs - 1 for valid, else 0
66 * side effects - complains to client, when warn != 0
67 */
68 static int
69 valid_xline(struct Client *source_p, const char *gecos)
70 {
71 if (!valid_wild_card_simple(gecos))
72 {
73 if (IsClient(source_p))
74 sendto_one_notice(source_p, &me, ":Please include at least %u non-wildcard characters with the xline",
75 ConfigGeneral.min_nonwildcard_simple);
76 return 0;
77 }
78
79 return 1;
80 }
81
82 /* xline_add()
83 *
84 * inputs - client taking credit for xline, gecos, reason, xline type
85 * outputs - none
86 * side effects - when successful, adds an xline to the conf
87 */
88 static void
89 xline_add(struct Client *source_p, const char *gecos, const char *reason,
90 time_t duration)
91 {
92 char buf[IRCD_BUFSIZE];
93
94 if (duration)
95 snprintf(buf, sizeof(buf), "Temporary X-line %ju min. - %.*s (%s)",
96 duration / 60, REASONLEN, reason, date_iso8601(0));
97 else
98 snprintf(buf, sizeof(buf), "%.*s (%s)", REASONLEN, reason, date_iso8601(0));
99
100 struct MaskItem *conf = conf_make(CONF_XLINE);
101 conf->name = xstrdup(gecos);
102 conf->reason = xstrdup(buf);
103 conf->setat = CurrentTime;
104 SetConfDatabase(conf);
105
106 if (duration)
107 {
108 conf->until = CurrentTime + duration;
109
110 if (IsClient(source_p))
111 sendto_one_notice(source_p, &me, ":Added temporary %ju min. X-Line [%s]",
112 duration / 60, conf->name);
113
114 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
115 "%s added temporary %ju min. X-Line for [%s] [%s]",
116 get_oper_name(source_p), duration / 60,
117 conf->name, conf->reason);
118 ilog(LOG_TYPE_XLINE, "%s added temporary %ju min. X-Line for [%s] [%s]",
119 get_oper_name(source_p), duration / 60, conf->name, conf->reason);
120 }
121 else
122 {
123 if (IsClient(source_p))
124 sendto_one_notice(source_p, &me, ":Added X-Line [%s] [%s]",
125 conf->name, conf->reason);
126
127 sendto_realops_flags(UMODE_SERVNOTICE, L_ALL, SEND_NOTICE,
128 "%s added X-Line for [%s] [%s]",
129 get_oper_name(source_p), conf->name,
130 conf->reason);
131 ilog(LOG_TYPE_XLINE, "%s added X-Line for [%s] [%s]",
132 get_oper_name(source_p), conf->name, conf->reason);
133 }
134
135 xline_check(conf);
136 }
137
138 static void
139 relay_xline(struct Client *source_p, char *parv[])
140 {
141 struct MaskItem *conf = NULL;
142
143 if (HasFlag(source_p, FLAGS_SERVICE) ||
144 shared_find(SHARED_XLINE, source_p->servptr->name,
145 source_p->username, source_p->host))
146 {
147 if ((conf = find_matching_name_conf(CONF_XLINE, parv[2], NULL, NULL, 0)))
148 {
149 if (IsClient(source_p))
150 sendto_one_notice(source_p, &me, ":[%s] already X-Lined by [%s] - %s",
151 parv[2], conf->name, conf->reason);
152 return;
153 }
154
155 xline_add(source_p, parv[2], parv[4], atoi(parv[3]));
156 }
157 }
158
159 /* mo_xline()
160 *
161 * inputs - pointer to server
162 * - pointer to client
163 * - parameter count
164 * - parameter list
165 * output -
166 * side effects - x line is added
167 *
168 */
169 static int
170 mo_xline(struct Client *source_p, int parc, char *parv[])
171 {
172 char *reason = NULL;
173 char *gecos = NULL;
174 struct MaskItem *conf = NULL;
175 char *target_server = NULL;
176 time_t duration = 0;
177
178 if (!HasOFlag(source_p, OPER_FLAG_XLINE))
179 {
180 sendto_one_numeric(source_p, &me, ERR_NOPRIVS, "xline");
181 return 0;
182 }
183
184 if (!parse_aline("XLINE", source_p, parc, parv, 0, &gecos, NULL,
185 &duration, &target_server, &reason))
186 return 0;
187
188 if (target_server)
189 {
190 sendto_match_servs(source_p, target_server, CAPAB_CLUSTER, "XLINE %s %s %ju :%s",
191 target_server, gecos, duration, reason);
192
193 /* Allow ON to apply local xline as well if it matches */
194 if (match(target_server, me.name))
195 return 0;
196 }
197 else
198 cluster_distribute(source_p, "XLINE", CAPAB_CLUSTER, CLUSTER_XLINE, "%s %ju :%s",
199 gecos, duration, reason);
200
201 if (!valid_xline(source_p, gecos))
202 return 0;
203
204 if ((conf = find_matching_name_conf(CONF_XLINE, gecos, NULL, NULL, 0)))
205 {
206 sendto_one_notice(source_p, &me, ":[%s] already X-Lined by [%s] - %s",
207 gecos, conf->name, conf->reason);
208 return 0;
209 }
210
211 xline_add(source_p, gecos, reason, duration);
212 return 0;
213 }
214
215 /*! \brief XLINE command handler
216 *
217 * \param source_p Pointer to allocated Client struct from which the message
218 * originally comes from. This can be a local or remote client.
219 * \param parc Integer holding the number of supplied arguments.
220 * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
221 * pointers.
222 * \note Valid arguments for this command are:
223 * - parv[0] = command
224 * - parv[1] = target server mask
225 * - parv[2] = gecos
226 * - parv[3] = duration in seconds
227 * - parv[4] = reason
228 */
229 static int
230 ms_xline(struct Client *source_p, int parc, char *parv[])
231 {
232 if (parc != 5 || EmptyString(parv[4]))
233 return 0;
234
235 sendto_match_servs(source_p, parv[1], CAPAB_CLUSTER, "XLINE %s %s %s :%s",
236 parv[1], parv[2], parv[3], parv[4]);
237
238 if (match(parv[1], me.name))
239 return 0;
240
241 if (!valid_xline(source_p, parv[2]))
242 return 0;
243
244 relay_xline(source_p, parv);
245 return 0;
246 }
247
248 static struct Message xline_msgtab =
249 {
250 .cmd = "XLINE",
251 .args_min = 2,
252 .args_max = MAXPARA,
253 .handlers[UNREGISTERED_HANDLER] = m_unregistered,
254 .handlers[CLIENT_HANDLER] = m_not_oper,
255 .handlers[SERVER_HANDLER] = ms_xline,
256 .handlers[ENCAP_HANDLER] = m_ignore,
257 .handlers[OPER_HANDLER] = mo_xline
258 };
259
260 static void
261 module_init(void)
262 {
263 mod_add_cmd(&xline_msgtab);
264 }
265
266 static void
267 module_exit(void)
268 {
269 mod_del_cmd(&xline_msgtab);
270 }
271
272 struct module module_entry =
273 {
274 .version = "$Revision$",
275 .modinit = module_init,
276 .modexit = module_exit,
277 };

Properties

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