]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/irc-info.c
Implement the IRC command "SERVLIST"
[ngircd-alex.git] / src / ngircd / irc-info.c
index 808a85703fa48defffe9128fe2cb503beb3533bd..4ac2a47857088ccf6eb269dc3181b3274418d49f 100644 (file)
@@ -270,12 +270,15 @@ IRC_LUSERS( CLIENT *Client, REQUEST *Req )
 
 
 /**
- * List registered services.
- * This function is a dummy that immediately returns RPL_SERVLISTEND.
+ * Handler for the IRC command "SERVLIST".
+ * List registered services, see RFC 2811, section 3.5.1: the syntax is
+ * "SERVLIST [<mask> [<type>]]".
  */
 GLOBAL bool
 IRC_SERVLIST(CLIENT *Client, REQUEST *Req)
 {
+       CLIENT *c;
+
        assert(Client != NULL);
        assert(Req != NULL);
 
@@ -283,6 +286,21 @@ IRC_SERVLIST(CLIENT *Client, REQUEST *Req)
                return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
                                          Client_ID(Client), Req->command);
 
+       if (Req->argc < 2 || strcmp(Req->argv[1], "0") == 0) {
+               for (c = Client_First(); c!= NULL; c = Client_Next(c)) {
+                       if (Client_Type(c) != CLIENT_SERVICE)
+                               continue;
+                       if (Req->argc > 0 && !MatchCaseInsensitive(Req->argv[0],
+                                                                 Client_ID(c)))
+                               continue;
+                       if (!IRC_WriteStrClient(Client, RPL_SERVLIST_MSG,
+                                       Client_ID(Client), Client_Mask(c),
+                                       Client_Mask(Client_Introducer(c)), "*",
+                                       0, Client_Hops(c), Client_Info(c)))
+                               return DISCONNECTED;
+               }
+       }
+
        return IRC_WriteStrClient(Client, RPL_SERVLISTEND_MSG, Client_ID(Client),
                                  Req->argc > 0 ? Req->argv[0] : "*",
                                  Req->argc > 1 ? Req->argv[1] : "0");
@@ -932,7 +950,14 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
                cl2chan = Channel_NextChannelOf( c, cl2chan );
 
                /* Secret channel? */
-               if( strchr( Channel_Modes( chan ), 's' ) && ! Channel_IsMemberOf( chan, Client )) continue;
+               if (strchr(Channel_Modes(chan), 's')
+                   && !Channel_IsMemberOf(chan, Client))
+                       continue;
+
+               /* Local channel and request is not from a user? */
+               if (Client_Type(Client) == CLIENT_SERVER
+                   && Channel_IsLocal(chan))
+                       continue;
 
                /* Concatenate channel names */
                if( str[strlen( str ) - 1] != ':' ) strlcat( str, " ", sizeof( str ));
@@ -1167,6 +1192,23 @@ Show_MOTD_End(CLIENT *Client)
        return IRC_WriteStrClient( Client, RPL_ENDOFMOTD_MSG, Client_ID( Client ));
 }
 
+#ifdef SSL_SUPPORT
+static bool Show_MOTD_SSLInfo(CLIENT *Client)
+{
+       bool ret = true;
+       char buf[COMMAND_LEN] = "Connected using Cipher ";
+
+       if (!Conn_GetCipherInfo(Client_Conn(Client), buf + 23, sizeof buf - 23))
+               return true;
+
+       if (!Show_MOTD_Sendline(Client, buf))
+               ret = false;
+
+       return ret;
+}
+#else
+static inline bool Show_MOTD_SSLInfo(UNUSED CLIENT *c) { return true; }
+#endif
 
 GLOBAL bool
 IRC_Show_MOTD( CLIENT *Client )
@@ -1181,13 +1223,17 @@ IRC_Show_MOTD( CLIENT *Client )
                        return DISCONNECTED;
                if (!Show_MOTD_Sendline(Client, Conf_MotdPhrase))
                        return DISCONNECTED;
-
-               return Show_MOTD_End(Client);
+               goto out;
        }
 
        fd = fopen( Conf_MotdFile, "r" );
        if( ! fd ) {
                Log( LOG_WARNING, "Can't read MOTD file \"%s\": %s", Conf_MotdFile, strerror( errno ));
+               if (Conn_UsesSSL(Client_Conn(Client))) {
+                       if (!Show_MOTD_Start(Client))
+                               return DISCONNECTED;
+                       goto out;
+               }
                return IRC_WriteStrClient( Client, ERR_NOMOTD_MSG, Client_ID( Client ) );
        }
 
@@ -1205,6 +1251,9 @@ IRC_Show_MOTD( CLIENT *Client )
                }
        }
        fclose(fd);
+out:
+       if (!Show_MOTD_SSLInfo(Client))
+               return DISCONNECTED;
        return Show_MOTD_End(Client);
 } /* IRC_Show_MOTD */