ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/m_gline.c
Revision: 1029
Committed: Sun Nov 8 13:10:50 2009 UTC (15 years, 9 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-7.3/modules/m_gline.c
File size: 21164 byte(s)
Log Message:
- branch off trunk to create 7.3 branch

File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     *
4     * Copyright (C) 2002 by the past and present ircd coders, and others.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19     * USA
20     */
21    
22 michael 1008 /*! \file m_gline.c
23     * \brief Includes required functions for processing the GLINE command.
24     * \version $Id$
25     */
26    
27 adx 30 #include "stdinc.h"
28 michael 1011 #include "list.h"
29 adx 30 #include "handlers.h"
30     #include "s_gline.h"
31     #include "channel.h"
32     #include "client.h"
33     #include "common.h"
34     #include "irc_string.h"
35     #include "sprintf_irc.h"
36     #include "ircd.h"
37     #include "hostmask.h"
38     #include "numeric.h"
39     #include "s_bsd.h"
40     #include "s_conf.h"
41     #include "s_misc.h"
42     #include "send.h"
43     #include "msg.h"
44     #include "fileio.h"
45     #include "s_serv.h"
46     #include "hash.h"
47     #include "parse.h"
48     #include "modules.h"
49     #include "s_log.h"
50    
51     #define GLINE_NOT_PLACED 0
52     #define GLINE_ALREADY_VOTED -1
53     #define GLINE_PLACED 1
54    
55    
56 michael 958 static void me_gline(struct Client *, struct Client *, int, char *[]);
57     static void ms_gline(struct Client *, struct Client *, int, char *[]);
58     static void mo_gline(struct Client *, struct Client *, int, char *[]);
59     static void me_gungline(struct Client *, struct Client *, int, char *[]);
60     static void mo_gungline(struct Client *, struct Client *, int, char *[]);
61 db 937
62 adx 30 /*
63     * gline enforces 3 parameters to force operator to give a reason
64     * a gline is not valid with "No reason"
65     * -db
66     */
67     struct Message gline_msgtab = {
68     "GLINE", 0, 0, 3, 0, MFLG_SLOW, 0,
69 michael 1008 { m_unregistered, m_not_oper, ms_gline, me_gline, mo_gline, m_ignore }
70 adx 30 };
71    
72 db 937 struct Message ungline_msgtab = {
73 db 940 "GUNGLINE", 0, 0, 3, 0, MFLG_SLOW, 0,
74 michael 1008 { m_unregistered, m_not_oper, m_ignore, me_gungline, mo_gungline, m_ignore }
75 db 937 };
76    
77 michael 958
78 adx 30 void
79     _modinit(void)
80     {
81 michael 957 mod_add_cmd(&gline_msgtab);
82     mod_add_cmd(&ungline_msgtab);
83     add_capability("GLN", CAP_GLN, 1);
84 adx 30 }
85    
86     void
87     _moddeinit(void)
88     {
89     mod_del_cmd(&gline_msgtab);
90 db 937 mod_del_cmd(&ungline_msgtab);
91 adx 30 delete_capability("GLN");
92     }
93    
94 knight 31 const char *_version = "$Revision$";
95 adx 30
96 michael 1009 /*! \brief Adds a GLINE to the configuration subsystem.
97     *
98     * \param source_p Operator requesting gline
99     * \param user Username covered by the gline
100     * \param host Hostname covered by the gline
101     * \param reason Reason for the gline
102     */
103     static void
104     set_local_gline(const struct Client *source_p, const char *user,
105     const char *host, const char *reason)
106     {
107     char buffer[IRCD_BUFSIZE];
108     struct ConfItem *conf;
109     struct AccessItem *aconf;
110 michael 1008
111    
112 michael 1009 conf = make_conf_item(GLINE_TYPE);
113     aconf = map_to_conf(conf);
114    
115     snprintf(buffer, sizeof(buffer), "%s (%s)", reason, smalldate(CurrentTime));
116     DupString(aconf->reason, buffer);
117     DupString(aconf->user, user);
118     DupString(aconf->host, host);
119    
120     aconf->hold = CurrentTime + ConfigFileEntry.gline_time;
121     add_temp_line(conf);
122    
123     sendto_realops_flags(UMODE_ALL, L_ALL,
124     "%s added G-Line for [%s@%s] [%s]",
125     get_oper_name(source_p),
126     aconf->user, aconf->host, aconf->reason);
127     ilog(L_TRACE, "%s added G-Line for [%s@%s] [%s]",
128     get_oper_name(source_p), aconf->user, aconf->host, aconf->reason);
129     log_oper_action(LOG_GLINE_TYPE, source_p, "[%s@%s] [%s]\n",
130     aconf->user, aconf->host, aconf->reason);
131     /* Now, activate gline against current online clients */
132     rehashed_klines = 1;
133     }
134    
135     /*! \brief Removes a GLINE from the configuration subsystem.
136     *
137     * \param user Username covered by the gline
138     * \param host Hostname covered by the gline
139     */
140     static int
141     remove_gline_match(const char *user, const char *host)
142     {
143     struct AccessItem *aconf;
144     dlink_node *ptr = NULL;
145     struct irc_ssaddr addr, caddr;
146     int nm_t, cnm_t, bits, cbits;
147    
148     nm_t = parse_netmask(host, &addr, &bits);
149    
150     DLINK_FOREACH(ptr, temporary_glines.head)
151     {
152     aconf = map_to_conf(ptr->data);
153     cnm_t = parse_netmask(aconf->host, &caddr, &cbits);
154    
155     if (cnm_t != nm_t || irccmp(user, aconf->user))
156     continue;
157    
158     if ((nm_t == HM_HOST && !irccmp(aconf->host, host)) ||
159     (nm_t == HM_IPV4 && bits == cbits && match_ipv4(&addr, &caddr, bits))
160     #ifdef IPV6
161     || (nm_t == HM_IPV6 && bits == cbits && match_ipv6(&addr, &caddr, bits))
162     #endif
163     )
164     {
165     dlinkDelete(ptr, &temporary_glines);
166     delete_one_address_conf(aconf->host, aconf);
167     return 1;
168     }
169     }
170    
171     return 0;
172     }
173    
174 michael 1008 /*! \brief This function is called once a majority of opers have agreed on a
175     * GLINE/GUNGLINE, and it can be placed. The information about an
176     * operator being passed to us happens to be the operator who pushed us
177     * over the "majority" level needed. See check_majority() for more
178     * information.
179 adx 30 *
180 michael 1008 * \param source_p Operator requesting gline
181     * \param user Username covered by the gline
182     * \param host Hostname covered by the gline
183     * \param reason Reason for the gline
184     * \param type Valid values are either GLINE_PENDING_ADD_TYPE, or
185     * GLINE_PENDING_DEL_TYPE
186 adx 30 */
187 michael 1008 static void
188     add_new_majority(const struct Client *source_p, const char *user,
189     const char *host, const char *reason, const unsigned int type)
190     {
191     struct gline_pending *pending = MyMalloc(sizeof(struct gline_pending));
192    
193     strlcpy(pending->vote_1.oper_nick, source_p->name, sizeof(pending->vote_1.oper_nick));
194     strlcpy(pending->vote_1.oper_user, source_p->username, sizeof(pending->vote_1.oper_user));
195     strlcpy(pending->vote_1.oper_host, source_p->host, sizeof(pending->vote_1.oper_host));
196     strlcpy(pending->vote_1.oper_server, source_p->servptr->name, sizeof(pending->vote_1.oper_server));
197    
198     strlcpy(pending->user, user, sizeof(pending->user));
199     strlcpy(pending->host, host, sizeof(pending->host));
200     strlcpy(pending->vote_1.reason, reason, sizeof(pending->vote_1.reason));
201    
202     pending->last_gline_time = CurrentTime;
203     pending->vote_1.time_request = CurrentTime;
204    
205     dlinkAdd(pending, &pending->node, &pending_glines[type]);
206     }
207    
208     /*! \brief See if there is a majority agreement on a GLINE on the given user.
209     * There must be at least 3 different opers agreeing on this
210     * GLINE/GUNGLINE
211 adx 30 *
212 michael 1008 * \param source_p Operator requesting gline
213     * \param user Username covered by the gline
214     * \param host Hostname covered by the gline
215     * \param reason Reason for the gline
216     * \param type Valid values are either GLINE_PENDING_ADD_TYPE, or
217     * GLINE_PENDING_DEL_TYPE
218     *
219     * \return
220     * - GLINE_ALREADY_VOTED returned if oper/server has already voted
221     * - GLINE_PLACED returned if this triggers a gline
222     * - GLINE_NOT_PLACED returned if not triggered
223 adx 30 */
224 michael 1008 static int
225     check_majority(const struct Client *source_p, const char *user,
226     const char *host, const char *reason, const int type)
227 adx 30 {
228 michael 1008 dlink_node *dn_ptr = NULL;
229 adx 30
230 michael 1008 cleanup_glines(NULL);
231 adx 30
232 michael 1008 /* if its already glined, why bother? :) -- fl_ */
233     if ((type == GLINE_PENDING_ADD_TYPE) && find_is_glined(host, user))
234     return GLINE_NOT_PLACED;
235    
236     DLINK_FOREACH(dn_ptr, pending_glines[type].head)
237 adx 30 {
238 michael 1008 struct gline_pending *gp_ptr = dn_ptr->data;
239 adx 30
240 michael 1008 if (irccmp(gp_ptr->user, user) ||
241     irccmp(gp_ptr->host, host))
242     continue;
243 adx 30
244 michael 1008 if ((!irccmp(gp_ptr->vote_1.oper_user, source_p->username) &&
245     !irccmp(gp_ptr->vote_1.oper_host, source_p->host)) ||
246     !irccmp(gp_ptr->vote_1.oper_server, source_p->servptr->name))
247     return GLINE_ALREADY_VOTED;
248    
249     if (gp_ptr->vote_2.oper_user[0] != '\0')
250 adx 30 {
251 michael 1008 /* if two other opers on two different servers have voted yes */
252     if ((!irccmp(gp_ptr->vote_2.oper_user, source_p->username) &&
253     !irccmp(gp_ptr->vote_2.oper_host, source_p->host)) ||
254     !irccmp(gp_ptr->vote_2.oper_server, source_p->servptr->name))
255     return GLINE_ALREADY_VOTED;
256    
257     if (type == GLINE_PENDING_DEL_TYPE)
258     {
259     if (remove_gline_match(user, host))
260     {
261     sendto_realops_flags(UMODE_ALL, L_ALL,
262     "%s has removed the G-Line for: [%s@%s]",
263     get_oper_name(source_p), user, host);
264     ilog(L_NOTICE, "%s removed G-Line for [%s@%s]",
265     get_oper_name(source_p), user, host);
266     }
267     }
268     else
269     /* trigger the gline using the original reason --fl */
270     set_local_gline(source_p, user, host, gp_ptr->vote_1.reason);
271    
272     cleanup_glines(gp_ptr);
273     return GLINE_PLACED;
274 adx 30 }
275 michael 1008
276     strlcpy(gp_ptr->vote_2.oper_nick, source_p->name,
277     sizeof(gp_ptr->vote_2.oper_nick));
278     strlcpy(gp_ptr->vote_2.oper_user, source_p->username,
279     sizeof(gp_ptr->vote_2.oper_user));
280     strlcpy(gp_ptr->vote_2.oper_host, source_p->host,
281     sizeof(gp_ptr->vote_2.oper_host));
282     strlcpy(gp_ptr->vote_2.reason, reason,
283     sizeof(gp_ptr->vote_2.reason));
284     strlcpy(gp_ptr->vote_2.oper_server, source_p->servptr->name,
285     sizeof(gp_ptr->vote_2.oper_server));
286     gp_ptr->last_gline_time = CurrentTime;
287     gp_ptr->vote_2.time_request = CurrentTime;
288     return GLINE_NOT_PLACED;
289 adx 30 }
290    
291 michael 552 /*
292 michael 1008 * Didn't find this user@host gline in pending gline list
293     * so add it.
294 adx 30 */
295 michael 1008 add_new_majority(source_p, user, host, reason, type);
296     return GLINE_NOT_PLACED;
297 adx 30 }
298    
299     static void
300 michael 1008 do_sgline(struct Client *source_p, int parc, char *parv[], int prop)
301 adx 30 {
302     const char *reason = NULL; /* reason for "victims" demise */
303     char *user = NULL;
304     char *host = NULL; /* user and host of GLINE "victim" */
305 michael 1008 int var_offset = 0, logged = 0;
306 adx 30 dlink_node *ptr;
307 michael 1008 struct Client *target_p = NULL;
308 adx 30
309 michael 1008 switch (parc)
310 adx 30 {
311 michael 1008 case 4: /* hyb-7 style */
312     if (!IsClient(source_p))
313     return;
314     break;
315     case 8: /* hyb-6 style */
316     if (!IsServer(source_p))
317     return;
318     target_p = find_person(source_p->from, parv[1]);
319     if (target_p == NULL || target_p->servptr != source_p)
320     return;
321     source_p = target_p, var_offset = 4;
322     break;
323     default:
324 adx 30 return;
325     }
326    
327     assert(source_p->servptr != NULL);
328    
329 michael 1008 user = parv[++var_offset];
330     host = parv[++var_offset];
331     reason = parv[++var_offset];
332 adx 30
333 michael 1011 var_offset = 0;
334    
335 adx 30 DLINK_FOREACH(ptr, gdeny_items.head)
336     {
337 michael 1008 struct ConfItem *conf = ptr->data;
338     struct AccessItem *aconf = map_to_conf(conf);
339 adx 30
340     if (match(conf->name, source_p->servptr->name) &&
341     match(aconf->user, source_p->username) &&
342     match(aconf->host, source_p->host))
343     {
344     var_offset = aconf->flags;
345     break;
346     }
347     }
348    
349     if (prop && !(var_offset & GDENY_BLOCK))
350     {
351 michael 1008 sendto_server(source_p->from, NULL, CAP_GLN, NOCAPS,
352 adx 30 ":%s GLINE %s %s :%s",
353     source_p->name, user, host, reason);
354     /* hyb-6 version to the rest */
355 michael 1008 sendto_server(source_p->from, NULL, NOCAPS, CAP_GLN,
356 adx 30 ":%s GLINE %s %s %s %s %s %s :%s",
357     source_p->servptr->name,
358     source_p->name, source_p->username, source_p->host,
359     source_p->servptr->name,
360     user, host, reason);
361     }
362     else if (ConfigFileEntry.gline_logging & GDENY_BLOCK && ServerInfo.hub)
363     {
364     sendto_realops_flags(UMODE_ALL, L_ALL, "Blocked G-Line %s requested on [%s@%s] [%s]",
365     get_oper_name(source_p), user, host, reason);
366     ilog(L_TRACE, "Blocked G-Line %s requested on [%s@%s] [%s]",
367     get_oper_name(source_p), user, host, reason);
368     logged = 1;
369     }
370    
371     if (var_offset & GDENY_REJECT)
372     {
373     if (ConfigFileEntry.gline_logging & GDENY_REJECT && !logged)
374     {
375     sendto_realops_flags(UMODE_ALL, L_ALL, "Rejected G-Line %s requested on [%s@%s] [%s]",
376     get_oper_name(source_p), user, host, reason);
377     ilog(L_TRACE, "Rejected G-Line %s requested on [%s@%s] [%s]",
378     get_oper_name(source_p), user, host, reason);
379     }
380 michael 958
381 adx 30 return;
382     }
383    
384     if (ConfigFileEntry.glines)
385     {
386     if (!valid_wild_card(source_p, YES, 2, user, host))
387     return;
388    
389     if (IsClient(source_p))
390     {
391     const char *p = NULL;
392 michael 958
393 adx 30 if ((p = strchr(host, '/')))
394     {
395     int bitlen = strtol(++p, NULL, 10);
396     int min_bitlen = strchr(host, ':') ? ConfigFileEntry.gline_min_cidr6 :
397     ConfigFileEntry.gline_min_cidr;
398    
399     if (bitlen < min_bitlen)
400     {
401     sendto_realops_flags(UMODE_ALL, L_ALL, "%s!%s@%s on %s is requesting "
402     "a GLINE with a CIDR mask < %d for [%s@%s] [%s]",
403     source_p->name, source_p->username, source_p->host,
404     source_p->servptr->name, min_bitlen, user, host, reason);
405     return;
406     }
407     }
408     }
409    
410     /* If at least 3 opers agree this user should be G lined then do it */
411 michael 988 if (check_majority(source_p, user, host, reason, GLINE_PENDING_ADD_TYPE) ==
412 adx 30 GLINE_ALREADY_VOTED)
413     {
414     sendto_realops_flags(UMODE_ALL, L_ALL, "oper or server has already voted");
415     return;
416     }
417    
418 michael 554 sendto_realops_flags(UMODE_ALL, L_ALL,
419     "%s requesting G-Line for [%s@%s] [%s]",
420     get_oper_name(source_p),
421     user, host, reason);
422 adx 30 ilog(L_TRACE, "#gline for %s@%s [%s] requested by %s",
423     user, host, reason, get_oper_name(source_p));
424     }
425     }
426    
427 michael 1008
428     /*! \brief GLINE command handler (called by operators)
429 adx 30 *
430 michael 1008 * \param client_p Pointer to allocated Client struct with physical connection
431     * to this server, i.e. with an open socket connected.
432     * \param source_p Pointer to allocated Client struct from which the message
433     * originally comes from. This can be a local or remote client.
434     * \param parc Integer holding the number of supplied arguments.
435     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
436     * pointers.
437     * \note Valid arguments for this command are:
438     * - parv[0] = sender prefix
439     * - parv[1] = user\@host mask
440     * - parv[2] = reason
441 adx 30 */
442     static void
443 michael 1008 mo_gline(struct Client *client_p, struct Client *source_p,
444     int parc, char *parv[])
445 adx 30 {
446 michael 1008 char *user = NULL;
447     char *host = NULL;
448     char *reason = NULL;
449     char *p;
450 adx 30
451 michael 1008 if (!ConfigFileEntry.glines)
452     {
453     sendto_one(source_p, ":%s NOTICE %s :GLINE disabled",
454     me.name, source_p->name);
455     return;
456     }
457 adx 30
458 michael 1008 if (!IsOperGline(source_p))
459     {
460     sendto_one(source_p, form_str(ERR_NOPRIVS),
461     me.name, source_p->name, "gline");
462     return;
463     }
464 adx 30
465 michael 1008 if (parse_aline("GLINE", source_p, parc, parv, AWILD,
466     &user, &host, NULL, NULL, &reason) < 0)
467     return;
468 adx 30
469 michael 1008 if ((p = strchr(host, '/')) != NULL)
470 adx 30 {
471 michael 1008 int bitlen = strtol(++p, NULL, 10);
472     int min_bitlen = strchr(host, ':') ? ConfigFileEntry.gline_min_cidr6 :
473     ConfigFileEntry.gline_min_cidr;
474     if (bitlen < min_bitlen)
475 adx 30 {
476 michael 1008 sendto_one(source_p, ":%s NOTICE %s :Cannot set G-Lines with CIDR length < %d",
477     me.name, source_p->name, min_bitlen);
478     return;
479 michael 957 }
480 adx 30 }
481 michael 1008
482     /* If at least 3 opers agree this user should be G lined then do it */
483     if (check_majority(source_p, user, host, reason, GLINE_PENDING_ADD_TYPE) ==
484     GLINE_ALREADY_VOTED)
485     {
486     sendto_one(source_p,
487     ":%s NOTICE %s :This server or oper has already voted",
488     me.name, source_p->name);
489     return;
490     }
491 adx 30
492 michael 957 /*
493 michael 1008 * call these two functions first so the 'requesting' notice always comes
494     * before the 'has triggered' notice. -bill
495 adx 30 */
496 michael 1008 sendto_realops_flags(UMODE_ALL, L_ALL,
497     "%s requesting G-Line for [%s@%s] [%s]",
498     get_oper_name(source_p),
499     user, host, reason);
500     ilog(L_TRACE, "#gline for %s@%s [%s] requested by %s!%s@%s",
501     user, host, reason, source_p->name, source_p->username,
502     source_p->host);
503 adx 30
504 michael 1008 /* 4 param version for hyb-7 servers */
505     sendto_server(NULL, NULL, CAP_GLN|CAP_TS6, NOCAPS,
506     ":%s GLINE %s %s :%s",
507     ID(source_p), user, host, reason);
508     sendto_server(NULL, NULL, CAP_GLN, CAP_TS6,
509     ":%s GLINE %s %s :%s",
510     source_p->name, user, host, reason);
511 adx 30
512 michael 1008 /* 8 param for hyb-6 */
513     sendto_server(NULL, NULL, CAP_TS6, CAP_GLN,
514     ":%s GLINE %s %s %s %s %s %s :%s",
515     ID(&me),
516     ID(source_p), source_p->username,
517     source_p->host, source_p->servptr->name, user, host,
518     reason);
519     sendto_server(NULL, NULL, NOCAPS, CAP_GLN|CAP_TS6,
520     ":%s GLINE %s %s %s %s %s %s :%s",
521     me.name, source_p->name, source_p->username,
522     source_p->host, source_p->servptr->name, user, host,
523     reason);
524 adx 30 }
525    
526 michael 1008 /* ms_gline()
527     * me_gline()
528     * do_sgline()
529 db 937 *
530     * inputs - The usual for a m_ function
531     * output -
532     * side effects -
533     *
534 michael 1008 * Place a G line if 3 opers agree on the identical user@host
535 db 937 *
536 michael 1008 * Allow this server to pass along GLINE if received and
537     * GLINES is not defined.
538     *
539     * ENCAP'd GLINES are propagated by encap code.
540 db 937 */
541    
542     static void
543 michael 1008 ms_gline(struct Client *client_p, struct Client *source_p,
544     int parc, char *parv[])
545 db 937 {
546 michael 1008 do_sgline(source_p, parc, parv, 1);
547 db 937 }
548    
549     static void
550 michael 1008 me_gline(struct Client *client_p, struct Client *source_p,
551     int parc, char *parv[])
552     {
553     do_sgline(source_p, parc, parv, 0);
554     }
555    
556     static void
557 michael 1006 do_sungline(struct Client *source_p, const char *user,
558     const char *host, const char *reason, int prop)
559 db 937 {
560     assert(source_p->servptr != NULL);
561    
562 michael 957 sendto_realops_flags(UMODE_ALL, L_ALL,
563     "%s requesting UNG-Line for [%s@%s] [%s]",
564 michael 1006 get_oper_name(source_p), user, host, reason);
565 michael 957 ilog(L_TRACE, "#ungline for %s@%s [%s] requested by %s",
566     user, host, reason, get_oper_name(source_p));
567 db 937
568 michael 957 /* If at least 3 opers agree this user should be un G lined then do it */
569 michael 958 if (check_majority(source_p, user, host, reason, GLINE_PENDING_DEL_TYPE) ==
570 michael 957 GLINE_ALREADY_VOTED)
571     sendto_realops_flags(UMODE_ALL, L_ALL, "oper or server has already voted");
572 michael 1006
573     if (prop)
574     {
575     sendto_server(source_p->from, NULL, CAP_ENCAP|CAP_TS6, NOCAPS,
576     ":%s ENCAP * GUNGLINE %s %s :%s",
577     ID(source_p), user, host, reason);
578     sendto_server(source_p->from, NULL, CAP_ENCAP, CAP_TS6,
579     ":%s ENCAP * GUNGLINE %s %s :%s",
580     source_p->name, user, host, reason);
581     }
582 db 937 }
583    
584 michael 1008 /*! \brief GUNGLINE command handler (called in response to an encapsulated
585     * GUNGLINE command)
586 db 937 *
587 michael 1008 * \param client_p Pointer to allocated Client struct with physical connection
588     * to this server, i.e. with an open socket connected.
589     * \param source_p Pointer to allocated Client struct from which the message
590     * originally comes from. This can be a local or remote client.
591     * \param parc Integer holding the number of supplied arguments.
592     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
593     * pointers.
594     * \note Valid arguments for this command are:
595     * - parv[0] = sender prefix
596     * - parv[1] = username
597     * - parv[2] = hostname
598     * - parv[3] = reason
599 db 937 */
600 michael 1008 static void
601     me_gungline(struct Client *client_p, struct Client *source_p,
602     int parc, char *parv[])
603     {
604     if (ConfigFileEntry.glines)
605     do_sungline(source_p, parv[1], parv[2], parv[3], 0);
606     }
607    
608     /*! \brief GUNGLINE command handler (called by operators)
609 db 937 *
610 michael 1008 * \param client_p Pointer to allocated Client struct with physical connection
611     * to this server, i.e. with an open socket connected.
612     * \param source_p Pointer to allocated Client struct from which the message
613     * originally comes from. This can be a local or remote client.
614     * \param parc Integer holding the number of supplied arguments.
615     * \param parv Argument vector where parv[0] .. parv[parc-1] are non-NULL
616     * pointers.
617     * \note Valid arguments for this command are:
618     * - parv[0] = sender prefix
619     * - parv[1] = user\@host mask
620     * - parv[2] = reason
621 db 937 */
622     static void
623 db 940 mo_gungline(struct Client *client_p, struct Client *source_p,
624 michael 957 int parc, char *parv[])
625 db 937 {
626     char *user = NULL;
627 michael 1008 char *host = NULL;
628     char *reason = NULL;
629 db 937
630     if (!ConfigFileEntry.glines)
631     {
632 michael 957 sendto_one(source_p, ":%s NOTICE %s :GUNGLINE disabled",
633 db 937 me.name, source_p->name);
634     return;
635     }
636    
637     if (!IsOperGline(source_p))
638     {
639     sendto_one(source_p, form_str(ERR_NOPRIVS),
640 michael 957 me.name, source_p->name, "gungline");
641 db 937 return;
642     }
643    
644 michael 957 if (parse_aline("GUNGLINE", source_p, parc, parv, 0, &user,
645     &host, NULL, NULL, &reason) < 0)
646 db 937 return;
647    
648 michael 1006 do_sungline(source_p, user, host, reason, 1);
649 db 937 }

Properties

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