Static analyzer bug fixes
[silc.git] / apps / silcd / command_reply.c
index e6858ae43e0fca5192173ab51f14ecf23803a750..41bec7f0cf27c29edbd67688cd1de55e24e423e8 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2005, 2007 Pekka Riikonen
+  Copyright (C) 1997 - 2009 Pekka Riikonen
 
   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
@@ -152,6 +152,7 @@ silc_server_command_process_error(SilcServerCommandReplyContext cmd,
 
       silc_server_remove_from_channels(server, NULL, client, TRUE,
                                       NULL, TRUE, FALSE);
+      silc_dlist_del(server->expired_clients, client);
       silc_idlist_del_data(client);
       silc_idlist_del_client(server->global_list, client);
     }
@@ -235,6 +236,10 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
     client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING;
     client->mode = mode;
     client->servername = servername[0] ? strdup(servername) : NULL;
+
+    SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
+                   server->stat.clients + 1));
+    server->stat.clients++;
   } else {
     /* We have the client already, update the data */
 
@@ -261,9 +266,10 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
       return FALSE;
     }
 
-    /* Remove the old cache entry  */
-    silc_idcache_del_by_context(global ? server->global_list->clients :
-                               server->local_list->clients, client, NULL);
+    /* Update entry */
+    silc_idcache_update_by_context(global ? server->global_list->clients :
+                                  server->local_list->clients, client, NULL,
+                                  nickname, TRUE);
 
     silc_free(client->nickname);
     silc_free(client->username);
@@ -277,11 +283,6 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
     client->mode = mode;
     client->data.status |= SILC_IDLIST_STATUS_RESOLVED;
     client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING;
-
-    /* Create new cache entry */
-    silc_idcache_add(global ? server->global_list->clients :
-                    server->local_list->clients, nickname, client->id,
-                    client);
   }
 
   /* Save channel list if it was sent to us */
@@ -385,9 +386,12 @@ silc_server_command_reply_whois_save_client(SilcServerCommandReplyContext cmd)
   SilcUInt32 len;
   SilcClientEntry client = silc_packet_get_context(cmd->sock);
 
+  if (!client)
+    return FALSE;
+
   /* Take Requested Attributes if set. */
   tmp = silc_argument_get_arg_type(cmd->args, 11, &len);
-  if (tmp && client) {
+  if (tmp) {
     silc_free(client->attrs);
     client->attrs = silc_memdup(tmp, len);
     client->attrs_len = len;
@@ -519,7 +523,7 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd)
     if (!nickname) {
       SILC_LOG_ERROR(("Malformed nickname '%s' received in WHOWAS reply "
                      "from %s",
-                     hostname ? hostname : "", nick));
+                     nick, hostname ? hostname : ""));
       return FALSE;
     }
 
@@ -537,22 +541,24 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd)
     client->servername = servername[0] ? strdup(servername) : NULL;
     client->data.status |= SILC_IDLIST_STATUS_RESOLVED;
     client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING;
+    client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
 
-    /* Remove the old cache entry and create a new one */
-    silc_idcache_del_by_context(global ? server->global_list->clients :
-                               server->local_list->clients, client, NULL);
-    silc_idcache_add(global ? server->global_list->clients :
-                    server->local_list->clients, nickname, client->id,
-                    client);
+    /* Update cache entry */
+    silc_idcache_update_by_context(global ? server->global_list->clients :
+                                  server->local_list->clients, client, NULL,
+                                  nickname, TRUE);
   }
 
   /* If client is global and is not on any channel then add that we'll
      expire the entry after a while. */
   if (global) {
-    silc_idlist_find_client_by_id(server->global_list, client->id,
-                                 FALSE, &cache);
-    if (!silc_hash_table_count(client->channels))
+    client = silc_idlist_find_client_by_id(server->global_list, client->id,
+                                          FALSE, &cache);
+    if (client && !silc_hash_table_count(client->channels)) {
+      client->data.created = silc_time();
+      silc_dlist_del(server->expired_clients, client);
       silc_dlist_add(server->expired_clients, client);
+    }
   }
 
   return TRUE;
@@ -600,7 +606,7 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
   char *name, *info;
   SilcClientID client_id;
   SilcServerID server_id;
-  SilcChannelID*channel_id;
+  SilcChannelID channel_id;
   SilcClientEntry client;
   SilcServerEntry server_entry;
   SilcChannelEntry channel;
