Implement invitation announcements (RPL_ISSUEDINVITE).
authorMichael Poole <mdpoole@troilus.org>
Wed, 19 May 2004 03:46:05 +0000 (03:46 +0000)
committerMichael Poole <mdpoole@troilus.org>
Wed, 19 May 2004 03:46:05 +0000 (03:46 +0000)
git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@1073 c9e4aea6-c8fd-4c43-8297-357d70d61c8c

13 files changed:
ChangeLog
include/ircd_features.h
include/numeric.h
include/send.h
ircd/channel.c
ircd/ircd_features.c
ircd/m_burst.c
ircd/m_invite.c
ircd/m_kick.c
ircd/m_topic.c
ircd/s_err.c
ircd/s_user.c
ircd/send.c

index 69dc3eba1ecfe1f41cbaabcb21e81a9ddd81b05b..12ebed2127b91edc0289d58471e2140608d5ff01 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2004-05-18  Michael Poole <mdpoole@troilus.org>
+
+       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 <mdpoole@troilus.org>
 
        * ircd/res_adns.c (res_ourserver): Remove unused function.
index b1e0cc585d941cbb2167aeeff69fda04a6c09d4e..d6671ae75a22a17047b04370748c9b5f24aeb600 100644 (file)
@@ -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,
index 334f7b0ba70d41755d3cd4d2d19003467404bc7f..24ef24bab5f0e9f10090cbdda3c1387155518628 100644 (file)
@@ -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 */
index bf7e754936a9d8fb349f04050c1772e9652748fc..11f7201a6f5be4cf0b3d1de2bd9b03679c5cd504 100644 (file)
@@ -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,
index be0e3367156ff3bc05dcacf032606001731a8a2a..fd2df7efc4e3f4301adef1efa6731bd94fc662e8 100644 (file)
@@ -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);
     }
   }
index 9fe5195719023bf7a7454f6d0104700dd94abdf9..0d22f6df93db02ceee8331f957bb70a291aae361 100644 (file)
@@ -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),
index 2ee26fa94842e1430333abbe00c31b5bdd21f270..c03a6c004bcfc5ab16d2b5dc30b57de86dee3929 100644 (file)
@@ -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
          {
index acb65e6bab86aa84e4f356fc11399363051ee806..d36e1df2d25099d393db2726a581e98ff005ae53 100644 (file)
@@ -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
index 2096bf5f04274ab8bc9b5a6347161a25b57d0465..56fad4287c646ae03aee90b10f0d4d25a9353a29 100644 (file)
@@ -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);
index 71979f2be3a1fade0c30b2722a068e9d81b469f2..4e444b9ecb374d665675ff25479735fd2846936f 100644 (file)
@@ -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
index 368df33334a94ce5434eda9a39bbb195ca6fd77f..5642402cb517cdfc01a831afe3a09d1e2a7975f7 100644 (file)
@@ -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 */
index ed641eb27f1ea32daa063c1aae4cb60c54202b8a..c77ef6f170eb7e4ee213d75bf4af60356b118c2f 100644 (file)
@@ -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;
index 33c8faa9f3f479e8d31f1f863b4f22582e09ad0f..10218f0a6a815daf753d8f2c07e445575e893a26 100644 (file)
@@ -426,11 +426,12 @@ void sendcmdto_common_channels_butone(struct Client *from, const char *cmd,
  * by <to>; <tok> 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 <to>; <cmd> and <skip> 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