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 $
38 #include "s_newconf.h"
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 **);
49 static int h_can_create_channel
;
50 static int h_channel_join
;
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}}
57 struct Message sjoin_msgtab
= {
58 "SJOIN", 0, 0, 0, MFLG_SLOW
,
59 {mg_unreg
, mg_ignore
, mg_ignore
, {ms_sjoin
, 4}, mg_ignore
, mg_ignore
}
62 mapi_clist_av1 join_clist
[] = { &join_msgtab
, &sjoin_msgtab
, NULL
};
64 mapi_hlist_av1 join_hlist
[] = {
65 { "can_create_channel", &h_can_create_channel
},
66 { "channel_join", &h_channel_join
},
70 DECLARE_MODULE_AV1(join
, NULL
, NULL
, join_clist
, join_hlist
, NULL
, "$Revision: 3494 $");
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
);
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
);
78 static void remove_ban_list(struct Channel
*chptr
, struct Client
*source_p
,
79 rb_dlink_list
* list
, char c
, int mems
);
81 static char modebuf
[MODEBUFLEN
];
82 static char parabuf
[MODEBUFLEN
];
83 static const char *para
[MAXMODEPARAMS
];
90 * parv[2] = channel password (key)
93 m_join(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
95 static char jbuf
[BUFSIZE
];
96 struct Channel
*chptr
= NULL
;
97 struct ConfItem
*aconf
;
102 char *p
= NULL
, *p2
= NULL
;
108 /* rebuild the list of channels theyre supposed to be joining.
109 * this code has a side effect of losing keys, but..
111 chanlist
= LOCAL_COPY(parv
[1]);
112 for(name
= rb_strtok_r(chanlist
, ",", &p
); name
; name
= rb_strtok_r(NULL
, ",", &p
))
114 /* check the length and name of channel is ok */
115 if(!check_channel_name_loc(source_p
, name
) || (strlen(name
) > LOC_CHANNELLEN
))
117 sendto_one_numeric(source_p
, ERR_BADCHANNAME
,
118 form_str(ERR_BADCHANNAME
), (unsigned char *) name
);
122 /* join 0 parts all channels */
123 if(*name
== '0' && (name
[1] == ',' || name
[1] == '\0') && name
== chanlist
)
125 (void) strcpy(jbuf
, "0");
129 /* check it begins with # or &, and local chans are disabled */
130 else if(!IsChannelName(name
))
132 sendto_one_numeric(source_p
, ERR_NOSUCHCHANNEL
,
133 form_str(ERR_NOSUCHCHANNEL
), name
);
137 /* see if its resv'd */
138 if(!IsExemptResv(source_p
) && (aconf
= hash_find_resv(name
)))
140 sendto_one_numeric(source_p
, ERR_BADCHANNAME
,
141 form_str(ERR_BADCHANNAME
), name
);
143 /* dont warn for opers */
144 if(!IsExemptJupe(source_p
) && !IsOper(source_p
))
145 sendto_realops_snomask(SNO_SPY
, L_NETWIDE
,
146 "User %s (%s@%s) is attempting to join locally juped channel %s (%s)",
147 source_p
->name
, source_p
->username
,
148 source_p
->orighost
, name
, aconf
->passwd
);
149 /* dont update tracking for jupe exempt users, these
150 * are likely to be spamtrap leaves
152 else if(IsExemptJupe(source_p
))
158 if(splitmode
&& !IsOper(source_p
) && (*name
!= '&') &&
159 ConfigChannel
.no_join_on_split
)
161 sendto_one(source_p
, form_str(ERR_UNAVAILRESOURCE
),
162 me
.name
, source_p
->name
, name
);
167 (void) strcat(jbuf
, ",");
168 (void) rb_strlcat(jbuf
, name
, sizeof(jbuf
));
173 mykey
= LOCAL_COPY(parv
[2]);
174 key
= rb_strtok_r(mykey
, ",", &p2
);
177 for(name
= rb_strtok_r(jbuf
, ",", &p
); name
;
178 key
= (key
) ? rb_strtok_r(NULL
, ",", &p2
) : NULL
, name
= rb_strtok_r(NULL
, ",", &p
))
180 hook_data_channel_activity hook_info
;
182 /* JOIN 0 simply parts all channels the user is in */
183 if(*name
== '0' && !atoi(name
))
185 if(source_p
->user
->channel
.head
== NULL
)
188 do_join_0(&me
, source_p
);
192 /* look for the channel */
193 if((chptr
= find_channel(name
)) != NULL
)
195 if(IsMember(source_p
, chptr
))
202 hook_data_client_approval moduledata
;
204 moduledata
.client
= source_p
;
205 moduledata
.approved
= 0;
207 call_hook(h_can_create_channel
, &moduledata
);
209 if(moduledata
.approved
!= 0)
211 sendto_one(source_p
, form_str(moduledata
.approved
),
212 me
.name
, source_p
->name
, name
);
216 if(splitmode
&& !IsOper(source_p
) && (*name
!= '&') &&
217 ConfigChannel
.no_create_on_split
)
219 sendto_one(source_p
, form_str(ERR_UNAVAILRESOURCE
),
220 me
.name
, source_p
->name
, name
);
227 if((rb_dlink_list_length(&source_p
->user
->channel
) >=
228 (unsigned long) ConfigChannel
.max_chans_per_user
) &&
229 (!IsOper(source_p
) ||
230 (rb_dlink_list_length(&source_p
->user
->channel
) >=
231 (unsigned long) ConfigChannel
.max_chans_per_user
* 3)))
233 sendto_one(source_p
, form_str(ERR_TOOMANYCHANNELS
),
234 me
.name
, source_p
->name
, name
);
238 if(chptr
== NULL
) /* If I already have a chptr, no point doing this */
240 chptr
= get_or_create_channel(source_p
, name
, NULL
);
244 sendto_one(source_p
, form_str(ERR_UNAVAILRESOURCE
),
245 me
.name
, source_p
->name
, name
);
250 /* can_join checks for +i key, bans etc */
251 if((i
= can_join(source_p
, chptr
, key
)))
253 if ((i
!= ERR_NEEDREGGEDNICK
&& i
!= ERR_THROTTLE
&& i
!= ERR_INVITEONLYCHAN
&& i
!= ERR_CHANNELISFULL
) ||
254 (!ConfigChannel
.use_forward
|| (chptr
= check_forward(source_p
, chptr
, key
)) == NULL
))
256 /* might be wrong, but is there any other better location for such?
257 * see extensions/chm_operonly.c for other comments on this
261 sendto_one(source_p
, form_str(i
), me
.name
, source_p
->name
, name
);
266 sendto_one_numeric(source_p
, ERR_LINKCHANNEL
, form_str(ERR_LINKCHANNEL
), name
, chptr
->chname
);
270 !IsOper(source_p
) && !IsExemptSpambot(source_p
))
271 check_spambot_warning(source_p
, name
);
273 /* add the user to the channel */
274 add_user_to_channel(chptr
, source_p
, flags
);
275 if (chptr
->mode
.join_num
&&
276 rb_current_time() - chptr
->join_delta
>= chptr
->mode
.join_time
)
278 chptr
->join_count
= 0;
279 chptr
->join_delta
= rb_current_time();
283 /* we send the user their join here, because we could have to
284 * send a mode out next.
286 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s!%s@%s JOIN :%s",
288 source_p
->username
, source_p
->host
, chptr
->chname
);
290 /* its a new channel, set +nt and burst. */
291 if(flags
& CHFL_CHANOP
)
293 chptr
->channelts
= rb_current_time();
294 chptr
->mode
.mode
|= MODE_TOPICLIMIT
;
295 chptr
->mode
.mode
|= MODE_NOPRIVMSGS
;
296 modes
= channel_modes(chptr
, &me
);
298 sendto_channel_local(ONLY_CHANOPS
, chptr
, ":%s MODE %s %s",
299 me
.name
, chptr
->chname
, modes
);
301 sendto_server(client_p
, chptr
, CAP_TS6
, NOCAPS
,
302 ":%s SJOIN %ld %s %s :@%s",
303 me
.id
, (long) chptr
->channelts
,
304 chptr
->chname
, modes
, source_p
->id
);
308 sendto_server(client_p
, chptr
, CAP_TS6
, NOCAPS
,
310 use_id(source_p
), (long) chptr
->channelts
,
314 del_invite(chptr
, source_p
);
316 if(chptr
->topic
!= NULL
)
318 sendto_one(source_p
, form_str(RPL_TOPIC
), me
.name
,
319 source_p
->name
, chptr
->chname
, chptr
->topic
);
321 sendto_one(source_p
, form_str(RPL_TOPICWHOTIME
),
322 me
.name
, source_p
->name
, chptr
->chname
,
323 chptr
->topic_info
, chptr
->topic_time
);
326 channel_member_names(chptr
, source_p
, 1);
328 hook_info
.client
= source_p
;
329 hook_info
.chptr
= chptr
;
331 call_hook(h_channel_join
, &hook_info
);
339 * parv[1] = channel TS
341 * parv[3] = "+", formerly channel modes but now unused
342 * alternatively, a single "0" parameter parts all channels
345 ms_join(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
347 struct Channel
*chptr
;
348 static struct Mode mode
;
352 int keep_our_modes
= YES
;
353 int keep_new_modes
= YES
;
354 rb_dlink_node
*ptr
, *next_ptr
;
356 /* special case for join 0 */
357 if((parv
[1][0] == '0') && (parv
[1][1] == '\0') && parc
== 2)
359 do_join_0(client_p
, source_p
);
366 if(!IsChannelName(parv
[2]) || !check_channel_name(parv
[2]))
369 /* joins for local channels cant happen. */
370 if(parv
[2][0] == '&')
374 mode
.key
[0] = mode
.forward
[0] = '\0';
375 mode
.mode
= mode
.limit
= mode
.join_num
= mode
.join_time
= 0;
377 if((chptr
= get_or_create_channel(source_p
, parv
[2], &isnew
)) == NULL
)
380 newts
= atol(parv
[1]);
381 oldts
= chptr
->channelts
;
383 #ifdef IGNORE_BOGUS_TS
384 if(newts
< 800000000)
386 sendto_realops_snomask(SNO_DEBUG
, L_ALL
,
387 "*** Bogus TS %ld on %s ignored from %s",
388 (long) newts
, chptr
->chname
, client_p
->name
);
389 newts
= (oldts
== 0) ? oldts
: 800000000;
392 /* making a channel TS0 */
393 if(!isnew
&& !newts
&& oldts
)
395 sendto_channel_local(ALL_MEMBERS
, chptr
,
396 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to 0",
397 me
.name
, chptr
->chname
, chptr
->chname
, (long) oldts
);
398 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
399 "Server %s changing TS on %s from %ld to 0",
400 source_p
->name
, chptr
->chname
, (long) oldts
);
405 chptr
->channelts
= newts
;
406 else if(newts
== 0 || oldts
== 0)
407 chptr
->channelts
= 0;
408 else if(newts
== oldts
)
410 else if(newts
< oldts
)
413 chptr
->channelts
= newts
;
418 /* Lost the TS, other side wins, so remove modes on this side */
421 set_final_mode(&mode
, &chptr
->mode
);
423 remove_our_modes(chptr
, source_p
);
424 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->invites
.head
)
426 del_invite(chptr
, ptr
->data
);
428 /* If setting -j, clear join throttle state -- jilles */
429 chptr
->join_count
= chptr
->join_delta
= 0;
430 sendto_channel_local(ALL_MEMBERS
, chptr
,
431 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
432 me
.name
, chptr
->chname
, chptr
->chname
,
433 (long) oldts
, (long) newts
);
434 /* Update capitalization in channel name, this makes the
435 * capitalization timestamped like modes are -- jilles */
436 strcpy(chptr
->chname
, parv
[2]);
438 sendto_channel_local(ALL_MEMBERS
, chptr
,
440 source_p
->servptr
->name
,
441 chptr
->chname
, modebuf
, parabuf
);
442 *modebuf
= *parabuf
= '\0';
445 if(!IsMember(source_p
, chptr
))
447 add_user_to_channel(chptr
, source_p
, CHFL_PEON
);
448 if (chptr
->mode
.join_num
&&
449 rb_current_time() - chptr
->join_delta
>= chptr
->mode
.join_time
)
451 chptr
->join_count
= 0;
452 chptr
->join_delta
= rb_current_time();
455 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s!%s@%s JOIN :%s",
456 source_p
->name
, source_p
->username
,
457 source_p
->host
, chptr
->chname
);
460 sendto_server(client_p
, chptr
, CAP_TS6
, NOCAPS
,
462 source_p
->id
, (long) chptr
->channelts
, chptr
->chname
);
467 ms_sjoin(struct Client
*client_p
, struct Client
*source_p
, int parc
, const char *parv
[])
469 static char buf_uid
[BUFSIZE
];
470 static const char empty_modes
[] = "0";
471 struct Channel
*chptr
;
472 struct Client
*target_p
, *fakesource_p
;
475 static struct Mode mode
, *oldmode
;
478 int keep_our_modes
= 1;
479 int keep_new_modes
= 1;
490 int i
, joinc
= 0, timeslice
= 0;
491 static char empty
[] = "";
492 rb_dlink_node
*ptr
, *next_ptr
;
494 if(!IsChannelName(parv
[2]) || !check_channel_name(parv
[2]))
497 /* SJOIN's for local channels can't happen. */
501 modebuf
[0] = parabuf
[0] = mode
.key
[0] = mode
.forward
[0] = '\0';
502 pargs
= mode
.mode
= mode
.limit
= mode
.join_num
= mode
.join_time
= 0;
504 /* Hide connecting server on netburst -- jilles */
505 if (ConfigServerHide
.flatten_links
&& !HasSentEob(source_p
))
508 fakesource_p
= source_p
;
511 newts
= atol(parv
[1]);
519 rb_strlcpy(mode
.forward
, parv
[4 + args
], sizeof(mode
.forward
));
525 sscanf(parv
[4 + args
], "%d:%d", &joinc
, ×lice
);
527 mode
.join_num
= joinc
;
528 mode
.join_time
= timeslice
;
533 rb_strlcpy(mode
.key
, parv
[4 + args
], sizeof(mode
.key
));
539 mode
.limit
= atoi(parv
[4 + args
]);
545 if(chmode_flags
[(int) *s
] != 0)
547 mode
.mode
|= chmode_flags
[(int) *s
];
556 /* remove any leading spaces */
563 if((chptr
= get_or_create_channel(source_p
, parv
[2], &isnew
)) == NULL
)
564 return 0; /* channel name too long? */
567 oldts
= chptr
->channelts
;
568 oldmode
= &chptr
->mode
;
570 #ifdef IGNORE_BOGUS_TS
571 if(newts
< 800000000)
573 sendto_realops_snomask(SNO_DEBUG
, L_ALL
,
574 "*** Bogus TS %ld on %s ignored from %s",
575 (long) newts
, chptr
->chname
, client_p
->name
);
577 newts
= (oldts
== 0) ? oldts
: 800000000;
580 if(!isnew
&& !newts
&& oldts
)
582 sendto_channel_local(ALL_MEMBERS
, chptr
,
583 ":%s NOTICE %s :*** Notice -- TS for %s "
584 "changed from %ld to 0",
585 me
.name
, chptr
->chname
, chptr
->chname
, (long) oldts
);
586 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
587 "Server %s changing TS on %s from %ld to 0",
588 source_p
->name
, chptr
->chname
, (long) oldts
);
593 chptr
->channelts
= newts
;
595 else if(newts
== 0 || oldts
== 0)
596 chptr
->channelts
= 0;
597 else if(newts
== oldts
)
599 else if(newts
< oldts
)
601 /* If configured, kick people trying to join +i/+k
602 * channels by recreating them on split servers.
603 * Don't kick if the source has sent EOB (services
604 * deopping everyone by TS-1 SJOIN).
606 if (ConfigChannel
.kick_on_split_riding
&&
607 !HasSentEob(source_p
) &&
608 ((mode
.mode
& MODE_INVITEONLY
) ||
609 (mode
.key
[0] != 0 && irccmp(mode
.key
, oldmode
->key
) != 0)))
611 struct membership
*msptr
;
613 int l
= rb_dlink_list_length(&chptr
->members
);
615 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->locmembers
.head
)
618 who
= msptr
->client_p
;
619 sendto_one(who
, ":%s KICK %s %s :Net Rider",
620 me
.name
, chptr
->chname
, who
->name
);
622 sendto_server(NULL
, chptr
, CAP_TS6
, NOCAPS
,
623 ":%s KICK %s %s :Net Rider",
624 me
.id
, chptr
->chname
,
626 remove_user_from_channel(msptr
);
632 /* Channel was emptied, create a new one */
633 if((chptr
= get_or_create_channel(source_p
, parv
[2], &isnew
)) == NULL
)
634 return 0; /* oops! */
636 oldmode
= &chptr
->mode
;
640 chptr
->channelts
= newts
;
647 else if(keep_our_modes
)
649 mode
.mode
|= oldmode
->mode
;
650 if(oldmode
->limit
> mode
.limit
)
651 mode
.limit
= oldmode
->limit
;
652 if(strcmp(mode
.key
, oldmode
->key
) < 0)
653 strcpy(mode
.key
, oldmode
->key
);
654 if(oldmode
->join_num
> mode
.join_num
||
655 (oldmode
->join_num
== mode
.join_num
&&
656 oldmode
->join_time
> mode
.join_time
))
658 mode
.join_num
= oldmode
->join_num
;
659 mode
.join_time
= oldmode
->join_time
;
661 if(irccmp(mode
.forward
, oldmode
->forward
) < 0)
662 strcpy(mode
.forward
, oldmode
->forward
);
666 /* If setting -j, clear join throttle state -- jilles */
668 chptr
->join_count
= chptr
->join_delta
= 0;
671 set_final_mode(&mode
, oldmode
);
674 /* Lost the TS, other side wins, so remove modes on this side */
677 remove_our_modes(chptr
, fakesource_p
);
678 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->invites
.head
)
680 del_invite(chptr
, ptr
->data
);
683 if(rb_dlink_list_length(&chptr
->banlist
) > 0)
684 remove_ban_list(chptr
, fakesource_p
, &chptr
->banlist
, 'b', ALL_MEMBERS
);
685 if(rb_dlink_list_length(&chptr
->exceptlist
) > 0)
686 remove_ban_list(chptr
, fakesource_p
, &chptr
->exceptlist
,
688 if(rb_dlink_list_length(&chptr
->invexlist
) > 0)
689 remove_ban_list(chptr
, fakesource_p
, &chptr
->invexlist
,
691 if(rb_dlink_list_length(&chptr
->quietlist
) > 0)
692 remove_ban_list(chptr
, fakesource_p
, &chptr
->quietlist
,
696 sendto_channel_local(ALL_MEMBERS
, chptr
,
697 ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld",
698 me
.name
, chptr
->chname
, chptr
->chname
,
699 (long) oldts
, (long) newts
);
700 /* Update capitalization in channel name, this makes the
701 * capitalization timestamped like modes are -- jilles */
702 strcpy(chptr
->chname
, parv
[2]);
706 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s MODE %s %s %s",
707 fakesource_p
->name
, chptr
->chname
, modebuf
, parabuf
);
709 *modebuf
= *parabuf
= '\0';
711 if(parv
[3][0] != '0' && keep_new_modes
)
712 modes
= channel_modes(chptr
, source_p
);
716 mlen_uid
= rb_sprintf(buf_uid
, ":%s SJOIN %ld %s %s :",
717 use_id(source_p
), (long) chptr
->channelts
, parv
[2], modes
);
718 ptr_uid
= buf_uid
+ mlen_uid
;
721 para
[0] = para
[1] = para
[2] = para
[3] = empty
;
723 len_nick
= len_uid
= 0;
725 /* if theres a space, theres going to be more than one nick, change the
726 * first space to \0, so s is just the first nick, and point p to the
729 if((p
= strchr(s
, ' ')) != NULL
)
740 for (i
= 0; i
< 2; i
++)
754 /* if the client doesnt exist or is fake direction, skip. */
755 if(!(target_p
= find_client(s
)) ||
756 (target_p
->from
!= client_p
) || !IsPerson(target_p
))
759 /* we assume for these we can fit at least one nick/uid in.. */
761 /* check we can fit another status+nick+space into a buffer */
762 if((mlen_uid
+ len_uid
+ IDLEN
+ 3) > (BUFSIZE
- 3))
764 *(ptr_uid
- 1) = '\0';
765 sendto_server(client_p
->from
, NULL
, CAP_TS6
, NOCAPS
, "%s", buf_uid
);
766 ptr_uid
= buf_uid
+ mlen_uid
;
786 /* copy the nick to the two buffers */
787 len
= rb_sprintf(ptr_uid
, "%s ", use_id(target_p
));
794 if(!IsMember(target_p
, chptr
))
796 add_user_to_channel(chptr
, target_p
, fl
);
797 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s!%s@%s JOIN :%s",
799 target_p
->username
, target_p
->host
, parv
[2]);
806 para
[pargs
++] = target_p
->name
;
808 /* a +ov user.. bleh */
811 /* its possible the +o has filled up MAXMODEPARAMS, if so, start
814 if(pargs
>= MAXMODEPARAMS
)
817 sendto_channel_local(ALL_MEMBERS
, chptr
,
818 ":%s MODE %s %s %s %s %s %s",
819 fakesource_p
->name
, chptr
->chname
,
821 para
[0], para
[1], para
[2], para
[3]);
824 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
829 para
[pargs
++] = target_p
->name
;
832 else if(fl
& CHFL_VOICE
)
835 para
[pargs
++] = target_p
->name
;
838 if(pargs
>= MAXMODEPARAMS
)
841 sendto_channel_local(ALL_MEMBERS
, chptr
,
842 ":%s MODE %s %s %s %s %s %s",
845 modebuf
, para
[0], para
[1], para
[2], para
[3]);
848 para
[0] = para
[1] = para
[2] = para
[3] = NULL
;
853 /* p points to the next nick */
856 /* if there was a trailing space and p was pointing to it, then we
857 * need to exit.. this has the side effect of breaking double spaces
858 * in an sjoin.. but that shouldnt happen anyway
860 if(s
&& (*s
== '\0'))
863 /* if p was NULL due to no spaces, s wont exist due to the above, so
864 * we cant check it for spaces.. if there are no spaces, then when
865 * we next get here, s will be NULL
867 if(s
&& ((p
= strchr(s
, ' ')) != NULL
))
876 sendto_channel_local(ALL_MEMBERS
, chptr
,
877 ":%s MODE %s %s %s %s %s %s",
878 fakesource_p
->name
, chptr
->chname
, modebuf
,
879 para
[0], CheckEmpty(para
[1]),
880 CheckEmpty(para
[2]), CheckEmpty(para
[3]));
883 if(!joins
&& !(chptr
->mode
.mode
& MODE_PERMANENT
) && isnew
)
885 destroy_channel(chptr
);
890 /* Keep the colon if we're sending an SJOIN without nicks -- jilles */
893 *(ptr_uid
- 1) = '\0';
896 sendto_server(client_p
->from
, NULL
, CAP_TS6
, NOCAPS
, "%s", buf_uid
);
904 * inputs - pointer to client doing join 0
906 * side effects - Use has decided to join 0. This is legacy
907 * from the days when channels were numbers not names. *sigh*
910 do_join_0(struct Client
*client_p
, struct Client
*source_p
)
912 struct membership
*msptr
;
913 struct Channel
*chptr
= NULL
;
916 /* Finish the flood grace period... */
917 if(MyClient(source_p
) && !IsFloodDone(source_p
))
918 flood_endgrace(source_p
);
920 sendto_server(client_p
, NULL
, CAP_TS6
, NOCAPS
, ":%s JOIN 0", use_id(source_p
));
922 while((ptr
= source_p
->user
->channel
.head
))
924 if(MyConnect(source_p
) &&
925 !IsOper(source_p
) && !IsExemptSpambot(source_p
))
926 check_spambot_warning(source_p
, NULL
);
929 chptr
= msptr
->chptr
;
930 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s!%s@%s PART %s",
932 source_p
->username
, source_p
->host
, chptr
->chname
);
933 remove_user_from_channel(msptr
);
938 check_channel_name_loc(struct Client
*source_p
, const char *name
)
942 s_assert(name
!= NULL
);
943 if(EmptyString(name
))
946 if(ConfigFileEntry
.disable_fake_channels
&& !IsOper(source_p
))
948 for(p
= name
; *p
; ++p
)
950 if(!IsChanChar(*p
) || IsFakeChanChar(*p
))
956 for(p
= name
; *p
; ++p
)
963 if(ConfigChannel
.only_ascii_channels
)
965 for(p
= name
; *p
; ++p
)
966 if(*p
< 33 || *p
> 126)
974 set_final_mode(struct Mode
*mode
, struct Mode
*oldmode
)
976 int dir
= MODE_QUERY
;
977 char *pbuf
= parabuf
;
981 /* ok, first get a list of modes we need to add */
982 for (i
= 0; i
< 256; i
++)
984 if((mode
->mode
& chmode_flags
[i
]) && !(oldmode
->mode
& chmode_flags
[i
]))
995 /* now the ones we need to remove. */
996 for (i
= 0; i
< 256; i
++)
998 if((oldmode
->mode
& chmode_flags
[i
]) && !(mode
->mode
& chmode_flags
[i
]))
1009 if(oldmode
->limit
&& !mode
->limit
)
1018 if(oldmode
->key
[0] && !mode
->key
[0])
1026 len
= rb_sprintf(pbuf
, "%s ", oldmode
->key
);
1029 if(oldmode
->join_num
&& !mode
->join_num
)
1038 if(oldmode
->forward
[0] && !mode
->forward
[0])
1047 if(mode
->limit
&& oldmode
->limit
!= mode
->limit
)
1055 len
= rb_sprintf(pbuf
, "%d ", mode
->limit
);
1058 if(mode
->key
[0] && strcmp(oldmode
->key
, mode
->key
))
1066 len
= rb_sprintf(pbuf
, "%s ", mode
->key
);
1069 if(mode
->join_num
&& (oldmode
->join_num
!= mode
->join_num
|| oldmode
->join_time
!= mode
->join_time
))
1077 len
= rb_sprintf(pbuf
, "%d:%d ", mode
->join_num
, mode
->join_time
);
1080 if(mode
->forward
[0] && strcmp(oldmode
->forward
, mode
->forward
) && ConfigChannel
.use_forward
)
1088 len
= rb_sprintf(pbuf
, "%s ", mode
->forward
);
1102 remove_our_modes(struct Channel
*chptr
, struct Client
*source_p
)
1104 struct membership
*msptr
;
1106 char lmodebuf
[MODEBUFLEN
];
1107 char *lpara
[MAXMODEPARAMS
];
1114 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1117 RB_DLINK_FOREACH(ptr
, chptr
->members
.head
)
1121 if(is_chanop(msptr
))
1123 msptr
->flags
&= ~CHFL_CHANOP
;
1124 lpara
[count
++] = msptr
->client_p
->name
;
1127 /* +ov, might not fit so check. */
1128 if(is_voiced(msptr
))
1130 if(count
>= MAXMODEPARAMS
)
1133 sendto_channel_local(ALL_MEMBERS
, chptr
,
1134 ":%s MODE %s %s %s %s %s %s",
1135 source_p
->name
, chptr
->chname
,
1136 lmodebuf
, lpara
[0], lpara
[1],
1137 lpara
[2], lpara
[3]);
1139 /* preserve the initial '-' */
1144 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1148 msptr
->flags
&= ~CHFL_VOICE
;
1149 lpara
[count
++] = msptr
->client_p
->name
;
1153 else if(is_voiced(msptr
))
1155 msptr
->flags
&= ~CHFL_VOICE
;
1156 lpara
[count
++] = msptr
->client_p
->name
;
1162 if(count
>= MAXMODEPARAMS
)
1165 sendto_channel_local(ALL_MEMBERS
, chptr
,
1166 ":%s MODE %s %s %s %s %s %s",
1167 source_p
->name
, chptr
->chname
, lmodebuf
,
1168 lpara
[0], lpara
[1], lpara
[2], lpara
[3]);
1173 for(i
= 0; i
< MAXMODEPARAMS
; i
++)
1181 sendto_channel_local(ALL_MEMBERS
, chptr
,
1182 ":%s MODE %s %s %s %s %s %s",
1183 source_p
->name
, chptr
->chname
, lmodebuf
,
1184 EmptyString(lpara
[0]) ? "" : lpara
[0],
1185 EmptyString(lpara
[1]) ? "" : lpara
[1],
1186 EmptyString(lpara
[2]) ? "" : lpara
[2],
1187 EmptyString(lpara
[3]) ? "" : lpara
[3]);
1192 /* remove_ban_list()
1194 * inputs - channel, source, list to remove, char of mode, caps needed
1196 * side effects - given list is removed, with modes issued to local clients
1199 remove_ban_list(struct Channel
*chptr
, struct Client
*source_p
,
1200 rb_dlink_list
* list
, char c
, int mems
)
1202 static char lmodebuf
[BUFSIZE
];
1203 static char lparabuf
[BUFSIZE
];
1206 rb_dlink_node
*next_ptr
;
1209 int cur_len
, mlen
, plen
;
1213 cur_len
= mlen
= rb_sprintf(lmodebuf
, ":%s MODE %s -", source_p
->name
, chptr
->chname
);
1214 mbuf
= lmodebuf
+ mlen
;
1216 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, list
->head
)
1220 /* trailing space, and the mode letter itself */
1221 plen
= strlen(banptr
->banstr
) + 2;
1223 if(count
>= MAXMODEPARAMS
|| (cur_len
+ plen
) > BUFSIZE
- 4)
1225 /* remove trailing space */
1229 sendto_channel_local(mems
, chptr
, "%s %s", lmodebuf
, lparabuf
);
1232 mbuf
= lmodebuf
+ mlen
;
1239 pbuf
+= rb_sprintf(pbuf
, "%s ", banptr
->banstr
);
1247 sendto_channel_local(mems
, chptr
, "%s %s", lmodebuf
, lparabuf
);
1249 list
->head
= list
->tail
= NULL
;