added gnutls backend and moved backend code into new files
[ircu2.10.12-pk.git] / ircd / m_invite.c
index 2b8cbcff0980fbe478960b14c4fbb7b4b2d9b338..2479753dd5f152f304cf6777d168b063c979ae68 100644 (file)
@@ -142,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;
   }
 
@@ -177,22 +174,26 @@ 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)) {
     if (feature_bool(FEAT_ANNOUNCE_INVITES)) {
       /* Announce to channel operators. */
-      sendcmdto_channel_butserv_butone(&me, get_error_numeric(RPL_ISSUEDINVITE)->str,
-                                       NULL, chptr, sptr, SKIP_NONOPS, 
+      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, but skip acptr,
-       * since they will be notified below. */
+      /* Announce to servers with channel operators. */
       sendcmdto_channel_servers_butone(sptr, NULL, TOK_INVITE, chptr, acptr, SKIP_NONOPS,
-                                       "%s :%H", cli_name(acptr), chptr);
+                                       "%s %H %Tu", cli_name(acptr),
+                                       chptr, chptr->creationtime);
     }
-    sendcmdto_one(sptr, CMD_INVITE, acptr, "%s :%H", cli_name(acptr), chptr);
   }
 
   return 0;
@@ -204,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).
@@ -213,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)) {
     /*
@@ -246,13 +252,20 @@ int ms_invite(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
 
   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;
@@ -266,23 +279,25 @@ int ms_invite(struct Client* cptr, struct Client* sptr, int parc, char* parv[])
   if (is_silenced(sptr, acptr))
     return 0;
 
-  if (MyConnect(acptr))
-      add_invite(acptr, chptr);
+  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(&me, get_error_numeric(RPL_ISSUEDINVITE)->str,
+    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, but skip acptr,
-     * since they will be notified below. */
+    /* Announce to servers with channel operators. */
     sendcmdto_channel_servers_butone(sptr, NULL, TOK_INVITE, chptr, acptr, SKIP_NONOPS,
-                                     "%s :%H", cli_name(acptr), chptr);
+                                     "%s %H %Tu", cli_name(acptr), chptr,
+                                     chptr->creationtime);
   }
 
-  sendcmdto_one(sptr, CMD_INVITE, acptr, "%s :%H", cli_name(acptr), chptr);
   return 0;
 }
-
-