ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/modules/core/m_sjoin.c
Revision: 3156
Committed: Fri Mar 14 19:57:38 2014 UTC (11 years, 5 months ago) by michael
Content type: text/x-csrc
File size: 20272 byte(s)
Log Message:
- Removed client_p pointers from everywhere

File Contents

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

Properties

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