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 = {
"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 $");
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[])
{
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));
+}