Apply +z to messages blocked by +b and +q as well.
This adds a new server capab EOPMOD which will be used for an extended topic command also.
This commit is contained in:
parent
1ba5ea0f06
commit
c4d2d01419
7 changed files with 193 additions and 9 deletions
|
@ -544,6 +544,9 @@ The target can be:
|
|||
with that status or higher only.
|
||||
capab: CHW
|
||||
propagation: all servers with -D users with appropriate status
|
||||
- '=' followed by a channel name, to send to chanops only, for cmode +z.
|
||||
capab: CHW and EOPMOD
|
||||
propagation: all servers with -D chanops
|
||||
- a user@server message, to send to users on a specific server. The exact
|
||||
meaning of the part before the '@' is not prescribed, except that "opers"
|
||||
allows IRC operators to send to all IRC operators on the server in an
|
||||
|
|
|
@ -16,7 +16,8 @@ NO PARAMETERS:
|
|||
+c - No color. All color codes in messages are stripped.
|
||||
+g - Free invite. Everyone may invite users. Significantly
|
||||
weakens +i control.
|
||||
+z - Op moderated. Messages blocked by +m are instead sent to ops.
|
||||
+z - Op moderated. Messages blocked by +m, +b and +q are instead
|
||||
sent to ops.
|
||||
+L - Large ban list. Increase maximum number of +beIq entries.
|
||||
Only settable by opers.
|
||||
+P - Permanent. Channel does not disappear when empty. Only
|
||||
|
|
|
@ -70,12 +70,13 @@ struct Capability
|
|||
#define CAP_RSFNC 0x20000 /* rserv FNC */
|
||||
#define CAP_SAVE 0x40000 /* supports SAVE (nick collision FNC) */
|
||||
#define CAP_EUID 0x80000 /* supports EUID (ext UID + nonencap CHGHOST) */
|
||||
#define CAP_EOPMOD 0x100000 /* supports EOPMOD (ext +z + ext topic) */
|
||||
|
||||
#define CAP_MASK (CAP_QS | CAP_EX | CAP_CHW | \
|
||||
CAP_IE | CAP_KLN | CAP_SERVICE |\
|
||||
CAP_CLUSTER | CAP_ENCAP | \
|
||||
CAP_ZIP | CAP_KNOCK | CAP_UNKLN | \
|
||||
CAP_RSFNC | CAP_SAVE | CAP_EUID)
|
||||
CAP_RSFNC | CAP_SAVE | CAP_EUID | CAP_EOPMOD)
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
#define CAP_ZIP_SUPPORTED CAP_ZIP
|
||||
|
|
|
@ -57,6 +57,9 @@ extern void sendto_server(struct Client *one, struct Channel *chptr,
|
|||
|
||||
extern void sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
|
||||
struct Channel *chptr, const char *, ...) AFP(5, 6);
|
||||
extern void sendto_channel_opmod(struct Client *one, struct Client *source_p,
|
||||
struct Channel *chptr, const char *command,
|
||||
const char *text);
|
||||
|
||||
extern void sendto_channel_local(int type, struct Channel *, const char *, ...) AFP(3, 4);
|
||||
extern void sendto_channel_local_butone(struct Client *, int type, struct Channel *, const char *, ...) AFP(4, 5);
|
||||
|
|
|
@ -97,8 +97,9 @@ static int flood_attack_channel(int p_or_n, struct Client *source_p,
|
|||
|
||||
#define ENTITY_NONE 0
|
||||
#define ENTITY_CHANNEL 1
|
||||
#define ENTITY_CHANOPS_ON_CHANNEL 2
|
||||
#define ENTITY_CLIENT 3
|
||||
#define ENTITY_CHANNEL_OPMOD 2
|
||||
#define ENTITY_CHANOPS_ON_CHANNEL 3
|
||||
#define ENTITY_CLIENT 4
|
||||
|
||||
static struct entity targets[512];
|
||||
static int ntargets = 0;
|
||||
|
@ -109,6 +110,11 @@ static void msg_channel(int p_or_n, const char *command,
|
|||
struct Client *client_p,
|
||||
struct Client *source_p, struct Channel *chptr, const char *text);
|
||||
|
||||
static void msg_channel_opmod(int p_or_n, const char *command,
|
||||
struct Client *client_p,
|
||||
struct Client *source_p, struct Channel *chptr,
|
||||
const char *text);
|
||||
|
||||
static void msg_channel_flags(int p_or_n, const char *command,
|
||||
struct Client *client_p,
|
||||
struct Client *source_p,
|
||||
|
@ -204,6 +210,11 @@ m_message(int p_or_n,
|
|||
(struct Channel *) targets[i].ptr, parv[2]);
|
||||
break;
|
||||
|
||||
case ENTITY_CHANNEL_OPMOD:
|
||||
msg_channel_opmod(p_or_n, command, client_p, source_p,
|
||||
(struct Channel *) targets[i].ptr, parv[2]);
|
||||
break;
|
||||
|
||||
case ENTITY_CHANOPS_ON_CHANNEL:
|
||||
msg_channel_flags(p_or_n, command, client_p, source_p,
|
||||
(struct Channel *) targets[i].ptr,
|
||||
|
@ -382,6 +393,32 @@ build_target_list(int p_or_n, const char *command, struct Client *client_p,
|
|||
continue;
|
||||
}
|
||||
|
||||
if(IsServer(client_p) && *nick == '=' && nick[1] == '#')
|
||||
{
|
||||
nick++;
|
||||
if((chptr = find_channel(nick)) != NULL)
|
||||
{
|
||||
if(!duplicate_ptr(chptr))
|
||||
{
|
||||
if(ntargets >= ConfigFileEntry.max_targets)
|
||||
{
|
||||
sendto_one(source_p, form_str(ERR_TOOMANYTARGETS),
|
||||
me.name, source_p->name, nick);
|
||||
return (1);
|
||||
}
|
||||
targets[ntargets].ptr = (void *) chptr;
|
||||
targets[ntargets++].type = ENTITY_CHANNEL_OPMOD;
|
||||
}
|
||||
}
|
||||
|
||||
/* non existant channel */
|
||||
else if(p_or_n != NOTICE)
|
||||
sendto_one_numeric(source_p, ERR_NOSUCHNICK,
|
||||
form_str(ERR_NOSUCHNICK), nick);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* no matching anything found - error if not NOTICE */
|
||||
if(p_or_n != NOTICE)
|
||||
{
|
||||
|
@ -476,16 +513,65 @@ msg_channel(int p_or_n, const char *command,
|
|||
}
|
||||
}
|
||||
else if(chptr->mode.mode & MODE_OPMODERATE &&
|
||||
chptr->mode.mode & MODE_MODERATED &&
|
||||
(!(chptr->mode.mode & MODE_NOPRIVMSGS) ||
|
||||
IsMember(source_p, chptr)))
|
||||
{
|
||||
/* only do +z for +m channels for now, as bans/quiets
|
||||
* aren't tested for remote clients -- jilles */
|
||||
if(!flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
|
||||
{
|
||||
sendto_channel_flags(client_p, ONLY_CHANOPS, source_p, chptr,
|
||||
"%s %s :%s", command, chptr->chname, text);
|
||||
sendto_channel_opmod(client_p, source_p, chptr,
|
||||
command, text);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(p_or_n != NOTICE)
|
||||
sendto_one_numeric(source_p, ERR_CANNOTSENDTOCHAN,
|
||||
form_str(ERR_CANNOTSENDTOCHAN), chptr->chname);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* msg_channel_opmod
|
||||
*
|
||||
* inputs - flag privmsg or notice
|
||||
* - pointer to command "PRIVMSG" or "NOTICE"
|
||||
* - pointer to client_p
|
||||
* - pointer to source_p
|
||||
* - pointer to channel
|
||||
* output - NONE
|
||||
* side effects - message given channel ops
|
||||
*
|
||||
* XXX - We need to rework this a bit, it's a tad ugly. --nenolod
|
||||
*/
|
||||
static void
|
||||
msg_channel_opmod(int p_or_n, const char *command,
|
||||
struct Client *client_p, struct Client *source_p,
|
||||
struct Channel *chptr, const char *text)
|
||||
{
|
||||
char text2[BUFSIZE];
|
||||
|
||||
if(chptr->mode.mode & MODE_NOCOLOR)
|
||||
{
|
||||
rb_strlcpy(text2, text, BUFSIZE);
|
||||
strip_colour(text2);
|
||||
text = text2;
|
||||
if (EmptyString(text))
|
||||
{
|
||||
/* could be empty after colour stripping and
|
||||
* that would cause problems later */
|
||||
if(p_or_n != NOTICE)
|
||||
sendto_one(source_p, form_str(ERR_NOTEXTTOSEND), me.name, source_p->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(chptr->mode.mode & MODE_OPMODERATE &&
|
||||
(!(chptr->mode.mode & MODE_NOPRIVMSGS) ||
|
||||
IsMember(source_p, chptr)))
|
||||
{
|
||||
if(!flood_attack_channel(p_or_n, source_p, chptr, chptr->chname))
|
||||
{
|
||||
sendto_channel_opmod(client_p, source_p, chptr,
|
||||
command, text);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -91,6 +91,7 @@ struct Capability captab[] = {
|
|||
{ "RSFNC", CAP_RSFNC },
|
||||
{ "SAVE", CAP_SAVE },
|
||||
{ "EUID", CAP_EUID },
|
||||
{ "EOPMOD", CAP_EOPMOD },
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
|
|
89
src/send.c
89
src/send.c
|
@ -531,6 +531,95 @@ sendto_channel_flags(struct Client *one, int type, struct Client *source_p,
|
|||
rb_linebuf_donebuf(&rb_linebuf_id);
|
||||
}
|
||||
|
||||
/* sendto_channel_flags()
|
||||
*
|
||||
* inputs - server not to send to, flags needed, source, channel, va_args
|
||||
* outputs - message is sent to channel members
|
||||
* side effects -
|
||||
*/
|
||||
void
|
||||
sendto_channel_opmod(struct Client *one, struct Client *source_p,
|
||||
struct Channel *chptr, const char *command,
|
||||
const char *text)
|
||||
{
|
||||
static char buf[BUFSIZE];
|
||||
va_list args;
|
||||
buf_head_t rb_linebuf_local;
|
||||
buf_head_t rb_linebuf_old;
|
||||
buf_head_t rb_linebuf_new;
|
||||
struct Client *target_p;
|
||||
struct membership *msptr;
|
||||
rb_dlink_node *ptr;
|
||||
rb_dlink_node *next_ptr;
|
||||
|
||||
rb_linebuf_newbuf(&rb_linebuf_local);
|
||||
rb_linebuf_newbuf(&rb_linebuf_old);
|
||||
rb_linebuf_newbuf(&rb_linebuf_new);
|
||||
|
||||
current_serial++;
|
||||
|
||||
if(IsServer(source_p))
|
||||
rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL,
|
||||
":%s %s %s :%s",
|
||||
source_p->name, command, chptr->chname, text);
|
||||
else
|
||||
rb_linebuf_putmsg(&rb_linebuf_local, NULL, NULL,
|
||||
":%s!%s@%s %s %s :%s",
|
||||
source_p->name, source_p->username,
|
||||
source_p->host, command, chptr->chname, text);
|
||||
|
||||
if (chptr->mode.mode & MODE_MODERATED)
|
||||
rb_linebuf_putmsg(&rb_linebuf_old, NULL, NULL,
|
||||
":%s %s %s :%s",
|
||||
use_id(source_p), command, chptr->chname, text);
|
||||
else
|
||||
rb_linebuf_putmsg(&rb_linebuf_old, NULL, NULL,
|
||||
":%s NOTICE @%s :<%s:%s> %s",
|
||||
use_id(source_p->servptr), chptr->chname,
|
||||
source_p->name, chptr->chname, text);
|
||||
rb_linebuf_putmsg(&rb_linebuf_new, NULL, NULL,
|
||||
":%s %s =%s :%s",
|
||||
use_id(source_p), command, chptr->chname, text);
|
||||
|
||||
RB_DLINK_FOREACH_SAFE(ptr, next_ptr, chptr->members.head)
|
||||
{
|
||||
msptr = ptr->data;
|
||||
target_p = msptr->client_p;
|
||||
|
||||
if(IsIOError(target_p->from) || target_p->from == one)
|
||||
continue;
|
||||
|
||||
if((msptr->flags & CHFL_CHANOP) == 0)
|
||||
continue;
|
||||
|
||||
if(IsDeaf(target_p))
|
||||
continue;
|
||||
|
||||
if(!MyClient(target_p))
|
||||
{
|
||||
/* if we've got a specific type, target must support
|
||||
* CHW.. --fl
|
||||
*/
|
||||
if(NotCapable(target_p->from, CAP_CHW))
|
||||
continue;
|
||||
|
||||
if(target_p->from->serial != current_serial)
|
||||
{
|
||||
if (IsCapable(target_p->from, CAP_EOPMOD))
|
||||
send_linebuf_remote(target_p, source_p, &rb_linebuf_new);
|
||||
else
|
||||
send_linebuf_remote(target_p, source_p, &rb_linebuf_old);
|
||||
target_p->from->serial = current_serial;
|
||||
}
|
||||
}
|
||||
else
|
||||
_send_linebuf(target_p, &rb_linebuf_local);
|
||||
}
|
||||
|
||||
rb_linebuf_donebuf(&rb_linebuf_local);
|
||||
rb_linebuf_donebuf(&rb_linebuf_old);
|
||||
rb_linebuf_donebuf(&rb_linebuf_new);
|
||||
}
|
||||
|
||||
/* sendto_channel_local()
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue