]> jfr.im git - irc/freenode/ircd-seven.git/commitdiff
Add propagation of MLOCK state for simple modes.
authorWilliam Pitcock <redacted>
Mon, 8 Mar 2010 05:13:39 +0000 (23:13 -0600)
committerWilliam Pitcock <redacted>
Mon, 8 Mar 2010 05:13:39 +0000 (23:13 -0600)
Special modes like +j can be tracked easily just by adding the necessary
code to parse them to set_channel_mlock().  This will cover propagation
as well.

include/channel.h
modules/core/m_mode.c
src/channel.c
src/chmode.c

index e37dd3ae1ce0b38cb618a306edc29dea61967f23..090f76590d59cb8377665deb04b72276922bdd7e 100644 (file)
@@ -259,6 +259,8 @@ extern void send_cap_mode_changes(struct Client *client_p, struct Client *source
 
 extern void set_channel_mode(struct Client *client_p, struct Client *source_p,
                struct Channel *chptr, struct membership *msptr, int parc, const char *parv[]);
+extern void set_channel_mlock(struct Client *client_p, struct Client *source_p,
+               struct Channel *chptr, int parc, const char *parv[]);
 
 extern struct ChannelMode chmode_table[256];
 
index 42df7ed2b8a0ebb75496b56e7eb8372c5342b7d6..219b031ce08542bd14ba07eef5020c34c89ce4a9 100644 (file)
@@ -45,6 +45,7 @@
 static int m_mode(struct Client *, struct Client *, int, const char **);
 static int ms_mode(struct Client *, struct Client *, int, const char **);
 static int ms_tmode(struct Client *, struct Client *, int, const char **);
+static int ms_mlock(struct Client *, struct Client *, int, const char **);
 static int ms_bmask(struct Client *, struct Client *, int, const char **);
 
 struct Message mode_msgtab = {
@@ -55,12 +56,16 @@ struct Message tmode_msgtab = {
        "TMODE", 0, 0, 0, MFLG_SLOW,
        {mg_ignore, mg_ignore, {ms_tmode, 4}, {ms_tmode, 4}, mg_ignore, mg_ignore}
 };
+struct Message mlock_msgtab = {
+       "MLOCK", 0, 0, 0, MFLG_SLOW,
+       {mg_ignore, mg_ignore, {ms_mlock, 4}, {ms_mlock, 4}, mg_ignore, mg_ignore}
+};
 struct Message bmask_msgtab = {
        "BMASK", 0, 0, 0, MFLG_SLOW,
        {mg_ignore, mg_ignore, mg_ignore, {ms_bmask, 5}, mg_ignore, mg_ignore}
 };
 
-mapi_clist_av1 mode_clist[] = { &mode_msgtab, &tmode_msgtab, &bmask_msgtab, NULL };
+mapi_clist_av1 mode_clist[] = { &mode_msgtab, &tmode_msgtab, &mlock_msgtab, &bmask_msgtab, NULL };
 
 DECLARE_MODULE_AV1(mode, NULL, NULL, mode_clist, NULL, NULL, "$Revision: 1006 $");
 
@@ -204,6 +209,37 @@ ms_tmode(struct Client *client_p, struct Client *source_p, int parc, const char
        return 0;
 }
 
+static int
+ms_mlock(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+       struct Channel *chptr = NULL;
+
+       /* Now, try to find the channel in question */
+       if(!IsChanPrefix(parv[2][0]) || !check_channel_name(parv[2]))
+       {
+               sendto_one_numeric(source_p, ERR_BADCHANNAME, form_str(ERR_BADCHANNAME), parv[2]);
+               return 0;
+       }
+
+       chptr = find_channel(parv[2]);
+
+       if(chptr == NULL)
+       {
+               sendto_one_numeric(source_p, ERR_NOSUCHCHANNEL,
+                                  form_str(ERR_NOSUCHCHANNEL), parv[2]);
+               return 0;
+       }
+
+       /* TS is higher, drop it. */
+       if(atol(parv[1]) > chptr->channelts)
+               return 0;
+
+       if(IsServer(source_p))
+               set_channel_mlock(client_p, source_p, chptr, parc - 3, parv + 3);
+
+       return 0;
+}
+
 static int
 ms_bmask(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
 {
index 3b0516bd64d6c60b60cf9f96b080934b3a1943e8..7483b6e50f690b4f0bbfd7b62e0531f0e9741ecd 100644 (file)
@@ -1122,7 +1122,7 @@ channel_modes_real(struct Channel *chptr, struct Mode *mode, struct Client *clie
 
                if(pbuf > buf2 || !IsClient(client_p) || IsMember(client_p, chptr))
                        pbuf += rb_sprintf(pbuf, " %d:%d", mode->join_num,
-                                          mode->oin_time);
+                                          mode->join_time);
        }
 
        if(*mode->forward && (ConfigChannel.use_forward || !IsClient(client_p)))
index c9069f38da8a41a8c883f29deb2e5a49f9514a85..68edd05bd72025edf0561679e8bafcef4d75312e 100644 (file)
@@ -1748,3 +1748,50 @@ set_channel_mode(struct Client *client_p, struct Client *source_p,
        if(MyClient(source_p) || rb_dlink_list_length(&serv_list) > 1)
                send_cap_mode_changes(client_p, source_p, chptr, mode_changes, mode_count);
 }
+
+/* set_channel_mlock()
+ *
+ * inputs      - client, source, channel, params
+ * output      - 
+ * side effects - channel mlock is changed / MLOCK is propagated
+ */
+void
+set_channel_mlock(struct Client *client_p, struct Client *source_p,
+                 struct Channel *chptr, int parc, const char *parv[])
+{
+       int dir = MODE_ADD;
+       const char *ml = parv[0];
+       char c;
+
+       memset(&chptr->mode_lock, '\0', sizeof(struct Mode));
+
+       for(; (c = *ml) != 0; ml++)
+       {
+               switch (c)
+               {
+               case '+':
+                       dir = MODE_ADD;
+                       break;
+               case '-':
+                       dir = MODE_DEL;
+                       break;
+               default:
+                       if (chmode_table[(unsigned char) c].set_func == chm_simple)
+                               switch(dir)
+                               {
+                               case MODE_ADD:
+                                       chptr->mode_lock.mode |= chmode_table[(unsigned char) c].mode_type;
+                                       chptr->mode_lock.off_mode &= ~chmode_table[(unsigned char) c].mode_type;
+                                       break;
+                               case MODE_DEL:
+                                       chptr->mode_lock.off_mode |= chmode_table[(unsigned char) c].mode_type;
+                                       chptr->mode_lock.mode &= ~chmode_table[(unsigned char) c].mode_type;
+                                       break;
+                               }
+                       break;
+               }
+       }
+
+       sendto_server(client_p, NULL, CAP_TS6 | CAP_MLOCK, NOCAPS, ":%s MLOCK %ld %s %s",
+                     source_p->id, (long) chptr->channelts, chptr->chname, channel_mlock(chptr, &me));
+}