Skip to content

Commit

Permalink
Allow multiple "Modes =" lines per [Channel] section
Browse files Browse the repository at this point in the history
  • Loading branch information
michi authored and alexbarton committed Mar 28, 2020
1 parent decf98d commit a3072ce
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 17 deletions.
34 changes: 22 additions & 12 deletions src/ngircd/channel.c
Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand Down
13 changes: 9 additions & 4 deletions src/ngircd/conf.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down
3 changes: 2 additions & 1 deletion src/ngircd/conf.h
Expand Up @@ -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 */
};


Expand Down

0 comments on commit a3072ce

Please sign in to comment.