]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/client.c
Make configure[.ng] compatible with autoconf 1.10 again
[ngircd-alex.git] / src / ngircd / client.c
index 92262b5d8b00c0ae3248c3010032ee8ff13ac0e1..37b168ff8d5dac07cb835b86eb37b366da6fcbe3 100644 (file)
@@ -41,6 +41,7 @@
 #include "hash.h"
 #include "irc-write.h"
 #include "log.h"
+#include "match.h"
 #include "messages.h"
 
 #include <exp.h>
@@ -239,9 +240,9 @@ Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool Sen
 
        assert( Client != NULL );
 
-       if( LogMsg ) txt = LogMsg;
-       else txt = FwdMsg;
-       if( ! txt ) txt = "Reason unknown.";
+       txt = LogMsg ? LogMsg : FwdMsg;
+       if (!txt)
+               txt = "Reason unknown";
 
        /* netsplit message */
        if( Client->type == CLIENT_SERVER ) {
@@ -281,10 +282,15 @@ Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool Sen
                                Destroy_UserOrService(c, txt, FwdMsg, SendQuit);
                        else if( c->type == CLIENT_SERVER )
                        {
-                               if( c != This_Server )
-                               {
-                                       if( c->conn_id != NONE ) Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" unregistered (connection %d): %s", c->id, c->conn_id, txt );
-                                       else Log( LOG_NOTICE|LOG_snotice, "Server \"%s\" unregistered: %s", c->id, txt );
+                               if (c != This_Server) {
+                                       if (c->conn_id != NONE)
+                                               Log(LOG_NOTICE|LOG_snotice,
+                                                   "Server \"%s\" unregistered (connection %d): %s.",
+                                               c->id, c->conn_id, txt);
+                                       else
+                                               Log(LOG_NOTICE|LOG_snotice,
+                                                   "Server \"%s\" unregistered: %s.",
+                                                   c->id, txt);
                                }
 
                                /* inform other servers */
@@ -296,13 +302,19 @@ Client_Destroy( CLIENT *Client, const char *LogMsg, const char *FwdMsg, bool Sen
                        }
                        else
                        {
-                               if( c->conn_id != NONE )
-                               {
-                                       if( c->id[0] ) Log( LOG_NOTICE, "Client \"%s\" unregistered (connection %d): %s", c->id, c->conn_id, txt );
-                                       else Log( LOG_NOTICE, "Client unregistered (connection %d): %s", c->conn_id, txt );
+                               if (c->conn_id != NONE) {
+                                       if (c->id[0])
+                                               Log(LOG_NOTICE,
+                                                   "Client \"%s\" unregistered (connection %d): %s.",
+                                                   c->id, c->conn_id, txt);
+                                       else
+                                               Log(LOG_NOTICE,
+                                                   "Client unregistered (connection %d): %s.",
+                                                   c->conn_id, txt);
                                } else {
-                                       Log(LOG_WARNING, "Unregistered unknown client \"%s\": %s",
-                                                               c->id[0] ? c->id : "(No Nick)", txt );
+                                       Log(LOG_WARNING,
+                                           "Unregistered unknown client \"%s\": %s",
+                                           c->id[0] ? c->id : "(No Nick)", txt);
                                }
                        }
 
@@ -545,13 +557,14 @@ Client_ModeDel( CLIENT *Client, char Mode )
 } /* Client_ModeDel */
 
 
+/**
+ * Search CLIENT structure of a given nick name.
+ *
+ * @return Pointer to CLIENT structure or NULL if not found.
+ */
 GLOBAL CLIENT *
 Client_Search( const char *Nick )
 {
-       /* return Client-Structure that has the corresponding Nick.
-        * If none is found, return NULL.
-        */
-
        char search_id[CLIENT_ID_LEN], *ptr;
        CLIENT *c = NULL;
        UINT32 search_hash;
@@ -572,7 +585,39 @@ Client_Search( const char *Nick )
                c = (CLIENT *)c->next;
        }
        return NULL;
-} /* Client_Search */
+}
+
+
+/**
+ * Serach first CLIENT structure matching a given mask of a server.
+ *
+ * The order of servers is arbitrary, but this function makes sure that the
+ * local server is always returned if the mask matches it.
+ *
+ * @return Pointer to CLIENT structure or NULL if no server could be found.
+ */
+GLOBAL CLIENT *
+Client_SearchServer(const char *Mask)
+{
+       CLIENT *c;
+
+       assert(Mask != NULL);
+
+       /* First check if mask matches the local server */
+       if (MatchCaseInsensitive(Mask, Client_ID(Client_ThisServer())))
+               return Client_ThisServer();
+
+       c = My_Clients;
+       while (c) {
+               if (Client_Type(c) == CLIENT_SERVER) {
+                       /* This is a server: check if Mask matches */
+                       if (MatchCaseInsensitive(Mask, c->id))
+                               return c;
+               }
+               c = (CLIENT *)c->next;
+       }
+       return NULL;
+}
 
 
 /**
@@ -671,7 +716,6 @@ Client_OrigUser(CLIENT *Client) {
 
 #endif
 
-
 /**
  * Return the hostname of a client.
  * @param Client Pointer to client structure
@@ -682,11 +726,22 @@ Client_Hostname(CLIENT *Client)
 {
        assert (Client != NULL);
        return Client->host;
-} /* Client_Hostname */
+}
 
