From a3072ce698873d3732160b1cee63a35ccb75d5b4 Mon Sep 17 00:00:00 2001 From: michi Date: Sat, 29 Feb 2020 16:32:52 +0000 Subject: [PATCH] Allow multiple "Modes =" lines per [Channel] section --- src/ngircd/channel.c | 34 ++++++++++++++++++++++------------ src/ngircd/conf.c | 13 +++++++++---- src/ngircd/conf.h | 3 ++- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/ngircd/channel.c b/src/ngircd/channel.c index b317ada4..0b194a09 100644 --- a/src/ngircd/channel.c +++ b/src/ngircd/channel.c @@ -99,7 +99,7 @@ Channel_InitPredefined( void ) const struct Conf_Channel *conf_chan; char *c; char modes[COMMAND_LEN], name[CHANNEL_NAME_LEN]; - size_t i, channel_count = array_length(&Conf_Channels, sizeof(*conf_chan)); + size_t i, n, channel_count = array_length(&Conf_Channels, sizeof(*conf_chan)); conf_chan = array_start(&Conf_Channels); @@ -138,21 +138,31 @@ Channel_InitPredefined( void ) if (conf_chan->topic[0]) Channel_SetTopic(new_chan, NULL, conf_chan->topic); - /* Evaluate modes string with a fake request */ - if(conf_chan->modes[0]) { - strlcpy(modes, conf_chan->modes, sizeof(modes)); + /* Evaluate modes strings with fake requests */ + if(conf_chan->modes_num) { + /* Prepare fake request structure */ strlcpy(name, conf_chan->name, sizeof(name)); - Log(LOG_DEBUG, "Evaluate \"MODE %s %s\".", name, modes); - Req.argc = 0; - Req.argv[Req.argc++] = name; + Log(LOG_INFO, "Evaluating predefined channel modes for \"%s\".", name); + Req.argv[0] = name; Req.prefix = Client_ID(Client_ThisServer()); Req.command = "MODE"; - c = strtok(modes, " "); - while (c && Req.argc<15) { - Req.argv[Req.argc++] = c; - c = strtok(0, " "); + + /* Iterate over channel modes strings */ + for (n = 0; n < conf_chan->modes_num; n++) { + Req.argc = 1; + strlcpy(modes, conf_chan->modes[n], sizeof(modes)); + Log(LOG_DEBUG, "Evaluate \"MODE %s %s\".", name, modes); + c = strtok(modes, " "); + while (c && Req.argc < 15) { + Req.argv[Req.argc++] = c; + c = strtok(0, " "); + } + if(Req.argc > 1) + IRC_MODE(Client_ThisServer(), &Req); + + /* Original channel modes srings are no longer needed */ + free(conf_chan->modes[n]); } - IRC_MODE(Client_ThisServer(), &Req); } Channel_SetKey(new_chan, conf_chan->key); diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c index ef36a2fe..373ea6b1 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -328,7 +328,7 @@ Conf_Test( void ) { struct passwd *pwd; struct group *grp; - unsigned int i; + unsigned int i, j; bool config_valid; size_t predef_channel_count; struct Conf_Channel *predef_chan; @@ -483,7 +483,8 @@ Conf_Test( void ) /* Valid "Channel" section */ puts( "[CHANNEL]" ); printf(" Name = %s\n", predef_chan->name); - printf(" Modes = %s\n", predef_chan->modes); + for(j = 0; j < predef_chan->modes_num; j++) + printf(" Modes = %s\n", predef_chan->modes[j]); printf(" Key = %s\n", predef_chan->key); printf(" MaxUsers = %lu\n", predef_chan->maxusers); printf(" Topic = %s\n", predef_chan->topic); @@ -2155,8 +2156,12 @@ Handle_CHANNEL(const char *File, int Line, char *Var, char *Arg) } if (strcasecmp(Var, "Modes") == 0) { /* Initial modes */ - len = strlcpy(chan->modes, Arg, sizeof(chan->modes)); - if (len >= sizeof(chan->modes)) + if(chan->modes_num >= sizeof(chan->modes)) { + Config_Error(LOG_ERR, "Too many Modes, option ignored."); + return; + } + chan->modes[chan->modes_num++] = strndup(Arg, COMMAND_LEN); + if(strlen(Arg) >= COMMAND_LEN) Config_Error_TooLong(File, Line, Var); return; } diff --git a/src/ngircd/conf.h b/src/ngircd/conf.h index 900338dd..0d2965c1 100644 --- a/src/ngircd/conf.h +++ b/src/ngircd/conf.h @@ -83,11 +83,12 @@ struct SSLOptions { /** Pre-defined channels */ struct Conf_Channel { char name[CHANNEL_NAME_LEN]; /**< Name of the channel */ - char modes[COMMAND_LEN]; /**< Initial channel modes to evaluate */ + char *modes[512]; /**< Initial channel modes to evaluate */ char key[CLIENT_PASS_LEN]; /**< Channel key ("password", mode "k" ) */ char topic[COMMAND_LEN]; /**< Initial topic */ char keyfile[512]; /**< Path and name of channel key file */ unsigned long maxusers; /**< User limit for this channel, mode "l" */ + unsigned int modes_num; /**< Number of channel modes to evaluate */ }; -- 2.39.2