2 * ircd-ratbox: A slightly useful ircd.
3 * channel.c: Controls channels.
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
36 #include "s_serv.h" /* captab */
40 #include "s_conf.h" /* ConfigFileEntry, ConfigChannel */
41 #include "s_newconf.h"
44 #include "irc_dictionary.h"
46 struct config_channel_entry ConfigChannel
;
47 rb_dlink_list global_channel_list
;
48 static rb_bh
*channel_heap
;
49 static rb_bh
*ban_heap
;
50 static rb_bh
*topic_heap
;
51 static rb_bh
*member_heap
;
53 static int channel_capabs
[] = { CAP_EX
, CAP_IE
,
58 #define NCHCAPS (sizeof(channel_capabs)/sizeof(int))
59 #define NCHCAP_COMBOS (1 << NCHCAPS)
61 static struct ChCapCombo chcap_combos
[NCHCAP_COMBOS
];
63 static void free_topic(struct Channel
*chptr
);
65 static int h_can_join
;
66 static int h_can_create_channel
;
67 static int h_channel_join
;
69 struct module_modes ModuleModes
;
75 * side effects - initialises the various blockheaps
80 channel_heap
= rb_bh_create(sizeof(struct Channel
), CHANNEL_HEAP_SIZE
, "channel_heap");
81 ban_heap
= rb_bh_create(sizeof(struct Ban
), BAN_HEAP_SIZE
, "ban_heap");
82 topic_heap
= rb_bh_create(TOPICLEN
+ 1 + USERHOST_REPLYLEN
, TOPIC_HEAP_SIZE
, "topic_heap");
83 member_heap
= rb_bh_create(sizeof(struct membership
), MEMBER_HEAP_SIZE
, "member_heap");
85 h_can_join
= register_hook("can_join");
86 h_channel_join
= register_hook("channel_join");
87 h_can_create_channel
= register_hook("can_create_channel");
90 /* is this the best place to put this? */
91 /* init_module_modes()
95 * side effects - various MODE_ values are set to 0
100 ModuleModes
.MODE_REGONLY
= 0;
101 ModuleModes
.MODE_NOCTCP
= 0;
102 ModuleModes
.MODE_NOCOLOR
= 0;
103 ModuleModes
.MODE_EXLIMIT
= 0;
104 ModuleModes
.MODE_PERMANENT
= 0;
105 ModuleModes
.MODE_OPMODERATE
= 0;
106 ModuleModes
.MODE_FREEINVITE
= 0;
107 ModuleModes
.MODE_FREETARGET
= 0;
108 ModuleModes
.MODE_DISFORWARD
= 0;
109 ModuleModes
.MODE_THROTTLE
= 0;
110 ModuleModes
.MODE_FORWARD
= 0;
111 ModuleModes
.MODE_NONOTICE
= 0;
112 ModuleModes
.MODE_NOACTION
= 0;
113 ModuleModes
.MODE_NOKICK
= 0;
114 ModuleModes
.MODE_NONICK
= 0;
115 ModuleModes
.MODE_NOCAPS
= 0;
116 ModuleModes
.MODE_NOREJOIN
= 0;
117 ModuleModes
.MODE_NOREPEAT
= 0;
118 ModuleModes
.MODE_NOOPERKICK
= 0;
120 ModuleModes
.CHFL_QUIET
= 0;
125 * allocate_channel - Allocates a channel
128 allocate_channel(const char *chname
)
130 struct Channel
*chptr
;
131 struct Dictionary
*metadata
;
132 chptr
= rb_bh_alloc(channel_heap
);
133 chptr
->chname
= rb_strdup(chname
);
135 metadata
= irc_dictionary_create(irccmp
);
136 chptr
->metadata
= metadata
;
141 free_channel(struct Channel
*chptr
)
143 channel_metadata_clear(chptr
);
144 rb_free(chptr
->chname
);
145 rb_bh_free(channel_heap
, chptr
);
149 allocate_ban(const char *banstr
, const char *who
)
152 bptr
= rb_bh_alloc(ban_heap
);
153 bptr
->banstr
= rb_strdup(banstr
);
154 bptr
->who
= rb_strdup(who
);
160 free_ban(struct Ban
*bptr
)
162 rb_free(bptr
->banstr
);
164 rb_bh_free(ban_heap
, bptr
);
168 /* find_channel_membership()
170 * input - channel to find them in, client to find
171 * output - membership of client in channel, else NULL
175 find_channel_membership(struct Channel
*chptr
, struct Client
*client_p
)
177 struct membership
*msptr
;
180 if(!IsClient(client_p
))
183 /* Pick the most efficient list to use to be nice to things like
184 * CHANSERV which could be in a large number of channels
186 if(rb_dlink_list_length(&chptr
->members
) < rb_dlink_list_length(&client_p
->user
->channel
))
188 RB_DLINK_FOREACH(ptr
, chptr
->members
.head
)
192 if(msptr
->client_p
== client_p
)
198 RB_DLINK_FOREACH(ptr
, client_p
->user
->channel
.head
)
202 if(msptr
->chptr
== chptr
)
210 /* find_channel_status()
212 * input - membership to get status for, whether we can combine flags
213 * output - flags of user on channel
217 find_channel_status(struct membership
*msptr
, int combine
)
219 static char buffer
[5];
254 * input - membership to check for halfops
255 * output - 1 if the user is halfopped, 0 if the user is not or halfop
261 is_halfop(struct membership
*msptr
)
263 if(!ConfigChannel
.use_halfop
)
265 if(is_chmode_h(msptr
))
273 * input - membership to check for admin
274 * output - 1 if the user is an admin, 0 if the user is not or admin
280 is_admin(struct membership
*msptr
)
282 if(!ConfigChannel
.use_admin
)
284 if(is_chmode_a(msptr
))
292 * input - membership to check for ops
293 * output - 1 if the user is op, halfop, or admin, 0 elsewise
297 is_any_op(struct membership
*msptr
)
299 if(is_chanop(msptr
) || is_halfop(msptr
) || is_admin(msptr
))
305 /* is_chanop_voiced()
307 * input - memebership to check for status
308 * output - 1 if the user is op, halfop, admin, or voice, 0 elsewise
312 is_chanop_voiced(struct membership
*msptr
)
314 if(is_chanop(msptr
) || is_voiced(msptr
) || is_halfop(msptr
) || is_admin(msptr
))
322 * input - two memeberships
323 * output - 1 if the first memebership can kick/deop the second, 0 elsewise
327 can_kick_deop(struct membership
*source
, struct membership
*target
)
329 if(is_chanop(source
) && !is_admin(target
))
331 else if(is_halfop(source
) && !is_any_op(target
))
333 else if(is_admin(source
))
339 /* add_user_to_channel()
341 * input - channel to add client to, client to add, channel flags
343 * side effects - user is added to channel
346 add_user_to_channel(struct Channel
*chptr
, struct Client
*client_p
, int flags
)
348 struct membership
*msptr
;
350 s_assert(client_p
->user
!= NULL
);
351 if(client_p
->user
== NULL
)
354 msptr
= rb_bh_alloc(member_heap
);
356 msptr
->chptr
= chptr
;
357 msptr
->client_p
= client_p
;
358 msptr
->flags
= flags
;
360 rb_dlinkAdd(msptr
, &msptr
->usernode
, &client_p
->user
->channel
);
361 rb_dlinkAdd(msptr
, &msptr
->channode
, &chptr
->members
);
363 if(MyClient(client_p
))
364 rb_dlinkAdd(msptr
, &msptr
->locchannode
, &chptr
->locmembers
);
367 /* remove_user_from_channel()
369 * input - membership pointer to remove from channel
371 * side effects - membership (thus user) is removed from channel
374 remove_user_from_channel(struct membership
*msptr
)
376 struct Client
*client_p
;
377 struct Channel
*chptr
;
378 s_assert(msptr
!= NULL
);
382 client_p
= msptr
->client_p
;
383 chptr
= msptr
->chptr
;
385 rb_dlinkDelete(&msptr
->usernode
, &client_p
->user
->channel
);
386 rb_dlinkDelete(&msptr
->channode
, &chptr
->members
);
388 if(client_p
->servptr
== &me
)
389 rb_dlinkDelete(&msptr
->locchannode
, &chptr
->locmembers
);
391 if(!(chptr
->mode
.mode
& ModuleModes
.MODE_PERMANENT
) && rb_dlink_list_length(&chptr
->members
) <= 0)
392 destroy_channel(chptr
);
394 rb_bh_free(member_heap
, msptr
);
399 /* remove_user_from_channels()
401 * input - user to remove from all channels
403 * side effects - user is removed from all channels
406 remove_user_from_channels(struct Client
*client_p
)
408 struct Channel
*chptr
;
409 struct membership
*msptr
;
411 rb_dlink_node
*next_ptr
;
416 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, client_p
->user
->channel
.head
)
419 chptr
= msptr
->chptr
;
421 rb_dlinkDelete(&msptr
->channode
, &chptr
->members
);
423 if(client_p
->servptr
== &me
)
424 rb_dlinkDelete(&msptr
->locchannode
, &chptr
->locmembers
);
426 if(!(chptr
->mode
.mode
& ModuleModes
.MODE_PERMANENT
) && rb_dlink_list_length(&chptr
->members
) <= 0)
427 destroy_channel(chptr
);
429 rb_bh_free(member_heap
, msptr
);
432 client_p
->user
->channel
.head
= client_p
->user
->channel
.tail
= NULL
;
433 client_p
->user
->channel
.length
= 0;
436 /* invalidate_bancache_user()
438 * input - user to invalidate ban cache for
440 * side effects - ban cache is invalidated for all memberships of that user
441 * to be used after a nick change
444 invalidate_bancache_user(struct Client
*client_p
)
446 struct membership
*msptr
;
452 RB_DLINK_FOREACH(ptr
, client_p
->user
->channel
.head
)
456 msptr
->flags
&= ~CHFL_BANNED
;
460 /* check_channel_name()
462 * input - channel name
463 * output - 1 if valid channel name, else 0
467 check_channel_name(const char *name
)
469 s_assert(name
!= NULL
);
473 for (; *name
; ++name
)
475 if(!IsChanChar(*name
))
482 /* free_channel_list()
484 * input - rb_dlink list to free
486 * side effects - list of b/e/I modes is cleared
489 free_channel_list(rb_dlink_list
* list
)
492 rb_dlink_node
*next_ptr
;
493 struct Ban
*actualBan
;
495 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, list
->head
)
497 actualBan
= ptr
->data
;
501 list
->head
= list
->tail
= NULL
;
507 * input - channel to destroy
509 * side effects - channel is obliterated
512 destroy_channel(struct Channel
*chptr
)
514 rb_dlink_node
*ptr
, *next_ptr
;
516 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->invites
.head
)
518 del_invite(chptr
, ptr
->data
);
521 /* free all bans/exceptions/denies */
522 free_channel_list(&chptr
->banlist
);
523 free_channel_list(&chptr
->exceptlist
);
524 free_channel_list(&chptr
->invexlist
);
525 free_channel_list(&chptr
->quietlist
);
530 rb_dlinkDelete(&chptr
->node
, &global_channel_list
);
531 del_from_channel_hash(chptr
->chname
, chptr
);
535 /* channel_pub_or_secret()
538 * output - "=" if public, "@" if secret, else "*"
542 channel_pub_or_secret(struct Channel
*chptr
)
544 if(PubChannel(chptr
))
546 else if(SecretChannel(chptr
))
551 /* channel_member_names()
553 * input - channel to list, client to list to, show endofnames
555 * side effects - client is given list of users on channel
558 channel_member_names(struct Channel
*chptr
, struct Client
*client_p
, int show_eon
)
560 struct membership
*msptr
;
561 struct Client
*target_p
;
569 int stack
= IsCapable(client_p
, CLICAP_MULTI_PREFIX
);
571 if(ShowChannel(client_p
, chptr
))
573 is_member
= IsMember(client_p
, chptr
);
575 cur_len
= mlen
= rb_sprintf(lbuf
, form_str(RPL_NAMREPLY
),
576 me
.name
, client_p
->name
,
577 channel_pub_or_secret(chptr
), chptr
->chname
);
581 RB_DLINK_FOREACH(ptr
, chptr
->members
.head
)
584 target_p
= msptr
->client_p
;
586 if(IsInvisible(target_p
) && !is_member
)
589 /* space, possible "@+" prefix */
590 if(cur_len
+ strlen(target_p
->name
) + 3 >= BUFSIZE
- 3)
593 sendto_one(client_p
, "%s", lbuf
);
598 tlen
= rb_sprintf(t
, "%s%s ", find_channel_status(msptr
, stack
),
605 /* The old behaviour here was to always output our buffer,
606 * even if there are no clients we can show. This happens
607 * when a client does "NAMES" with no parameters, and all
608 * the clients on a -sp channel are +i. I dont see a good
609 * reason for keeping that behaviour, as it just wastes
615 sendto_one(client_p
, "%s", lbuf
);
620 sendto_one(client_p
, form_str(RPL_ENDOFNAMES
),
621 me
.name
, client_p
->name
, chptr
->chname
);
626 * input - channel to remove invite from, client to remove
628 * side effects - user is removed from invite list, if exists
631 del_invite(struct Channel
*chptr
, struct Client
*who
)
633 rb_dlinkFindDestroy(who
, &chptr
->invites
);
634 rb_dlinkFindDestroy(chptr
, &who
->user
->invited
);
639 * input - channel to check bans for, user to check bans against
640 * optional prebuilt buffers
641 * output - 1 if banned, else 0
645 is_banned(struct Channel
*chptr
, struct Client
*who
, struct membership
*msptr
,
646 const char *s
, const char *s2
)
648 char src_host
[NICKLEN
+ USERLEN
+ HOSTLEN
+ 6];
649 char src_iphost
[NICKLEN
+ USERLEN
+ HOSTLEN
+ 6];
650 char src_althost
[NICKLEN
+ USERLEN
+ HOSTLEN
+ 6];
653 struct Ban
*actualBan
= NULL
;
654 struct Ban
*actualExcept
= NULL
;
659 /* if the buffers havent been built, do it here */
662 rb_sprintf(src_host
, "%s!%s@%s", who
->name
, who
->username
, who
->host
);
663 rb_sprintf(src_iphost
, "%s!%s@%s", who
->name
, who
->username
, who
->sockhost
);
668 if(who
->localClient
->mangledhost
!= NULL
)
670 /* if host mangling mode enabled, also check their real host */
671 if(!strcmp(who
->host
, who
->localClient
->mangledhost
))
673 rb_sprintf(src_althost
, "%s!%s@%s", who
->name
, who
->username
, who
->orighost
);
676 /* if host mangling mode not enabled and no other spoof,
677 * also check the mangled form of their host */
678 else if (!IsDynSpoof(who
))
680 rb_sprintf(src_althost
, "%s!%s@%s", who
->name
, who
->username
, who
->localClient
->mangledhost
);
685 RB_DLINK_FOREACH(ptr
, chptr
->banlist
.head
)
687 actualBan
= ptr
->data
;
688 if(match(actualBan
->banstr
, s
) ||
689 match(actualBan
->banstr
, s2
) ||
690 match_cidr(actualBan
->banstr
, s2
) ||
691 match_extban(actualBan
->banstr
, who
, chptr
, CHFL_BAN
) ||
692 (s3
!= NULL
&& match(actualBan
->banstr
, s3
)))
698 if((actualBan
!= NULL
) && ConfigChannel
.use_except
)
700 RB_DLINK_FOREACH(ptr
, chptr
->exceptlist
.head
)
702 actualExcept
= ptr
->data
;
704 /* theyre exempted.. */
705 if(match(actualExcept
->banstr
, s
) ||
706 match(actualExcept
->banstr
, s2
) ||
707 match_cidr(actualExcept
->banstr
, s2
) ||
708 match_extban(actualExcept
->banstr
, who
, chptr
, CHFL_EXCEPTION
) ||
709 (s3
!= NULL
&& match(actualExcept
->banstr
, s3
)))
711 /* cache the fact theyre not banned */
714 msptr
->bants
= chptr
->bants
;
715 msptr
->flags
&= ~CHFL_BANNED
;
718 return CHFL_EXCEPTION
;
723 /* cache the banned/not banned status */
726 msptr
->bants
= chptr
->bants
;
728 if(actualBan
!= NULL
)
730 msptr
->flags
|= CHFL_BANNED
;
735 msptr
->flags
&= ~CHFL_BANNED
;
740 return ((actualBan
? CHFL_BAN
: 0));
745 * input - channel to check bans for, user to check bans against
746 * optional prebuilt buffers
747 * output - 1 if banned, else 0
751 is_quieted(struct Channel
*chptr
, struct Client
*who
, struct membership
*msptr
,
752 const char *s
, const char *s2
)
754 char src_host
[NICKLEN
+ USERLEN
+ HOSTLEN
+ 6];
755 char src_iphost
[NICKLEN
+ USERLEN
+ HOSTLEN
+ 6];
756 char src_althost
[NICKLEN
+ USERLEN
+ HOSTLEN
+ 6];
759 struct Ban
*actualBan
= NULL
;
760 struct Ban
*actualExcept
= NULL
;
762 /* check to make sure quiets even exist on this server first */
763 if(ModuleModes
.CHFL_QUIET
== 0)
769 /* if the buffers havent been built, do it here */
772 rb_sprintf(src_host
, "%s!%s@%s", who
->name
, who
->username
, who
->host
);
773 rb_sprintf(src_iphost
, "%s!%s@%s", who
->name
, who
->username
, who
->sockhost
);
778 if(who
->localClient
->mangledhost
!= NULL
)
780 /* if host mangling mode enabled, also check their real host */
781 if(!strcmp(who
->host
, who
->localClient
->mangledhost
))
783 rb_sprintf(src_althost
, "%s!%s@%s", who
->name
, who
->username
, who
->orighost
);
786 /* if host mangling mode not enabled and no other spoof,
787 * also check the mangled form of their host */
788 else if (!IsDynSpoof(who
))
790 rb_sprintf(src_althost
, "%s!%s@%s", who
->name
, who
->username
, who
->localClient
->mangledhost
);
795 RB_DLINK_FOREACH(ptr
, chptr
->quietlist
.head
)
797 actualBan
= ptr
->data
;
798 if(match(actualBan
->banstr
, s
) ||
799 match(actualBan
->banstr
, s2
) ||
800 match_cidr(actualBan
->banstr
, s2
) ||
801 match_extban(actualBan
->banstr
, who
, chptr
, ModuleModes
.CHFL_QUIET
) ||
802 (s3
!= NULL
&& match(actualBan
->banstr
, s3
)))
808 if((actualBan
!= NULL
) && ConfigChannel
.use_except
)
810 RB_DLINK_FOREACH(ptr
, chptr
->exceptlist
.head
)
812 actualExcept
= ptr
->data
;
814 /* theyre exempted.. */
815 if(match(actualExcept
->banstr
, s
) ||
816 match(actualExcept
->banstr
, s2
) ||
817 match_cidr(actualExcept
->banstr
, s2
) ||
818 match_extban(actualExcept
->banstr
, who
, chptr
, CHFL_EXCEPTION
) ||
819 (s3
!= NULL
&& match(actualExcept
->banstr
, s3
)))
821 /* cache the fact theyre not banned */
824 msptr
->bants
= chptr
->bants
;
825 msptr
->flags
&= ~CHFL_BANNED
;
828 return CHFL_EXCEPTION
;
833 /* cache the banned/not banned status */
836 msptr
->bants
= chptr
->bants
;
838 if(actualBan
!= NULL
)
840 msptr
->flags
|= CHFL_BANNED
;
845 msptr
->flags
&= ~CHFL_BANNED
;
850 return ((actualBan
? CHFL_BAN
: 0));
855 * input - client to check, channel to check for, key
856 * output - reason for not being able to join, else 0
860 can_join(struct Client
*source_p
, struct Channel
*chptr
, char *key
)
862 rb_dlink_node
*invite
= NULL
;
864 struct Ban
*invex
= NULL
;
865 char src_host
[NICKLEN
+ USERLEN
+ HOSTLEN
+ 6];
866 char src_iphost
[NICKLEN
+ USERLEN
+ HOSTLEN
+ 6];
867 char src_althost
[NICKLEN
+ USERLEN
+ HOSTLEN
+ 6];
871 hook_data_channel moduledata
;
873 struct DictionaryIter iter
;
875 s_assert(source_p
->localClient
!= NULL
);
877 rb_sprintf(src_host
, "%s!%s@%s", source_p
->name
, source_p
->username
, source_p
->host
);
878 rb_sprintf(src_iphost
, "%s!%s@%s", source_p
->name
, source_p
->username
, source_p
->sockhost
);
879 if(source_p
->localClient
->mangledhost
!= NULL
)
881 /* if host mangling mode enabled, also check their real host */
882 if(!strcmp(source_p
->host
, source_p
->localClient
->mangledhost
))
884 rb_sprintf(src_althost
, "%s!%s@%s", source_p
->name
, source_p
->username
, source_p
->orighost
);
887 /* if host mangling mode not enabled and no other spoof,
888 * also check the mangled form of their host */
889 else if (!IsDynSpoof(source_p
))
891 rb_sprintf(src_althost
, "%s!%s@%s", source_p
->name
, source_p
->username
, source_p
->localClient
->mangledhost
);
896 if((is_banned(chptr
, source_p
, NULL
, src_host
, src_iphost
)) == CHFL_BAN
)
897 return (ERR_BANNEDFROMCHAN
);
899 rb_snprintf(text
, sizeof(text
), "K%s", source_p
->id
);
901 DICTIONARY_FOREACH(md
, &iter
, chptr
->metadata
)
903 if(!strcmp(md
->value
, "KICKNOREJOIN") && !strcmp(md
->name
, text
) && (md
->timevalue
+ 2 > rb_current_time()))
904 return ERR_KICKNOREJOIN
;
905 /* cleanup any stale KICKNOREJOIN metadata we find while we're at it */
906 if(!strcmp(md
->value
, "KICKNOREJOIN") && !(md
->timevalue
+ 2 > rb_current_time()))
907 channel_metadata_delete(chptr
, md
->name
, 0);
910 if(chptr
->mode
.mode
& MODE_INVITEONLY
)
912 RB_DLINK_FOREACH(invite
, source_p
->user
->invited
.head
)
914 if(invite
->data
== chptr
)
919 if(!ConfigChannel
.use_invex
)
920 return (ERR_INVITEONLYCHAN
);
921 RB_DLINK_FOREACH(ptr
, chptr
->invexlist
.head
)
924 if(match(invex
->banstr
, src_host
)
925 || match(invex
->banstr
, src_iphost
)
926 || match_cidr(invex
->banstr
, src_iphost
)
927 || match_extban(invex
->banstr
, source_p
, chptr
, CHFL_INVEX
)
928 || (use_althost
&& match(invex
->banstr
, src_althost
)))
932 return (ERR_INVITEONLYCHAN
);
936 if(*chptr
->mode
.key
&& (EmptyString(key
) || irccmp(chptr
->mode
.key
, key
)))
937 return (ERR_BADCHANNELKEY
);
939 if(chptr
->mode
.limit
&&
940 rb_dlink_list_length(&chptr
->members
) >= (unsigned long) chptr
->mode
.limit
)
941 i
= ERR_CHANNELISFULL
;
942 if(chptr
->mode
.mode
& ModuleModes
.MODE_REGONLY
&& EmptyString(source_p
->user
->suser
))
943 i
= ERR_NEEDREGGEDNICK
;
944 /* join throttling stuff --nenolod */
945 /* only check for throttles if they exist on this server --Taros */
946 else if(ModuleModes
.MODE_THROTTLE
)
948 if(chptr
->mode
.join_num
> 0 && chptr
->mode
.join_time
> 0)
950 if ((rb_current_time() - chptr
->join_delta
<=
951 chptr
->mode
.join_time
) && (chptr
->join_count
>=
952 chptr
->mode
.join_num
))
957 /* allow /invite to override +l/+r/+j also -- jilles */
958 if (i
!= 0 && invite
== NULL
)
960 RB_DLINK_FOREACH(invite
, source_p
->user
->invited
.head
)
962 if(invite
->data
== chptr
)
969 moduledata
.client
= source_p
;
970 moduledata
.chptr
= chptr
;
971 moduledata
.approved
= 0;
973 call_hook(h_can_join
, &moduledata
);
975 return moduledata
.approved
;
980 * input - user to check in channel, membership pointer
981 * output - whether can explicitly send or not, else CAN_SEND_NONOP
985 can_send(struct Channel
*chptr
, struct Client
*source_p
, struct membership
*msptr
)
987 if(IsServer(source_p
) || IsService(source_p
))
990 if(MyClient(source_p
) && hash_find_resv(chptr
->chname
) &&
991 !IsOper(source_p
) && !IsExemptResv(source_p
))
996 msptr
= find_channel_membership(chptr
, source_p
);
1000 /* if its +m or +n and theyre not in the channel,
1001 * they cant send. we dont check bans here because
1002 * theres no possibility of caching them --fl
1004 if(chptr
->mode
.mode
& MODE_NOPRIVMSGS
|| chptr
->mode
.mode
& MODE_MODERATED
)
1007 return CAN_SEND_NONOP
;
1011 if(is_chanop_voiced(msptr
))
1012 return CAN_SEND_OPV
;
1014 if(chptr
->mode
.mode
& MODE_MODERATED
)
1017 if(MyClient(source_p
))
1019 /* cached can_send */
1020 if(msptr
->bants
== chptr
->bants
)
1022 if(can_send_banned(msptr
))
1025 else if(is_banned(chptr
, source_p
, msptr
, NULL
, NULL
) == CHFL_BAN
1026 || is_quieted(chptr
, source_p
, msptr
, NULL
, NULL
) == CHFL_BAN
)
1030 return CAN_SEND_NONOP
;
1033 /* find_bannickchange_channel()
1034 * Input: client to check
1035 * Output: channel preventing nick change
1038 find_bannickchange_channel(struct Client
*client_p
)
1040 struct Channel
*chptr
;
1041 struct membership
*msptr
;
1043 char src_host
[NICKLEN
+ USERLEN
+ HOSTLEN
+ 6];
1044 char src_iphost
[NICKLEN
+ USERLEN
+ HOSTLEN
+ 6];
1046 if (!MyClient(client_p
) || IsOverride(client_p
))
1049 rb_sprintf(src_host
, "%s!%s@%s", client_p
->name
, client_p
->username
, client_p
->host
);
1050 rb_sprintf(src_iphost
, "%s!%s@%s", client_p
->name
, client_p
->username
, client_p
->sockhost
);
1052 RB_DLINK_FOREACH(ptr
, client_p
->user
->channel
.head
)
1055 chptr
= msptr
->chptr
;
1056 if (is_chanop_voiced(msptr
))
1058 /* cached can_send */
1059 if (msptr
->bants
== chptr
->bants
)
1061 if (can_send_banned(msptr
))
1064 else if (is_banned(chptr
, client_p
, msptr
, src_host
, src_iphost
) == CHFL_BAN
1065 || is_quieted(chptr
, client_p
, msptr
, src_host
, src_iphost
) == CHFL_BAN
)
1071 /* find_nonickchange_channel()
1072 * Input: client to check
1073 * Output: channel preventing nick change
1076 find_nonickchange_channel(struct Client
*client_p
)
1078 struct Channel
*chptr
;
1079 struct membership
*msptr
;
1082 if (!MyClient(client_p
))
1085 RB_DLINK_FOREACH(ptr
, client_p
->user
->channel
.head
)
1088 chptr
= msptr
->chptr
;
1089 if (chptr
->mode
.mode
& ModuleModes
.MODE_NONICK
&& (!ConfigChannel
.exempt_cmode_N
|| !is_any_op(msptr
)))
1095 /* void check_spambot_warning(struct Client *source_p)
1096 * Input: Client to check, channel name or NULL if this is a part.
1098 * Side-effects: Updates the client's oper_warn_count_down, warns the
1099 * IRC operators if necessary, and updates join_leave_countdown as
1103 check_spambot_warning(struct Client
*source_p
, const char *name
)
1106 int decrement_count
;
1107 if((GlobalSetOptions
.spam_num
&&
1108 (source_p
->localClient
->join_leave_count
>= GlobalSetOptions
.spam_num
)))
1110 if(source_p
->localClient
->oper_warn_count_down
> 0)
1111 source_p
->localClient
->oper_warn_count_down
--;
1113 source_p
->localClient
->oper_warn_count_down
= 0;
1114 if(source_p
->localClient
->oper_warn_count_down
== 0 &&
1117 /* Its already known as a possible spambot */
1118 sendto_realops_snomask(SNO_BOTS
, L_NETWIDE
,
1119 "User %s (%s@%s) trying to join %s is a possible spambot",
1121 source_p
->username
, source_p
->orighost
, name
);
1122 source_p
->localClient
->oper_warn_count_down
= OPER_SPAM_COUNTDOWN
;
1128 (rb_current_time() - source_p
->localClient
->last_leave_time
)) >
1129 JOIN_LEAVE_COUNT_EXPIRE_TIME
)
1131 decrement_count
= (t_delta
/ JOIN_LEAVE_COUNT_EXPIRE_TIME
);
1134 else if(decrement_count
> source_p
->localClient
->join_leave_count
)
1135 source_p
->localClient
->join_leave_count
= 0;
1137 source_p
->localClient
->join_leave_count
-= decrement_count
;
1141 if((rb_current_time() -
1142 (source_p
->localClient
->last_join_time
)) < GlobalSetOptions
.spam_time
)
1144 /* oh, its a possible spambot */
1145 source_p
->localClient
->join_leave_count
++;
1149 source_p
->localClient
->last_join_time
= rb_current_time();
1151 source_p
->localClient
->last_leave_time
= rb_current_time();
1155 /* check_splitmode()
1159 * side effects - compares usercount and servercount against their split
1160 * values and adjusts splitmode accordingly
1163 check_splitmode(void *unused
)
1165 if(splitchecking
&& (ConfigChannel
.no_join_on_split
|| ConfigChannel
.no_create_on_split
))
1167 /* not split, we're being asked to check now because someone
1172 if(eob_count
< split_servers
|| Count
.total
< split_users
)
1175 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
1176 "Network split, activating splitmode");
1177 check_splitmode_ev
= rb_event_addish("check_splitmode", check_splitmode
, NULL
, 2);
1180 /* in splitmode, check whether its finished */
1181 else if(eob_count
>= split_servers
&& Count
.total
>= split_users
)
1185 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
1186 "Network rejoined, deactivating splitmode");
1188 rb_event_delete(check_splitmode_ev
);
1189 check_splitmode_ev
= NULL
;
1197 * input - channel to allocate topic for
1198 * output - 1 on success, else 0
1199 * side effects - channel gets a topic allocated
1202 allocate_topic(struct Channel
*chptr
)
1209 ptr
= rb_bh_alloc(topic_heap
);
1211 /* Basically we allocate one large block for the topic and
1212 * the topic info. We then split it up into two and shove it
1216 chptr
->topic_info
= (char *) ptr
+ TOPICLEN
+ 1;
1217 *chptr
->topic
= '\0';
1218 *chptr
->topic_info
= '\0';
1223 * input - channel which has topic to free
1225 * side effects - channels topic is free'd
1228 free_topic(struct Channel
*chptr
)
1232 if(chptr
== NULL
|| chptr
->topic
== NULL
)
1235 /* This is safe for now - If you change allocate_topic you
1236 * MUST change this as well
1239 rb_bh_free(topic_heap
, ptr
);
1240 chptr
->topic
= NULL
;
1241 chptr
->topic_info
= NULL
;
1244 /* set_channel_topic()
1246 * input - channel, topic to set, topic info and topic ts
1248 * side effects - channels topic, topic info and TS are set.
1251 set_channel_topic(struct Channel
*chptr
, const char *topic
, const char *topic_info
, time_t topicts
)
1253 if(strlen(topic
) > 0)
1255 if(chptr
->topic
== NULL
)
1256 allocate_topic(chptr
);
1257 rb_strlcpy(chptr
->topic
, topic
, TOPICLEN
+ 1);
1258 rb_strlcpy(chptr
->topic_info
, topic_info
, USERHOST_REPLYLEN
);
1259 chptr
->topic_time
= topicts
;
1263 if(chptr
->topic
!= NULL
)
1265 chptr
->topic_time
= 0;
1269 /* has_common_channel()
1271 * input - pointer to client
1272 * - pointer to another client
1273 * output - 1 if the two have a channel in common, 0 elsewise
1274 * side effects - none
1277 has_common_channel(struct Client
*client1
, struct Client
*client2
)
1281 RB_DLINK_FOREACH(ptr
, client1
->user
->channel
.head
)
1283 if(IsMember(client2
, ((struct membership
*)ptr
->data
)->chptr
))
1289 /* channel_modes_real()
1291 * inputs - pointer to channel
1292 * - pointer to channel mode struct
1293 * - pointer to client
1294 * output - string with simple modes
1295 * side effects - result from previous calls overwritten
1297 * Stolen from ShadowIRCd 4 --nenolod
1300 channel_modes_real(struct Channel
*chptr
, struct Mode
*mode
, struct Client
*client_p
)
1305 static char final
[BUFSIZE
];
1312 for (i
= 0; i
< 256; i
++)
1314 if(chmode_table
[i
].set_func
== chm_hidden
&& !IsOper(client_p
) && IsClient(client_p
))
1316 if(mode
->mode
& chmode_flags
[i
])
1324 if(!IsClient(client_p
) || IsMember(client_p
, chptr
))
1325 pbuf
+= rb_sprintf(pbuf
, " %d", mode
->limit
);
1332 if(pbuf
> buf2
|| !IsClient(client_p
) || IsMember(client_p
, chptr
))
1333 pbuf
+= rb_sprintf(pbuf
, " %s", mode
->key
);
1340 if(pbuf
> buf2
|| !IsClient(client_p
) || IsMember(client_p
, chptr
))
1341 pbuf
+= rb_sprintf(pbuf
, " %d:%d", mode
->join_num
,
1345 if(mode
->forward
&& (ModuleModes
.MODE_FORWARD
|| !IsClient(client_p
)))
1349 if(pbuf
> buf2
|| !IsClient(client_p
) || IsMember(client_p
, chptr
))
1350 pbuf
+= rb_sprintf(pbuf
, " %s", mode
->forward
);
1355 rb_strlcpy(final
, buf1
, sizeof final
);
1356 rb_strlcat(final
, buf2
, sizeof final
);
1360 /* Now lets do some stuff to keep track of what combinations of
1362 * Note that the number of combinations doubles each time you add
1363 * something to this list. Each one is only quick if no servers use that
1364 * combination, but if the numbers get too high here MODE will get too
1365 * slow. I suggest if you get more than 7 here, you consider getting rid
1366 * of some and merging or something. If it wasn't for irc+cs we would
1367 * probably not even need to bother about most of these, but unfortunately
1371 /* void init_chcap_usage_counts(void)
1375 * Side-effects - Initialises the usage counts to zero. Fills in the
1376 * chcap_yes and chcap_no combination tables.
1379 init_chcap_usage_counts(void)
1381 unsigned long m
, c
, y
, n
;
1383 memset(chcap_combos
, 0, sizeof(chcap_combos
));
1385 /* For every possible combination */
1386 for (m
= 0; m
< NCHCAP_COMBOS
; m
++)
1388 /* Check each capab */
1389 for (c
= y
= n
= 0; c
< NCHCAPS
; c
++)
1391 if((m
& (1 << c
)) == 0)
1392 n
|= channel_capabs
[c
];
1394 y
|= channel_capabs
[c
];
1396 chcap_combos
[m
].cap_yes
= y
;
1397 chcap_combos
[m
].cap_no
= n
;
1401 /* void set_chcap_usage_counts(struct Client *serv_p)
1402 * Input: serv_p; The client whose capabs to register.
1404 * Side-effects: Increments the usage counts for the correct capab
1408 set_chcap_usage_counts(struct Client
*serv_p
)
1412 for (n
= 0; n
< NCHCAP_COMBOS
; n
++)
1414 if(IsCapable(serv_p
, chcap_combos
[n
].cap_yes
) &&
1415 NotCapable(serv_p
, chcap_combos
[n
].cap_no
))
1417 chcap_combos
[n
].count
++;
1422 /* This should be impossible -A1kmm. */
1426 /* void set_chcap_usage_counts(struct Client *serv_p)
1428 * Inputs - serv_p; The client whose capabs to register.
1430 * Side-effects - Decrements the usage counts for the correct capab
1434 unset_chcap_usage_counts(struct Client
*serv_p
)
1438 for (n
= 0; n
< NCHCAP_COMBOS
; n
++)
1440 if(IsCapable(serv_p
, chcap_combos
[n
].cap_yes
) &&
1441 NotCapable(serv_p
, chcap_combos
[n
].cap_no
))
1443 /* Hopefully capabs can't change dynamically or anything... */
1444 s_assert(chcap_combos
[n
].count
> 0);
1446 if(chcap_combos
[n
].count
> 0)
1447 chcap_combos
[n
].count
--;
1452 /* This should be impossible -A1kmm. */
1456 /* void send_cap_mode_changes(struct Client *client_p,
1457 * struct Client *source_p,
1458 * struct Channel *chptr, int cap, int nocap)
1459 * Input: The client sending(client_p), the source client(source_p),
1460 * the channel to send mode changes for(chptr)
1462 * Side-effects: Sends the appropriate mode changes to capable servers.
1464 * Reverted back to my original design, except that we now keep a count
1465 * of the number of servers which each combination as an optimisation, so
1466 * the capabs combinations which are not needed are not worked out. -A1kmm
1469 send_cap_mode_changes(struct Client
*client_p
, struct Client
*source_p
,
1470 struct Channel
*chptr
, struct ChModeChange mode_changes
[], int mode_count
)
1472 static char modebuf
[BUFSIZE
];
1473 static char parabuf
[BUFSIZE
];
1474 int i
, mbl
, pbl
, nc
, mc
, preflen
, len
;
1483 /* Now send to servers... */
1484 for (j
= 0; j
< NCHCAP_COMBOS
; j
++)
1486 if(chcap_combos
[j
].count
== 0)
1496 cap
= chcap_combos
[j
].cap_yes
;
1497 nocap
= chcap_combos
[j
].cap_no
;
1499 mbl
= preflen
= rb_sprintf(modebuf
, ":%s TMODE %ld %s ",
1500 use_id(source_p
), (long) chptr
->channelts
,
1503 /* loop the list of - modes we have */
1504 for (i
= 0; i
< mode_count
; i
++)
1506 /* if they dont support the cap we need, or they do support a cap they
1507 * cant have, then dont add it to the modebuf.. that way they wont see
1510 if((mode_changes
[i
].letter
== 0) ||
1511 ((cap
& mode_changes
[i
].caps
) != mode_changes
[i
].caps
)
1512 || ((nocap
& mode_changes
[i
].nocaps
) != mode_changes
[i
].nocaps
))
1515 if(!EmptyString(mode_changes
[i
].id
))
1516 arg
= mode_changes
[i
].id
;
1518 arg
= mode_changes
[i
].arg
;
1522 arglen
= strlen(arg
);
1524 /* dont even think about it! --fl */
1525 if(arglen
> MODEBUFLEN
- 5)
1529 /* if we're creeping past the buf size, we need to send it and make
1530 * another line for the other modes
1531 * XXX - this could give away server topology with uids being
1532 * different lengths, but not much we can do, except possibly break
1533 * them as if they were the longest of the nick or uid at all times,
1534 * which even then won't work as we don't always know the uid -A1kmm.
1536 if(arg
&& ((mc
== MAXMODEPARAMSSERV
) ||
1537 ((mbl
+ pbl
+ arglen
+ 4) > (BUFSIZE
- 3))))
1540 sendto_server(client_p
, chptr
, cap
, nocap
,
1541 "%s %s", modebuf
, parabuf
);
1552 if(dir
!= mode_changes
[i
].dir
)
1554 modebuf
[mbl
++] = (mode_changes
[i
].dir
== MODE_ADD
) ? '+' : '-';
1555 dir
= mode_changes
[i
].dir
;
1558 modebuf
[mbl
++] = mode_changes
[i
].letter
;
1564 len
= rb_sprintf(pbuf
, "%s ", arg
);
1571 if(pbl
&& parabuf
[pbl
- 1] == ' ')
1572 parabuf
[pbl
- 1] = 0;
1575 sendto_server(client_p
, chptr
, cap
, nocap
, "%s %s", modebuf
, parabuf
);
1580 resv_chan_forcepart(const char *name
, const char *reason
, int temp_time
)
1583 rb_dlink_node
*next_ptr
;
1584 struct Channel
*chptr
;
1585 struct membership
*msptr
;
1586 struct Client
*target_p
;
1588 if(!ConfigChannel
.resv_forcepart
)
1591 /* for each user on our server in the channel list
1592 * send them a PART, and notify opers.
1594 chptr
= find_channel(name
);
1597 RB_DLINK_FOREACH_SAFE(ptr
, next_ptr
, chptr
->locmembers
.head
)
1600 target_p
= msptr
->client_p
;
1602 if(IsExemptResv(target_p
))
1605 sendto_server(target_p
, chptr
, CAP_TS6
, NOCAPS
,
1606 ":%s PART %s", target_p
->id
, chptr
->chname
);
1608 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s!%s@%s PART %s :%s",
1609 target_p
->name
, target_p
->username
,
1610 target_p
->host
, chptr
->chname
, target_p
->name
);
1612 remove_user_from_channel(msptr
);
1614 /* notify opers & user they were removed from the channel */
1615 sendto_realops_snomask(SNO_GENERAL
, L_ALL
,
1616 "Forced PART for %s!%s@%s from %s (%s)",
1617 target_p
->name
, target_p
->username
,
1618 target_p
->host
, name
, reason
);
1621 sendto_one_notice(target_p
, ":*** Channel %s is temporarily unavailable on this server.",
1624 sendto_one_notice(target_p
, ":*** Channel %s is no longer available on this server.",
1630 /* Check what we will forward to, without sending any notices to the user
1634 check_forward(struct Client
*source_p
, struct Channel
*chptr
,
1640 if (IsNoForward(source_p
))
1645 chptr
= find_channel(chptr
->mode
.forward
);
1646 /* Can only forward to existing channels */
1649 /* Already on there, show original error message */
1650 if (IsMember(source_p
, chptr
))
1652 /* Juped. Sending a warning notice would be unfair */
1653 if (hash_find_resv(chptr
->chname
))
1655 /* Don't forward to +Q channel */
1656 if (chptr
->mode
.mode
& ModuleModes
.MODE_DISFORWARD
)
1658 i
= can_join(source_p
, chptr
, key
);
1661 if (i
!= ERR_INVITEONLYCHAN
&& i
!= ERR_NEEDREGGEDNICK
&& i
!= ERR_THROTTLE
&& i
!= ERR_CHANNELISFULL
)
1672 * inputs - pointer to client doing join 0
1674 * side effects - Use has decided to join 0. This is legacy
1675 * from the days when channels were numbers not names. *sigh*
1678 do_join_0(struct Client
*client_p
, struct Client
*source_p
)
1680 struct membership
*msptr
;
1681 struct Channel
*chptr
= NULL
;
1684 /* Finish the flood grace period... */
1685 if(MyClient(source_p
) && !IsFloodDone(source_p
))
1686 flood_endgrace(source_p
);
1688 sendto_server(client_p
, NULL
, CAP_TS6
, NOCAPS
, ":%s JOIN 0", use_id(source_p
));
1690 while((ptr
= source_p
->user
->channel
.head
))
1692 if(source_p
->user
->channel
.head
&& MyConnect(source_p
) &&
1693 !IsOper(source_p
) && !IsExemptSpambot(source_p
))
1694 check_spambot_warning(source_p
, NULL
);
1697 chptr
= msptr
->chptr
;
1698 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s!%s@%s PART %s",
1700 source_p
->username
, source_p
->host
, chptr
->chname
);
1701 remove_user_from_channel(msptr
);
1706 check_channel_name_loc(struct Client
*source_p
, const char *name
)
1710 s_assert(name
!= NULL
);
1711 if(EmptyString(name
))
1714 if(ConfigFileEntry
.disable_fake_channels
&& !IsOper(source_p
))
1716 for(p
= name
; *p
; ++p
)
1718 if(!IsChanChar(*p
) || IsFakeChanChar(*p
))
1724 for(p
= name
; *p
; ++p
)
1731 if(ConfigChannel
.only_ascii_channels
)
1733 for(p
= name
; *p
; ++p
)
1734 if(*p
< 33 || *p
> 126)
1742 void user_join(struct Client
* client_p
, struct Client
* source_p
, const char * channels
, const char * keys
)
1744 static char jbuf
[BUFSIZE
];
1745 struct Channel
*chptr
= NULL
;
1746 struct ConfItem
*aconf
;
1751 char *p
= NULL
, *p2
= NULL
;
1757 if(channels
== NULL
)
1760 /* rebuild the list of channels theyre supposed to be joining.
1761 * this code has a side effect of losing keys, but..
1763 chanlist
= LOCAL_COPY(channels
);
1764 for(name
= rb_strtok_r(chanlist
, ",", &p
); name
; name
= rb_strtok_r(NULL
, ",", &p
))
1766 /* check the length and name of channel is ok */
1767 if(!check_channel_name_loc(source_p
, name
) || (strlen(name
) > LOC_CHANNELLEN
))
1769 sendto_one_numeric(source_p
, ERR_BADCHANNAME
,
1770 form_str(ERR_BADCHANNAME
), (unsigned char *) name
);
1774 /* join 0 parts all channels */
1775 if(*name
== '0' && (name
[1] == ',' || name
[1] == '\0') && name
== chanlist
)
1777 (void) strcpy(jbuf
, "0");
1781 /* check it begins with # or &, and local chans are disabled */
1782 else if(!IsChannelName(name
) ||
1783 ( !ConfigChannel
.use_local_channels
&& name
[0] == '&'))
1785 sendto_one_numeric(source_p
, ERR_NOSUCHCHANNEL
,
1786 form_str(ERR_NOSUCHCHANNEL
), name
);
1790 /* see if its resv'd */
1791 if(!IsExemptResv(source_p
) && (aconf
= hash_find_resv(name
)))
1793 sendto_one_numeric(source_p
, ERR_BADCHANNAME
,
1794 form_str(ERR_BADCHANNAME
), name
);
1796 /* dont warn for opers */
1797 if(!IsExemptJupe(source_p
) && !IsOper(source_p
))
1798 sendto_realops_snomask(SNO_SPY
, L_NETWIDE
,
1799 "User %s (%s@%s) is attempting to join locally juped channel %s (%s)",
1800 source_p
->name
, source_p
->username
,
1801 source_p
->orighost
, name
, aconf
->passwd
);
1802 /* dont update tracking for jupe exempt users, these
1803 * are likely to be spamtrap leaves
1805 else if(IsExemptJupe(source_p
))
1811 if(splitmode
&& !IsOper(source_p
) && (*name
!= '&') &&
1812 ConfigChannel
.no_join_on_split
)
1814 sendto_one(source_p
, form_str(ERR_UNAVAILRESOURCE
),
1815 me
.name
, source_p
->name
, name
);
1820 (void) strcat(jbuf
, ",");
1821 (void) rb_strlcat(jbuf
, name
, sizeof(jbuf
));
1826 mykey
= LOCAL_COPY(keys
);
1827 key
= rb_strtok_r(mykey
, ",", &p2
);
1830 for(name
= rb_strtok_r(jbuf
, ",", &p
); name
;
1831 key
= (key
) ? rb_strtok_r(NULL
, ",", &p2
) : NULL
, name
= rb_strtok_r(NULL
, ",", &p
))
1833 hook_data_channel_activity hook_info
;
1835 /* JOIN 0 simply parts all channels the user is in */
1836 if(*name
== '0' && !atoi(name
))
1838 if(source_p
->user
->channel
.head
== NULL
)
1841 do_join_0(&me
, source_p
);
1845 /* look for the channel */
1846 if((chptr
= find_channel(name
)) != NULL
)
1848 if(IsMember(source_p
, chptr
))
1855 hook_data_client_approval moduledata
;
1857 moduledata
.client
= source_p
;
1858 moduledata
.approved
= 0;
1860 call_hook(h_can_create_channel
, &moduledata
);
1862 if(moduledata
.approved
!= 0)
1864 sendto_one(source_p
, form_str(moduledata
.approved
),
1865 me
.name
, source_p
->name
, name
);
1869 if(splitmode
&& !IsOper(source_p
) && (*name
!= '&') &&
1870 ConfigChannel
.no_create_on_split
)
1872 sendto_one(source_p
, form_str(ERR_UNAVAILRESOURCE
),
1873 me
.name
, source_p
->name
, name
);
1877 if(ConfigChannel
.admin_on_channel_create
&& ConfigChannel
.use_admin
)
1878 flags
= CHFL_ADMIN
| CHFL_CHANOP
;
1880 flags
= CHFL_CHANOP
;
1883 if((rb_dlink_list_length(&source_p
->user
->channel
) >=
1884 (unsigned long) ConfigChannel
.max_chans_per_user
) &&
1885 (!IsOper(source_p
) ||
1886 (rb_dlink_list_length(&source_p
->user
->channel
) >=
1887 (unsigned long) ConfigChannel
.max_chans_per_user
* 3)))
1889 sendto_one(source_p
, form_str(ERR_TOOMANYCHANNELS
),
1890 me
.name
, source_p
->name
, name
);
1894 if(chptr
== NULL
) /* If I already have a chptr, no point doing this */
1896 chptr
= get_or_create_channel(source_p
, name
, NULL
);
1900 sendto_one(source_p
, form_str(ERR_UNAVAILRESOURCE
),
1901 me
.name
, source_p
->name
, name
);
1906 /* can_join checks for +i key, bans etc */
1907 if((i
= can_join(source_p
, chptr
, key
)))
1909 if(IsOverride(source_p
))
1911 sendto_wallops_flags(UMODE_WALLOP
, &me
,
1912 "%s is overriding JOIN to [%s]",
1913 get_oper_name(source_p
), chptr
->chname
);
1914 sendto_server(NULL
, chptr
, NOCAPS
, NOCAPS
,
1915 ":%s WALLOPS :%s is overriding JOIN to [%s]",
1916 me
.name
, get_oper_name(source_p
), chptr
->chname
);
1918 else if ((i
!= ERR_NEEDREGGEDNICK
&& i
!= ERR_THROTTLE
&& i
!= ERR_INVITEONLYCHAN
&& i
!= ERR_CHANNELISFULL
) ||
1919 (!ModuleModes
.MODE_FORWARD
|| (chptr
= check_forward(source_p
, chptr
, key
)) == NULL
))
1921 /* might be wrong, but is there any other better location for such?
1922 * see extensions/chm_operonly.c for other comments on this
1926 sendto_one(source_p
, form_str(i
), me
.name
, source_p
->name
, name
);
1931 sendto_one_numeric(source_p
, ERR_LINKCHANNEL
, form_str(ERR_LINKCHANNEL
), name
, chptr
->chname
);
1935 !IsOper(source_p
) && !IsExemptSpambot(source_p
))
1936 check_spambot_warning(source_p
, name
);
1938 /* add the user to the channel */
1939 add_user_to_channel(chptr
, source_p
, flags
);
1940 if (chptr
->mode
.join_num
&&
1941 rb_current_time() - chptr
->join_delta
>= chptr
->mode
.join_time
)
1943 chptr
->join_count
= 0;
1944 chptr
->join_delta
= rb_current_time();
1946 chptr
->join_count
++;
1948 /* we send the user their join here, because we could have to
1949 * send a mode out next.
1951 sendto_channel_local(ALL_MEMBERS
, chptr
, ":%s!%s@%s JOIN :%s",
1953 source_p
->username
, source_p
->host
, chptr
->chname
);
1955 /* its a new channel, set +nt and burst. */
1956 if(flags
& CHFL_CHANOP
)
1958 chptr
->channelts
= rb_current_time();
1960 /* autochanmodes stuff */
1961 if(ConfigChannel
.autochanmodes
)
1964 for(ch
= ConfigChannel
.autochanmodes
; *ch
; *ch
++)
1966 chptr
->mode
.mode
|= chmode_table
[*ch
].mode_type
;
1971 chptr
->mode
.mode
|= MODE_TOPICLIMIT
;
1972 chptr
->mode
.mode
|= MODE_NOPRIVMSGS
;
1975 modes
= channel_modes(chptr
, &me
);
1977 sendto_channel_local(ONLY_CHANOPS
, chptr
, ":%s MODE %s %s",
1978 me
.name
, chptr
->chname
, modes
);
1980 sendto_server(client_p
, chptr
, CAP_TS6
, NOCAPS
,
1981 ":%s SJOIN %ld %s %s :@%s",
1982 me
.id
, (long) chptr
->channelts
,
1983 chptr
->chname
, modes
, source_p
->id
);
1987 sendto_server(client_p
, chptr
, CAP_TS6
, NOCAPS
,
1988 ":%s JOIN %ld %s +",
1989 use_id(source_p
), (long) chptr
->channelts
,
1993 del_invite(chptr
, source_p
);
1995 if(chptr
->topic
!= NULL
)
1997 sendto_one(source_p
, form_str(RPL_TOPIC
), me
.name
,
1998 source_p
->name
, chptr
->chname
, chptr
->topic
);
2000 sendto_one(source_p
, form_str(RPL_TOPICWHOTIME
),
2001 me
.name
, source_p
->name
, chptr
->chname
,
2002 chptr
->topic_info
, chptr
->topic_time
);
2005 channel_member_names(chptr
, source_p
, 1);
2007 hook_info
.client
= source_p
;
2008 hook_info
.chptr
= chptr
;
2009 hook_info
.key
= key
;
2010 call_hook(h_channel_join
, &hook_info
);
2017 * channel_metadata_add
2019 * inputs - pointer to channel struct
2020 * - name of metadata item you wish to add
2021 * - value of metadata item
2022 * - 1 if metadata should be propegated, 0 if not
2024 * side effects - metadata is added to the channel in question
2025 * - metadata is propegated if propegate is set.
2028 channel_metadata_add(struct Channel
*target
, const char *name
, const char *value
, int propegate
)
2030 struct Metadata
*md
;
2032 md
= rb_malloc(sizeof(struct Metadata
));
2033 md
->name
= rb_strdup(name
);
2034 md
->value
= rb_strdup(value
);
2036 irc_dictionary_add(target
->metadata
, md
->name
, md
);
2039 sendto_match_servs(&me
, "*", CAP_ENCAP
, NOCAPS
, "ENCAP * METADATA ADD %s %s :%s",
2040 target
->chname
, name
, value
);
2046 * channel_metadata_time_add
2048 * inputs - pointer to channel struct
2049 * - name of metadata item you wish to add
2050 * - time_t you wish to add
2051 * - value you wish to add
2053 * side effects - metadata is added to the channel in question
2056 channel_metadata_time_add(struct Channel
*target
, const char *name
, time_t timevalue
, const char *value
)
2058 struct Metadata
*md
;
2060 md
= rb_malloc(sizeof(struct Metadata
));
2061 md
->name
= rb_strdup(name
);
2062 md
->value
= rb_strdup(value
);
2063 md
->timevalue
= timevalue
;
2065 irc_dictionary_add(target
->metadata
, md
->name
, md
);
2071 * channel_metadata_delete
2073 * inputs - pointer to channel struct
2074 * - name of metadata item you wish to delete
2076 * side effects - metadata is deleted from the channel in question
2077 * - deletion is propegated if propegate is set
2080 channel_metadata_delete(struct Channel
*target
, const char *name
, int propegate
)
2082 struct Metadata
*md
= channel_metadata_find(target
, name
);
2087 irc_dictionary_delete(target
->metadata
, md
->name
);
2092 sendto_match_servs(&me
, "*", CAP_ENCAP
, NOCAPS
, "ENCAP * METADATA DELETE %s %s",
2093 target
->chname
, name
);
2097 * channel_metadata_find
2099 * inputs - pointer to channel struct
2100 * - name of metadata item you wish to read
2101 * output - the requested metadata, if it exists, elsewise null.
2105 channel_metadata_find(struct Channel
*target
, const char *name
)
2110 if(!target
->metadata
)
2113 return irc_dictionary_retrieve(target
->metadata
, name
);
2117 * channel_metadata_clear
2119 * inputs - pointer to channel struct
2121 * side effects - metadata is cleared from the channel in question
2124 channel_metadata_clear(struct Channel
*chptr
)
2126 struct Metadata
*md
;
2127 struct DictionaryIter iter
;
2129 DICTIONARY_FOREACH(md
, &iter
, chptr
->metadata
)
2131 channel_metadata_delete(chptr
, md
->name
, 0);