From 923424fa8bb6557bfeba194a583c3a8daad023ed Mon Sep 17 00:00:00 2001 From: pk910 Date: Sat, 2 Jul 2011 17:06:58 +0200 Subject: [PATCH] send QUIT's only to users seeing the leaving user on MODE_AUDITORIUM channels --- include/send.h | 7 +++++++ ircd/s_misc.c | 3 ++- ircd/send.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/include/send.h b/include/send.h index 1fb416a..0d550f2 100644 --- a/include/send.h +++ b/include/send.h @@ -61,6 +61,13 @@ extern void sendcmdto_common_channels_butone(struct Client *from, const char *tok, struct Client *one, const char *pattern, ...); + +/* Send command to all channels user is on (check audit) */ +extern void sendcmdto_common_channels_butone_audit(struct Client *from, + const char *cmd, + const char *tok, + struct Client *one, + const char *pattern, ...); /* Send command to all channel users on this server */ extern void sendcmdto_channel_butserv_butone(struct Client *from, diff --git a/ircd/s_misc.c b/ircd/s_misc.c index 203f34e..48b2dd9 100644 --- a/ircd/s_misc.c +++ b/ircd/s_misc.c @@ -205,7 +205,8 @@ static void exit_one_client(struct Client* bcptr, const char* comment) * that the client can show the "**signoff" message). * (Note: The notice is to the local clients *only*) */ - sendcmdto_common_channels_butone(bcptr, CMD_QUIT, NULL, ":%s", comment); + + sendcmdto_common_channels_butone_audit(bcptr, CMD_QUIT, NULL, ":%s", comment); remove_user_from_all_channels(bcptr); diff --git a/ircd/send.c b/ircd/send.c index 828b518..ff8d115 100644 --- a/ircd/send.c +++ b/ircd/send.c @@ -514,6 +514,60 @@ void sendcmdto_common_channels_butone(struct Client *from, const char *cmd, msgq_clean(mb); } +/** Send a (prefixed) command to all channels that \a from is on. (Check audit) + * @param[in] from Client originating the command. + * @param[in] cmd Long name of command. + * @param[in] tok Short name of command. + * @param[in] one Client direction to skip (or NULL). + * @param[in] pattern Format string for command arguments. + */ +void sendcmdto_common_channels_butone_audit(struct Client *from, const char *cmd, + const char *tok, struct Client *one, + const char *pattern, ...) +{ + struct VarData vd; + struct MsgBuf *mb; + struct Membership *chan; + struct Membership *member; + + assert(0 != from); + assert(0 != cli_from(from)); + assert(0 != pattern); + assert(!IsServer(from) && !IsMe(from)); + + vd.vd_format = pattern; /* set up the struct VarData for %v */ + + va_start(vd.vd_args, pattern); + + /* build the buffer */ + mb = msgq_make(0, "%:#C %s %v", from, cmd, &vd); + va_end(vd.vd_args); + + bump_sentalong(from); + /* + * loop through from's channels, and the members on their channels + */ + for (chan = cli_user(from)->channel; chan; chan = chan->next_channel) { + if (IsZombie(chan) || IsDelayedJoin(chan)) + continue; + for (member = chan->channel->members; member; + member = member->next_member) + if (MyConnect(member->user) + && -1 < cli_fd(cli_from(member->user)) + && member->user != one + && cli_sentalong(member->user) != sentalong_marker + && (!(chan->channel->mode.mode & MODE_AUDITORIUM) || IsVoicedOrOpped(chan) || IsChanOp(member))) { + cli_sentalong(member->user) = sentalong_marker; + send_buffer(member->user, mb, 0); + } + } + + if (MyConnect(from) && from != one) + send_buffer(from, mb, 0); + + msgq_clean(mb); +} + /** Send a (prefixed) command to all local users on a channel. * @param[in] from Client originating the command. * @param[in] cmd Long name of command. -- 2.20.1