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