added basic ssl support to ircu
[ircu2.10.12-pk.git] / ircd / m_invite.c
index acb65e6bab86aa84e4f356fc11399363051ee806..2479753dd5f152f304cf6777d168b063c979ae68 100644 (file)
@@ -85,6 +85,8 @@
 #include "client.h"
 #include "hash.h"
 #include "ircd.h"
+#include "ircd_features.h"
+#include "ircd_log.h"
 #include "ircd_reply.h"
 #include "ircd_string.h"
 #include "list.h"
@@ -95,7 +97,7 @@
 #include "send.h"
 #include "struct.h"
 
-#include <assert.h>
+/* #include <assert.h> -- Now using assert in ircd_log.h */
 
 /*
  * m_invite - generic message handler
@@ -140,13 +142,10 @@ int m_invite(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
   if (is_silenced(sptr, acptr))
     return 0;
 
-  clean_channelname(parv[2]);
-
-  if (!IsChannelPrefix(*parv[2]))
-    return 0;
-
-  if (!(chptr = FindChannel(parv[2]))) {
-    send_reply(sptr, ERR_NOTONCHANNEL, parv[2]);
+  if (!IsChannelName(parv[2])
+      || !strIsIrcCh(parv[2])
+      || !(chptr = FindChannel(parv[2]))) {
+    send_reply(sptr, ERR_NOSUCHCHANNEL, parv[2]);
     return 0;
   }
 
@@ -175,11 +174,27 @@ int m_invite(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
   if (cli_user(acptr)->away)
     send_reply(sptr, RPL_AWAY, cli_name(acptr), cli_user(acptr)->away);
 
-  if (MyConnect(acptr))
+  if (MyConnect(acptr)) {
     add_invite(acptr, chptr);
+    sendcmdto_one(sptr, CMD_INVITE, acptr, "%s %H", cli_name(acptr), chptr);
+  } else if (!IsLocalChannel(chptr->chname)) {
+    sendcmdto_one(sptr, CMD_INVITE, acptr, "%s %H %Tu", cli_name(acptr), chptr,
+                  chptr->creationtime);
+  }
 
-  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)) {
+      /* Announce to channel operators. */
+      sendcmdto_channel_butserv_butone(&his, get_error_numeric(RPL_ISSUEDINVITE)->str,
+                                       NULL, chptr, sptr, SKIP_NONOPS,
+                                       "%H %C %C :%C has been invited by %C",
+                                       chptr, acptr, sptr, acptr, sptr);
+      /* Announce to servers with channel operators. */
+      sendcmdto_channel_servers_butone(sptr, NULL, TOK_INVITE, chptr, acptr, SKIP_NONOPS,
+                                       "%s %H %Tu", cli_name(acptr),
+                                       chptr, chptr->creationtime);
+    }
+  }
 
   return 0;
 }
@@ -190,6 +205,7 @@ int m_invite(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
  *   parv[0] - sender prefix
  *   parv[1] - user to invite
  *   parv[2] - channel name
+ *   parv[3] - (optional) channel timestamp
  *
  * - INVITE now is accepted only if who does it is chanop (this of course
  *   implies that channel must exist and he must be on it).
@@ -199,11 +215,15 @@ int m_invite(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
  *
  * - Invite with no parameters now lists the channels you are invited to.
  *                                                         - Isomer 23 Oct 99
+ *
+ * - Invite with too-late timestamp, or with no timestamp from a bursting
+ *   server, is silently discarded.                   - Entrope 19 Jan 05
  */
 int ms_invite(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
 {
   struct Client *acptr;
   struct Channel *chptr;
+  time_t invite_ts;
   
   if (IsServer(sptr)) {
     /*
@@ -229,37 +249,55 @@ int ms_invite(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
     send_reply(sptr, ERR_NOSUCHNICK, parv[1]);
     return 0;
   }
-  if (!MyUser(acptr)) {
-    /*
-     * just relay the message
-     */
-    sendcmdto_one(sptr, CMD_INVITE, acptr, "%s :%s", cli_name(acptr), parv[2]);
-    return 0;
-  }
-
-  if (is_silenced(sptr, acptr))
-    return 0;
 
   if (!(chptr = FindChannel(parv[2]))) {
     /*
-     * allow invites to non existant channels, bleah
+     * allow invites to non existent channels, bleah
      * avoid JOIN, INVITE, PART abuse
      */
     sendcmdto_one(sptr, CMD_INVITE, acptr, "%C :%s", acptr, parv[2]);
     return 0;
   }
 
+  if (parc > 3) {
+    invite_ts = atoi(parv[3]);
+    if (invite_ts > chptr->creationtime)
+      return 0;
+  } else if (IsBurstOrBurstAck(cptr))
+    return 0;
+
   if (!IsChannelService(sptr) && !find_channel_member(sptr, chptr)) {
     send_reply(sptr, ERR_NOTONCHANNEL, chptr->chname);
     return 0;
   }
+
   if (find_channel_member(acptr, chptr)) {
     send_reply(sptr, ERR_USERONCHANNEL, cli_name(acptr), chptr->chname);
     return 0;
   }
-  add_invite(acptr, chptr);
-  sendcmdto_one(sptr, CMD_INVITE, acptr, "%s :%H", cli_name(acptr), chptr);
-  return 0;
-}
 
+  if (is_silenced(sptr, acptr))
+    return 0;
+
+  if (MyConnect(acptr)) {
+    add_invite(acptr, chptr);
+    sendcmdto_one(sptr, CMD_INVITE, acptr, "%s %H", cli_name(acptr), chptr);
+  } else {
+    sendcmdto_one(sptr, CMD_INVITE, acptr, "%s %H %Tu", cli_name(acptr), chptr,
+                  chptr->creationtime);
+  }
 
+  if (feature_bool(FEAT_ANNOUNCE_INVITES)) {
+    /* Announce to channel operators. */
+    sendcmdto_channel_butserv_butone(&his, get_error_numeric(RPL_ISSUEDINVITE)->str,
+                                     NULL, chptr, sptr, SKIP_NONOPS,
+                                     "%H %C %C :%C has been invited by %C",
+                                     chptr, acptr, sptr, acptr, sptr);
+    /* Announce to servers with channel operators. */
+    sendcmdto_channel_servers_butone(sptr, NULL, TOK_INVITE, chptr, acptr, SKIP_NONOPS,
+                                     "%s %H %Tu", cli_name(acptr), chptr,
+                                     chptr->creationtime);
+  }
+
+  return 0;
+}