+/**
+ * Return the cloaked hostname of a client, if set.
+ * @param Client Pointer to the client structure.
+ * @return Pointer to the cloaked hostname or NULL if not set.
+ */
+GLOBAL char *
+Client_HostnameCloaked(CLIENT *Client)
+{
+       assert(Client != NULL);
+       return Client->cloaked;
+}
 
 /**
- * Get potentially cloaked hostname of a client.
+ * Get (potentially cloaked) hostname of a client to display it to other users.
  *
  * If the client has not enabled cloaking, the real hostname is used.
  * Please note that this function uses a global static buffer, so you can't
@@ -696,28 +751,63 @@ Client_Hostname(CLIENT *Client)
  * @return Pointer to client hostname
  */
 GLOBAL char *
-Client_HostnameCloaked(CLIENT *Client)
+Client_HostnameDisplayed(CLIENT *Client)
 {
-       static char Cloak_Buffer[CLIENT_HOST_LEN];
-
        assert(Client != NULL);
 
+       /* Client isn't cloaked at all, return real hostname: */
        if (!Client_HasMode(Client, 'x'))
                return Client_Hostname(Client);
 
-       /* Do simple mapping to the server ID? */
-       if (!*Conf_CloakHostModeX)
-               return Client_ID(Client->introducer);
-
-       strlcpy(Cloak_Buffer, Client->host, CLIENT_HOST_LEN);
-       strlcat(Cloak_Buffer, Conf_CloakHostSalt, CLIENT_HOST_LEN);
+       /* Use an already saved cloaked hostname, if there is one */
+       if (Client->cloaked[0])
+               return Client->cloaked;
 
-       snprintf(Cloak_Buffer, CLIENT_HOST_LEN, Conf_CloakHostModeX,
-                Hash(Cloak_Buffer));
+       Client_UpdateCloakedHostname(Client, NULL, NULL);
+       return Client->cloaked;
+}
 
-       return Cloak_Buffer;
-} /* Client_HostnameCloaked */
+/**
+ * Update (and generate, if necessary) the cloaked hostname of a client.
+ *
+ * The newly set cloaked hostname is announced in the network using METADATA
+ * commands to peers that support this feature.
+ *
+ * @param Client The client of which the cloaked hostname should be updated.
+ * @param Origin The originator of the hostname change, or NULL if this server.
+ * @param Hostname The new cloaked hostname, or NULL if it should be generated.
+ */
+GLOBAL void
+Client_UpdateCloakedHostname(CLIENT *Client, CLIENT *Origin,
+                            const char *Hostname)
+{
+       static char Cloak_Buffer[CLIENT_HOST_LEN];
 
+       assert(Client != NULL);
+       if (!Origin)
+               Origin = Client_ThisServer();
+
+       if (!Hostname) {
+               /* Generate new cloaked hostname */
+               if (*Conf_CloakHostModeX) {
+                       strlcpy(Cloak_Buffer, Client->host, CLIENT_HOST_LEN);
+                       strlcat(Cloak_Buffer, Conf_CloakHostSalt,
+                               CLIENT_HOST_LEN);
+                       snprintf(Client->cloaked, sizeof(Client->cloaked),
+                                Conf_CloakHostModeX, Hash(Cloak_Buffer));
+               } else
+                       strlcpy(Client->cloaked, Client_ID(Client->introducer),
+                               sizeof(Client->cloaked));
+       } else
+               strlcpy(Client->cloaked, Hostname, sizeof(Client->cloaked));
+       LogDebug("Cloaked hostname of \"%s\" updated to \"%s\"",
+                Client_ID(Client), Client->cloaked);
+
+       /* Inform other servers in the network */
+       IRC_WriteStrServersPrefixFlag(Client_NextHop(Origin), Origin, 'M',
+                                     "METADATA %s cloakhost :%s",
+                                     Client_ID(Client), Client->cloaked);
+}
 
 GLOBAL char *
 Client_Modes( CLIENT *Client )
@@ -830,7 +920,7 @@ Client_MaskCloaked(CLIENT *Client)
                return Client_Mask(Client);
 
        snprintf(Mask_Buffer, GETID_LEN, "%s!%s@%s", Client->id, Client->user,
-                Client_HostnameCloaked(Client));
+                Client_HostnameDisplayed(Client));
 
        return Mask_Buffer;
 } /* Client_MaskCloaked */
@@ -1339,7 +1429,7 @@ Client_RegisterWhowas( CLIENT *Client )
                 sizeof( My_Whowas[slot].id ));
        strlcpy( My_Whowas[slot].user, Client_User( Client ),
                 sizeof( My_Whowas[slot].user ));
-       strlcpy( My_Whowas[slot].host, Client_HostnameCloaked( Client ),
+       strlcpy( My_Whowas[slot].host, Client_HostnameDisplayed( Client ),
                 sizeof( My_Whowas[slot].host ));
        strlcpy( My_Whowas[slot].info, Client_Info( Client ),
                 sizeof( My_Whowas[slot].info ));
@@ -1379,7 +1469,7 @@ Destroy_UserOrService(CLIENT *Client, const char *Txt, const char *FwdMsg, bool
        if(Client->conn_id != NONE) {
                /* Local (directly connected) client */
                Log(LOG_NOTICE,
-                   "%s \"%s\" unregistered (connection %d): %s",
+                   "%s \"%s\" unregistered (connection %d): %s.",
                    Client_TypeText(Client), Client_Mask(Client),
                    Client->conn_id, Txt);
                Log_ServerNotice('c', "Client exiting: %s (%s@%s) [%s]",
@@ -1397,7 +1487,7 @@ Destroy_UserOrService(CLIENT *Client, const char *Txt, const char *FwdMsg, bool
                }
        } else {
                /* Remote client */
-               LogDebug("%s \"%s\" unregistered: %s",
+               LogDebug("%s \"%s\" unregistered: %s.",
                         Client_TypeText(Client), Client_Mask(Client), Txt);
 
                if(SendQuit) {