ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/core/m_sjoin.c
Revision: 1230
Committed: Thu Sep 22 19:41:19 2011 UTC (13 years, 11 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-8/modules/core/m_sjoin.c
File size: 21163 byte(s)
Log Message:
- cleanup module loader. Make module api more flexible

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

Properties

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