implement configurable channel modes (closes #31)

While functionally compatible with the implementation in ElementalIRCd, our approach is different,
specifically pre-calculating the bitmask at config load time.  This is more efficient, and allows us
to report errors as part of the configuration phase.
This commit is contained in:
William Pitcock 2015-12-11 15:36:53 -06:00
parent bac8c4829f
commit 63eb8567cb
6 changed files with 48 additions and 2 deletions

View file

@ -361,6 +361,7 @@ channel {
resv_forcepart = yes; resv_forcepart = yes;
channel_target_change = yes; channel_target_change = yes;
disable_local_channels = no; disable_local_channels = no;
autochanmodes = "+nt";
}; };
serverhide { serverhide {

View file

@ -794,6 +794,11 @@ channel {
* supported. * supported.
*/ */
disable_local_channels = no; disable_local_channels = no;
/* autochanmodes: the channel modes that should be automatically set
* when a channel is created.
*/
autochanmodes = "+nt";
}; };

View file

@ -258,6 +258,7 @@ struct config_channel_entry
int resv_forcepart; int resv_forcepart;
int channel_target_change; int channel_target_change;
int disable_local_channels; int disable_local_channels;
unsigned int autochanmodes;
}; };
struct config_server_hide struct config_server_hide

View file

@ -341,8 +341,7 @@ m_join(struct Client *client_p, struct Client *source_p, int parc, const char *p
if(flags & CHFL_CHANOP) if(flags & CHFL_CHANOP)
{ {
chptr->channelts = rb_current_time(); chptr->channelts = rb_current_time();
chptr->mode.mode |= MODE_TOPICLIMIT; chptr->mode.mode |= ConfigChannel.autochanmodes;
chptr->mode.mode |= MODE_NOPRIVMSGS;
modes = channel_modes(chptr, &me); modes = channel_modes(chptr, &me);
sendto_channel_local(ONLY_CHANOPS, chptr, ":%s MODE %s %s", sendto_channel_local(ONLY_CHANOPS, chptr, ":%s MODE %s %s",

View file

@ -29,6 +29,7 @@
#include "blacklist.h" #include "blacklist.h"
#include "sslproc.h" #include "sslproc.h"
#include "privilege.h" #include "privilege.h"
#include "chmode.h"
#define CF_TYPE(x) ((x) & CF_MTYPE) #define CF_TYPE(x) ((x) & CF_MTYPE)
@ -1797,6 +1798,42 @@ conf_set_alias_target(void *data)
yy_alias->target = rb_strdup(data); yy_alias->target = rb_strdup(data);
} }
static void
conf_set_channel_autochanmodes(void *data)
{
char *pm;
int what = MODE_ADD;
ConfigChannel.autochanmodes = 0;
for (pm = (char *) data; *pm; pm++)
{
switch (*pm)
{
case '+':
what = MODE_ADD;
break;
case '-':
what = MODE_DEL;
break;
default:
if (chmode_table[(unsigned char) *pm].set_func == chm_simple)
{
if (what == MODE_ADD)
ConfigChannel.autochanmodes |= chmode_table[(unsigned char) *pm].mode_type;
else
ConfigChannel.autochanmodes &= ~chmode_table[(unsigned char) *pm].mode_type;
}
else
{
conf_report_error("channel::autochanmodes -- Invalid channel mode %c", pm);
continue;
}
break;
}
}
}
/* XXX for below */ /* XXX for below */
static void conf_set_blacklist_reason(void *data); static void conf_set_blacklist_reason(void *data);
@ -2419,6 +2456,7 @@ static struct ConfEntry conf_channel_table[] =
{ "resv_forcepart", CF_YESNO, NULL, 0, &ConfigChannel.resv_forcepart }, { "resv_forcepart", CF_YESNO, NULL, 0, &ConfigChannel.resv_forcepart },
{ "channel_target_change", CF_YESNO, NULL, 0, &ConfigChannel.channel_target_change }, { "channel_target_change", CF_YESNO, NULL, 0, &ConfigChannel.channel_target_change },
{ "disable_local_channels", CF_YESNO, NULL, 0, &ConfigChannel.disable_local_channels }, { "disable_local_channels", CF_YESNO, NULL, 0, &ConfigChannel.disable_local_channels },
{ "autochanmodes", CF_QSTRING, conf_set_channel_autochanmodes, 0, NULL },
{ "\0", 0, NULL, 0, NULL } { "\0", 0, NULL, 0, NULL }
}; };

View file

@ -793,6 +793,8 @@ set_default_conf(void)
ConfigChannel.channel_target_change = YES; ConfigChannel.channel_target_change = YES;
ConfigChannel.disable_local_channels = NO; ConfigChannel.disable_local_channels = NO;
ConfigChannel.autochanmodes = MODE_TOPICLIMIT | MODE_NOPRIVMSGS;
ConfigServerHide.flatten_links = 0; ConfigServerHide.flatten_links = 0;
ConfigServerHide.links_delay = 300; ConfigServerHide.links_delay = 300;
ConfigServerHide.hidden = 0; ConfigServerHide.hidden = 0;