ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/core/m_sjoin.c
Revision: 1121
Committed: Sun Jan 9 11:03:03 2011 UTC (14 years, 7 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-7.3/modules/core/m_sjoin.c
File size: 21114 byte(s)
Log Message:
- removed all instances of STATIC_MODULES since we don't have
  static modules anymore
- removed m_mkpasswd module from contrib

File Contents

# User Rev Content
1 adx 30 /*
2     * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3     * m_sjoin.c: Joins a user to a channel.
4     *
5     * Copyright (C) 2002 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 michael 1011 #include "list.h"
27 adx 30 #include "handlers.h"
28     #include "channel.h"
29     #include "channel_mode.h"
30     #include "client.h"
31     #include "hash.h"
32     #include "irc_string.h"
33     #include "sprintf_irc.h"
34     #include "ircd.h"
35     #include "numeric.h"
36     #include "send.h"
37     #include "common.h"
38     #include "msg.h"
39     #include "parse.h"
40     #include "modules.h"
41     #include "s_serv.h"
42     #include "s_conf.h"
43    
44     static void ms_sjoin(struct Client *, struct Client *, int, char *[]);
45    
46     struct Message sjoin_msgtab = {
47     "SJOIN", 0, 0, 0, 0, MFLG_SLOW, 0,
48     {m_unregistered, m_ignore, ms_sjoin, m_ignore, m_ignore, m_ignore}
49     };
50    
51     void
52     _modinit(void)
53     {
54     mod_add_cmd(&sjoin_msgtab);
55     }
56    
57     void
58     _moddeinit(void)
59     {
60     mod_del_cmd(&sjoin_msgtab);
61     }
62    
63 knight 31 const char *_version = "$Revision$";
64 adx 30
65     static char modebuf[MODEBUFLEN];
66     static char parabuf[MODEBUFLEN];
67     static char sendbuf[MODEBUFLEN];
68     static const char *para[MAXMODEPARAMS];
69     static char *mbuf;
70     static int pargs;
71    
72     static void set_final_mode(struct Mode *, struct Mode *);
73     static void remove_our_modes(struct Channel *, struct Client *);
74     static void remove_a_mode(struct Channel *, struct Client *, int, char);
75     static void remove_ban_list(struct Channel *, struct Client *, dlink_list *, char, int);
76    
77 michael 885
78 adx 30 /* ms_sjoin()
79     *
80     * parv[0] - sender
81     * parv[1] - TS
82     * parv[2] - channel
83     * parv[3] - modes + n arguments (key and/or limit)
84     * parv[4+n] - flags+nick list (all in one parameter)
85     *
86     * process a SJOIN, taking the TS's into account to either ignore the
87     * incoming modes or undo the existing ones or merge them, and JOIN
88     * all the specified users while sending JOIN/MODEs to local clients
89     */
90     static void
91     ms_sjoin(struct Client *client_p, struct Client *source_p,
92     int parc, char *parv[])
93     {
94 michael 632 struct Channel *chptr = NULL;
95     struct Client *target_p = NULL;
96 adx 30 time_t newts;
97     time_t oldts;
98     time_t tstosend;
99 michael 632 struct Mode mode, *oldmode;
100 adx 30 int args = 0;
101     char keep_our_modes = YES;
102     char keep_new_modes = YES;
103     char have_many_nicks = NO;
104     int lcount;
105     char nick_prefix[4];
106     char uid_prefix[4];
107     char *np, *up;
108     int len_nick = 0;
109     int len_uid = 0;
110 michael 632 int isnew = 0;
111 adx 30 int buflen = 0;
112     int slen;
113     unsigned int fl;
114     char *s;
115     char *sptr;
116     char nick_buf[IRCD_BUFSIZE]; /* buffer for modes and prefix */
117     char uid_buf[IRCD_BUFSIZE]; /* buffer for modes/prefixes for CAP_TS6 servers */
118     char *nick_ptr, *uid_ptr; /* pointers used for making the two mode/prefix buffers */
119     char *p; /* pointer used making sjbuf */
120     dlink_node *m;
121     const char *servername = (ConfigServerHide.hide_servers || IsHidden(source_p)) ?
122     me.name : source_p->name;
123    
124     if (IsClient(source_p) || parc < 5)
125     return;
126    
127     /* SJOIN's for local channels can't happen. */
128     if (*parv[2] != '#')
129     return;
130    
131 michael 632 if (!check_channel_name(parv[2], 0))
132     {
133     sendto_realops_flags(UMODE_DEBUG, L_ALL,
134     "*** Too long or invalid channel name from %s: %s",
135     client_p->name, parv[2]);
136 adx 30 return;
137 michael 632 }
138 adx 30
139     modebuf[0] = '\0';
140     mbuf = modebuf;
141     pargs = 0;
142     newts = atol(parv[1]);
143    
144     mode.mode = 0;
145     mode.limit = 0;
146     mode.key[0] = '\0';
147    
148 michael 632 for (s = parv[3]; *s; ++s)
149 adx 30 {
150 michael 632 switch (*s)
151 adx 30 {
152     case 't':
153     mode.mode |= MODE_TOPICLIMIT;
154     break;
155     case 'n':
156     mode.mode |= MODE_NOPRIVMSGS;
157     break;
158     case 's':
159     mode.mode |= MODE_SECRET;
160     break;
161     case 'm':
162     mode.mode |= MODE_MODERATED;
163     break;
164     case 'i':
165     mode.mode |= MODE_INVITEONLY;
166     break;
167     case 'p':
168     mode.mode |= MODE_PRIVATE;
169     break;
170     case 'k':
171     strlcpy(mode.key, parv[4 + args], sizeof(mode.key));
172     args++;
173 michael 632
174     if (parc < 5 + args)
175 adx 30 return;
176     break;
177     case 'l':
178     mode.limit = atoi(parv[4 + args]);
179     args++;
180 michael 632
181     if (parc < 5 + args)
182 adx 30 return;
183     break;
184     }
185     }
186    
187 michael 632 if ((chptr = hash_find_channel(parv[2])) == NULL)
188     {
189     isnew = 1;
190     chptr = make_channel(parv[2]);
191     }
192    
193 adx 30 parabuf[0] = '\0';
194 michael 632 oldts = chptr->channelts;
195 adx 30 oldmode = &chptr->mode;
196    
197     if (ConfigFileEntry.ignore_bogus_ts)
198     {
199     if (newts < 800000000)
200     {
201     sendto_realops_flags(UMODE_DEBUG, L_ALL,
202     "*** Bogus TS %lu on %s ignored from %s",
203     (unsigned long)newts, chptr->chname,
204     client_p->name);
205    
206     newts = (oldts == 0) ? 0 : 800000000;
207     }
208     }
209     else
210     {
211     if (!newts && !isnew && oldts)
212     {
213     sendto_channel_local(ALL_MEMBERS, NO, chptr,
214     ":%s NOTICE %s :*** Notice -- TS for %s changed from %lu to 0",
215     me.name, chptr->chname, chptr->chname, (unsigned long)oldts);
216     sendto_realops_flags(UMODE_ALL, L_ALL,
217     "Server %s changing TS on %s from %lu to 0",
218     source_p->name, chptr->chname, (unsigned long)oldts);
219     }
220     }
221    
222     if (isnew)
223     chptr->channelts = tstosend = newts;
224     else if (newts == 0 || oldts == 0)
225     chptr->channelts = tstosend = 0;
226     else if (newts == oldts)
227     tstosend = oldts;
228     else if (newts < oldts)
229     {
230     keep_our_modes = NO;
231     chptr->channelts = tstosend = newts;
232     }
233     else
234     {
235     keep_new_modes = NO;
236     tstosend = oldts;
237     }
238    
239     if (!keep_new_modes)
240     mode = *oldmode;
241     else if (keep_our_modes)
242     {
243     mode.mode |= oldmode->mode;
244     if (oldmode->limit > mode.limit)
245     mode.limit = oldmode->limit;
246     if (strcmp(mode.key, oldmode->key) < 0)
247     strcpy(mode.key, oldmode->key);
248     }
249     set_final_mode(&mode, oldmode);
250     chptr->mode = mode;
251    
252     /* Lost the TS, other side wins, so remove modes on this side */
253     if (!keep_our_modes)
254     {
255     remove_our_modes(chptr, source_p);
256 michael 873
257     if (chptr->topic)
258     {
259     set_channel_topic(chptr, NULL, NULL, 0);
260     chptr->topic_time = 0;
261     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s TOPIC %s :",
262     (IsHidden(source_p) ||
263     ConfigServerHide.hide_servers) ?
264     me.name : source_p->name, chptr->chname);
265     }
266    
267 adx 30 sendto_channel_local(ALL_MEMBERS, NO, chptr,
268     ":%s NOTICE %s :*** Notice -- TS for %s changed from %lu to %lu",
269     me.name, chptr->chname, chptr->chname,
270     (unsigned long)oldts, (unsigned long)newts);
271     }
272    
273     if (*modebuf != '\0')
274     {
275     /* This _SHOULD_ be to ALL_MEMBERS
276     * It contains only +imnpstlk, etc */
277     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s MODE %s %s %s",
278     servername, chptr->chname, modebuf, parabuf);
279     }
280    
281     if (parv[3][0] != '0' && keep_new_modes)
282     {
283     channel_modes(chptr, source_p, modebuf, parabuf);
284     }
285     else
286     {
287     modebuf[0] = '0';
288     modebuf[1] = '\0';
289     }
290    
291     buflen = ircsprintf(nick_buf, ":%s SJOIN %lu %s %s %s:",
292     source_p->name, (unsigned long)tstosend,
293     chptr->chname, modebuf, parabuf);
294     nick_ptr = nick_buf + buflen;
295    
296     buflen = ircsprintf(uid_buf, ":%s SJOIN %lu %s %s %s:",
297     ID(source_p), (unsigned long)tstosend,
298     chptr->chname, modebuf, parabuf);
299     uid_ptr = uid_buf + buflen;
300    
301     /* check we can fit a nick on the end, as well as \r\n and a prefix "
302     * @%+", and a space.
303     */
304     if (buflen >= (IRCD_BUFSIZE - IRCD_MAX(NICKLEN, IDLEN) - 2 - 3 - 1))
305     {
306     sendto_realops_flags(UMODE_ALL, L_ALL,
307     "Long SJOIN from server: %s(via %s) (ignored)",
308     source_p->name, client_p->name);
309     return;
310     }
311    
312     mbuf = modebuf;
313     sendbuf[0] = '\0';
314     pargs = 0;
315    
316     *mbuf++ = '+';
317    
318     s = parv[args + 4];
319     while (*s == ' ')
320     s++;
321     if ((p = strchr(s, ' ')) != NULL)
322     {
323     *p++ = '\0';
324     while (*p == ' ')
325     p++;
326     have_many_nicks = *p;
327     }
328    
329     while (*s)
330     {
331     int valid_mode = YES;
332     fl = 0;
333    
334     do
335     {
336     switch (*s)
337     {
338     case '@':
339     fl |= CHFL_CHANOP;
340     s++;
341     break;
342     #ifdef HALFOPS
343     case '%':
344     fl |= CHFL_HALFOP;
345     s++;
346     break;
347     #endif
348     case '+':
349     fl |= CHFL_VOICE;
350     s++;
351     break;
352     default:
353     valid_mode = NO;
354     break;
355     }
356     } while (valid_mode);
357    
358     target_p = find_chasing(client_p, source_p, s, NULL);
359    
360     /*
361     * if the client doesnt exist, or if its fake direction/server, skip.
362     * we cannot send ERR_NOSUCHNICK here because if its a UID, we cannot
363     * lookup the nick, and its better to never send the numeric than only
364     * sometimes.
365     */
366     if (target_p == NULL ||
367     target_p->from != client_p ||
368     !IsClient(target_p))
369     {
370     goto nextnick;
371     }
372    
373     len_nick = strlen(target_p->name);
374     len_uid = strlen(ID(target_p));
375    
376     np = nick_prefix;
377     up = uid_prefix;
378    
379     if (keep_new_modes)
380     {
381     if (fl & CHFL_CHANOP)
382     {
383     *np++ = '@';
384     *up++ = '@';
385     len_nick++;
386     len_uid++;
387     }
388     #ifdef HALFOPS
389     if (fl & CHFL_HALFOP)
390     {
391     *np++ = '%';
392     *up++ = '%';
393     len_nick++;
394     len_uid++;
395     }
396     #endif
397     if (fl & CHFL_VOICE)
398     {
399     *np++ = '+';
400     *up++ = '+';
401     len_nick++;
402     len_uid++;
403     }
404     }
405     else
406     {
407     if (fl & (CHFL_CHANOP|CHFL_HALFOP))
408     fl = CHFL_DEOPPED;
409     else
410     fl = 0;
411     }
412     *np = *up = '\0';
413    
414     if ((nick_ptr - nick_buf + len_nick) > (IRCD_BUFSIZE - 2))
415     {
416 michael 885 sendto_server(client_p, chptr, 0, CAP_TS6, "%s", nick_buf);
417 adx 30
418     buflen = ircsprintf(nick_buf, ":%s SJOIN %lu %s %s %s:",
419     source_p->name, (unsigned long)tstosend,
420     chptr->chname, modebuf, parabuf);
421     nick_ptr = nick_buf + buflen;
422     }
423 michael 885
424 adx 30 nick_ptr += ircsprintf(nick_ptr, "%s%s ", nick_prefix, target_p->name);
425    
426     if ((uid_ptr - uid_buf + len_uid) > (IRCD_BUFSIZE - 2))
427     {
428 michael 885 sendto_server(client_p, chptr, CAP_TS6, 0, "%s", uid_buf);
429 adx 30
430     buflen = ircsprintf(uid_buf, ":%s SJOIN %lu %s %s %s:",
431     ID(source_p), (unsigned long)tstosend,
432     chptr->chname, modebuf, parabuf);
433     uid_ptr = uid_buf + buflen;
434     }
435    
436     uid_ptr += ircsprintf(uid_ptr, "%s%s ", uid_prefix, ID(target_p));
437    
438     if (!IsMember(target_p, chptr))
439     {
440     add_user_to_channel(chptr, target_p, fl, !have_many_nicks);
441     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s!%s@%s JOIN :%s",
442     target_p->name, target_p->username,
443     target_p->host, chptr->chname);
444     }
445    
446     if (fl & CHFL_CHANOP)
447     {
448     *mbuf++ = 'o';
449     para[pargs++] = target_p->name;
450    
451     if (pargs >= MAXMODEPARAMS)
452     {
453     /*
454     * Ok, the code is now going to "walk" through
455     * sendbuf, filling in para strings. So, I will use sptr
456     * to point into the sendbuf.
457     * Notice, that ircsprintf() returns the number of chars
458     * successfully inserted into string.
459     * - Dianora
460     */
461    
462     sptr = sendbuf;
463     *mbuf = '\0';
464     for(lcount = 0; lcount < MAXMODEPARAMS; lcount++)
465     {
466     slen = ircsprintf(sptr, " %s", para[lcount]); /* see? */
467     sptr += slen; /* ready for next */
468     }
469     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s MODE %s %s%s",
470     servername, chptr->chname, modebuf, sendbuf);
471     mbuf = modebuf;
472     *mbuf++ = '+';
473    
474     sendbuf[0] = '\0';
475     pargs = 0;
476     }
477     }
478     #ifdef HALFOPS
479     if (fl & CHFL_HALFOP)
480     {
481     *mbuf++ = 'h';
482     para[pargs++] = target_p->name;
483    
484     if (pargs >= MAXMODEPARAMS)
485     {
486     sptr = sendbuf;
487     *mbuf = '\0';
488     for(lcount = 0; lcount < MAXMODEPARAMS; lcount++)
489     {
490     slen = ircsprintf(sptr, " %s", para[lcount]);
491     sptr += slen;
492     }
493     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s MODE %s %s%s",
494     servername, chptr->chname, modebuf, sendbuf);
495    
496     mbuf = modebuf;
497     *mbuf++ = '+';
498    
499     sendbuf[0] = '\0';
500     pargs = 0;
501     }
502     }
503     #endif
504     if (fl & CHFL_VOICE)
505     {
506     *mbuf++ = 'v';
507     para[pargs++] = target_p->name;
508    
509     if (pargs >= MAXMODEPARAMS)
510     {
511     sptr = sendbuf;
512     *mbuf = '\0';
513     for (lcount = 0; lcount < MAXMODEPARAMS; lcount++)
514     {
515     slen = ircsprintf(sptr, " %s", para[lcount]);
516     sptr += slen;
517     }
518     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s MODE %s %s%s",
519     servername, chptr->chname, modebuf, sendbuf);
520    
521     mbuf = modebuf;
522     *mbuf++ = '+';
523    
524     sendbuf[0] = '\0';
525     pargs = 0;
526     }
527     }
528    
529     nextnick:
530     if ((s = p) == NULL)
531     break;
532     while (*s == ' ')
533     s++;
534     if ((p = strchr(s, ' ')) != NULL)
535     {
536     *p++ = 0;
537     while (*p == ' ')
538     p++;
539     }
540     }
541    
542     *mbuf = '\0';
543     *(nick_ptr - 1) = '\0';
544     *(uid_ptr - 1) = '\0';
545    
546     /*
547     * checking for lcount < MAXMODEPARAMS at this time is wrong
548     * since the code has already verified above that pargs < MAXMODEPARAMS
549     * checking for para[lcount] != '\0' is also wrong, since
550     * there is no place where para[lcount] is set!
551     * - Dianora
552     */
553    
554     if (pargs != 0)
555     {
556     sptr = sendbuf;
557    
558     for (lcount = 0; lcount < pargs; lcount++)
559     {
560     slen = ircsprintf(sptr, " %s", para[lcount]);
561     sptr += slen;
562     }
563    
564     sendto_channel_local(ALL_MEMBERS, NO, chptr, ":%s MODE %s %s%s",
565     servername, chptr->chname, modebuf, sendbuf);
566     }
567    
568     /* If this happens, its the result of a malformed SJOIN
569     * a remnant from the old persistent channel code. *sigh*
570     * Or it could be the result of a client just leaving
571     * and leaving us with a channel formed just as the client parts.
572     * - Dianora
573     */
574    
575     if ((dlink_list_length(&chptr->members) == 0) && isnew)
576     {
577     destroy_channel(chptr);
578     return;
579     }
580    
581     if (parv[4 + args][0] == '\0')
582     return;
583    
584     /* relay the SJOIN to other servers */
585     DLINK_FOREACH(m, serv_list.head)
586     {
587     target_p = m->data;
588    
589     if (target_p == client_p)
590     continue;
591    
592     if (IsCapable(target_p, CAP_TS6))
593     sendto_one(target_p, "%s", uid_buf);
594     else
595     sendto_one(target_p, "%s", nick_buf);
596     }
597    
598     if (HasID(source_p) && !keep_our_modes)
599     {
600     if (dlink_list_length(&chptr->banlist) > 0)
601     remove_ban_list(chptr, client_p, &chptr->banlist,
602     'b', NOCAPS);
603    
604     if (dlink_list_length(&chptr->exceptlist) > 0)
605     remove_ban_list(chptr, client_p, &chptr->exceptlist,
606     'e', CAP_EX);
607    
608     if (dlink_list_length(&chptr->invexlist) > 0)
609     remove_ban_list(chptr, client_p, &chptr->invexlist,
610     'I', CAP_IE);
611     clear_ban_cache(chptr);
612     }
613     }
614    
615     /* set_final_mode
616     *
617     * inputs - channel mode
618     * - old channel mode
619     * output - NONE
620     * side effects - walk through all the channel modes turning off modes
621     * that were on in oldmode but aren't on in mode.
622     * Then walk through turning on modes that are on in mode
623     * but were not set in oldmode.
624     */
625    
626     static const struct mode_letter
627     {
628     unsigned int mode;
629     unsigned char letter;
630     } flags[] = {
631     { MODE_NOPRIVMSGS, 'n' },
632     { MODE_TOPICLIMIT, 't' },
633     { MODE_SECRET, 's' },
634     { MODE_MODERATED, 'm' },
635     { MODE_INVITEONLY, 'i' },
636     { MODE_PRIVATE, 'p' },
637     { 0, '\0' }
638     };
639    
640     static void
641     set_final_mode(struct Mode *mode, struct Mode *oldmode)
642     {
643     char *pbuf = parabuf;
644     int len;
645     int i;
646    
647     *mbuf++ = '-';
648    
649     for (i = 0; flags[i].letter; i++)
650     {
651     if ((flags[i].mode & oldmode->mode) &&
652     !(flags[i].mode & mode->mode))
653     *mbuf++ = flags[i].letter;
654     }
655    
656     if (oldmode->limit != 0 && mode->limit == 0)
657     *mbuf++ = 'l';
658    
659     if (oldmode->key[0] && !mode->key[0])
660     {
661     *mbuf++ = 'k';
662     len = ircsprintf(pbuf, "%s ", oldmode->key);
663     pbuf += len;
664     pargs++;
665     }
666    
667     if (*(mbuf-1) == '-')
668     *(mbuf-1) = '+';
669     else
670     *mbuf++ = '+';
671    
672     for (i = 0; flags[i].letter; i++)
673     {
674     if ((flags[i].mode & mode->mode) &&
675     !(flags[i].mode & oldmode->mode))
676     *mbuf++ = flags[i].letter;
677     }
678    
679     if (mode->limit != 0 && oldmode->limit != mode->limit)
680     {
681     *mbuf++ = 'l';
682     len = ircsprintf(pbuf, "%d ", mode->limit);
683     pbuf += len;
684     pargs++;
685     }
686    
687     if (mode->key[0] && strcmp(oldmode->key, mode->key))
688     {
689     *mbuf++ = 'k';
690     len = ircsprintf(pbuf, "%s ", mode->key);
691     pbuf += len;
692     pargs++;
693     }
694     if (*(mbuf-1) == '+')
695     *(mbuf-1) = '\0';
696     else
697     *mbuf = '\0';
698     }
699    
700     /* remove_our_modes()
701     *
702     * inputs - pointer to channel to remove modes from
703     * - client pointer
704     * output - NONE
705     * side effects - Go through the local members, remove all their
706     * chanop modes etc., this side lost the TS.
707     */
708     static void
709     remove_our_modes(struct Channel *chptr, struct Client *source_p)
710     {
711     remove_a_mode(chptr, source_p, CHFL_CHANOP, 'o');
712     #ifdef HALFOPS
713     remove_a_mode(chptr, source_p, CHFL_HALFOP, 'h');
714     #endif
715     remove_a_mode(chptr, source_p, CHFL_VOICE, 'v');
716     }
717    
718     /* remove_a_mode()
719     *
720     * inputs - pointer to channel
721     * - server or client removing the mode
722     * - mask o/h/v mask to be removed
723     * - flag o/h/v to be removed
724     * output - NONE
725     * side effects - remove ONE mode from all members of a channel
726     */
727     static void
728     remove_a_mode(struct Channel *chptr, struct Client *source_p,
729     int mask, char flag)
730     {
731     dlink_node *ptr;
732     struct Membership *ms;
733     char lmodebuf[MODEBUFLEN];
734     char *sp=sendbuf;
735     const char *lpara[MAXMODEPARAMS];
736     int count = 0;
737     int i;
738     int l;
739    
740     mbuf = lmodebuf;
741     *mbuf++ = '-';
742     *sp = '\0';
743    
744     DLINK_FOREACH(ptr, chptr->members.head)
745     {
746     ms = ptr->data;
747    
748     if ((ms->flags & mask) == 0)
749     continue;
750    
751     ms->flags &= ~mask;
752    
753     lpara[count++] = ms->client_p->name;
754    
755     *mbuf++ = flag;
756    
757     if (count >= MAXMODEPARAMS)
758     {
759     for(i = 0; i < MAXMODEPARAMS; i++)
760     {
761     l = ircsprintf(sp, " %s", lpara[i]);
762     sp += l;
763     }
764    
765     *mbuf = '\0';
766     sendto_channel_local(ALL_MEMBERS, NO, chptr,
767     ":%s MODE %s %s%s",
768     (IsHidden(source_p) ||
769     ConfigServerHide.hide_servers) ?
770     me.name : source_p->name,
771     chptr->chname, lmodebuf, sendbuf);
772     mbuf = lmodebuf;
773     *mbuf++ = '-';
774     count = 0;
775     sp = sendbuf;
776     *sp = '\0';
777     }
778     }
779    
780     if (count != 0)
781     {
782     *mbuf = '\0';
783     for(i = 0; i < count; i++)
784     {
785     l = ircsprintf(sp, " %s", lpara[i]);
786     sp += l;
787     }
788     sendto_channel_local(ALL_MEMBERS, NO, chptr,
789     ":%s MODE %s %s%s",
790     (IsHidden(source_p) || ConfigServerHide.hide_servers) ?
791     me.name : source_p->name,
792     chptr->chname, lmodebuf, sendbuf);
793     }
794     }
795    
796     /* remove_ban_list()
797     *
798     * inputs - channel, source, list to remove, char of mode, caps required
799     * outputs - none
800     * side effects - given ban list is removed, modes are sent to local clients and
801     * non-ts6 servers linked through another uplink other than source_p
802     */
803     static void
804     remove_ban_list(struct Channel *chptr, struct Client *source_p,
805     dlink_list *list, char c, int cap)
806     {
807     char lmodebuf[MODEBUFLEN];
808     char lparabuf[IRCD_BUFSIZE];
809     struct Ban *banptr = NULL;
810     dlink_node *ptr = NULL;
811     dlink_node *next_ptr = NULL;
812     char *pbuf = NULL;
813     int count = 0;
814     int cur_len, mlen, plen;
815    
816     pbuf = lparabuf;
817    
818     cur_len = mlen = ircsprintf(lmodebuf, ":%s MODE %s -",
819     source_p->name, chptr->chname);
820     mbuf = lmodebuf + mlen;
821    
822     DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
823     {
824     banptr = ptr->data;
825    
826     plen = banptr->len + 4; /* another +b and "!@ " */
827     if (count >= MAXMODEPARAMS ||
828     (cur_len + 1 /* space between */ + (plen - 1)) > IRCD_BUFSIZE - 2)
829     {
830     /* NUL-terminate and remove trailing space */
831     *mbuf = *(pbuf - 1) = '\0';
832     sendto_channel_local(ALL_MEMBERS, NO, chptr, "%s %s",
833     lmodebuf, lparabuf);
834 michael 885 sendto_server(source_p, chptr, cap, CAP_TS6,
835 adx 30 "%s %s", lmodebuf, lparabuf);
836    
837     cur_len = mlen;
838     mbuf = lmodebuf + mlen;
839     pbuf = lparabuf;
840     count = 0;
841     }
842    
843     *mbuf++ = c;
844     cur_len += plen;
845     pbuf += ircsprintf(pbuf, "%s!%s@%s ", banptr->name, banptr->username,
846     banptr->host);
847     ++count;
848    
849     remove_ban(banptr, list);
850     }
851    
852     *mbuf = *(pbuf - 1) = '\0';
853     sendto_channel_local(ALL_MEMBERS, NO, chptr, "%s %s", lmodebuf, lparabuf);
854 michael 885 sendto_server(source_p, chptr, cap, CAP_TS6,
855 adx 30 "%s %s", lmodebuf, lparabuf);
856     }

Properties

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