Add propagation of MLOCK state for simple modes.

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.
This commit is contained in:
William Pitcock 2010-03-07 23:13:39 -06:00
parent b99c9ae0bf
commit 8727cbe88a
4 changed files with 87 additions and 2 deletions

View 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];

View 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[])
{

View 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)))

View 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));
}