ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/core/m_sjoin.c
Revision: 1309
Committed: Sun Mar 25 11:24:18 2012 UTC (13 years, 5 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-8/modules/core/m_sjoin.c
File size: 21099 byte(s)
Log Message:
- renaming files:

  ircd_parser.y -> conf_parser.y
  ircd_lexer.l  -> conf_lexer.l
  s_conf.c      -> conf.c
  s_conf.h      -> conf.h
  s_log.c       -> log.c
  s_log.h       -> log.h

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

Properties

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