]> arthur.barton.de Git - ngircd.git/blobdiff - src/ngircd/irc.c
Fix PRIVMSG/NOTICE handler (II): keep command when forwarding to channels.
[ngircd.git] / src / ngircd / irc.c
index 92f29ac8ae3387119ab589266bd82be03305a9b5..8d2291fe20a0dabdbfe0e0ac109bf1cc18c346a5 100644 (file)
@@ -33,14 +33,18 @@ static char UNUSED id[] = "$Id: irc.c,v 1.132 2008/01/15 22:28:14 fw Exp $";
 #include "match.h"
 #include "messages.h"
 #include "parse.h"
+#include "tool.h"
 
 #include "exp.h"
 #include "irc.h"
 
 
 static char *Option_String PARAMS((CONN_ID Idx));
-static bool Send_Message PARAMS((CLIENT *Client, REQUEST *Req, int ForceType, bool SendErrors));
-static bool Send_Message_Mask PARAMS((CLIENT *from, char *targetMask, char *message, bool SendErrors));
+static bool Send_Message PARAMS((CLIENT *Client, REQUEST *Req, int ForceType,
+                                bool SendErrors));
+static bool Send_Message_Mask PARAMS((CLIENT *from, char *command,
+                                     char *targetMask, char *message,
+                                     bool SendErrors));
 
 
 GLOBAL bool
@@ -312,26 +316,26 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
        CLIENT *cl, *from;
        CHANNEL *chan;
        char *currentTarget = Req->argv[0];
-       char *lastCurrentTarget;
+       char *lastCurrentTarget = NULL;
 
        assert(Client != NULL);
        assert(Req != NULL);
 
        if (Req->argc == 0) {
                if (!SendErrors)
-                       return true;
+                       return CONNECTED;
                return IRC_WriteStrClient(Client, ERR_NORECIPIENT_MSG,
                                          Client_ID(Client), Req->command);
        }
        if (Req->argc == 1) {
                if (!SendErrors)
-                       return true;
+                       return CONNECTED;
                return IRC_WriteStrClient(Client, ERR_NOTEXTTOSEND_MSG,
                                          Client_ID(Client));
        }
        if (Req->argc > 2) {
                if (!SendErrors)
-                       return true;
+                       return CONNECTED;
                return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
                                          Client_ID(Client), Req->command);
        }
@@ -346,6 +350,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 
        /* handle msgtarget = msgto *("," msgto) */
        currentTarget = strtok_r(currentTarget, ",", &lastCurrentTarget);
+       ngt_UpperStr(Req->command);
 
        while (currentTarget) {
                /* Check for and handle valid <msgto> of form:
@@ -397,7 +402,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
                        for (cl = Client_First(); cl != NULL; cl = Client_Next(cl)) {
                                if (Client_Type(cl) != CLIENT_USER)
                                        continue;
-                               if (nick != NULL) {
+                               if (nick != NULL && host != NULL) {
                                        if (strcmp(nick, Client_ID(cl)) == 0 &&
                                            strcmp(user, Client_User(cl)) == 0 &&
                                            strcasecmp(host, Client_Hostname(cl)) == 0)
@@ -419,46 +424,53 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 
                if (cl) {
                        /* Target is a user, enforce type */
+#ifndef STRICT_RFC
+                       if (Client_Type(cl) != ForceType &&
+                           !(ForceType == CLIENT_USER &&
+                             (Client_Type(cl) == CLIENT_USER ||
+                              Client_Type(cl) == CLIENT_SERVICE))) {
+#else
                        if (Client_Type(cl) != ForceType) {
+#endif
                                if (!SendErrors)
-                                       return true;
-                               if (!IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
+                                       return CONNECTED;
+                               return IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
                                                          Client_ID(from),
-                                                         currentTarget))
-                                       return false;
-                       } else if (SendErrors
-                                  && (Client_Type(Client) != CLIENT_SERVER)
-                                  && strchr(Client_Modes(cl), 'a')) {
+                                                         currentTarget);
+                       }
+                       if (SendErrors && (Client_Type(Client) != CLIENT_SERVER)
+                           && strchr(Client_Modes(cl), 'a')) {
                                /* Target is away */
-                               if (!SendErrors)
-                                       return true;
-                               if (!IRC_WriteStrClient
-                                   (from, RPL_AWAY_MSG, Client_ID(from),
-                                    Client_ID(cl), Client_Away(cl)))
+                               if (!IRC_WriteStrClient(from, RPL_AWAY_MSG,
+                                                       Client_ID(from),
+                                                       Client_ID(cl),
+                                                       Client_Away(cl)))
                                        return DISCONNECTED;
                        }
                        if (Client_Conn(from) > NONE) {
                                Conn_UpdateIdle(Client_Conn(from));
                        }
