]> jfr.im git - irc/rqf/shadowircd.git/blob - modules/core/m_join.c
.cvsignore files removed, SVN-Access replaced by Mercurial-Access
[irc/rqf/shadowircd.git] / modules / core / m_join.c
1 /*
2 * ircd-ratbox: A slightly useful ircd.
3 * m_join.c: Joins a channel.
4 *
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 * USA
23 *
24 * $Id: m_join.c 3494 2007-05-27 13:07:27Z jilles $
25 */
26
27 #include "stdinc.h"
28 #include "channel.h"
29 #include "client.h"
30 #include "common.h"
31 #include "hash.h"
32 #include "irc_string.h"
33 #include "ircd.h"
34 #include "numeric.h"
35 #include "send.h"
36 #include "s_serv.h"
37 #include "s_conf.h"
38 #include "s_newconf.h"
39 #include "msg.h"
40 #include "parse.h"
41 #include "modules.h"
42 #include "sprintf_irc.h"
43 #include "packet.h"
44
45 static int m_join(struct Client *, struct Client *, int, const char **);
46 static int ms_join(struct Client *, struct Client *, int, const char **);
47 static int ms_sjoin(struct Client *, struct Client *, int, const char **);
48
49 static int h_can_create_channel;
50 static int h_channel_join;
51
52 struct Message join_msgtab = {
53 "JOIN", 0, 0, 0, MFLG_SLOW,
54 {mg_unreg, {m_join, 2}, {ms_join, 2}, mg_ignore, mg_ignore, {m_join, 2}}
55 };
56
57 struct Message sjoin_msgtab = {
58 "SJOIN", 0, 0, 0, MFLG_SLOW,
59 {mg_unreg, mg_ignore, mg_ignore, {ms_sjoin, 0}, mg_ignore, mg_ignore}
60 };
61
62 mapi_clist_av1 join_clist[] = { &join_msgtab, &sjoin_msgtab, NULL };
63
64 mapi_hlist_av1 join_hlist[] = {
65 { "can_create_channel", &h_can_create_channel },
66 { "channel_join", &h_channel_join },
67 { NULL, NULL },
68 };
69
70 DECLARE_MODULE_AV1(join, NULL, NULL, join_clist, join_hlist, NULL, "$Revision: 3494 $");
71
72 static void do_join_0(struct Client *client_p, struct Client *source_p);
73 static int check_channel_name_loc(struct Client *source_p, const char *name);
74
75 static void set_final_mode(struct Mode *mode, struct Mode *oldmode);
76 static void remove_our_modes(struct Channel *chptr, struct Client *source_p);
77
78 static void remove_ban_list(struct Channel *chptr, struct Client *source_p,
79 rb_dlink_list * list, char c, int cap, int mems);
80
81 static char modebuf[MODEBUFLEN];
82 static char parabuf[MODEBUFLEN];
83 static const char *para[MAXMODEPARAMS];
84 static char *mbuf;
85 static int pargs;
86
87 /* Check what we will forward to, without sending any notices to the user
88 * -- jilles
89 */
90 static struct Channel *
91 check_forward(struct Client *source_p, struct Channel *chptr,
92 char *key)
93 {
94 int depth = 0, i;
95
96 /* User is +Q */
97 if (IsNoForward(source_p))
98 return NULL;
99
100 while (depth < 16)
101 {
102 chptr = find_channel(chptr->mode.forward);
103 /* Can only forward to existing channels */
104 if (chptr == NULL)
105 return NULL;
106 /* Already on there, show original error message */
107 if (IsMember(source_p, chptr))
108 return NULL;
109 /* Juped. Sending a warning notice would be unfair */
110 if (hash_find_resv(chptr->chname))
111 return NULL;
112 /* Don't forward to +Q channel */
113 if (chptr->mode.mode & MODE_DISFORWARD)
114 return NULL;
115 i = can_join(source_p, chptr, key);
116 if (i == 0)
117 return chptr;
118 if (i != ERR_INVITEONLYCHAN && i != ERR_NEEDREGGEDNICK && i != ERR_THROTTLE && i != ERR_CHANNELISFULL)
119 return NULL;
120 depth++;
121 }
122
123 return NULL;
124 }
125
126 /*
127 * m_join
128 * parv[0] = sender prefix
129 * parv[1] = channel
130 * parv[2] = channel password (key)
131 */
132 static int
133 m_join(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
134 {
135 static char jbuf[BUFSIZE];
136 struct Channel *chptr = NULL;
137 struct ConfItem *aconf;
138 char *name;
139 char *key = NULL;
140 int i, flags = 0;
141 char *p = NULL, *p2 = NULL;
142 char *chanlist;
143 char *mykey;
144 int successful_join_count = 0; /* Number of channels successfully joined */
145
146 jbuf[0] = '\0';
147
148 /* rebuild the list of channels theyre supposed to be joining.
149 * this code has a side effect of losing keys, but..
150 */
151 chanlist = LOCAL_COPY(parv[1]);
152 for(name = strtoken(&p, chanlist, ","); name; name = strtoken(&p, NULL, ","))
153 {
154 /* check the length and name of channel is ok */
155 if(!check_channel_name_loc(source_p, name) || (strlen(name) > LOC_CHANNELLEN))
156 {
157 sendto_one_numeric(source_p, ERR_BADCHANNAME,
158 form_str(ERR_BADCHANNAME), (unsigned char *) name);
159 continue;
160 }
161
162 /* join 0 parts all channels */
163 if(*name == '0' && (name[1] == ',' || name[1] == '\0') && name == chanlist)
164 {
165 (void) strcpy(jbuf, "0");
166 continue;
167 }
168
169 /* check it begins with # or &, and local chans are disabled */
170 else if(!IsChannelName(name))
171 {
172 sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
173 form_str(ERR_NOSUCHCHANNEL), name);
174 continue;
175 }
176
177 /* see if its resv'd */
178 if(!IsExemptResv(source_p) && (aconf = hash_find_resv(name)))
179 {
180 sendto_one_numeric(source_p, ERR_BADCHANNAME,
181 form_str(ERR_BADCHANNAME), name);
182
183 /* dont warn for opers */
184 if(!IsExemptJupe(source_p) && !IsOper(source_p))
185 sendto_realops_snomask(SNO_SPY, L_NETWIDE,
186 "User %s (%s@%s) is attempting to join locally juped channel %s (%s)",
187 source_p->name, source_p->username,
188 source_p->orighost, name, aconf->passwd);
189 /* dont update tracking for jupe exempt users, these
190 * are likely to be spamtrap leaves
191 */
192 else if(IsExemptJupe(source_p))
193 aconf->port--;
194
195 continue;
196 }
197
198 if(splitmode && !IsOper(source_p) && (*name != '&') &&
199 ConfigChannel.no_join_on_split)
200 {
201 sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
202 me.name, source_p->name, name);
203 continue;
204 }
205
206 if(*jbuf)
207 (void) strcat(jbuf, ",");
208 (void) strlcat(jbuf, name, sizeof(jbuf));
209 }
210
211 if(parc > 2)
212 {
213 mykey = LOCAL_COPY(parv[2]);
214 key = strtoken(&p2, mykey, ",");
215 }
216
217 for(name = strtoken(&p, jbuf, ","); name;
218 key = (key) ? strtoken(&p2, NULL, ",") : NULL, name = strtoken(&p, NULL, ","))
219 {
220 hook_data_channel_activity hook_info;
221
222 /* JOIN 0 simply parts all channels the user is in */
223 if(*name == '0' && !atoi(name))
224 {
225 if(source_p->user->channel.head == NULL)
226 continue;
227
228 do_join_0(&me, source_p);
229 continue;
230 }
231
232 /* look for the channel */
233 if((chptr = find_channel(name)) != NULL)
234 {
235 if(IsMember(source_p, chptr))
236 continue;
237
238 flags = 0;
239 }
240 else
241 {
242 hook_data_client_approval moduledata;
243
244 moduledata.client = source_p;
245 moduledata.approved = 0;
246
247 call_hook(h_can_create_channel, &moduledata);
248
249 if(moduledata.approved != 0)
250 {
251 sendto_one(source_p, form_str(moduledata.approved),
252 me.name, source_p->name, name);
253 continue;
254 }
255
256 if(splitmode && !IsOper(source_p) && (*name != '&') &&
257 ConfigChannel.no_create_on_split)
258 {
259 sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
260 me.name, source_p->name, name);
261 continue;
262 }
263
264 flags = CHFL_CHANOP;
265 }
266
267 if((rb_dlink_list_length(&source_p->user->channel) >=
268 (unsigned long) ConfigChannel.max_chans_per_user) &&
269 (!IsOper(source_p) ||
270 (rb_dlink_list_length(&source_p->user->channel) >=
271 (unsigned long) ConfigChannel.max_chans_per_user * 3)))
272 {
273 sendto_one(source_p, form_str(ERR_TOOMANYCHANNELS),
274 me.name, source_p->name, name);
275 if(successful_join_count)
276 source_p->localClient->last_join_time = rb_current_time();
277 return 0;
278 }
279
280 if(flags == 0) /* if channel doesn't exist, don't penalize */
281 successful_join_count++;
282
283 if(chptr == NULL) /* If I already have a chptr, no point doing this */
284 {
285 chptr = get_or_create_channel(source_p, name, NULL);
286
287 if(chptr == NULL)
288 {
289 sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
290 me.name, source_p->name, name);
291 if(successful_join_count > 0)
292 successful_join_count--;
293 continue;
294 }
295 }
296
297 if(!IsOper(source_p) && !IsExemptSpambot(source_p))
298 check_spambot_warning(source_p, name);
299
300 /* can_join checks for +i key, bans etc */
301 if((i = can_join(source_p, chptr, key)))
302 {
303 if ((i != ERR_NEEDREGGEDNICK && i != ERR_THROTTLE && i != ERR_INVITEONLYCHAN && i != ERR_CHANNELISFULL) ||
304 (!ConfigChannel.use_forward || (chptr = check_forward(source_p, chptr, key)) == NULL))
305 {
306 sendto_one(source_p, form_str(i), me.name, source_p->name, name);
307 if(successful_join_count > 0)
308 successful_join_count--;
309 continue;
310 }
311 sendto_one_numeric(source_p, ERR_LINKCHANNEL, form_str(ERR_LINKCHANNEL), name, chptr->chname);
312 }
313
314 /* add the user to the channel */
315 add_user_to_channel(chptr, source_p, flags);
316 if (chptr->mode.join_num &&
317 rb_current_time() - chptr->join_delta >= chptr->mode.join_time)
318 {
319 chptr->join_count = 0;
320 chptr->join_delta = rb_current_time();
321 }
322 chptr->join_count++;
323
324 /* we send the user their join here, because we could have to
325 * send a mode out next.
326 */
327 sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s",
328 source_p->name,
329 source_p->username, source_p->host, chptr->chname);
330
331 /* its a new channel, set +nt and burst. */
332 if(flags & CHFL_CHANOP)
333 {
334 chptr->channelts = rb_current_time();
335 chptr->mode.mode |= MODE_TOPICLIMIT;
336 chptr->mode.mode |= MODE_NOPRIVMSGS;
337
338 sendto_channel_local(ONLY_CHANOPS, chptr, ":%s MODE %s +nt",
339 me.name, chptr->chname);
340
341 if(*chptr->chname == '#')
342 {
343 sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
344 ":%s SJOIN %ld %s +nt :@%s",
345 me.id, (long) chptr->channelts,
346 chptr->chname, source_p->id);
347 sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
348 ":%s SJOIN %ld %s +nt :@%s",
349 me.name, (long) chptr->channelts,
350 chptr->chname, source_p->name);
351 }
352 }
353 else
354 {
355 sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
356 ":%s JOIN %ld %s +",
357 use_id(source_p), (long) chptr->channelts,
358 chptr->chname);
359
360 sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
361 ":%s SJOIN %ld %s + :%s",
362 me.name, (long) chptr->channelts,
363 chptr->chname, source_p->name);
364 }
365
366 del_invite(chptr, source_p);
367
368 if(chptr->topic != NULL)
369 {
370 sendto_one(source_p, form_str(RPL_TOPIC), me.name,
371 source_p->name, chptr->chname, chptr->topic);
372
373 sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
374 me.name, source_p->name, chptr->chname,
375 chptr->topic_info, chptr->topic_time);
376 }
377
378 channel_member_names(chptr, source_p, 1);
379
380 if(successful_join_count)
381 source_p->localClient->last_join_time = rb_current_time();
382
383 hook_info.client = source_p;
384 hook_info.chptr = chptr;
385 hook_info.key = key;
386 call_hook(h_channel_join, &hook_info);
387 }
388
389 return 0;
390 }
391
392 /*
393 * ms_join
394 *
395 * inputs -
396 * output - none
397 * side effects - handles remote JOIN's sent by servers. In TSora
398 * remote clients are joined using SJOIN, hence a
399 * JOIN sent by a server on behalf of a client is an error.
400 * here, the initial code is in to take an extra parameter
401 * and use it for the TimeStamp on a new channel.
402 */
403 static int
404 ms_join(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
405 {
406 struct Channel *chptr;
407 static struct Mode mode;
408 time_t oldts;
409 time_t newts;
410 int isnew;
411 int keep_our_modes = YES;
412 int keep_new_modes = YES;
413 rb_dlink_node *ptr, *next_ptr;
414
415 /* special case for join 0 */
416 if((parv[1][0] == '0') && (parv[1][1] == '\0') && parc == 2)
417 {
418 do_join_0(client_p, source_p);
419 return 0;
420 }
421
422 if(parc < 4)
423 return 0;
424
425 if(!IsChannelName(parv[2]) || !check_channel_name(parv[2]))
426 return 0;
427
428 /* joins for local channels cant happen. */
429 if(parv[2][0] == '&')
430 return 0;
431
432 mbuf = modebuf;
433 mode.key[0] = mode.forward[0] = '\0';
434 mode.mode = mode.limit = mode.join_num = mode.join_time = 0;
435
436 if((chptr = get_or_create_channel(source_p, parv[2], &isnew)) == NULL)
437 return 0;
438
439 newts = atol(parv[1]);
440 oldts = chptr->channelts;
441
442 #ifdef IGNORE_BOGUS_TS
443 if(newts < 800000000)
444 {
445 sendto_realops_snomask(SNO_DEBUG, L_ALL,
446 "*** Bogus TS %ld on %s ignored from %s",
447 (long) newts, chptr->chname, client_p->name);
448 newts = (oldts == 0) ? oldts : 800000000;
449 }
450 #else
451 /* making a channel TS0 */
452 if(!isnew && !newts && oldts)
453 {
454 sendto_channel_local(ALL_MEMBERS, chptr,
455 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to 0",
456 me.name, chptr->chname, chptr->chname, (long) oldts);
457 sendto_realops_snomask(SNO_GENERAL, L_ALL,
458 "Server %s changing TS on %s from %ld to 0",
459 source_p->name, chptr->chname, (long) oldts);
460 }
461 #endif
462
463 if(isnew)
464 chptr->channelts = newts;
465 else if(newts == 0 || oldts == 0)
466 chptr->channelts = 0;
467 else if(newts == oldts)
468 ;
469 else if(newts < oldts)
470 {
471 keep_our_modes = NO;
472 chptr->channelts = newts;
473 }
474 else
475 keep_new_modes = NO;
476
477 /* Lost the TS, other side wins, so remove modes on this side */
478 if(!keep_our_modes)
479 {
480 set_final_mode(&mode, &chptr->mode);
481 chptr->mode = mode;
482 remove_our_modes(chptr, source_p);
483 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head)
484 {
485 del_invite(chptr, ptr->data);
486 }
487 /* If setting -j, clear join throttle state -- jilles */
488 chptr->join_count = chptr->join_delta = 0;
489 sendto_channel_local(ALL_MEMBERS, chptr,
490 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
491 me.name, chptr->chname, chptr->chname,
492 (long) oldts, (long) newts);
493 /* Update capitalization in channel name, this makes the
494 * capitalization timestamped like modes are -- jilles */
495 strcpy(chptr->chname, parv[2]);
496 if(*modebuf != '\0')
497 sendto_channel_local(ALL_MEMBERS, chptr,
498 ":%s MODE %s %s %s",
499 source_p->servptr->name,
500 chptr->chname, modebuf, parabuf);
501 *modebuf = *parabuf = '\0';
502 }
503
504 if(!IsMember(source_p, chptr))
505 {
506 add_user_to_channel(chptr, source_p, CHFL_PEON);
507 if (chptr->mode.join_num &&
508 rb_current_time() - chptr->join_delta >= chptr->mode.join_time)
509 {
510 chptr->join_count = 0;
511 chptr->join_delta = rb_current_time();
512 }
513 chptr->join_count++;
514 sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s",
515 source_p->name, source_p->username,
516 source_p->host, chptr->chname);
517 }
518
519 sendto_server(client_p, chptr, CAP_TS6, NOCAPS,
520 ":%s JOIN %ld %s +",
521 source_p->id, (long) chptr->channelts, chptr->chname);
522 sendto_server(client_p, chptr, NOCAPS, CAP_TS6,
523 ":%s SJOIN %ld %s %s :%s",
524 source_p->servptr->name, (long) chptr->channelts,
525 chptr->chname, keep_new_modes ? "+" : "0",
526 source_p->name);
527 return 0;
528 }
529
530 static int
531 ms_sjoin(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
532 {
533 static char buf_nick[BUFSIZE];
534 static char buf_uid[BUFSIZE];
535 static const char empty_modes[] = "0";
536 struct Channel *chptr;
537 struct Client *target_p, *fakesource_p;
538 time_t newts;
539 time_t oldts;
540 static struct Mode mode, *oldmode;
541 const char *modes;
542 int args = 0;
543 int keep_our_modes = 1;
544 int keep_new_modes = 1;
545 int fl;
546 int isnew;
547 int mlen_nick, mlen_uid;
548 int len_nick;
549 int len_uid;
550 int len;
551 int joins = 0;
552 const char *s;
553 char *ptr_nick;
554 char *ptr_uid;
555 char *p;
556 int i, joinc = 0, timeslice = 0;
557 static char empty[] = "";
558 rb_dlink_node *ptr, *next_ptr;
559
560 if(!IsChannelName(parv[2]) || !check_channel_name(parv[2]))
561 return 0;
562
563 /* SJOIN's for local channels can't happen. */
564 if(*parv[2] == '&')
565 return 0;
566
567 modebuf[0] = parabuf[0] = mode.key[0] = mode.forward[0] = '\0';
568 pargs = mode.mode = mode.limit = mode.join_num = mode.join_time = 0;
569
570 /* Hide connecting server on netburst -- jilles */
571 if (ConfigServerHide.flatten_links && !HasSentEob(source_p))
572 fakesource_p = &me;
573 else
574 fakesource_p = source_p;
575
576 mbuf = modebuf;
577 newts = atol(parv[1]);
578
579 s = parv[3];
580 while (*s)
581 {
582 switch (*(s++))
583 {
584 case 'i':
585 mode.mode |= MODE_INVITEONLY;
586 break;
587 case 'n':
588 mode.mode |= MODE_NOPRIVMSGS;
589 break;
590 case 'p':
591 mode.mode |= MODE_PRIVATE;
592 break;
593 case 's':
594 mode.mode |= MODE_SECRET;
595 break;
596 case 'm':
597 mode.mode |= MODE_MODERATED;
598 break;
599 case 't':
600 mode.mode |= MODE_TOPICLIMIT;
601 break;
602 case 'r':
603 mode.mode |= MODE_REGONLY;
604 break;
605 case 'L':
606 mode.mode |= MODE_EXLIMIT;
607 break;
608 case 'P':
609 mode.mode |= MODE_PERMANENT;
610 break;
611 case 'c':
612 mode.mode |= MODE_NOCOLOR;
613 break;
614 case 'g':
615 mode.mode |= MODE_FREEINVITE;
616 break;
617 case 'z':
618 mode.mode |= MODE_OPMODERATE;
619 break;
620 case 'F':
621 mode.mode |= MODE_FREETARGET;
622 break;
623 case 'Q':
624 mode.mode |= MODE_DISFORWARD;
625 break;
626 case 'f':
627 strlcpy(mode.forward, parv[4 + args], sizeof(mode.forward));
628 args++;
629 if(parc < 5 + args)
630 return 0;
631 break;
632 case 'j':
633 sscanf(parv[4 + args], "%d:%d", &joinc, &timeslice);
634 args++;
635 mode.join_num = joinc;
636 mode.join_time = timeslice;
637 if(parc < 5 + args)
638 return 0;
639 break;
640 case 'k':
641 strlcpy(mode.key, parv[4 + args], sizeof(mode.key));
642 args++;
643 if(parc < 5 + args)
644 return 0;
645 break;
646 case 'l':
647 mode.limit = atoi(parv[4 + args]);
648 args++;
649 if(parc < 5 + args)
650 return 0;
651 break;
652 }
653 }
654
655 if(parv[args + 4])
656 {
657 s = parv[args + 4];
658
659 /* remove any leading spaces */
660 while (*s == ' ')
661 s++;
662 }
663 else
664 s = "";
665
666 if((chptr = get_or_create_channel(source_p, parv[2], &isnew)) == NULL)
667 return 0; /* channel name too long? */
668
669
670 oldts = chptr->channelts;
671 oldmode = &chptr->mode;
672
673 #ifdef IGNORE_BOGUS_TS
674 if(newts < 800000000)
675 {
676 sendto_realops_snomask(SNO_DEBUG, L_ALL,
677 "*** Bogus TS %ld on %s ignored from %s",
678 (long) newts, chptr->chname, client_p->name);
679
680 newts = (oldts == 0) ? oldts : 800000000;
681 }
682 #else
683 if(!isnew && !newts && oldts)
684 {
685 sendto_channel_local(ALL_MEMBERS, chptr,
686 ":%s NOTICE %s :*** Notice -- TS for %s "
687 "changed from %ld to 0",
688 me.name, chptr->chname, chptr->chname, (long) oldts);
689 sendto_realops_snomask(SNO_GENERAL, L_ALL,
690 "Server %s changing TS on %s from %ld to 0",
691 source_p->name, chptr->chname, (long) oldts);
692 }
693 #endif
694
695 if(isnew)
696 chptr->channelts = newts;
697
698 else if(newts == 0 || oldts == 0)
699 chptr->channelts = 0;
700 else if(newts == oldts)
701 ;
702 else if(newts < oldts)
703 {
704 /* If configured, kick people trying to join +i/+k
705 * channels by recreating them on split servers.
706 * Don't kick if the source has sent EOB (services
707 * deopping everyone by TS-1 SJOIN).
708 * -- jilles */
709 if (ConfigChannel.kick_on_split_riding &&
710 !HasSentEob(source_p) &&
711 ((mode.mode & MODE_INVITEONLY) ||
712 (mode.key[0] != 0 && irccmp(mode.key, oldmode->key) != 0)))
713 {
714 struct membership *msptr;
715 struct Client *who;
716 int l = rb_dlink_list_length(&chptr->members);
717 int b = rb_dlink_list_length(&chptr->banlist) +
718 rb_dlink_list_length(&chptr->exceptlist) +
719 rb_dlink_list_length(&chptr->invexlist) +
720 rb_dlink_list_length(&chptr->quietlist);
721
722 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->locmembers.head)
723 {
724 msptr = ptr->data;
725 who = msptr->client_p;
726 sendto_one(who, ":%s KICK %s %s :Net Rider",
727 me.name, chptr->chname, who->name);
728
729 sendto_server(NULL, chptr, CAP_TS6, NOCAPS,
730 ":%s KICK %s %s :Net Rider",
731 me.id, chptr->chname,
732 who->id);
733 sendto_server(NULL, chptr, NOCAPS, CAP_TS6,
734 ":%s KICK %s %s :Net Rider",
735 me.name, chptr->chname, who->name);
736 remove_user_from_channel(msptr);
737 if (--l == 0)
738 break;
739 }
740 if (l == 0)
741 {
742 /* Channel was emptied, create a new one */
743 if((chptr = get_or_create_channel(source_p, parv[2], &isnew)) == NULL)
744 return 0; /* oops! */
745
746 /* If the source does not do TS6,
747 * nontimestamped bans have been sent to it,
748 * but we have just lost those here. Let's
749 * warn the channel about this. Because
750 * of the kicks, any users on the channel
751 * will be at client_p. -- jilles */
752 if (!has_id(source_p) && b > 0)
753 sendto_one(client_p, ":%s NOTICE %s :*** Notice -- possible ban desync on %s, please remove any bans just added by servers", get_id(&me, client_p), parv[2], parv[2]);
754 oldmode = &chptr->mode;
755 }
756 }
757 keep_our_modes = NO;
758 chptr->channelts = newts;
759 }
760 else
761 keep_new_modes = NO;
762
763 if(!keep_new_modes)
764 mode = *oldmode;
765 else if(keep_our_modes)
766 {
767 mode.mode |= oldmode->mode;
768 if(oldmode->limit > mode.limit)
769 mode.limit = oldmode->limit;
770 if(strcmp(mode.key, oldmode->key) < 0)
771 strcpy(mode.key, oldmode->key);
772 if(oldmode->join_num > mode.join_num ||
773 (oldmode->join_num == mode.join_num &&
774 oldmode->join_time > mode.join_time))
775 {
776 mode.join_num = oldmode->join_num;
777 mode.join_time = oldmode->join_time;
778 }
779 if(irccmp(mode.forward, oldmode->forward) < 0)
780 strcpy(mode.forward, oldmode->forward);
781 }
782 else
783 {
784 /* If setting -j, clear join throttle state -- jilles */
785 if (!mode.join_num)
786 chptr->join_count = chptr->join_delta = 0;
787 }
788
789 set_final_mode(&mode, oldmode);
790 chptr->mode = mode;
791
792 /* Lost the TS, other side wins, so remove modes on this side */
793 if(!keep_our_modes)
794 {
795 remove_our_modes(chptr, fakesource_p);
796 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->invites.head)
797 {
798 del_invite(chptr, ptr->data);
799 }
800 sendto_channel_local(ALL_MEMBERS, chptr,
801 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
802 me.name, chptr->chname, chptr->chname,
803 (long) oldts, (long) newts);
804 /* Update capitalization in channel name, this makes the
805 * capitalization timestamped like modes are -- jilles */
806 strcpy(chptr->chname, parv[2]);
807 }
808
809 if(*modebuf != '\0')
810 sendto_channel_local(ALL_MEMBERS, chptr, ":%s MODE %s %s %s",
811 fakesource_p->name, chptr->chname, modebuf, parabuf);
812
813 *modebuf = *parabuf = '\0';
814
815 if(parv[3][0] != '0' && keep_new_modes)
816 modes = channel_modes(chptr, source_p);
817 else
818 modes = empty_modes;
819
820 mlen_nick = rb_sprintf(buf_nick, ":%s SJOIN %ld %s %s :",
821 source_p->name, (long) chptr->channelts, parv[2], modes);
822 ptr_nick = buf_nick + mlen_nick;
823
824 /* working on the presumption eventually itll be more efficient to
825 * build a TS6 buffer without checking its needed..
826 */
827 mlen_uid = rb_sprintf(buf_uid, ":%s SJOIN %ld %s %s :",
828 use_id(source_p), (long) chptr->channelts, parv[2], modes);
829 ptr_uid = buf_uid + mlen_uid;
830
831 mbuf = modebuf;
832 para[0] = para[1] = para[2] = para[3] = empty;
833 pargs = 0;
834 len_nick = len_uid = 0;
835
836 /* if theres a space, theres going to be more than one nick, change the
837 * first space to \0, so s is just the first nick, and point p to the
838 * second nick
839 */
840 if((p = strchr(s, ' ')) != NULL)
841 {
842 *p++ = '\0';
843 }
844
845 *mbuf++ = '+';
846
847 while (s)
848 {
849 fl = 0;
850
851 for (i = 0; i < 2; i++)
852 {
853 if(*s == '@')
854 {
855 fl |= CHFL_CHANOP;
856 s++;
857 }
858 else if(*s == '+')
859 {
860 fl |= CHFL_VOICE;
861 s++;
862 }
863 }
864
865 /* if the client doesnt exist or is fake direction, skip. */
866 if(!(target_p = find_client(s)) ||
867 (target_p->from != client_p) || !IsPerson(target_p))
868 goto nextnick;
869
870 /* we assume for these we can fit at least one nick/uid in.. */
871
872 /* check we can fit another status+nick+space into a buffer */
873 if((mlen_nick + len_nick + NICKLEN + 3) > (BUFSIZE - 3))
874 {
875 *(ptr_nick - 1) = '\0';
876 sendto_server(client_p->from, NULL, NOCAPS, CAP_TS6, "%s", buf_nick);
877 ptr_nick = buf_nick + mlen_nick;
878 len_nick = 0;
879 }
880
881 if((mlen_uid + len_uid + IDLEN + 3) > (BUFSIZE - 3))
882 {
883 *(ptr_uid - 1) = '\0';
884 sendto_server(client_p->from, NULL, CAP_TS6, NOCAPS, "%s", buf_uid);
885 ptr_uid = buf_uid + mlen_uid;
886 len_uid = 0;
887 }
888
889 if(keep_new_modes)
890 {
891 if(fl & CHFL_CHANOP)
892 {
893 *ptr_nick++ = '@';
894 *ptr_uid++ = '@';
895 len_nick++;
896 len_uid++;
897 }
898 if(fl & CHFL_VOICE)
899 {
900 *ptr_nick++ = '+';
901 *ptr_uid++ = '+';
902 len_nick++;
903 len_uid++;
904 }
905 }
906
907 /* copy the nick to the two buffers */
908 len = rb_sprintf(ptr_nick, "%s ", target_p->name);
909 ptr_nick += len;
910 len_nick += len;
911 len = rb_sprintf(ptr_uid, "%s ", use_id(target_p));
912 ptr_uid += len;
913 len_uid += len;
914
915 if(!keep_new_modes)
916 fl = 0;
917
918 if(!IsMember(target_p, chptr))
919 {
920 add_user_to_channel(chptr, target_p, fl);
921 sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s",
922 target_p->name,
923 target_p->username, target_p->host, parv[2]);
924 joins++;
925 }
926
927 if(fl & CHFL_CHANOP)
928 {
929 *mbuf++ = 'o';
930 para[pargs++] = target_p->name;
931
932 /* a +ov user.. bleh */
933 if(fl & CHFL_VOICE)
934 {
935 /* its possible the +o has filled up MAXMODEPARAMS, if so, start
936 * a new buffer
937 */
938 if(pargs >= MAXMODEPARAMS)
939 {
940 *mbuf = '\0';
941 sendto_channel_local(ALL_MEMBERS, chptr,
942 ":%s MODE %s %s %s %s %s %s",
943 fakesource_p->name, chptr->chname,
944 modebuf,
945 para[0], para[1], para[2], para[3]);
946 mbuf = modebuf;
947 *mbuf++ = '+';
948 para[0] = para[1] = para[2] = para[3] = NULL;
949 pargs = 0;
950 }
951
952 *mbuf++ = 'v';
953 para[pargs++] = target_p->name;
954 }
955 }
956 else if(fl & CHFL_VOICE)
957 {
958 *mbuf++ = 'v';
959 para[pargs++] = target_p->name;
960 }
961
962 if(pargs >= MAXMODEPARAMS)
963 {
964 *mbuf = '\0';
965 sendto_channel_local(ALL_MEMBERS, chptr,
966 ":%s MODE %s %s %s %s %s %s",
967 fakesource_p->name,
968 chptr->chname,
969 modebuf, para[0], para[1], para[2], para[3]);
970 mbuf = modebuf;
971 *mbuf++ = '+';
972 para[0] = para[1] = para[2] = para[3] = NULL;
973 pargs = 0;
974 }
975
976 nextnick:
977 /* p points to the next nick */
978 s = p;
979
980 /* if there was a trailing space and p was pointing to it, then we
981 * need to exit.. this has the side effect of breaking double spaces
982 * in an sjoin.. but that shouldnt happen anyway
983 */
984 if(s && (*s == '\0'))
985 s = p = NULL;
986
987 /* if p was NULL due to no spaces, s wont exist due to the above, so
988 * we cant check it for spaces.. if there are no spaces, then when
989 * we next get here, s will be NULL
990 */
991 if(s && ((p = strchr(s, ' ')) != NULL))
992 {
993 *p++ = '\0';
994 }
995 }
996
997 *mbuf = '\0';
998 if(pargs)
999 {
1000 sendto_channel_local(ALL_MEMBERS, chptr,
1001 ":%s MODE %s %s %s %s %s %s",
1002 fakesource_p->name, chptr->chname, modebuf,
1003 para[0], CheckEmpty(para[1]),
1004 CheckEmpty(para[2]), CheckEmpty(para[3]));
1005 }
1006
1007 if(!joins && !(chptr->mode.mode & MODE_PERMANENT) && isnew)
1008 {
1009 destroy_channel(chptr);
1010
1011 return 0;
1012 }
1013
1014 /* Keep the colon if we're sending an SJOIN without nicks -- jilles */
1015 if (joins)
1016 {
1017 *(ptr_nick - 1) = '\0';
1018 *(ptr_uid - 1) = '\0';
1019 }
1020
1021 sendto_server(client_p->from, NULL, CAP_TS6, NOCAPS, "%s", buf_uid);
1022 sendto_server(client_p->from, NULL, NOCAPS, CAP_TS6, "%s", buf_nick);
1023
1024 /* if the source does TS6 we have to remove our bans. Its now safe
1025 * to issue -b's to the non-ts6 servers, as the sjoin we've just
1026 * sent will kill any ops they have.
1027 */
1028 if(!keep_our_modes && source_p->id[0] != '\0')
1029 {
1030 if(rb_dlink_list_length(&chptr->banlist) > 0)
1031 remove_ban_list(chptr, fakesource_p, &chptr->banlist, 'b', NOCAPS, ALL_MEMBERS);
1032
1033 if(rb_dlink_list_length(&chptr->exceptlist) > 0)
1034 remove_ban_list(chptr, fakesource_p, &chptr->exceptlist,
1035 'e', CAP_EX, ONLY_CHANOPS);
1036
1037 if(rb_dlink_list_length(&chptr->invexlist) > 0)
1038 remove_ban_list(chptr, fakesource_p, &chptr->invexlist,
1039 'I', CAP_IE, ONLY_CHANOPS);
1040
1041 if(rb_dlink_list_length(&chptr->quietlist) > 0)
1042 remove_ban_list(chptr, fakesource_p, &chptr->quietlist,
1043 'q', NOCAPS, ALL_MEMBERS);
1044
1045 chptr->bants++;
1046 }
1047
1048 return 0;
1049 }
1050
1051 /*
1052 * do_join_0
1053 *
1054 * inputs - pointer to client doing join 0
1055 * output - NONE
1056 * side effects - Use has decided to join 0. This is legacy
1057 * from the days when channels were numbers not names. *sigh*
1058 * There is a bunch of evilness necessary here due to
1059 * anti spambot code.
1060 */
1061 static void
1062 do_join_0(struct Client *client_p, struct Client *source_p)
1063 {
1064 struct membership *msptr;
1065 struct Channel *chptr = NULL;
1066 rb_dlink_node *ptr;
1067
1068 /* Finish the flood grace period... */
1069 if(MyClient(source_p) && !IsFloodDone(source_p))
1070 flood_endgrace(source_p);
1071
1072
1073 sendto_server(client_p, NULL, CAP_TS6, NOCAPS, ":%s JOIN 0", use_id(source_p));
1074 sendto_server(client_p, NULL, NOCAPS, CAP_TS6, ":%s JOIN 0", source_p->name);
1075
1076 if(source_p->user->channel.head && MyConnect(source_p) &&
1077 !IsOper(source_p) && !IsExemptSpambot(source_p))
1078 check_spambot_warning(source_p, NULL);
1079
1080 while((ptr = source_p->user->channel.head))
1081 {
1082 msptr = ptr->data;
1083 chptr = msptr->chptr;
1084 sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s PART %s",
1085 source_p->name,
1086 source_p->username, source_p->host, chptr->chname);
1087 remove_user_from_channel(msptr);
1088 }
1089 }
1090
1091 static int
1092 check_channel_name_loc(struct Client *source_p, const char *name)
1093 {
1094 s_assert(name != NULL);
1095 if(EmptyString(name))
1096 return 0;
1097
1098 if(ConfigFileEntry.disable_fake_channels && !IsOper(source_p))
1099 {
1100 for(; *name; ++name)
1101 {
1102 if(!IsChanChar(*name) || IsFakeChanChar(*name))
1103 return 0;
1104 }
1105 }
1106 else
1107 {
1108 for(; *name; ++name)
1109 {
1110 if(!IsChanChar(*name))
1111 return 0;
1112 }
1113 }
1114
1115 return 1;
1116 }
1117
1118 static void
1119 set_final_mode(struct Mode *mode, struct Mode *oldmode)
1120 {
1121 int dir = MODE_QUERY;
1122 char *pbuf = parabuf;
1123 int len;
1124 int i;
1125
1126 /* ok, first get a list of modes we need to add */
1127 for (i = 0; chmode_flags[i].letter; i++)
1128 {
1129 if((mode->mode & chmode_flags[i].mode) && !(oldmode->mode & chmode_flags[i].mode))
1130 {
1131 if(dir != MODE_ADD)
1132 {
1133 *mbuf++ = '+';
1134 dir = MODE_ADD;
1135 }
1136 *mbuf++ = chmode_flags[i].letter;
1137 }
1138 }
1139
1140 /* now the ones we need to remove. */
1141 for (i = 0; chmode_flags[i].letter; i++)
1142 {
1143 if((oldmode->mode & chmode_flags[i].mode) && !(mode->mode & chmode_flags[i].mode))
1144 {
1145 if(dir != MODE_DEL)
1146 {
1147 *mbuf++ = '-';
1148 dir = MODE_DEL;
1149 }
1150 *mbuf++ = chmode_flags[i].letter;
1151 }
1152 }
1153
1154 if(oldmode->limit && !mode->limit)
1155 {
1156 if(dir != MODE_DEL)
1157 {
1158 *mbuf++ = '-';
1159 dir = MODE_DEL;
1160 }
1161 *mbuf++ = 'l';
1162 }
1163 if(oldmode->key[0] && !mode->key[0])
1164 {
1165 if(dir != MODE_DEL)
1166 {
1167 *mbuf++ = '-';
1168 dir = MODE_DEL;
1169 }
1170 *mbuf++ = 'k';
1171 len = rb_sprintf(pbuf, "%s ", oldmode->key);
1172 pbuf += len;
1173 }
1174 if(oldmode->join_num && !mode->join_num)
1175 {
1176 if(dir != MODE_DEL)
1177 {
1178 *mbuf++ = '-';
1179 dir = MODE_DEL;
1180 }
1181 *mbuf++ = 'j';
1182 }
1183 if(oldmode->forward[0] && !mode->forward[0])
1184 {
1185 if(dir != MODE_DEL)
1186 {
1187 *mbuf++ = '-';
1188 dir = MODE_DEL;
1189 }
1190 *mbuf++ = 'f';
1191 }
1192 if(mode->limit && oldmode->limit != mode->limit)
1193 {
1194 if(dir != MODE_ADD)
1195 {
1196 *mbuf++ = '+';
1197 dir = MODE_ADD;
1198 }
1199 *mbuf++ = 'l';
1200 len = rb_sprintf(pbuf, "%d ", mode->limit);
1201 pbuf += len;
1202 }
1203 if(mode->key[0] && strcmp(oldmode->key, mode->key))
1204 {
1205 if(dir != MODE_ADD)
1206 {
1207 *mbuf++ = '+';
1208 dir = MODE_ADD;
1209 }
1210 *mbuf++ = 'k';
1211 len = rb_sprintf(pbuf, "%s ", mode->key);
1212 pbuf += len;
1213 }
1214 if(mode->join_num && (oldmode->join_num != mode->join_num || oldmode->join_time != mode->join_time))
1215 {
1216 if(dir != MODE_ADD)
1217 {
1218 *mbuf++ = '+';
1219 dir = MODE_ADD;
1220 }
1221 *mbuf++ = 'j';
1222 len = rb_sprintf(pbuf, "%d:%d ", mode->join_num, mode->join_time);
1223 pbuf += len;
1224 }
1225 if(mode->forward[0] && strcmp(oldmode->forward, mode->forward) && ConfigChannel.use_forward)
1226 {
1227 if(dir != MODE_ADD)
1228 {
1229 *mbuf++ = '+';
1230 dir = MODE_ADD;
1231 }
1232 *mbuf++ = 'f';
1233 len = rb_sprintf(pbuf, "%s ", mode->forward);
1234 pbuf += len;
1235 }
1236 *mbuf = '\0';
1237 }
1238
1239 /*
1240 * remove_our_modes
1241 *
1242 * inputs -
1243 * output -
1244 * side effects -
1245 */
1246 static void
1247 remove_our_modes(struct Channel *chptr, struct Client *source_p)
1248 {
1249 struct membership *msptr;
1250 rb_dlink_node *ptr;
1251 char lmodebuf[MODEBUFLEN];
1252 char *lpara[MAXMODEPARAMS];
1253 int count = 0;
1254 int i;
1255
1256 mbuf = lmodebuf;
1257 *mbuf++ = '-';
1258
1259 for(i = 0; i < MAXMODEPARAMS; i++)
1260 lpara[i] = NULL;
1261
1262 RB_DLINK_FOREACH(ptr, chptr->members.head)
1263 {
1264 msptr = ptr->data;
1265
1266 if(is_chanop(msptr))
1267 {
1268 msptr->flags &= ~CHFL_CHANOP;
1269 lpara[count++] = msptr->client_p->name;
1270 *mbuf++ = 'o';
1271
1272 /* +ov, might not fit so check. */
1273 if(is_voiced(msptr))
1274 {
1275 if(count >= MAXMODEPARAMS)
1276 {
1277 *mbuf = '\0';
1278 sendto_channel_local(ALL_MEMBERS, chptr,
1279 ":%s MODE %s %s %s %s %s %s",
1280 me.name, chptr->chname,
1281 lmodebuf, lpara[0], lpara[1],
1282 lpara[2], lpara[3]);
1283
1284 /* preserve the initial '-' */
1285 mbuf = lmodebuf;
1286 *mbuf++ = '-';
1287 count = 0;
1288
1289 for(i = 0; i < MAXMODEPARAMS; i++)
1290 lpara[i] = NULL;
1291 }
1292
1293 msptr->flags &= ~CHFL_VOICE;
1294 lpara[count++] = msptr->client_p->name;
1295 *mbuf++ = 'v';
1296 }
1297 }
1298 else if(is_voiced(msptr))
1299 {
1300 msptr->flags &= ~CHFL_VOICE;
1301 lpara[count++] = msptr->client_p->name;
1302 *mbuf++ = 'v';
1303 }
1304 else
1305 continue;
1306
1307 if(count >= MAXMODEPARAMS)
1308 {
1309 *mbuf = '\0';
1310 sendto_channel_local(ALL_MEMBERS, chptr,
1311 ":%s MODE %s %s %s %s %s %s",
1312 me.name, chptr->chname, lmodebuf,
1313 lpara[0], lpara[1], lpara[2], lpara[3]);
1314 mbuf = lmodebuf;
1315 *mbuf++ = '-';
1316 count = 0;
1317
1318 for(i = 0; i < MAXMODEPARAMS; i++)
1319 lpara[i] = NULL;
1320 }
1321 }
1322
1323 if(count != 0)
1324 {
1325 *mbuf = '\0';
1326 sendto_channel_local(ALL_MEMBERS, chptr,
1327 ":%s MODE %s %s %s %s %s %s",
1328 me.name, chptr->chname, lmodebuf,
1329 EmptyString(lpara[0]) ? "" : lpara[0],
1330 EmptyString(lpara[1]) ? "" : lpara[1],
1331 EmptyString(lpara[2]) ? "" : lpara[2],
1332 EmptyString(lpara[3]) ? "" : lpara[3]);
1333
1334 }
1335 }
1336
1337 /* remove_ban_list()
1338 *
1339 * inputs - channel, source, list to remove, char of mode, caps needed
1340 * outputs -
1341 * side effects - given list is removed, with modes issued to local clients
1342 * and non-TS6 servers.
1343 */
1344 static void
1345 remove_ban_list(struct Channel *chptr, struct Client *source_p,
1346 rb_dlink_list * list, char c, int cap, int mems)
1347 {
1348 static char lmodebuf[BUFSIZE];
1349 static char lparabuf[BUFSIZE];
1350 struct Ban *banptr;
1351 rb_dlink_node *ptr;
1352 rb_dlink_node *next_ptr;
1353 char *pbuf;
1354 int count = 0;
1355 int cur_len, mlen, plen;
1356
1357 pbuf = lparabuf;
1358
1359 cur_len = mlen = rb_sprintf(lmodebuf, ":%s MODE %s -", source_p->name, chptr->chname);
1360 mbuf = lmodebuf + mlen;
1361
1362 RB_DLINK_FOREACH_SAFE(ptr, next_ptr, list->head)
1363 {
1364 banptr = ptr->data;
1365
1366 /* trailing space, and the mode letter itself */
1367 plen = strlen(banptr->banstr) + 2;
1368
1369 if(count >= MAXMODEPARAMS || (cur_len + plen) > BUFSIZE - 4)
1370 {
1371 /* remove trailing space */
1372 *mbuf = '\0';
1373 *(pbuf - 1) = '\0';
1374
1375 sendto_channel_local(mems, chptr, "%s %s", lmodebuf, lparabuf);
1376 /* Tricky tricky. If we changed source_p to &me
1377 * in ms_sjoin(), this still won't send stuff
1378 * where it should not be sent, because the
1379 * real source_p does TS6 -- jilles */
1380 sendto_server(source_p, chptr, cap, CAP_TS6, "%s %s", lmodebuf, lparabuf);
1381
1382 cur_len = mlen;
1383 mbuf = lmodebuf + mlen;
1384 pbuf = lparabuf;
1385 count = 0;
1386 }
1387
1388 *mbuf++ = c;
1389 cur_len += plen;
1390 pbuf += rb_sprintf(pbuf, "%s ", banptr->banstr);
1391 count++;
1392
1393 free_ban(banptr);
1394 }
1395
1396 *mbuf = '\0';
1397 *(pbuf - 1) = '\0';
1398 sendto_channel_local(mems, chptr, "%s %s", lmodebuf, lparabuf);
1399 sendto_server(source_p, chptr, cap, CAP_TS6, "%s %s", lmodebuf, lparabuf);
1400
1401 list->head = list->tail = NULL;
1402 list->length = 0;
1403 }