]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/irc-info.c
Fix ERR_{SUMMON|USERS}DISABLED: don't repeat command name in reply
[ngircd-alex.git] / src / ngircd / irc-info.c
index 42b22643c63405a0f4a16d43f324636a3fd9584e..93c43b75f14072b71aa17ef3843f3fdcee6b8c8a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2011 Alexander Barton (alex@barton.de) and Contributors.
+ * 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
@@ -37,6 +37,7 @@
 #include "match.h"
 #include "tool.h"
 #include "parse.h"
+#include "irc.h"
 #include "irc-write.h"
 
 #include "exp.h"
@@ -647,10 +648,10 @@ IRC_STATS( CLIENT *Client, REQUEST *Req )
  * therefore answers with ERR_SUMMONDISABLED.
  */
 GLOBAL bool
-IRC_SUMMON(CLIENT * Client, REQUEST * Req)
+IRC_SUMMON(CLIENT * Client, UNUSED REQUEST * Req)
 {
        return IRC_WriteStrClient(Client, ERR_SUMMONDISABLED_MSG,
-                                 Client_ID(Client), Req->command);
+                                 Client_ID(Client));
 } /* IRC_SUMMON */
 
 
@@ -740,10 +741,10 @@ IRC_USERHOST(CLIENT *Client, REQUEST *Req)
  * See RFC 2812 section 4.6. As suggested there the command is disabled.
  */
 GLOBAL bool
-IRC_USERS(CLIENT * Client, REQUEST * Req)
+IRC_USERS(CLIENT * Client, UNUSED REQUEST * Req)
 {
        return IRC_WriteStrClient(Client, ERR_USERSDISABLED_MSG,
-                                 Client_ID(Client), Req->command);
+                                 Client_ID(Client));
 } /* IRC_USERS */
 
 
@@ -833,6 +834,7 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
        const char *chan_user_modes;
        char flags[8];
        CLIENT *c;
+       int count = 0;
 
        assert( Client != NULL );
        assert( Chan != NULL );
@@ -855,6 +857,9 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
 
                is_visible = strchr(client_modes, 'i') == NULL;
                if (is_member || is_visible) {
+                       if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO"))
+                               break;
+
                        strcpy(flags, who_flags_status(client_modes));
                        if (is_ircop)
                                strlcat(flags, "*", sizeof(flags));
@@ -866,6 +871,7 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool OnlyOps)
                        if (!write_whoreply(Client, c, Channel_Name(Chan),
                                            flags))
                                return DISCONNECTED;
+                       count++;
                }
        }
        return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client),
@@ -889,6 +895,7 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps)
        CHANNEL *chan;
        bool client_match, is_visible;
        char flags[4];
+       int count = 0;
 
        assert (Client != NULL);
 
@@ -939,13 +946,16 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps)
                if (!is_visible)        /* target user is not visible */
                        continue;
 
+               if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO"))
+                       break;
+
                strcpy(flags, who_flags_status(Client_Modes(c)));
                if (strchr(Client_Modes(c), 'o'))
                        strlcat(flags, "*", sizeof(flags));
 
                if (!write_whoreply(Client, c, "*", flags))
                        return DISCONNECTED;
-
+               count++;
        }
 
        return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client),
@@ -1015,10 +1025,10 @@ IRC_WHO(CLIENT *Client, REQUEST *Req)
 /**
  * Generate WHOIS reply of one actual client.
  *
- * @param Client       The client from which this command has been received.
- * @param from         The client requesting the information ("originator").
- * @param c            The client of which information should be returned.
- * @returns            CONNECTED or DISCONNECTED.
+ * @param Client The client from which this command has been received.
+ * @param from The client requesting the information ("originator").
+ * @param c The client of which information should be returned.
+ * @return CONNECTED or DISCONNECTED.
  */
 static bool
 IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c)
@@ -1027,6 +1037,10 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c)
        CL2CHAN *cl2chan;
        CHANNEL *chan;
 
