From 0066009565b01e5c5e52000d97cb7b20ae8c667c Mon Sep 17 00:00:00 2001 From: Michael Poole Date: Wed, 19 May 2004 03:46:05 +0000 Subject: [PATCH] Implement invitation announcements (RPL_ISSUEDINVITE). git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@1073 c9e4aea6-c8fd-4c43-8297-357d70d61c8c --- ChangeLog | 21 +++++++++++++++++ include/ircd_features.h | 1 + include/numeric.h | 1 + include/send.h | 10 +++++++++ ircd/channel.c | 12 +++++----- ircd/ircd_features.c | 1 + ircd/m_burst.c | 6 ++--- ircd/m_invite.c | 28 +++++++++++++++++++++-- ircd/m_kick.c | 4 ++-- ircd/m_topic.c | 2 +- ircd/s_err.c | 2 +- ircd/s_user.c | 6 ++--- ircd/send.c | 50 ++++++++++++++++++++++++++++++++++++++--- 13 files changed, 123 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index 69dc3eb..12ebed2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2004-05-18 Michael Poole + + Announce invitations to other channel operators. + + * include/ircd_features.h, ircd/ircd_features.c + (ANNOUNCE_INVITES): Add new boolean feature, default off. + + * include/numeric.h, ircd/s_err.c (RPL_ISSUEDINVITE): Add new + reply. + + * include/send.h, ircd/send.c (sendcmdto_channel_butserv_butone): + Add 'skip' parameter that is needed elsewhere. + (sendcmdto_channel_servers_butone): New function. + + * ircd/channel.c, ircd/m_burst.c, ircd/m_kick.c, ircd/m_topic.c, + ircd/s_user.c: Add argument for 'skip' to calls to s_c_b_b. + + * ircd/m_invite.c (m_invite, ms_invite): If ANNOUNCE_INVITES, send + the INVITE message to all interested servers, and send a numeric + to all local chanops. + 2004-05-18 Michael Poole * ircd/res_adns.c (res_ourserver): Remove unused function. diff --git a/include/ircd_features.h b/include/ircd_features.h index b1e0cc5..d6671ae 100644 --- a/include/ircd_features.h +++ b/include/ircd_features.h @@ -87,6 +87,7 @@ enum Feature { FEAT_IRCD_RES_RETRIES, FEAT_IRCD_RES_TIMEOUT, FEAT_AUTH_TIMEOUT, + FEAT_ANNOUNCE_INVITES, /* features that affect all operators */ FEAT_CRYPT_OPER_PASSWORD, diff --git a/include/numeric.h b/include/numeric.h index 334f7b0..24ef24b 100644 --- a/include/numeric.h +++ b/include/numeric.h @@ -257,6 +257,7 @@ extern const struct Numeric* get_error_numeric(int err); #define RPL_INVITING 341 /* RPL_SUMMONING 342 removed from RFC1459 */ +#define RPL_ISSUEDINVITE 345 /* Undernet extension */ #define RPL_INVITELIST 346 /* IRCnet, Undernet extension */ #define RPL_ENDOFINVITELIST 347 /* IRCnet, Undernet extension */ /* RPL_EXCEPTLIST 348 IRCnet extension */ diff --git a/include/send.h b/include/send.h index bf7e754..11f7201 100644 --- a/include/send.h +++ b/include/send.h @@ -61,8 +61,18 @@ extern void sendcmdto_channel_butserv_butone(struct Client *from, const char *tok, struct Channel *to, struct Client *one, + unsigned int skip, const char *pattern, ...); +/* Send command to all servers interested in a channel */ +extern void sendcmdto_channel_servers_butone(struct Client *from, + const char *cmd, + const char *tok, + struct Channel *to, + struct Client *one, + unsigned int skip, + const char *pattern, ...); + /* Send command to all interested channel users */ extern void sendcmdto_channel_butone(struct Client *from, const char *cmd, const char *tok, struct Channel *to, diff --git a/ircd/channel.c b/ircd/channel.c index be0e336..fd2df7e 100644 --- a/ircd/channel.c +++ b/ircd/channel.c @@ -1736,7 +1736,7 @@ modebuf_flush_int(struct ModeBuf *mbuf, int all) addbuf_i ? "+" : "", addbuf, remstr, addstr); if (mbuf->mb_dest & MODEBUF_DEST_CHANNEL) - sendcmdto_channel_butserv_butone(app_source, CMD_MODE, mbuf->mb_channel, NULL, + sendcmdto_channel_butserv_butone(app_source, CMD_MODE, mbuf->mb_channel, NULL, 0, "%H %s%s%s%s%s%s", mbuf->mb_channel, rembuf_i ? "-" : "", rembuf, addbuf_i ? "+" : "", addbuf, remstr, addstr); @@ -3207,7 +3207,7 @@ joinbuf_join(struct JoinBuf *jbuf, struct Channel *chan, unsigned int flags) /* Send notification to channel */ if (!(flags & (CHFL_ZOMBIE | CHFL_DELAYED))) - sendcmdto_channel_butserv_butone(jbuf->jb_source, CMD_PART, chan, NULL, + sendcmdto_channel_butserv_butone(jbuf->jb_source, CMD_PART, chan, NULL, 0, (flags & CHFL_BANNED || !jbuf->jb_comment) ? ":%H" : "%H :%s", chan, jbuf->jb_comment); else if (MyUser(jbuf->jb_source)) @@ -3238,11 +3238,11 @@ joinbuf_join(struct JoinBuf *jbuf, struct Channel *chan, unsigned int flags) if (!((chan->mode.mode & MODE_DELJOINS) && !(flags & CHFL_VOICED_OR_OPPED))) { /* Send the notification to the channel */ - sendcmdto_channel_butserv_butone(jbuf->jb_source, CMD_JOIN, chan, NULL, "%H", chan); + sendcmdto_channel_butserv_butone(jbuf->jb_source, CMD_JOIN, chan, NULL, 0, "%H", chan); /* send an op, too, if needed */ if (!MyUser(jbuf->jb_source) && jbuf->jb_type == JOINBUF_TYPE_CREATE) - sendcmdto_channel_butserv_butone(jbuf->jb_source, CMD_MODE, chan, NULL, "%H +o %C", + sendcmdto_channel_butserv_butone(jbuf->jb_source, CMD_MODE, chan, NULL, 0, "%H +o %C", chan, jbuf->jb_source); } else if (MyUser(jbuf->jb_source)) sendcmdto_one(jbuf->jb_source, CMD_JOIN, jbuf->jb_source, ":%H", chan); @@ -3328,7 +3328,7 @@ int IsInvited(struct Client* cptr, const void* chptr) void RevealDelayedJoin(struct Membership *member) { ClearDelayedJoin(member); - sendcmdto_channel_butserv_butone(member->user, CMD_JOIN, member->channel, member->user, ":%H", + sendcmdto_channel_butserv_butone(member->user, CMD_JOIN, member->channel, member->user, 0, ":%H", member->channel); CheckDelayedJoins(member->channel); } @@ -3346,7 +3346,7 @@ void CheckDelayedJoins(struct Channel *chan) { if (!memb2) { /* clear +d */ chan->mode.mode &= ~MODE_WASDELJOINS; - sendcmdto_channel_butserv_butone(&me, CMD_MODE, chan, NULL, + sendcmdto_channel_butserv_butone(&me, CMD_MODE, chan, NULL, 0, "%H -d", chan); } } diff --git a/ircd/ircd_features.c b/ircd/ircd_features.c index 9fe5195..0d22f6d 100644 --- a/ircd/ircd_features.c +++ b/ircd/ircd_features.c @@ -293,6 +293,7 @@ static struct FeatureDesc { F_I(IRCD_RES_RETRIES, 0, 2, 0), F_I(IRCD_RES_TIMEOUT, 0, 4, 0), F_I(AUTH_TIMEOUT, 0, 9, 0), + F_B(ANNOUNCE_INVITES, 0, 0, 0), /* features that affect all operators */ F_B(CRYPT_OPER_PASSWORD, FEAT_MYOPER | FEAT_READ, 1, 0), diff --git a/ircd/m_burst.c b/ircd/m_burst.c index 2ee26fa..c03a6c0 100644 --- a/ircd/m_burst.c +++ b/ircd/m_burst.c @@ -212,7 +212,7 @@ int ms_burst(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) if (!MyUser(member->user) || IsZombie(member)) continue; sendcmdto_serv_butone(&me, CMD_KICK, NULL, "%H %C :Net Rider", chptr, member->user); - sendcmdto_channel_butserv_butone(&me, CMD_KICK, chptr, NULL, "%H %C :Net Rider", chptr, member->user); + sendcmdto_channel_butserv_butone(&me, CMD_KICK, chptr, NULL, 0, "%H %C :Net Rider", chptr, member->user); make_zombie(member, member->user, &me, &me, chptr); } } @@ -253,7 +253,7 @@ int ms_burst(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) *chptr->topic = '\0'; *chptr->topic_nick = '\0'; chptr->topic_time = 0; - sendcmdto_channel_butserv_butone(&me, CMD_TOPIC, chptr, NULL, + sendcmdto_channel_butserv_butone(&me, CMD_TOPIC, chptr, NULL, 0, "%H :%s", chptr, chptr->topic); } } else if (chptr->creationtime == timestamp) { @@ -432,7 +432,7 @@ int ms_burst(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) { add_user_to_channel(chptr, acptr, current_mode, oplevel); if (!(current_mode & CHFL_DELAYED)) - sendcmdto_channel_butserv_butone(acptr, CMD_JOIN, chptr, NULL, "%H", chptr); + sendcmdto_channel_butserv_butone(acptr, CMD_JOIN, chptr, NULL, 0, "%H", chptr); } else { diff --git a/ircd/m_invite.c b/ircd/m_invite.c index acb65e6..d36e1df 100644 --- a/ircd/m_invite.c +++ b/ircd/m_invite.c @@ -85,6 +85,7 @@ #include "client.h" #include "hash.h" #include "ircd.h" +#include "ircd_features.h" #include "ircd_reply.h" #include "ircd_string.h" #include "list.h" @@ -178,8 +179,20 @@ int m_invite(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) if (MyConnect(acptr)) add_invite(acptr, chptr); - if (!IsLocalChannel(chptr->chname) || MyConnect(acptr)) - sendcmdto_one(sptr, CMD_INVITE, acptr, "%s :%H", cli_name(acptr), chptr); + if (!IsLocalChannel(chptr->chname) || MyConnect(acptr)) { + if (feature_bool(FEAT_ANNOUNCE_INVITES)) { + sendcmdto_channel_butserv_butone(&me, get_error_numeric(RPL_ISSUEDINVITE)->str, + NULL, chptr, sptr, SKIP_NONOPS, + "%C %C :%C has been invited by %C", + acptr, sptr, acptr, sptr); + sendcmdto_channel_servers_butone(sptr, NULL, TOK_INVITE, chptr, sptr, 0, + "%s :%H", cli_name(acptr), chptr); + if (MyConnect(acptr)) + sendcmdto_one(sptr, CMD_INVITE, acptr, "%s :%H", cli_name(acptr), chptr); + } + else + sendcmdto_one(sptr, CMD_INVITE, acptr, "%s :%H", cli_name(acptr), chptr); + } return 0; } @@ -229,6 +242,17 @@ int ms_invite(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) send_reply(sptr, ERR_NOSUCHNICK, parv[1]); return 0; } + if (feature_bool(FEAT_ANNOUNCE_INVITES)) { + sendcmdto_channel_butserv_butone(&me, get_error_numeric(RPL_ISSUEDINVITE)->str, + NULL, chptr, sptr, SKIP_NONOPS, + "%C %C :%C has been invited by %C", + acptr, sptr, acptr, sptr); + sendcmdto_channel_servers_butone(sptr, NULL, TOK_INVITE, chptr, sptr, 0, + "%s :%H", cli_name(acptr), chptr); + if (MyConnect(acptr)) + sendcmdto_one(sptr, CMD_INVITE, acptr, "%s :%H", cli_name(acptr), chptr); + return 0; + } if (!MyUser(acptr)) { /* * just relay the message diff --git a/ircd/m_kick.c b/ircd/m_kick.c index 2096bf5..56fad42 100644 --- a/ircd/m_kick.c +++ b/ircd/m_kick.c @@ -162,7 +162,7 @@ int m_kick(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) sendcmdto_one(sptr, CMD_KICK, sptr, "%H %C :%s", chptr, who, comment); CheckDelayedJoins(chptr); } else - sendcmdto_channel_butserv_butone(sptr, CMD_KICK, chptr, NULL, "%H %C :%s", chptr, who, + sendcmdto_channel_butserv_butone(sptr, CMD_KICK, chptr, NULL, 0, "%H %C :%s", chptr, who, comment); make_zombie(member, who, cptr, sptr, chptr); @@ -245,7 +245,7 @@ int ms_kick(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) if (member) { /* and tell the channel about it */ sendcmdto_channel_butserv_butone(IsServer(sptr) ? &me : sptr, CMD_KICK, - chptr, NULL, "%H %C :%s", chptr, who, + chptr, NULL, 0, "%H %C :%s", chptr, who, comment); make_zombie(member, who, cptr, sptr, chptr); diff --git a/ircd/m_topic.c b/ircd/m_topic.c index 71979f2..4e444b9 100644 --- a/ircd/m_topic.c +++ b/ircd/m_topic.c @@ -130,7 +130,7 @@ static void do_settopic(struct Client *sptr, struct Client *cptr, sendcmdto_serv_butone(sptr, CMD_TOPIC, cptr, "%H %Tu %Tu :%s", chptr, chptr->creationtime, chptr->topic_time, chptr->topic); if (newtopic) - sendcmdto_channel_butserv_butone(sptr, CMD_TOPIC, chptr, NULL, + sendcmdto_channel_butserv_butone(sptr, CMD_TOPIC, chptr, NULL, 0, "%H :%s", chptr, chptr->topic); /* if this is the same topic as before we send it to the person that * set it (so they knew it went through ok), but don't bother sending diff --git a/ircd/s_err.c b/ircd/s_err.c index 368df33..5642402 100644 --- a/ircd/s_err.c +++ b/ircd/s_err.c @@ -722,7 +722,7 @@ static Numeric replyTable[] = { /* 344 */ { 0 }, /* 345 */ - { 0 }, + { RPL_ISSUEDINVITE, "%s %s %s :%s has been invited by %s", "345" }, /* 346 */ { RPL_INVITELIST, ":%s", "346" }, /* 347 */ diff --git a/ircd/s_user.c b/ircd/s_user.c index ed641eb..c77ef6f 100644 --- a/ircd/s_user.c +++ b/ircd/s_user.c @@ -1107,14 +1107,14 @@ hide_hostmask(struct Client *cptr, unsigned int flag) && (chan->channel->mode.mode & MODE_DELJOINS)) SetDelayedJoin(chan); else - sendcmdto_channel_butserv_butone(cptr, CMD_JOIN, chan->channel, cptr, + sendcmdto_channel_butserv_butone(cptr, CMD_JOIN, chan->channel, cptr, 0, "%H", chan->channel); if (IsChanOp(chan) && HasVoice(chan)) - sendcmdto_channel_butserv_butone(&me, CMD_MODE, chan->channel, cptr, + sendcmdto_channel_butserv_butone(&me, CMD_MODE, chan->channel, cptr, 0, "%H +ov %C %C", chan->channel, cptr, cptr); else if (IsChanOp(chan) || HasVoice(chan)) - sendcmdto_channel_butserv_butone(&me, CMD_MODE, chan->channel, cptr, + sendcmdto_channel_butserv_butone(&me, CMD_MODE, chan->channel, cptr, 0, "%H +%c %C", chan->channel, IsChanOp(chan) ? 'o' : 'v', cptr); } return 0; diff --git a/ircd/send.c b/ircd/send.c index 33c8faa..10218f0 100644 --- a/ircd/send.c +++ b/ircd/send.c @@ -426,11 +426,12 @@ void sendcmdto_common_channels_butone(struct Client *from, const char *cmd, * by ; is ignored by this function * * Update: don't send to 'one', if any. --Vampire + * Update: use 'skip' like sendcmdto_channel_butone. --Entrope */ void sendcmdto_channel_butserv_butone(struct Client *from, const char *cmd, const char *tok, struct Channel *to, - struct Client *one, const char *pattern, - ...) + struct Client *one, unsigned int skip, + const char *pattern, ...) { struct VarData vd; struct MsgBuf *mb; @@ -445,13 +446,56 @@ void sendcmdto_channel_butserv_butone(struct Client *from, const char *cmd, /* send the buffer to each local channel member */ for (member = to->members; member; member = member->next_member) { - if (MyConnect(member->user) && member->user != one && !IsZombie(member)) + if (!MyConnect(member->user) + || member->user == one + || IsZombie(member) + || (skip & SKIP_DEAF && IsDeaf(member->user)) + || (skip & SKIP_NONOPS && !IsChanOp(member)) + || (skip & SKIP_NONVOICES && !IsChanOp(member) && !HasVoice(member))) + continue; send_buffer(member->user, mb, 0); } msgq_clean(mb); } +/* + * Send a (prefixed) command to all servers with users on the channel + * specified by ; and are ignored by this function. + * + * XXX sentalong_marker used XXX + */ +void sendcmdto_channel_servers_butone(struct Client *from, const char *cmd, + const char *tok, struct Channel *to, + struct Client *one, unsigned int skip, + const char *pattern, ...) +{ + struct VarData vd; + struct MsgBuf *serv_mb; + struct Membership *member; + + /* build the buffer */ + vd.vd_format = pattern; + va_start(vd.vd_args, pattern); + serv_mb = msgq_make(&me, "%:#C %s %v", from, tok, &vd); + va_end(vd.vd_args); + + /* send the buffer to each server */ + sentalong_marker++; + for (member = to->members; member; member = member->next_member) { + if (cli_from(member->user) == one + || MyConnect(member->user) + || IsZombie(member) + || cli_fd(cli_from(member->user)) < 0 + || sentalong[cli_fd(cli_from(member->user))] == sentalong_marker) + continue; + sentalong[cli_fd(cli_from(member->user))] = sentalong_marker; + send_buffer(member->user, serv_mb, 0); + } + msgq_clean(serv_mb); +} + + /* * Send a (prefixed) command to all users on this channel, including * remote users; users to skip may be specified by setting appropriate -- 2.20.1