]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/irc.c
Added missing modes to USERMODES #define
[ngircd-alex.git] / src / ngircd / irc.c
index b88d5d7db7cc7a1320eb94027ca6835518c9a4cc..2466b6bf9e47ef9ed7c084fe0a2af93a6570cf0f 100644 (file)
@@ -400,7 +400,8 @@ 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)
+                               if (Client_Type(cl) != CLIENT_USER &&
+                                   Client_Type(cl) != CLIENT_SERVICE)
                                        continue;
                                if (nick != NULL && host != NULL) {
                                        if (strcmp(nick, Client_ID(cl)) == 0 &&
@@ -438,6 +439,17 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
                                                          Client_ID(from),
                                                          currentTarget);
                        }
+
+#ifndef STRICT_RFC
+                       if (ForceType == CLIENT_SERVICE &&
+                           (Conn_Options(Client_Conn(Client_NextHop(cl)))
+                            & CONN_RFC1459)) {
+                               /* SQUERY command but RFC 1459 link: convert
+                                * request to PRIVMSG command */
+                               Req->command = "PRIVMSG";
+                       }
+#endif
+
                        if (SendErrors && (Client_Type(Client) != CLIENT_SERVER)
                            && strchr(Client_Modes(cl), 'a')) {
                                /* Target is away */
@@ -455,18 +467,18 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
                                                      Req->argv[1]))
                                return DISCONNECTED;
                } else if (ForceType != CLIENT_SERVICE
+                          && (chan = Channel_Search(currentTarget))) {
+                       if (!Channel_Write(chan, from, Client, Req->command,
+                                          SendErrors, Req->argv[1]))
+                                       return DISCONNECTED;
+               } else if (ForceType != CLIENT_SERVICE
+                       /* $#: server/target mask, RFC 2812, sec. 3.3.1 */
                           && strchr("$#", currentTarget[0])
                           && strchr(currentTarget, '.')) {
                        /* targetmask */
                        if (!Send_Message_Mask(from, Req->command, currentTarget,
                                               Req->argv[1], SendErrors))
                                return DISCONNECTED;
-               } else if (ForceType != CLIENT_SERVICE
-                          && (chan = Channel_Search(currentTarget))) {
-                       /* channel */
-                       if (!Channel_Write(chan, from, Client, Req->command,
-                                          SendErrors, Req->argv[1]))
-                                       return DISCONNECTED;
                } else {
                        if (!SendErrors)
                                return CONNECTED;
@@ -489,6 +501,7 @@ Send_Message_Mask(CLIENT * from, char * command, char * targetMask,
        CLIENT *cl;
        bool client_match;
        char *mask = targetMask + 1;
+       const char *check_wildcards;
 
        cl = NULL;
 
@@ -499,6 +512,21 @@ Send_Message_Mask(CLIENT * from, char * command, char * targetMask,
                                          Client_ID(from));
        }
 
+       /*
+        * RFC 2812, sec. 3.3.1 requires that targetMask have at least one
+        * dot (".") and no wildcards ("*", "?") following the last one.
+        */
+       check_wildcards = strrchr(targetMask, '.');
+       assert(check_wildcards != NULL);
+       if (check_wildcards &&
+               check_wildcards[strcspn(check_wildcards, "*?")])
+       {
+               if (!SendErrors)
+                       return true;
+               return IRC_WriteStrClient(from, ERR_WILDTOPLEVEL, targetMask);
+       }
+
+       /* #: hostmask, see RFC 2812, sec. 3.3.1 */
        if (targetMask[0] == '#') {
                for (cl = Client_First(); cl != NULL; cl = Client_Next(cl)) {
                        if (Client_Type(cl) != CLIENT_USER)
@@ -510,6 +538,7 @@ Send_Message_Mask(CLIENT * from, char * command, char * targetMask,
                                        return false;
                }
        } else {
+               assert(targetMask[0] == '$'); /* $: server mask, see RFC 2812, sec. 3.3.1 */
                for (cl = Client_First(); cl != NULL; cl = Client_Next(cl)) {
                        if (Client_Type(cl) != CLIENT_USER)
                                continue;