]> arthur.barton.de Git - ngircd.git/commitdiff
Allow multiple "Modes =" lines per [Channel] section
authormichi <michi+ngircd@dataswamp.org>
Sat, 29 Feb 2020 16:32:52 +0000 (16:32 +0000)
committerAlexander Barton <alex@barton.de>
Sat, 28 Mar 2020 23:29:50 +0000 (00:29 +0100)
src/ngircd/channel.c
src/ngircd/conf.c
src/ngircd/conf.h

index b317ada41efb0b1fd645f776272f869da96c65d7..0b194a0968bae23f89c56798a9f300e13b55fb99 100644 (file)
@@ -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);
index ef36a2fe5d1c1842c851624c5322c91979554084..373ea6b1ed7bf6709038f84d3b08be11eefffa3b 100644 (file)
@@ -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;
        }
index 900338dd0124e3d8f36a5b9dfa8bca39c45a81a0..0d2965c1f2059fa508ce3b5cb4c5fe3a0bb6acb7 100644 (file)
@@ -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 */
 };