-                       if (!IRC_WriteStrClientPrefix(cl, from, "PRIVMSG %s :%s",
-                                               Client_ID(cl), Req->argv[1]))
-                               return false;
+                       if (!IRC_WriteStrClientPrefix(cl, from, "%s %s :%s",
+                                                     Req->command, Client_ID(cl),
+                                                     Req->argv[1]))
+                               return DISCONNECTED;
                } else if (strchr("$#", currentTarget[0])
                           && strchr(currentTarget, '.')) {
                        /* targetmask */
-                       if (!Send_Message_Mask(from, currentTarget,
+                       if (!Send_Message_Mask(from, Req->command, currentTarget,
                                               Req->argv[1], SendErrors))
-                               return false;
+                               return DISCONNECTED;
                } else if ((chan = Channel_Search(currentTarget))) {
                        /* channel */
-                       if (!Channel_Write(chan, from, Client, Req->argv[1]))
-                               return false;
+                       if (!Channel_Write(chan, from, Client, Req->command,
+                                          SendErrors, Req->argv[1]))
+                                       return DISCONNECTED;
                } else {
                        if (!SendErrors)
-                               return true;
+                               return CONNECTED;
                        if (!IRC_WriteStrClient(from, ERR_NOSUCHNICK_MSG,
                                                Client_ID(from), currentTarget))
-                               return false;
+                               return DISCONNECTED;
                }
 
                currentTarget = strtok_r(NULL, ",", &lastCurrentTarget);
@@ -469,7 +481,8 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 
 
 static bool
-Send_Message_Mask(CLIENT * from, char * targetMask, char * message, bool SendErrors)
+Send_Message_Mask(CLIENT * from, char * command, char * targetMask,
+                 char * message, bool SendErrors)
 {
        CLIENT *cl;
        bool client_match;
@@ -490,8 +503,8 @@ Send_Message_Mask(CLIENT * from, char * targetMask, char * message, bool SendErr
                                continue;
                        client_match = MatchCaseInsensitive(mask, Client_Hostname(cl));
                        if (client_match)
-                               if (!IRC_WriteStrClientPrefix(cl, from, "PRIVMSG %s :%s",
-                                                       Client_ID(cl), message))
+                               if (!IRC_WriteStrClientPrefix(cl, from, "%s %s :%s",
+                                               command, Client_ID(cl), message))
                                        return false;
                }
        } else {
@@ -501,8 +514,8 @@ Send_Message_Mask(CLIENT * from, char * targetMask, char * message, bool SendErr
                        client_match = MatchCaseInsensitive(mask,
                                        Client_ID(Client_Introducer(cl)));
                        if (client_match)
-                               if (!IRC_WriteStrClientPrefix(cl, from, "PRIVMSG %s :%s",
-                                                       Client_ID(cl), message))
+                               if (!IRC_WriteStrClientPrefix(cl, from, "%s %s :%s",
+                                               command, Client_ID(cl), message))
                                        return false;
                }
        }