]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/irc.c
PRIVMSG/NOTICE: don't stop list processing on invalid target
[ngircd-alex.git] / src / ngircd / irc.c
index 69dd61a797994886c63bf0426a6d4434192a993c..5af79396ee0add0ef82f5dd8a7905ccdce912636 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2004 Alexander Barton <alex@barton.de>
+ * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -45,6 +45,35 @@ static bool Send_Message_Mask PARAMS((CLIENT *from, char *command,
                                      bool SendErrors));
 
 
+/**
+ * Check if a list limit is reached and inform client accordingly.
+ *
+ * @param From The client.
+ * @param Count Reply item count.
+ * @param Limit Reply limit.
+ * @param Name Name of the list.
+ * @return true if list limit has been reached; false otherwise.
+ */
+GLOBAL bool
+IRC_CheckListTooBig(CLIENT *From, const int Count, const int Limit,
+                   const char *Name)
+{
+       assert(From != NULL);
+       assert(Count >= 0);
+       assert(Limit > 0);
+       assert(Name != NULL);
+
+       if (Count < Limit)
+               return false;
+
+       (void)IRC_WriteStrClient(From,
+                                "NOTICE %s :%s list limit (%d) reached!",
+                                Client_ID(From), Name, Limit);
+       IRC_SetPenalty(From, 2);
+       return true;
+}
+
+
 GLOBAL bool
 IRC_ERROR( CLIENT *Client, REQUEST *Req )
 {
@@ -320,6 +349,7 @@ static bool
 Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 {
        CLIENT *cl, *from;
+       CL2CHAN *cl2chan;
        CHANNEL *chan;
        char *currentTarget = Req->argv[0];
        char *lastCurrentTarget = NULL;
@@ -439,11 +469,11 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 #else
                        if (Client_Type(cl) != ForceType) {
 #endif
-                               if (!SendErrors)
-                                       return CONNECTED;
-                               return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
-                                                         Client_ID(from),
-                                                         currentTarget);
+                               if (SendErrors && !IRC_WriteStrClient(
+                                   from, ERR_NOSUCHNICK_MSG,Client_ID(from),
+                                   currentTarget))
+                                       return DISCONNECTED;
+                               goto send_next_target;
                        }
 
 #ifndef STRICT_RFC
@@ -456,6 +486,23 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
                        }
 #endif
 
+                       if (Client_HasMode(cl, 'C')) {
+                               cl2chan = Channel_FirstChannelOf(cl);
+                               while (cl2chan) {
+                                       chan = Channel_GetChannel(cl2chan);
+                                       if (Channel_IsMemberOf(chan, from))
+                                               break;
+                                       cl2chan = Channel_NextChannelOf(cl, cl2chan);
+                               }
+                               if (!cl2chan) {
+                                       if (SendErrors && !IRC_WriteStrClient(
+                                           from, ERR_NOTONSAMECHANNEL_MSG,
+                                           Client_ID(from), Client_ID(cl)))
+                                               return DISCONNECTED;
+                                       goto send_next_target;
+                               }
+                       }
+
                        if (SendErrors && (Client_Type(Client) != CLIENT_SERVER)
                            && strchr(Client_Modes(cl), 'a')) {
                                /* Target is away */
@@ -493,7 +540,10 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
                                return DISCONNECTED;
                }
 
+       send_next_target:
                currentTarget = strtok_r(NULL, ",", &lastCurrentTarget);
+               if (currentTarget)
+                       Conn_SetPenalty(Client_Conn(Client), 1);
        }
 
        return CONNECTED;