@@ -616,6 +622,8 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
   if (!idp)
     return FALSE;
 
+  memset(nick, 0, sizeof(nick));
+
   name = silc_argument_get_arg_type(cmd->args, 3, &len);
   info = silc_argument_get_arg_type(cmd->args, 4, &len);
 
@@ -649,7 +657,8 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
         to global list since server didn't have it in the lists so it must be
         global. */
       client = silc_idlist_add_client(server->global_list,
-                                     nick[0] ? nick : NULL, info, NULL,
+                                     nick[0] ? strdup(nick) : NULL,
+                                     info ? strdup(info) : NULL, NULL,
                                      silc_id_dup(&client_id, SILC_ID_CLIENT),
                                      silc_packet_get_context(cmd->sock),
                                      NULL);
@@ -661,6 +670,10 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
       client->data.status |= SILC_IDLIST_STATUS_REGISTERED;
       client->data.status |= SILC_IDLIST_STATUS_RESOLVED;
       client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING;
+
+      SILC_LOG_DEBUG(("stat.clients %d->%d", server->stat.clients,
+                     server->stat.clients + 1));
+      server->stat.clients++;
     } else {
       /* We have the client already, update the data */
 
@@ -679,17 +692,13 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd)
          return FALSE;
        }
 
-       /* Remove the old cache entry */
-       silc_idcache_del_by_context(global ? server->global_list->clients :
-                                   server->local_list->clients, client, NULL);
-
        silc_free(client->nickname);
        client->nickname = strdup(nick);
 
-       /* Add new cache entry */
-       silc_idcache_add(global ? server->global_list->clients :
-                        server->local_list->clients, name, client->id,
-                        client);
+       /* Update the context */
+       silc_idcache_update_by_context(global ? server->global_list->clients :
+                                      server->local_list->clients, client,
+                                      NULL, name, TRUE);
       }
 
       if (info) {
@@ -1203,7 +1212,8 @@ SILC_SERVER_CMD_REPLY_FUNC(join)
     silc_hmac_free(hmac);
   silc_server_command_reply_free(cmd);
 
-  silc_pkcs_public_key_free(founder_key);
+  if (founder_key)
+    silc_pkcs_public_key_free(founder_key);
   if (client_id_list)
     silc_buffer_free(client_id_list);
   if (client_mode_list)
@@ -1246,6 +1256,8 @@ SILC_SERVER_CMD_REPLY_FUNC(stats)
                         SILC_STR_END);
   }
 
+  SILC_LOG_DEBUG(("stat.clients = %d", server->stat.clients));
+
  out:
   SILC_SERVER_PENDING_EXEC(cmd, SILC_COMMAND_STATS);
  err:
@@ -1280,7 +1292,7 @@ SILC_SERVER_CMD_REPLY_FUNC(users)
     if (!channel) {
       SilcBuffer idp;
 
-      if (server->server_type != SILC_SERVER)
+      if (cmd->pending || server->server_type != SILC_SERVER)
        goto out;
 
       idp = silc_id_payload_encode(SILC_ID_GET_ID(id), SILC_ID_CHANNEL);
@@ -1295,6 +1307,8 @@ SILC_SERVER_CMD_REPLY_FUNC(users)
       silc_server_command_pending(server, SILC_COMMAND_IDENTIFY,
                                  server->cmd_ident,
                                  silc_server_command_reply_users, cmd);
+
+      cmd->pending = TRUE;
       return;
     }
   }
@@ -1434,7 +1448,6 @@ SILC_SERVER_CMD_REPLY_FUNC(list)
   SilcIDCacheEntry cache;
   unsigned char *tmp, *name, *namec = NULL, *topic;
   SilcUInt32 usercount = 0;
-  SilcBool global_list = FALSE;
 
   COMMAND_CHECK_STATUS;
 
@@ -1455,11 +1468,9 @@ SILC_SERVER_CMD_REPLY_FUNC(list)
   /* Add the channel entry if we do not have it already */
   channel = silc_idlist_find_channel_by_name(server->local_list,
                                             namec, &cache);
-  if (!channel) {
+  if (!channel)
     channel = silc_idlist_find_channel_by_name(server->global_list,
                                               namec, &cache);
-    global_list = TRUE;
-  }
   if (!channel) {
     /* If router did not find such channel in its lists then this must
        be bogus channel or some router in the net is buggy. */