2 * ircd-ratbox: A slightly useful ircd.
3 * m_join.c: Joins a channel.
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
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.
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.
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
24 * $Id: m_join.c 3494 2007-05-27 13:07:27Z jilles $
32 #include "irc_string.h"
38 #include "s_newconf.h"
44 static int m_join(struct Client
*, struct Client
*, int, const char **);
45 static int ms_join(struct Client
*, struct Client
*, int, const char **);
46 static int ms_sjoin(struct Client
*, struct Client
*, int, const char **);
48 static int h_can_create_channel
;
49 static int h_channel_join
;
51 struct Message join_msgtab
= {
52 "JOIN", 0, 0, 0, MFLG_SLOW
,
53 {mg_unreg
, {m_join
, 2}, {ms_join
, 2}, mg_ignore
, mg_ignore
, {m_join
, 2}}
56 struct Message sjoin_msgtab
= {
57 "SJOIN", 0, 0, 0, MFLG_SLOW
,
58 {mg_unreg
, mg_ignore
, mg_ignore
, {ms_sjoin
, 0}, mg_ignore
, mg_ignore
}
61 mapi_clist_av1 join_clist
[] = { &join_msgtab
, &sjoin_msgtab
, NULL
};
63 mapi_hlist_av1 join_hlist
[] = {
64 { "can_create_channel", &h_can_create_channel
},
65 { "channel_join", &h_channel_join
},
69 DECLARE_MODULE_AV1(join
, NULL
, NULL
, join_clist
, join_hlist
, NULL
, "$Revision: 3494 $");
71 static void do_join_0(struct Client
*client_p
, struct Client
*source_p
);
72 static int check_channel_name_loc(struct Client
*source_p
, const char *name
);
74 static void set_final_mode(struct Mode
*mode
, struct Mode
*oldmode
);
75 static void remove_our_modes(struct Channel
*chptr
, struct Client
*source_p
);
77 static void remove_ban_list(struct Channel
*chptr
, struct Client
*source_p
,
78 rb_dlink_list
* list
, char c
, int cap
, int mems
);
80 static char modebuf
[MODEBUFLEN
];
81 static char parabuf
[MODEBUFLEN
];
82 static const char *para
[MAXMODEPARAMS
];
86 /* Check what we will forward to, without sending any notices to the user
89 static struct Channel
*
90 check_forward(struct Client
*source_p
, struct Channel
*chptr
,
96 if (IsNoForward(source_p
))
101 chptr
= find_channel(chptr
->mode
.forward
);
102 /* Can only forward to existing channels */
105 /* Already on there, show original error message */
106 if (IsMember(source_p
, chptr
))
108 /* Juped. Sending a warning notice would be unfair */
109 if (hash_find_resv(chptr
->chname
))
111 /* Don't forward to +Q channel */
112 if (chptr
->mode
.mode
& MODE_DISFORWARD
)
114 i
= can_join(source_p
, chptr
, key
);
117 if (i
!= ERR_INVITEONLYCHAN
&& i
!= ERR_NEEDREGGEDNICK
&& i
!= ERR_THROTTLE
&& i
!= ERR_CHANNELISFULL
)
127 * parv[0] = sender prefix
129 * parv[2] = channel password (key)
132 m_join(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
134 static char jbuf
[BUFSIZE
];
135 struct Channel
*chptr
= NULL
;
136 struct ConfItem
*aconf
;
140 char *p
= NULL
, *p2
= NULL
;
143 int successful_join_count
= 0; /* Number of channels successfully joined */
147 /* rebuild the list of channels theyre supposed to be joining.
148 * this code has a side effect of losing keys, but..
150 chanlist
= LOCAL_COPY(parv
[1]);
151 for(name
= rb_strtok_r(chanlist
, ",", &p
); name
; name
= rb_strtok_r(NULL
, ",", &p
))
153 /* check the length and name of channel is ok */
154 if(!check_channel_name_loc(source_p
, name
) || (strlen(name
) > LOC_CHANNELLEN
))
156 sendto_one_numeric(source_p
, ERR_BADCHANNAME
,
157 form_str(ERR_BADCHANNAME
), (unsigned char *) name
);
161 /* join 0 parts all channels */
162 if(*name
== '0' && (name
[1] == ',' || name
[1] == '\0') && name
== chanlist
)
164 (void) strcpy(jbuf
, "0");
168 /* check it begins with # or &, and local chans are disabled */
169 else if(!IsChannelName(name
))
171 sendto_one_numeric(source_p
, ERR_NOSUCHCHANNEL
,
172 form_str(ERR_NOSUCHCHANNEL
), name
);
176 /* see if its resv'd */
177 if(!IsExemptResv(source_p
) && (aconf
= hash_find_resv(name
)))
179 sendto_one_numeric(source_p
, ERR_BADCHANNAME
,
180 form_str(ERR_BADCHANNAME
), name
);
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
,
187 source_p
->orighost
, name
, aconf
->passwd
);
188 /* dont update tracking for jupe exempt users, these
189 * are likely to be spamtrap leaves
191 else if(IsExemptJupe(source_p
))
197 if(splitmode
&& !IsOper(source_p
) && (*name
!= '&') &&
198 ConfigChannel
.no_join_on_split
)
200 sendto_one(source_p
, form_str(ERR_UNAVAILRESOURCE
),
201 me
.name
, source_p
->name
, name
);
206 (void) strcat(jbuf
, ",");
207 (void) rb_strlcat(jbuf
, name
, sizeof(jbuf
));
212 mykey
= LOCAL_COPY(parv
[2]);
213 key
= rb_strtok_r(mykey
, ",", &p2
);
216 for(name
= rb_strtok_r(jbuf
, ",", &p
); name
;
217 key
= (key
) ? rb_strtok_r(NULL
, ",", &p2
) : NULL
, name
= rb_strtok_r(NULL
, ",", &p
))
219 hook_data_channel_activity hook_info
;
221 /* JOIN 0 simply parts all channels the user is in */
222 if(*name
== '0' && !atoi(name
))
224 if(source_p
->user
->channel
.head
== NULL
)
227 do_join_0(&me
, source_p
);
231 /* look for the channel */
232 if((chptr
= find_channel(name
)) != NULL
)
234 if(IsMember(source_p
, chptr
))
241 hook_data_client_approval moduledata
;
243 moduledata
.client
= source_p
;
244 moduledata
.approved
= 0;
246 call_hook(h_can_create_channel
, &moduledata
);
248 if(moduledata
.approved
!= 0)
250 sendto_one(source_p
, form_str(moduledata
.approved
),
251 me
.name
, source_p
->name
, name
);
255 if(splitmode
&& !IsOper(source_p
) && (*name
!= '&') &&
256 ConfigChannel
.no_create_on_split
)
258 sendto_one(source_p
, form_str(ERR_UNAVAILRESOURCE
),
259 me
.name
, source_p
->name
, name
);
266 if((rb_dlink_list_length(&source_p
->user
->channel
) >=
267 (unsigned long) ConfigChannel
.max_chans_per_user
) &&
268 (!IsOper(source_p
) ||
269 (rb_dlink_list_length(&source_p
->user
->channel
) >=
270 (unsigned long) ConfigChannel
.max_chans_per_user
* 3)))
272 sendto_one(source_p
, form_str(ERR_TOOMANYCHANNELS
),
273 me
.name
, source_p
->name
, name
);
274 if(successful_join_count
)
275 source_p
->localClient
->last_join_time
= rb_current_time();
279 if(flags
== 0) /* if channel doesn't exist, don't penalize */
280 successful_join_count
++;
282 if(chptr
== NULL
) /* If I already have a chptr, no point doing this */
284 chptr
= get_or_create_channel(source_p
, name
, NULL
);
288 sendto_one(source_p
, form_str(ERR_UNAVAILRESOURCE
),
289 me
.name
, source_p
->name
, name
);
290 if(successful_join_count
> 0)
291 successful_join_count
--;
296 if(!IsOper(source_p
) && !IsExemptSpambot(source_p
))
297 check_spambot_warning(source_p
, name
);
299 /* can_join checks for +i key, bans etc */
300 if((i
= can_join(source_p
, chptr
, key
)))
302 if ((i
!= ERR_NEEDREGGEDNICK
&& i
!= ERR_THROTTLE
&& i
!= ERR_INVITEONLYCHAN
&& i
!= ERR_CHANNELISFULL
) ||
303 (!ConfigChannel
.use_forward
|| (chptr
= check_forward(source_p
, chptr
, key
)) == NULL
))
305 sendto_one(source_p
, form_str(i
), me
.name
, source_p
->name
, name
);
306 if(successful_join_count
> 0)
307 successful_join_count
--;
310 sendto_one_numeric(source_p
, ERR_LINKCHANNEL
, form_str(ERR_LINKCHANNEL
), name
, chptr
->chname
);
313 /* add the user to the channel */
314 add_user_to_channel(chptr
, source_p
, flags
);
315 if (chptr
->mode
.join_num
&&
316 rb_current_time() - chptr
->join_delta
>= chptr
->mode
.join_time
)
318 chptr
->join_count
= 0;
319 chptr
->join_delta
= rb_current_time();
323 /* we send the user their join here, because we could have to
324 * send a mode out next.
326 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s!%s@%s JOIN :%s",
328 source_p
->username
, source_p
->host
, chptr
->chname
);
330 /* its a new channel, set +nt and burst. */
331 if(flags
& CHFL_CHANOP
)
333 chptr
->channelts
= rb_current_time();
334 chptr
->mode
.mode
|= MODE_TOPICLIMIT
;
335 chptr
->mode
.mode
|= MODE_NOPRIVMSGS
;
337 sendto_channel_local(ONLY_CHANOPS
, chptr
, ":%s MODE %s +nt",
338 me
.name
, chptr
->chname
);
340 if(*chptr
->chname
== '#')
342 sendto_server(client_p
, chptr
, CAP_TS6
, NOCAPS
,
343 ":%s SJOIN %ld %s +nt :@%s",
344 me
.id
, (long) chptr
->channelts
,
345 chptr
->chname
, source_p
->id
);
346 sendto_server(client_p
, chptr
, NOCAPS
, CAP_TS6
,
347 ":%s SJOIN %ld %s +nt :@%s",
348 me
.name
, (long) chptr
->channelts
,
349 chptr
->chname
, source_p
->name
);
354 sendto_server(client_p
, chptr
, CAP_TS6
, NOCAPS
,
356 use_id(source_p
), (long) chptr
->channelts
,
359 sendto_server(client_p
, chptr
, NOCAPS
, CAP_TS6
,
360 ":%s SJOIN %ld %s + :%s",
361 me
.name
, (long) chptr
->channelts
,
362 chptr
->chname
, source_p
->name
);
365 del_invite(chptr
, source_p
);
367 if(chptr
->topic
!= NULL
)
369 sendto_one(source_p
, form_str(RPL_TOPIC
), me
.name
,
370 source_p
->name
, chptr
->chname
, chptr
->topic
);
372 sendto_one(source_p
, form_str(RPL_TOPICWHOTIME
),
373 me
.name
, source_p
->name
, chptr
->chname
,
374 chptr
->topic_info
, chptr
->topic_time
);
377 channel_member_names(chptr
, source_p
, 1);
379 if(successful_join_count
)
380 source_p
->localClient
->last_join_time
= rb_current_time();
382 hook_info
.client
= source_p
;
383 hook_info
.chptr
= chptr
;
385 call_hook(h_channel_join
, &hook_info
);
396 * side effects - handles remote JOIN's sent by servers. In TSora
397 * remote clients are joined using SJOIN, hence a
398 * JOIN sent by a server on behalf of a client is an error.
399 * here, the initial code is in to take an extra parameter
400 * and use it for the TimeStamp on a new channel.
403 ms_join(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
405 struct Channel
*chptr
;
406 static struct Mode mode
;
410 int keep_our_modes
= YES
;
411 int keep_new_modes
= YES
;
412 rb_dlink_node
*ptr
, *next_ptr
;
414 /* special case for join 0 */
415 if((parv
[1][0] == '0') && (parv
[1][1] == '\0') && parc
== 2)
417 do_join_0(client_p
, source_p
);
424 if(!IsChannelName(parv
[2]) || !check_channel_name(parv
[2]))
427 /* joins for local channels cant happen. */
428 if(parv
[2][0] == '&')
432 mode
.key
[0] = mode
.forward
[0] = '\0';
433 mode
.mode
= mode
.limit
= mode
.join_num
= mode
.join_time
= 0;
435 if((chptr
= get_or_create_channel(source_p
, parv
[2], &isnew
)) == NULL
)
438 newts
= atol(parv
[1]);
439 oldts
= chptr
->channelts
;
441 #ifdef IGNORE_BOGUS_TS
442 if(newts
< 800000000)
444 sendto_realops_snomask(SNO_DEBUG
, L_ALL
,
445 "*** Bogus TS %ld on %s ignored from %s",
446 (long) newts
, chptr
->chname
, client_p
->name
);
447 newts
= (oldts
== 0) ? oldts
: 800000000;
450 /* making a channel TS0 */
451 if(!isnew
&& !newts
&& oldts
)
453 sendto_channel_local(ALL_MEMBERS
, chptr
,
454 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to 0",
455 me
.name
, chptr
->chname
, chptr
->chname
, (long) oldts
);
456 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
457 "Server %s changing TS on %s from %ld to 0",
458 source_p
->name
, chptr
->chname
, (long) oldts
);
463 chptr
->channelts
= newts
;
464 else if(newts
== 0 || oldts
== 0)
465 chptr
->channelts
= 0;
466 else if(newts
== oldts
)
468 else if(newts
< oldts
)
471 chptr
->channelts
= newts
;
476 /* Lost the TS, other side wins, so remove modes on this side */
479 set_final_mode(&mode
, &chptr
->mode
);
481 remove_our_modes(chptr
, source_p
);
482 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->invites
.head
)
484 del_invite(chptr
, ptr
->data
);
486 /* If setting -j, clear join throttle state -- jilles */
487 chptr
->join_count
= chptr
->join_delta
= 0;
488 sendto_channel_local(ALL_MEMBERS
, chptr
,
489 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
490 me
.name
, chptr
->chname
, chptr
->chname
,
491 (long) oldts
, (long) newts
);
492 /* Update capitalization in channel name, this makes the
493 * capitalization timestamped like modes are -- jilles */
494 strcpy(chptr
->chname
, parv
[2]);
496 sendto_channel_local(ALL_MEMBERS
, chptr
,
498 source_p
->servptr
->name
,
499 chptr
->chname
, modebuf
, parabuf
);
500 *modebuf
= *parabuf
= '\0';
503 if(!IsMember(source_p
, chptr
))
505 add_user_to_channel(chptr
, source_p
, CHFL_PEON
);
506 if (chptr
->mode
.join_num
&&
507 rb_current_time() - chptr
->join_delta
>= chptr
->mode
.join_time
)
509 chptr
->join_count
= 0;
510 chptr
->join_delta
= rb_current_time();
513 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s!%s@%s JOIN :%s",
514 source_p
->name
, source_p
->username
,
515 source_p
->host
, chptr
->chname
);
518 sendto_server(client_p
, chptr
, CAP_TS6
, NOCAPS
,
520 source_p
->id
, (long) chptr
->channelts
, chptr
->chname
);
521 sendto_server(client_p
, chptr
, NOCAPS
, CAP_TS6
,
522 ":%s SJOIN %ld %s %s :%s",
523 source_p
->servptr
->name
, (long) chptr
->channelts
,
524 chptr
->chname
, keep_new_modes
? "+" : "0",
530 ms_sjoin(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
532 static char buf_nick
[BUFSIZE
];
533 static char buf_uid
[BUFSIZE
];
534 static const char empty_modes
[] = "0";
535 struct Channel
*chptr
;
536 struct Client
*target_p
, *fakesource_p
;
539 static struct Mode mode
, *oldmode
;
542 int keep_our_modes
= 1;
543 int keep_new_modes
= 1;
546 int mlen_nick
, mlen_uid
;
555 int i
, joinc
= 0, timeslice
= 0;
556 static char empty
[] = "";
557 rb_dlink_node
*ptr
, *next_ptr
;
559 if(!IsChannelName(parv
[2]) || !check_channel_name(parv
[2]))
562 /* SJOIN's for local channels can't happen. */
566 modebuf
[0] = parabuf
[0] = mode
.key
[0] = mode
.forward
[0] = '\0';
567 pargs
= mode
.mode
= mode
.limit
= mode
.join_num
= mode
.join_time
= 0;
569 /* Hide connecting server on netburst -- jilles */
570 if (ConfigServerHide
.flatten_links
&& !HasSentEob(source_p
))
573 fakesource_p
= source_p
;
576 newts
= atol(parv
[1]);
584 mode
.mode
|= MODE_INVITEONLY
;
587 mode
.mode
|= MODE_NOPRIVMSGS
;
590 mode
.mode
|= MODE_PRIVATE
;
593 mode
.mode
|= MODE_SECRET
;
596 mode
.mode
|= MODE_MODERATED
;
599 mode
.mode
|= MODE_TOPICLIMIT
;
602 mode
.mode
|= MODE_REGONLY
;
605 mode
.mode
|= MODE_EXLIMIT
;
608 mode
.mode
|= MODE_PERMANENT
;
611 mode
.mode
|= MODE_NOCOLOR
;
614 mode
.mode
|= MODE_FREEINVITE
;
617 mode
.mode
|= MODE_OPMODERATE
;
620 mode
.mode
|= MODE_FREETARGET
;
623 mode
.mode
|= MODE_DISFORWARD
;
626 rb_strlcpy(mode
.forward
, parv
[4 + args
], sizeof(mode
.forward
));
632 sscanf(parv
[4 + args
], "%d:%d", &joinc
, ×lice
);
634 mode
.join_num
= joinc
;
635 mode
.join_time
= timeslice
;
640 rb_strlcpy(mode
.key
, parv
[4 + args
], sizeof(mode
.key
));
646 mode
.limit
= atoi(parv
[4 + args
]);
658 /* remove any leading spaces */
665 if((chptr
= get_or_create_channel(source_p
, parv
[2], &isnew
)) == NULL
)
666 return 0; /* channel name too long? */
669 oldts
= chptr
->channelts
;
670 oldmode
= &chptr
->mode
;
672 #ifdef IGNORE_BOGUS_TS
673 if(newts
< 800000000)
675 sendto_realops_snomask(SNO_DEBUG
, L_ALL
,
676 "*** Bogus TS %ld on %s ignored from %s",
677 (long) newts
, chptr
->chname
, client_p
->name
);
679 newts
= (oldts
== 0) ? oldts
: 800000000;
682 if(!isnew
&& !newts
&& oldts
)
684 sendto_channel_local(ALL_MEMBERS
, chptr
,
685 ":%s NOTICE %s :*** Notice -- TS for %s "
686 "changed from %ld to 0",
687 me
.name
, chptr
->chname
, chptr
->chname
, (long) oldts
);
688 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
689 "Server %s changing TS on %s from %ld to 0",
690 source_p
->name
, chptr
->chname
, (long) oldts
);
695 chptr
->channelts
= newts
;
697 else if(newts
== 0 || oldts
== 0)
698 chptr
->channelts
= 0;
699 else if(newts
== oldts
)
701 else if(newts
< oldts
)
703 /* If configured, kick people trying to join +i/+k
704 * channels by recreating them on split servers.
705 * Don't kick if the source has sent EOB (services
706 * deopping everyone by TS-1 SJOIN).
708 if (ConfigChannel
.kick_on_split_riding
&&
709 !HasSentEob(source_p
) &&
710 ((mode
.mode
& MODE_INVITEONLY
) ||
711 (mode
.key
[0] != 0 && irccmp(mode
.key
, oldmode
->key
) != 0)))
713 struct membership
*msptr
;
715 int l
= rb_dlink_list_length(&chptr
->members
);
716 int b
= rb_dlink_list_length(&chptr
->banlist
) +
717 rb_dlink_list_length(&chptr
->exceptlist
) +
718 rb_dlink_list_length(&chptr
->invexlist
) +
719 rb_dlink_list_length(&chptr
->quietlist
);
721 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->locmembers
.head
)
724 who
= msptr
->client_p
;
725 sendto_one(who
, ":%s KICK %s %s :Net Rider",
726 me
.name
, chptr
->chname
, who
->name
);
728 sendto_server(NULL
, chptr
, CAP_TS6
, NOCAPS
,
729 ":%s KICK %s %s :Net Rider",
730 me
.id
, chptr
->chname
,
732 sendto_server(NULL
, chptr
, NOCAPS
, CAP_TS6
,
733 ":%s KICK %s %s :Net Rider",
734 me
.name
, chptr
->chname
, who
->name
);
735 remove_user_from_channel(msptr
);
741 /* Channel was emptied, create a new one */
742 if((chptr
= get_or_create_channel(source_p
, parv
[2], &isnew
)) == NULL
)
743 return 0; /* oops! */
745 /* If the source does not do TS6,
746 * nontimestamped bans have been sent to it,
747 * but we have just lost those here. Let's
748 * warn the channel about this. Because
749 * of the kicks, any users on the channel
750 * will be at client_p. -- jilles */
751 if (!has_id(source_p
) && b
> 0)
752 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]);
753 oldmode
= &chptr
->mode
;
757 chptr
->channelts
= newts
;
764 else if(keep_our_modes
)
766 mode
.mode
|= oldmode
->mode
;
767 if(oldmode
->limit
> mode
.limit
)
768 mode
.limit
= oldmode
->limit
;
769 if(strcmp(mode
.key
, oldmode
->key
) < 0)
770 strcpy(mode
.key
, oldmode
->key
);
771 if(oldmode
->join_num
> mode
.join_num
||
772 (oldmode
->join_num
== mode
.join_num
&&
773 oldmode
->join_time
> mode
.join_time
))
775 mode
.join_num
= oldmode
->join_num
;
776 mode
.join_time
= oldmode
->join_time
;
778 if(irccmp(mode
.forward
, oldmode
->forward
) < 0)
779 strcpy(mode
.forward
, oldmode
->forward
);
783 /* If setting -j, clear join throttle state -- jilles */
785 chptr
->join_count
= chptr
->join_delta
= 0;
788 set_final_mode(&mode
, oldmode
);
791 /* Lost the TS, other side wins, so remove modes on this side */
794 remove_our_modes(chptr
, fakesource_p
);
795 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->invites
.head
)
797 del_invite(chptr
, ptr
->data
);
799 sendto_channel_local(ALL_MEMBERS
, chptr
,
800 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
801 me
.name
, chptr
->chname
, chptr
->chname
,
802 (long) oldts
, (long) newts
);
803 /* Update capitalization in channel name, this makes the
804 * capitalization timestamped like modes are -- jilles */
805 strcpy(chptr
->chname
, parv
[2]);
809 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s MODE %s %s %s",
810 fakesource_p
->name
, chptr
->chname
, modebuf
, parabuf
);
812 *modebuf
= *parabuf
= '\0';
814 if(parv
[3][0] != '0' && keep_new_modes
)
815 modes
= channel_modes(chptr
, source_p
);
819 mlen_nick
= rb_sprintf(buf_nick
, ":%s SJOIN %ld %s %s :",
820 source_p
->name
, (long) chptr
->channelts
, parv
[2], modes
);
821 ptr_nick
= buf_nick
+ mlen_nick
;
823 /* working on the presumption eventually itll be more efficient to
824 * build a TS6 buffer without checking its needed..
826 mlen_uid
= rb_sprintf(buf_uid
, ":%s SJOIN %ld %s %s :",
827 use_id(source_p
), (long) chptr
->channelts
, parv
[2], modes
);
828 ptr_uid
= buf_uid
+ mlen_uid
;
831 para
[0] = para
[1] = para
[2] = para
[3] = empty
;
833 len_nick
= len_uid
= 0;
835 /* if theres a space, theres going to be more than one nick, change the
836 * first space to \0, so s is just the first nick, and point p to the
839 if((p
= strchr(s
, ' ')) != NULL
)
850 for (i
= 0; i
< 2; i
++)
864 /* if the client doesnt exist or is fake direction, skip. */
865 if(!(target_p
= find_client(s
)) ||
866 (target_p
->from
!= client_p
) || !IsPerson(target_p
))
869 /* we assume for these we can fit at least one nick/uid in.. */
871 /* check we can fit another status+nick+space into a buffer */
872 if((mlen_nick
+ len_nick
+ NICKLEN
+ 3) > (BUFSIZE
- 3))
874 *(ptr_nick
- 1) = '\0';
875 sendto_server(client_p
->from
, NULL
, NOCAPS
, CAP_TS6
, "%s", buf_nick
);
876 ptr_nick
= buf_nick
+ mlen_nick
;
880 if((mlen_uid
+ len_uid
+ IDLEN
+ 3) > (BUFSIZE
- 3))
882 *(ptr_uid
- 1) = '\0';
883 sendto_server(client_p
->from
, NULL
, CAP_TS6
, NOCAPS
, "%s", buf_uid
);
884 ptr_uid
= buf_uid
+ mlen_uid
;
906 /* copy the nick to the two buffers */
907 len
= rb_sprintf(ptr_nick
, "%s ", target_p
->name
);
910 len
= rb_sprintf(ptr_uid
, "%s ", use_id(target_p
));
917 if(!IsMember(target_p
, chptr
))
919 add_user_to_channel(chptr
, target_p
, fl
);
920 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s!%s@%s JOIN :%s",
922 target_p
->username
, target_p
->host
, parv
[2]);
929 para
[pargs
++] = target_p
->name
;
931 /* a +ov user.. bleh */
934 /* its possible the +o has filled up MAXMODEPARAMS, if so, start
937 if(pargs
>= MAXMODEPARAMS
)
940 sendto_channel_local(ALL_MEMBERS
, chptr
,
941 ":%s MODE %s %s %s %s %s %s",
942 fakesource_p
->name
, chptr
->chname
,
944 para
[0], para
[1], para
[2], para
[3]);
947 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
952 para
[pargs
++] = target_p
->name
;
955 else if(fl
& CHFL_VOICE
)
958 para
[pargs
++] = target_p
->name
;
961 if(pargs
>= MAXMODEPARAMS
)
964 sendto_channel_local(ALL_MEMBERS
, chptr
,
965 ":%s MODE %s %s %s %s %s %s",
968 modebuf
, para
[0], para
[1], para
[2], para
[3]);
971 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
976 /* p points to the next nick */
979 /* if there was a trailing space and p was pointing to it, then we
980 * need to exit.. this has the side effect of breaking double spaces
981 * in an sjoin.. but that shouldnt happen anyway
983 if(s
&& (*s
== '\0'))
986 /* if p was NULL due to no spaces, s wont exist due to the above, so
987 * we cant check it for spaces.. if there are no spaces, then when
988 * we next get here, s will be NULL
990 if(s
&& ((p
= strchr(s
, ' ')) != NULL
))
999 sendto_channel_local(ALL_MEMBERS
, chptr
,
1000 ":%s MODE %s %s %s %s %s %s",
1001 fakesource_p
->name
, chptr
->chname
, modebuf
,
1002 para
[0], CheckEmpty(para
[1]),
1003 CheckEmpty(para
[2]), CheckEmpty(para
[3]));
1006 if(!joins
&& !(chptr
->mode
.mode
& MODE_PERMANENT
) && isnew
)
1008 destroy_channel(chptr
);
1013 /* Keep the colon if we're sending an SJOIN without nicks -- jilles */
1016 *(ptr_nick
- 1) = '\0';
1017 *(ptr_uid
- 1) = '\0';
1020 sendto_server(client_p
->from
, NULL
, CAP_TS6
, NOCAPS
, "%s", buf_uid
);
1021 sendto_server(client_p
->from
, NULL
, NOCAPS
, CAP_TS6
, "%s", buf_nick
);
1023 /* if the source does TS6 we have to remove our bans. Its now safe
1024 * to issue -b's to the non-ts6 servers, as the sjoin we've just
1025 * sent will kill any ops they have.
1027 if(!keep_our_modes
&& source_p
->id
[0] != '\0')
1029 if(rb_dlink_list_length(&chptr
->banlist
) > 0)
1030 remove_ban_list(chptr
, fakesource_p
, &chptr
->banlist
, 'b', NOCAPS
, ALL_MEMBERS
);
1032 if(rb_dlink_list_length(&chptr
->exceptlist
) > 0)
1033 remove_ban_list(chptr
, fakesource_p
, &chptr
->exceptlist
,
1034 'e', CAP_EX
, ONLY_CHANOPS
);
1036 if(rb_dlink_list_length(&chptr
->invexlist
) > 0)
1037 remove_ban_list(chptr
, fakesource_p
, &chptr
->invexlist
,
1038 'I', CAP_IE
, ONLY_CHANOPS
);
1040 if(rb_dlink_list_length(&chptr
->quietlist
) > 0)
1041 remove_ban_list(chptr
, fakesource_p
, &chptr
->quietlist
,
1042 'q', NOCAPS
, ALL_MEMBERS
);
1053 * inputs - pointer to client doing join 0
1055 * side effects - Use has decided to join 0. This is legacy
1056 * from the days when channels were numbers not names. *sigh*
1057 * There is a bunch of evilness necessary here due to
1058 * anti spambot code.
1061 do_join_0(struct Client
*client_p
, struct Client
*source_p
)
1063 struct membership
*msptr
;
1064 struct Channel
*chptr
= NULL
;
1067 /* Finish the flood grace period... */
1068 if(MyClient(source_p
) && !IsFloodDone(source_p
))
1069 flood_endgrace(source_p
);
1072 sendto_server(client_p
, NULL
, CAP_TS6
, NOCAPS
, ":%s JOIN 0", use_id(source_p
));
1073 sendto_server(client_p
, NULL
, NOCAPS
, CAP_TS6
, ":%s JOIN 0", source_p
->name
);
1075 if(source_p
->user
->channel
.head
&& MyConnect(source_p
) &&
1076 !IsOper(source_p
) && !IsExemptSpambot(source_p
))
1077 check_spambot_warning(source_p
, NULL
);
1079 while((ptr
= source_p
->user
->channel
.head
))
1082 chptr
= msptr
->chptr
;
1083 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s!%s@%s PART %s",
1085 source_p
->username
, source_p
->host
, chptr
->chname
);
1086 remove_user_from_channel(msptr
);
1091 check_channel_name_loc(struct Client
*source_p
, const char *name
)
1093 s_assert(name
!= NULL
);
1094 if(EmptyString(name
))
1097 if(ConfigFileEntry
.disable_fake_channels
&& !IsOper(source_p
))
1099 for(; *name
; ++name
)
1101 if(!IsChanChar(*name
) || IsFakeChanChar(*name
))
1107 for(; *name
; ++name
)
1109 if(!IsChanChar(*name
))
1118 set_final_mode(struct Mode
*mode
, struct Mode
*oldmode
)
1120 int dir
= MODE_QUERY
;
1121 char *pbuf
= parabuf
;
1125 /* ok, first get a list of modes we need to add */
1126 for (i
= 0; chmode_flags
[i
].letter
; i
++)
1128 if((mode
->mode
& chmode_flags
[i
].mode
) && !(oldmode
->mode
& chmode_flags
[i
].mode
))
1135 *mbuf
++ = chmode_flags
[i
].letter
;
1139 /* now the ones we need to remove. */
1140 for (i
= 0; chmode_flags
[i
].letter
; i
++)
1142 if((oldmode
->mode
& chmode_flags
[i
].mode
) && !(mode
->mode
& chmode_flags
[i
].mode
))
1149 *mbuf
++ = chmode_flags
[i
].letter
;
1153 if(oldmode
->limit
&& !mode
->limit
)
1162 if(oldmode
->key
[0] && !mode
->key
[0])
1170 len
= rb_sprintf(pbuf
, "%s ", oldmode
->key
);
1173 if(oldmode
->join_num
&& !mode
->join_num
)
1182 if(oldmode
->forward
[0] && !mode
->forward
[0])
1191 if(mode
->limit
&& oldmode
->limit
!= mode
->limit
)
1199 len
= rb_sprintf(pbuf
, "%d ", mode
->limit
);
1202 if(mode
->key
[0] && strcmp(oldmode
->key
, mode
->key
))
1210 len
= rb_sprintf(pbuf
, "%s ", mode
->key
);
1213 if(mode
->join_num
&& (oldmode
->join_num
!= mode
->join_num
|| oldmode
->join_time
!= mode
->join_time
))
1221 len
= rb_sprintf(pbuf
, "%d:%d ", mode
->join_num
, mode
->join_time
);
1224 if(mode
->forward
[0] && strcmp(oldmode
->forward
, mode
->forward
) && ConfigChannel
.use_forward
)
1232 len
= rb_sprintf(pbuf
, "%s ", mode
->forward
);
1246 remove_our_modes(struct Channel
*chptr
, struct Client
*source_p
)
1248 struct membership
*msptr
;
1250 char lmodebuf
[MODEBUFLEN
];
1251 char *lpara
[MAXMODEPARAMS
];
1258 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1261 RB_DLINK_FOREACH(ptr
, chptr
->members
.head
)
1265 if(is_chanop(msptr
))
1267 msptr
->flags
&= ~CHFL_CHANOP
;
1268 lpara
[count
++] = msptr
->client_p
->name
;
1271 /* +ov, might not fit so check. */
1272 if(is_voiced(msptr
))
1274 if(count
>= MAXMODEPARAMS
)
1277 sendto_channel_local(ALL_MEMBERS
, chptr
,
1278 ":%s MODE %s %s %s %s %s %s",
1279 me
.name
, chptr
->chname
,
1280 lmodebuf
, lpara
[0], lpara
[1],
1281 lpara
[2], lpara
[3]);
1283 /* preserve the initial '-' */
1288 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1292 msptr
->flags
&= ~CHFL_VOICE
;
1293 lpara
[count
++] = msptr
->client_p
->name
;
1297 else if(is_voiced(msptr
))
1299 msptr
->flags
&= ~CHFL_VOICE
;
1300 lpara
[count
++] = msptr
->client_p
->name
;
1306 if(count
>= MAXMODEPARAMS
)
1309 sendto_channel_local(ALL_MEMBERS
, chptr
,
1310 ":%s MODE %s %s %s %s %s %s",
1311 me
.name
, chptr
->chname
, lmodebuf
,
1312 lpara
[0], lpara
[1], lpara
[2], lpara
[3]);
1317 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1325 sendto_channel_local(ALL_MEMBERS
, chptr
,
1326 ":%s MODE %s %s %s %s %s %s",
1327 me
.name
, chptr
->chname
, lmodebuf
,
1328 EmptyString(lpara
[0]) ? "" : lpara
[0],
1329 EmptyString(lpara
[1]) ? "" : lpara
[1],
1330 EmptyString(lpara
[2]) ? "" : lpara
[2],
1331 EmptyString(lpara
[3]) ? "" : lpara
[3]);
1336 /* remove_ban_list()
1338 * inputs - channel, source, list to remove, char of mode, caps needed
1340 * side effects - given list is removed, with modes issued to local clients
1341 * and non-TS6 servers.
1344 remove_ban_list(struct Channel
*chptr
, struct Client
*source_p
,
1345 rb_dlink_list
* list
, char c
, int cap
, int mems
)
1347 static char lmodebuf
[BUFSIZE
];
1348 static char lparabuf
[BUFSIZE
];
1351 rb_dlink_node
*next_ptr
;
1354 int cur_len
, mlen
, plen
;
1358 cur_len
= mlen
= rb_sprintf(lmodebuf
, ":%s MODE %s -", source_p
->name
, chptr
->chname
);
1359 mbuf
= lmodebuf
+ mlen
;
1361 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, list
->head
)
1365 /* trailing space, and the mode letter itself */
1366 plen
= strlen(banptr
->banstr
) + 2;
1368 if(count
>= MAXMODEPARAMS
|| (cur_len
+ plen
) > BUFSIZE
- 4)
1370 /* remove trailing space */
1374 sendto_channel_local(mems
, chptr
, "%s %s", lmodebuf
, lparabuf
);
1375 /* Tricky tricky. If we changed source_p to &me
1376 * in ms_sjoin(), this still won't send stuff
1377 * where it should not be sent, because the
1378 * real source_p does TS6 -- jilles */
1379 sendto_server(source_p
, chptr
, cap
, CAP_TS6
, "%s %s", lmodebuf
, lparabuf
);
1382 mbuf
= lmodebuf
+ mlen
;
1389 pbuf
+= rb_sprintf(pbuf
, "%s ", banptr
->banstr
);
1397 sendto_channel_local(mems
, chptr
, "%s %s", lmodebuf
, lparabuf
);
1398 sendto_server(source_p
, chptr
, cap
, CAP_TS6
, "%s %s", lmodebuf
, lparabuf
);
1400 list
->head
= list
->tail
= NULL
;