Committer : entrope
CVSROOT : /cvsroot/undernet-ircu
Module : ircu2.10
Commit time: 2005-09-27 02:42:07 UTC
Modified files:
ChangeLog include/channel.h ircd/channel.c ircd/m_burst.c
ircd/m_clearmode.c ircd/m_create.c ircd/m_kick.c
Log message:
Fix desync when an oplevel deop is bounced (#1298140).
---------------------- diff included ----------------------
Index: ircu2.10/ChangeLog
diff -u ircu2.10/ChangeLog:1.706 ircu2.10/ChangeLog:1.707
--- ircu2.10/ChangeLog:1.706 Fri Sep 23 19:57:20 2005
+++ ircu2.10/ChangeLog Mon Sep 26 19:41:57 2005
@@ -1,3 +1,26 @@
+2005-09-26 Michael Poole <[EMAIL PROTECTED]>
+
+ * include/channel.h (struct ModeBuf): Add mbm_oplevel to args
+ array.
+ (MB_OPLEVEL): New corresponding macro.
+ (modebuf_mode_client): Add corresponding argument.
+
+ * ircd/channel.c (modebuf_flush_int): Adjust worst-case buffer
+ usage to include :999 suffix. Change format for oplevel passing.
+ (modebuf_mode_client): Set oplevel field in mbuf args array.
+ (struct ParseState): Add oplevel field to cli_change array.
+ (mode_parse_client): Accept and record oplevel suffix from
+ servers; fix it up if we're bouncing a deop.
+ (mode_process_clients): If a valid oplevel was parsed, use it.
+
+ * ircd/m_burst.c (ms_burst): Pass oplevel to modebuf_mode_client().
+
+ * ircd/m_clearmode.c (do_clearmode): Likewise.
+
+ * ircd/m_create.c (ms_create): Likewise.
+
+ * ircd/m_kick.c (ms_kick): Likewise.
+
2005-09-23 Michael Poole <[EMAIL PROTECTED]>
* include/whocmds.h (WHOSELECT_DELAY): Define new constant.
Index: ircu2.10/include/channel.h
diff -u ircu2.10/include/channel.h:1.54 ircu2.10/include/channel.h:1.55
--- ircu2.10/include/channel.h:1.54 Tue Sep 13 08:17:46 2005
+++ ircu2.10/include/channel.h Mon Sep 26 19:41:57 2005
@@ -19,7 +19,7 @@
*/
/** @file
* @brief Channel management and maintenance.
- * @version $Id: channel.h,v 1.54 2005/09/13 15:17:46 entrope Exp $
+ * @version $Id: channel.h,v 1.55 2005/09/27 02:41:57 entrope Exp $
*/
#ifndef INCLUDED_channel_h
#define INCLUDED_channel_h
@@ -317,6 +317,7 @@
char *mbma_string; /**< A string */
struct Client *mbma_client; /**< A client */
} mbm_arg; /**< The mode argument */
+ unsigned short mbm_oplevel; /**< Oplevel for a bounce */
} mb_modeargs[MAXMODEPARAMS];
/**< A mode w/args */
};
@@ -339,6 +340,7 @@
#define MB_UINT(mb, i) ((mb)->mb_modeargs[(i)].mbm_arg.mbma_uint)
#define MB_STRING(mb, i) ((mb)->mb_modeargs[(i)].mbm_arg.mbma_string)
#define MB_CLIENT(mb, i) ((mb)->mb_modeargs[(i)].mbm_arg.mbma_client)
+#define MB_OPLEVEL(mb, i) ((mb)->mb_modeargs[(i)].mbm_oplevel)
/** A buffer represeting a list of joins to send */
struct JoinBuf {
@@ -421,7 +423,7 @@
extern void modebuf_mode_string(struct ModeBuf *mbuf, unsigned int mode,
char *string, int free);
extern void modebuf_mode_client(struct ModeBuf *mbuf, unsigned int mode,
- struct Client *client);
+ struct Client *client, int oplevel);
extern int modebuf_flush(struct ModeBuf *mbuf);
extern void modebuf_extract(struct ModeBuf *mbuf, char *buf);
Index: ircu2.10/ircd/channel.c
diff -u ircu2.10/ircd/channel.c:1.154 ircu2.10/ircd/channel.c:1.155
--- ircu2.10/ircd/channel.c:1.154 Thu Sep 22 18:15:51 2005
+++ ircu2.10/ircd/channel.c Mon Sep 26 19:41:57 2005
@@ -19,7 +19,7 @@
*/
/** @file
* @brief Channel management and maintenance
- * @version $Id: channel.c,v 1.154 2005/09/23 01:15:51 entrope Exp $
+ * @version $Id: channel.c,v 1.155 2005/09/27 02:41:57 entrope Exp $
*/
#include "config.h"
@@ -1574,11 +1574,11 @@
if (MB_TYPE(mbuf, i) & (MODE_CHANOP | MODE_VOICE)) {
tmp = strlen(cli_name(MB_CLIENT(mbuf, i)));
- if ((totalbuflen - IRCD_MAX(5, tmp)) <= 0) /* don't overflow buffer */
+ if ((totalbuflen - IRCD_MAX(9, tmp)) <= 0) /* don't overflow buffer */
MB_TYPE(mbuf, i) |= MODE_SAVE; /* save for later */
else {
bufptr[(*bufptr_i)++] = MB_TYPE(mbuf, i) & MODE_CHANOP ? 'o' : 'v';
- totalbuflen -= IRCD_MAX(5, tmp) + 1;
+ totalbuflen -= IRCD_MAX(9, tmp) + 1;
}
} else if (MB_TYPE(mbuf, i) & (MODE_BAN | MODE_APASS | MODE_UPASS)) {
tmp = strlen(MB_STRING(mbuf, i));
@@ -1748,8 +1748,17 @@
strptr_i = &remstr_i;
}
- /* deal with modes that take clients */
- if (MB_TYPE(mbuf, i) & (MODE_CHANOP | MODE_VOICE))
+ /* if we're changing oplevels we know the oplevel, pass it on */
+ if (mbuf->mb_channel->mode.apass[0]
+ && (MB_TYPE(mbuf, i) & MODE_CHANOP)
+ && MB_OPLEVEL(mbuf, i) < MAXOPLEVEL)
+ *strptr_i += ircd_snprintf(0, strptr + *strptr_i, BUFSIZE -
*strptr_i,
+ " %s%s:%d",
+ NumNick(MB_CLIENT(mbuf, i)),
+ MB_OPLEVEL(mbuf, i));
+
+ /* deal with other modes that take clients */
+ else if (MB_TYPE(mbuf, i) & (MODE_CHANOP | MODE_VOICE))
build_string(strptr, strptr_i, NumNick(MB_CLIENT(mbuf, i)), ' ');
/* deal with modes that take strings */
@@ -1969,16 +1978,18 @@
* @param mbuf The modebuf to append the mode to.
* @param mode The mode to append.
* @param client The client argument to append.
+ * @param oplevel The oplevel the user had or will have
*/
void
modebuf_mode_client(struct ModeBuf *mbuf, unsigned int mode,
- struct Client *client)
+ struct Client *client, int oplevel)
{
assert(0 != mbuf);
assert(0 != (mode & (MODE_ADD | MODE_DEL)));
MB_TYPE(mbuf, mbuf->mb_count) = mode;
MB_CLIENT(mbuf, mbuf->mb_count) = client;
+ MB_OPLEVEL(mbuf, mbuf->mb_count) = oplevel;
/* when we've reached the maximal count, flush the buffer */
if (++mbuf->mb_count >=
@@ -2149,6 +2160,7 @@
struct Ban banlist[MAXPARA];
struct {
unsigned int flag;
+ unsigned short oplevel;
struct Client *client;
} cli_change[MAXPARA];
};
@@ -2829,6 +2841,8 @@
{
char *t_str;
struct Client *acptr;
+ struct Membership *member;
+ int oplevel = MAXOPLEVEL + 1;
int i;
if (MyUser(state->sptr) && state->max_args <= 0) /* drop if too many args */
@@ -2849,8 +2863,13 @@
if (MyUser(state->sptr)) /* find client we're manipulating */
acptr = find_chasing(state->sptr, t_str, NULL);
- else
+ else {
+ if (t_str[5] == ':') {
+ t_str[5] = '\0';
+ oplevel = atoi(t_str + 6);
+ }
acptr = findNUser(t_str);
+ }
if (!acptr)
return; /* find_chasing() already reported an error to the user */
@@ -2860,8 +2879,16 @@
state->cli_change[i].flag & flag_p[0]))
break; /* found a slot */
+ /* If we are going to bounce this deop, mark the correct oplevel. */
+ if (state->flags & MODE_PARSE_BOUNCE
+ && state->dir == MODE_DEL
+ && flag_p[0] == MODE_CHANOP
+ && (member = find_member_link(state->chptr, acptr)))
+ oplevel = OpLevel(member);
+
/* Store what we're doing to them */
state->cli_change[i].flag = state->dir | flag_p[0];
+ state->cli_change[i].oplevel = oplevel;
state->cli_change[i].client = acptr;
}
@@ -2939,20 +2966,22 @@
"deop", equal ? "the same" : "a higher");
continue;
}
- }
+ }
}
/* set op-level of member being opped */
if ((state->cli_change[i].flag & (MODE_ADD | MODE_CHANOP)) ==
(MODE_ADD | MODE_CHANOP)) {
- /* If being opped by an outsider, get oplevel 1 for an apass
- * channel, else MAXOPLEVEL.
+ /* If a valid oplevel was specified, use it.
+ * Otherwise, if being opped by an outsider, get MAXOPLEVEL.
* Otherwise, if not an apass channel, or state->member has
* MAXOPLEVEL, get oplevel MAXOPLEVEL.
* Otherwise, get state->member's oplevel+1.
*/
- if (!state->member)
- SetOpLevel(member, state->chptr->mode.apass[0] ? 1 : MAXOPLEVEL);
+ if (state->cli_change[i].oplevel <= MAXOPLEVEL)
+ SetOpLevel(member, state->cli_change[i].oplevel);
+ else if (!state->member)
+ SetOpLevel(member, MAXOPLEVEL);
else if (!state->chptr->mode.apass[0] || OpLevel(state->member) ==
MAXOPLEVEL)
SetOpLevel(member, MAXOPLEVEL);
else
@@ -2975,7 +3004,8 @@
/* accumulate the change */
modebuf_mode_client(state->mbuf, state->cli_change[i].flag,
- state->cli_change[i].client);
+ state->cli_change[i].client,
+ state->cli_change[i].oplevel);
} /* for (i = 0; state->cli_change[i].flags; i++) */
}
Index: ircu2.10/ircd/m_burst.c
diff -u ircu2.10/ircd/m_burst.c:1.39 ircu2.10/ircd/m_burst.c:1.40
--- ircu2.10/ircd/m_burst.c:1.39 Sun Sep 11 20:40:17 2005
+++ ircu2.10/ircd/m_burst.c Mon Sep 26 19:41:57 2005
@@ -20,7 +20,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: m_burst.c,v 1.39 2005/09/12 03:40:17 entrope Exp $
+ * $Id: m_burst.c,v 1.40 2005/09/27 02:41:57 entrope Exp $
*/
/*
@@ -523,14 +523,14 @@
for (member = chptr->members; member; member = member->next_member) {
if (member->status & CHFL_BURST_JOINED) { /* joined during burst */
if ((member->status & CHFL_CHANOP) && !(member->status &
CHFL_BURST_ALREADY_OPPED))
- modebuf_mode_client(mbuf, MODE_ADD | CHFL_CHANOP, member->user);
+ modebuf_mode_client(mbuf, MODE_ADD | CHFL_CHANOP, member->user,
OpLevel(member));
if ((member->status & CHFL_VOICE) && !(member->status &
CHFL_BURST_ALREADY_VOICED))
- modebuf_mode_client(mbuf, MODE_ADD | CHFL_VOICE, member->user);
+ modebuf_mode_client(mbuf, MODE_ADD | CHFL_VOICE, member->user,
OpLevel(member));
} else if (parse_flags & MODE_PARSE_WIPEOUT) { /* wipeout old ops */
if (member->status & CHFL_CHANOP)
- modebuf_mode_client(mbuf, MODE_DEL | CHFL_CHANOP, member->user);
+ modebuf_mode_client(mbuf, MODE_DEL | CHFL_CHANOP, member->user,
OpLevel(member));
if (member->status & CHFL_VOICE)
- modebuf_mode_client(mbuf, MODE_DEL | CHFL_VOICE, member->user);
+ modebuf_mode_client(mbuf, MODE_DEL | CHFL_VOICE, member->user,
OpLevel(member));
member->status = (member->status
& ~(CHFL_CHANNEL_MANAGER | CHFL_CHANOP | CHFL_VOICE))
| CHFL_DEOPPED;
Index: ircu2.10/ircd/m_clearmode.c
diff -u ircu2.10/ircd/m_clearmode.c:1.30 ircu2.10/ircd/m_clearmode.c:1.31
--- ircu2.10/ircd/m_clearmode.c:1.30 Thu Jun 16 20:55:13 2005
+++ ircu2.10/ircd/m_clearmode.c Mon Sep 26 19:41:57 2005
@@ -21,7 +21,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: m_clearmode.c,v 1.30 2005/06/17 03:55:13 entrope Exp $
+ * $Id: m_clearmode.c,v 1.31 2005/09/27 02:41:57 entrope Exp $
*/
/*
@@ -200,13 +200,13 @@
/* Drop channel operator status */
if (IsChanOp(member) && del_mode & MODE_CHANOP) {
- modebuf_mode_client(&mbuf, MODE_DEL | MODE_CHANOP, member->user);
+ modebuf_mode_client(&mbuf, MODE_DEL | MODE_CHANOP, member->user,
MAXOPLEVEL + 1);
member->status &= ~CHFL_CHANOP;
}
/* Drop voice */
if (HasVoice(member) && del_mode & MODE_VOICE) {
- modebuf_mode_client(&mbuf, MODE_DEL | MODE_VOICE, member->user);
+ modebuf_mode_client(&mbuf, MODE_DEL | MODE_VOICE, member->user,
MAXOPLEVEL + 1);
member->status &= ~CHFL_VOICE;
}
}
Index: ircu2.10/ircd/m_create.c
diff -u ircu2.10/ircd/m_create.c:1.17 ircu2.10/ircd/m_create.c:1.18
--- ircu2.10/ircd/m_create.c:1.17 Sun Mar 20 05:45:28 2005
+++ ircu2.10/ircd/m_create.c Mon Sep 26 19:41:57 2005
@@ -20,7 +20,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: m_create.c,v 1.17 2005/03/20 13:45:28 entrope Exp $
+ * $Id: m_create.c,v 1.18 2005/09/27 02:41:57 entrope Exp $
*/
/*
@@ -174,7 +174,7 @@
MODEBUF_DEST_HACK2 | /* Send a HACK(2) message */
MODEBUF_DEST_BOUNCE)); /* And bounce the mode */
- modebuf_mode_client(&mbuf, MODE_ADD | MODE_CHANOP, sptr);
+ modebuf_mode_client(&mbuf, MODE_ADD | MODE_CHANOP, sptr, MAXOPLEVEL +
1);
modebuf_flush(&mbuf);
Index: ircu2.10/ircd/m_kick.c
diff -u ircu2.10/ircd/m_kick.c:1.17 ircu2.10/ircd/m_kick.c:1.18
--- ircu2.10/ircd/m_kick.c:1.17 Tue Aug 16 19:14:45 2005
+++ ircu2.10/ircd/m_kick.c Mon Sep 26 19:41:57 2005
@@ -20,7 +20,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: m_kick.c,v 1.17 2005/08/17 02:14:45 entrope Exp $
+ * $Id: m_kick.c,v 1.18 2005/09/27 02:41:57 entrope Exp $
*/
/*
@@ -234,9 +234,9 @@
MODEBUF_DEST_BOUNCE)); /* And bounce the MODE */
if (IsChanOp(member))
- modebuf_mode_client(&mbuf, MODE_DEL | MODE_CHANOP, who);
+ modebuf_mode_client(&mbuf, MODE_DEL | MODE_CHANOP, who, MAXOPLEVEL + 1);
if (HasVoice(member))
- modebuf_mode_client(&mbuf, MODE_DEL | MODE_VOICE, who);
+ modebuf_mode_client(&mbuf, MODE_DEL | MODE_VOICE, who, MAXOPLEVEL + 1);
modebuf_flush(&mbuf);
}
----------------------- End of diff -----------------------
_______________________________________________
Patches mailing list
[email protected]
http://undernet.sbg.org/mailman/listinfo/patches