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: 3751
Committed: Sun Jun 1 17:57:48 2014 UTC (9 years, 10 months ago) by michael
Content type: text/x-csrc
File size: 20158 byte(s)
Log Message:
- m_sjoin.c: style corrections

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

Properties

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