ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/branches/8.2.x/modules/core/m_sjoin.c
Revision: 1474
Committed: Sun Jul 22 14:44:07 2012 UTC (11 years, 8 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-8/modules/core/m_sjoin.c
File size: 20986 byte(s)
Log Message:
- removed &localchannels

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

Properties

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