Issue 15 - Patch by tilman2: Drop privileges optionally
[umurmur.git] / src / client.c
index e515a454e0082ae731d4bc9b15f3fa24c0730b76..367f18dee165e383f892b9c4ae3f2e979a8a4759 100644 (file)
@@ -200,7 +200,7 @@ void recheckCodecVersions()
        // it as alpha and announce it. If another codec now got the
        // majority set it as the opposite of the currently valid bPreferAlpha
        // and announce it.
-       if (version == (uint32_t)0x8000000a)
+       if (version == (uint32_t)0x8000000b)
                bPreferAlpha = true;
        else
                bPreferAlpha = ! bPreferAlpha;
@@ -259,6 +259,8 @@ int Client_add(int fd, struct sockaddr_in *remote)
        }
        newclient->availableBandwidth = maxBandwidth;
        Timer_init(&newclient->lastActivity);
+       Timer_init(&newclient->connectTime);
+       Timer_init(&newclient->idleTime);
        newclient->sessionId = findFreeSessionId();
        if (newclient->sessionId < 0)
                Log_fatal("Could not find a free session ID");
@@ -317,6 +319,8 @@ void Client_free(client_t *client)
                free(client->release);
        if (client->os)
                free(client->os);                       
+       if (client->os_version)
+               free(client->os_version);                       
        if (client->username)
                free(client->username);
        if (client->context)
@@ -501,6 +505,15 @@ int Client_write(client_t *client)
        return 0;
 }
 
+int Client_send_message_ver(client_t *client, message_t *msg, uint32_t version)
+{
+       if ((version == 0) || (client->version >= version) ||
+               ((version & 0x80000000) && (client->version < (~version))))
+               return Client_send_message(client, msg);
+       else
+               Msg_free(msg);
+}
+
 int Client_send_message(client_t *client, message_t *msg)
 {
        if (!client->authenticated && msg->messageType != Version) {
@@ -573,6 +586,29 @@ int Client_send_message_except(client_t *client, message_t *msg)
        return 0;
 }
 
+int Client_send_message_except_ver(client_t *client, message_t *msg, uint32_t version)
+{
+       client_t *itr = NULL;
+       int count = 0;
+       
+       Msg_inc_ref(msg); /* Make sure a reference is held during the whole iteration. */
+       while (Client_iterate(&itr) != NULL) {
+               if (itr != client) {
+                       if (count++ > 0)
+                               Msg_inc_ref(msg); /* One extra reference for each new copy */
+                       Log_debug("Msg %d to %s refcount %d",  msg->messageType, itr->username, msg->refcount);
+                       Client_send_message_ver(itr, msg, version);
+               }
+       }
+       Msg_free(msg); /* Free our reference to the message */
+       
+       if (count == 0)
+               Msg_free(msg); /* If only 1 client is connected then no message is passed
+                                               * to Client_send_message(). Free it here. */
+               
+       return 0;
+}
+
 static bool_t checkDecrypt(client_t *client, const uint8_t *encrypted, uint8_t *plain, unsigned int len)
 {
        if (CryptState_isValid(&client->cryptState) &&
@@ -719,6 +755,8 @@ int Client_voiceMsg(client_t *client, uint8_t *data, int len)
                goto out; /* Discard */
        client->availableBandwidth -= packetsize;
        
+       Timer_restart(&client->idleTime);
+       
        counter = Pds_get_numval(pdi); /* step past session id */
        do {
                counter = Pds_next8(pdi);