diff --git a/include/supported.h b/include/supported.h index 506955a7..27d8e07a 100644 --- a/include/supported.h +++ b/include/supported.h @@ -38,6 +38,7 @@ extern const void *change_isupport(const char *, const char *(*)(const void *), extern void delete_isupport(const char *); extern void show_isupport(struct Client *); extern void init_isupport(void); +extern void chantypes_update(void); extern const char *isupport_intptr(const void *); extern const char *isupport_boolean(const void *); diff --git a/ircd/s_conf.c b/ircd/s_conf.c index 74df1cfa..f2685bcb 100644 --- a/ircd/s_conf.c +++ b/ircd/s_conf.c @@ -52,6 +52,7 @@ #include "hook.h" #include "s_assert.h" #include "authproc.h" +#include "supported.h" struct config_server_hide ConfigServerHide; @@ -918,6 +919,12 @@ validate_conf(void) splitmode = 0; splitchecking = 0; } + + CharAttrs['&'] |= CHANPFX_C; + if (ConfigChannel.disable_local_channels) + CharAttrs['&'] &= ~CHANPFX_C; + + chantypes_update(); } /* add_temp_kline() diff --git a/ircd/supported.c b/ircd/supported.c index c28ed9d0..0b4505d2 100644 --- a/ircd/supported.c +++ b/ircd/supported.c @@ -80,6 +80,7 @@ #include "chmode.h" #include "send.h" +static char allowed_chantypes[BUFSIZE]; rb_dlink_list isupportlist; struct isupportitem @@ -245,19 +246,12 @@ isupport_chanmodes(const void *ptr) return result; } -static const char * -isupport_chantypes(const void *ptr) -{ - return ConfigChannel.disable_local_channels ? "#" : "&#"; -} - static const char * isupport_chanlimit(const void *ptr) { static char result[30]; - snprintf(result, sizeof result, "%s:%i", - ConfigChannel.disable_local_channels ? "#" : "&#", ConfigChannel.max_chans_per_user); + snprintf(result, sizeof result, "%s:%i", allowed_chantypes, ConfigChannel.max_chans_per_user); return result; } @@ -314,7 +308,7 @@ init_isupport(void) static int topiclen = TOPICLEN; static int maxnicklen = NICKLEN - 1; - add_isupport("CHANTYPES", isupport_chantypes, NULL); + add_isupport("CHANTYPES", isupport_stringptr, &allowed_chantypes); add_isupport("EXCEPTS", isupport_boolean, &ConfigChannel.use_except); add_isupport("INVEX", isupport_boolean, &ConfigChannel.use_invex); add_isupport("CHANMODES", isupport_chanmodes, NULL); @@ -335,3 +329,18 @@ init_isupport(void) add_isupport("EXTBAN", isupport_extban, NULL); add_isupport("CLIENTVER", isupport_string, "3.0"); } + +void +chantypes_update(void) +{ + unsigned char *p; + memset(allowed_chantypes, '\0', sizeof allowed_chantypes); + + p = (unsigned char *) allowed_chantypes; + + for (unsigned int i = 0; i < 256; i++) + { + if (IsChanPrefix(i)) + *p++ = (unsigned char) i; + } +} diff --git a/modules/core/m_join.c b/modules/core/m_join.c index f74d7dd5..2eb9d7b7 100644 --- a/modules/core/m_join.c +++ b/modules/core/m_join.c @@ -183,9 +183,8 @@ m_join(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p continue; } - /* check it begins with # or &, and local chans are disabled */ - else if(!IsChannelName(name) || - ( ConfigChannel.disable_local_channels && name[0] == '&')) + /* check it begins with a valid channel prefix per policy. */ + else if (!IsChannelName(name)) { sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL, form_str(ERR_NOSUCHCHANNEL), name);