+       assert(Client != NULL);
+       assert(from != NULL);
+       assert(c != NULL);
+
        /* Nick, user, hostname and client info */
        if (!IRC_WriteStrClient(from, RPL_WHOISUSER_MSG, Client_ID(from),
                                Client_ID(c), Client_User(c),
@@ -1084,30 +1098,35 @@ IRC_WHOIS_SendReply(CLIENT *Client, CLIENT *from, CLIENT *c)
 
        /* IRC-Operator? */
        if (Client_HasMode(c, 'o') &&
-               !IRC_WriteStrClient(from, RPL_WHOISOPERATOR_MSG,
-                                   Client_ID(from), Client_ID(c)))
-                       return DISCONNECTED;
+           !IRC_WriteStrClient(from, RPL_WHOISOPERATOR_MSG,
+                               Client_ID(from), Client_ID(c)))
+               return DISCONNECTED;
 
        /* Connected using SSL? */
        if (Conn_UsesSSL(Client_Conn(c)) &&
-               !IRC_WriteStrClient(from, RPL_WHOISSSL_MSG,
-                                   Client_ID(from), Client_ID(c)))
-                       return DISCONNECTED;
+           !IRC_WriteStrClient(from, RPL_WHOISSSL_MSG, Client_ID(from),
+                               Client_ID(c)))
+               return DISCONNECTED;
+
+       /* Registered nick name? */
+       if (Client_HasMode(c, 'R') &&
+           !IRC_WriteStrClient(from, RPL_WHOISREGNICK_MSG,
+                               Client_ID(from), Client_ID(c)))
+               return DISCONNECTED;
 
        /* Idle and signon time (local clients only!) */
        if (!Conf_MorePrivacy && Client_Conn(c) > NONE &&
-               !IRC_WriteStrClient(from, RPL_WHOISIDLE_MSG,
-                                   Client_ID(from), Client_ID(c),
-                                   (unsigned long)Conn_GetIdle(Client_Conn(c)),
-                                   (unsigned long)Conn_GetSignon(Client_Conn(c))))
-                       return DISCONNECTED;
+           !IRC_WriteStrClient(from, RPL_WHOISIDLE_MSG,
+                               Client_ID(from), Client_ID(c),
+                               (unsigned long)Conn_GetIdle(Client_Conn(c)),
+                               (unsigned long)Conn_GetSignon(Client_Conn(c))))
+               return DISCONNECTED;
 
        /* Away? */
        if (Client_HasMode(c, 'a') &&
-               !IRC_WriteStrClient(from, RPL_AWAY_MSG,
-                                   Client_ID(from), Client_ID(c),
-                                   Client_Away(c)))
-                       return DISCONNECTED;
+           !IRC_WriteStrClient(from, RPL_AWAY_MSG,
+                               Client_ID(from), Client_ID(c), Client_Away(c)))
+               return DISCONNECTED;
 
        return CONNECTED;
 } /* IRC_WHOIS_SendReply */
@@ -1182,7 +1201,7 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
                 *  - no wildcards for remote clients
                 *  - only one wildcard target per local client
                 *
-                *  also, at most ten matches are returned.
+                *  Also, at most MAX_RPL_WHOIS matches are returned.
                 */
                if (!has_wildcards || is_remote) {
                        c = Client_Search(query);
@@ -1208,13 +1227,18 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
                got_wildcard = true;
                IRC_SetPenalty(Client, 3);
 
-               for (c = Client_First(); c && match_count < 10; c = Client_Next(c)) {
+               for (c = Client_First(); c; c = Client_Next(c)) {
+                       if (IRC_CheckListTooBig(Client, match_count,
+                                           MAX_RPL_WHOIS, "WHOIS"))
+                               break;
+
                        if (Client_Type(c) != CLIENT_USER)
                                continue;
                        if (!MatchCaseInsensitive(query, Client_ID(c)))
                                continue;
                        if (!IRC_WHOIS_SendReply(Client, from, c))
                                return DISCONNECTED;
+
                        match_count++;
                }
 
@@ -1306,11 +1330,11 @@ IRC_WHOWAS( CLIENT *Client, REQUEST *Req )
        if (last < 0)
                last = 0;
 
-       max = DEFAULT_WHOWAS;
+       max = DEF_RPL_WHOWAS;
        if (Req->argc > 1) {
                max = atoi(Req->argv[1]);
                if (max < 1)
-                       max = MAX_WHOWAS;
+                       max = MAX_RPL_WHOWAS;
        }
 
        /*
@@ -1568,7 +1592,8 @@ IRC_Send_ISUPPORT(CLIENT * Client)
        return IRC_WriteStrClient(Client, RPL_ISUPPORT2_MSG, Client_ID(Client),
                                  CHANNEL_NAME_LEN - 1, Conf_MaxNickLength - 1,
                                  COMMAND_LEN - 23, CLIENT_AWAY_LEN - 1,
-                                 COMMAND_LEN - 113);
+                                 COMMAND_LEN - 113, MAX_HNDL_MODES_ARG,
+                                 MAX_HNDL_CHANNEL_LISTS);
 } /* IRC_Send_ISUPPORT */