silc_client_unref_client fixes.
authorPekka Riikonen <priikone@silcnet.org>
Sat, 11 Nov 2006 20:29:09 +0000 (20:29 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sat, 11 Nov 2006 20:29:09 +0000 (20:29 +0000)
lib/silcclient/client.c
lib/silcclient/client_entry.c
lib/silcclient/client_prvmsg.c
lib/silcclient/command.c
lib/silcclient/command_reply.c

index 8834c272f92278f5a263594520cc3e9ac9e6d89a..7f29c4ad5e4f1e90cba95e2a40479083d6c6bfdb 100644 (file)
@@ -38,7 +38,6 @@ static SilcBool silc_client_packet_receive(SilcPacketEngine engine,
                                           void *callback_context,
                                           void *stream_context)
 {
-  SilcClient client = callback_context;
   SilcClientConnection conn = stream_context;
 
   /* Packets we do not handle */
@@ -329,9 +328,10 @@ SILC_FSM_STATE(silc_client_new_id)
     goto out;
 
   /* Create local client entry */
-  conn->local_entry = silc_client_add_client(client, conn, (client->nickname ?
-                                                           client->nickname :
-                                                           client->username),
+  conn->local_entry = silc_client_add_client(client, conn,
+                                            (client->nickname ?
+                                             client->nickname :
+                                             client->username),
                                             client->username,
                                             client->realname,
                                             &id.u.client_id, 0);
@@ -1098,117 +1098,6 @@ static void silc_client_resume_session_cb(SilcClient client,
   }
 }
 
-/* Processes the received new Client ID from server. Old Client ID is
-   deleted from cache and new one is added. */
-
-void silc_client_receive_new_id(SilcClient client,
-                               SilcClientConnection conn,
-                               SilcIDPayload idp)
-{
-  SilcClientConnection conn = (SilcClientConnection)sock->user_data;
-  int connecting = FALSE;
-  SilcClientID *client_id = silc_id_payload_get_id(idp);
-  char *nickname;
-
-  if (!conn->local_entry)
-    connecting = TRUE;
-
-  /* Delete old ID from ID cache */
-  if (conn->local_id) {
-    /* Check whether they are different */
-    if (SILC_ID_CLIENT_COMPARE(conn->local_id, client_id)) {
-      silc_free(client_id);
-      return;
-    }
-
-    silc_idcache_del_by_context(conn->internal->client_cache,
-                               conn->local_entry);
-    silc_free(conn->local_id);
-  }
-
-  /* Save the new ID */
-
-  if (conn->local_id_data)
-    silc_free(conn->local_id_data);
-
-  conn->local_id = client_id;
-  conn->local_id_data = silc_id_payload_get_data(idp);
-  conn->local_id_data_len = silc_id_payload_get_len(idp);;
-
-  if (!conn->local_entry)
-    conn->local_entry = silc_calloc(1, sizeof(*conn->local_entry));
-
-  conn->local_entry->nickname = conn->nickname;
-  if (!conn->local_entry->username)
-    conn->local_entry->username = strdup(client->username);
-  if (!conn->local_entry->server)
-    conn->local_entry->server = strdup(conn->remote_host);
-  conn->local_entry->id = conn->local_id;
-  conn->local_entry->valid = TRUE;
-  if (!conn->local_entry->channels)
-    conn->local_entry->channels = silc_hash_table_alloc(1, silc_hash_ptr,
-                                                       NULL, NULL,
-                                                       NULL, NULL, NULL,
-                                                       TRUE);
-
-  /* Normalize nickname */
-  nickname = silc_identifier_check(conn->nickname, strlen(conn->nickname),
-                                  SILC_STRING_UTF8, 128, NULL);
-  if (!nickname)
-    return;
-
-    /* Put it to the ID cache */
-  silc_idcache_add(conn->internal->client_cache, nickname, conn->local_id,
-                  (void *)conn->local_entry, 0, NULL);
-
-#if 0
-  if (connecting) {
-    SilcBuffer sidp;
-
-    /* Issue IDENTIFY command for itself to get resolved hostname
-       correctly from server. */
-    silc_client_command_register(client, SILC_COMMAND_IDENTIFY, NULL, NULL,
-                                silc_client_command_reply_identify_i, 0,
-                                ++conn->cmd_ident);
-    sidp = silc_id_payload_encode(conn->local_entry->id, SILC_ID_CLIENT);
-    silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY,
-                            conn->cmd_ident, 1, 5, sidp->data, sidp->len);
-    silc_buffer_free(sidp);
-
-    if (!conn->internal->params.detach_data) {
-      /* Send NICK command if the nickname was set by the application (and is
-        not same as the username). Send this with little timeout. */
-      if (client->nickname &&
-         !silc_utf8_strcasecmp(client->nickname, client->username))
-       silc_schedule_task_add(client->schedule, 0,
-                              silc_client_send_auto_nick, conn,
-                              1, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
-
-      /* Notify application of successful connection. We do it here now that
-        we've received the Client ID and are allowed to send traffic. */
-      client->internal->ops->connected(client, conn, SILC_CLIENT_CONN_SUCCESS);
-
-      /* Issue INFO command to fetch the real server name and server
-        information and other stuff. */
-      silc_client_command_register(client, SILC_COMMAND_INFO, NULL, NULL,
-                                  silc_client_command_reply_info_i, 0,
-                                  ++conn->cmd_ident);
-      sidp = silc_id_payload_encode(conn->remote_id, SILC_ID_SERVER);
-      silc_client_command_send(client, conn, SILC_COMMAND_INFO,
-                              conn->cmd_ident, 1, 2, sidp->data, sidp->len);
-      silc_buffer_free(sidp);
-    } else {
-      /* We are resuming session.  Start resolving informations from the
-        server we need to set the client libary in the state before
-        detaching the session.  The connect client operation is called
-        after this is successfully completed */
-      silc_client_resume_session(client, conn, silc_client_resume_session_cb,
-                                NULL);
-    }
-  }
-#endif /* 0 */
-}
-
 /* Removes a client entry from all channels it has joined. */
 
 void silc_client_remove_from_channels(SilcClient client,
index 4db54f03d12ca9459d3faf9305e2456bf11e3a1c..87f2c6589ec650c9f0347196e90e99b98d6877da 100644 (file)
@@ -345,10 +345,8 @@ static SilcBool silc_client_get_clients_list_cb(SilcClient client,
 
     /* Get client entry */
     client_entry = silc_client_get_client_by_id(client, conn, &id.u.client_id);
-    if (client_entry) {
-      silc_client_ref_client(client, conn, client_entry);
+    if (client_entry)
       silc_dlist_add(clients, client_entry);
-    }
 
     if (!silc_buffer_pull(i->client_id_list, idp_len)) {
       status = SILC_STATUS_ERR_BAD_CLIENT_ID;
@@ -416,13 +414,16 @@ void silc_client_get_clients_by_list(SilcClient client,
     /* Check if we have this client cached already.  If we don't have the
        entry or it has incomplete info, then resolve it from the server. */
     entry = silc_client_get_client_by_id(client, conn, &id.u.client_id);
-    if (!entry || !entry->nickname || !entry->username || !entry->realname) {
+    if (!entry || !entry->nickname[0] || !entry->username[0] ||
+       !entry->realname) {
       if (!res_argv) {
        res_argv = silc_calloc(list_count, sizeof(*res_argv));
        res_argv_lens = silc_calloc(list_count, sizeof(*res_argv_lens));
        res_argv_types = silc_calloc(list_count, sizeof(*res_argv_types));
-       if (!res_argv || !res_argv_lens || !res_argv_types)
+       if (!res_argv || !res_argv_lens || !res_argv_types) {
+         silc_client_unref_client(client, conn, entry);
          goto err;
+       }
       }
 
       res_argv[res_argc] = client_id_list->data;
@@ -430,6 +431,7 @@ void silc_client_get_clients_by_list(SilcClient client,
       res_argv_types[res_argc] = res_argc + 5;
       res_argc++;
     }
+    silc_client_unref_client(client, conn, entry);
 
     if (!silc_buffer_pull(client_id_list, idp_len))
       goto err;
@@ -557,7 +559,7 @@ void silc_client_get_clients_by_channel(SilcClient client,
     entry = chu->client;
 
     /* If the entry has incomplete info, then resolve it from the server. */
-    if (!entry->nickname || !entry->realname) {
+    if (!entry->nickname[0] || !entry->realname) {
       if (entry->status & SILC_CLIENT_STATUS_RESOLVING) {
        /* Attach to this resolving and wait until it finishes */
        silc_client_command_pending(
@@ -809,10 +811,9 @@ void silc_client_ref_client(SilcClient client, SilcClientConnection conn,
 void silc_client_unref_client(SilcClient client, SilcClientConnection conn,
                              SilcClientEntry client_entry)
 {
-  if (silc_atomic_sub_int8(&client_entry->internal.refcnt, 1) == 0) {
+  if (client_entry &&
+      silc_atomic_sub_int8(&client_entry->internal.refcnt, 1) == 0)
     silc_client_del_client(client, conn, client_entry);
-    return;
-  }
 }
 
 /* Free client entry list */
@@ -822,11 +823,13 @@ void silc_client_list_free(SilcClient client, SilcClientConnection conn,
 {
   SilcClientEntry client_entry;
 
-  silc_dlist_start(client_list);
-  while ((client_entry = silc_dlist_get(client_list)))
-    silc_client_unref_client(client, conn, client_entry);
+  if (client_list) {
+    silc_dlist_start(client_list);
+    while ((client_entry = silc_dlist_get(client_list)))
+      silc_client_unref_client(client, conn, client_entry);
 
-  silc_dlist_uninit(client_list);
+    silc_dlist_uninit(client_list);
+  }
 }
 
 
@@ -1347,7 +1350,7 @@ void silc_client_nickname_format(SilcClient client,
   if (!client->internal->params->nickname_format[0])
     return;
 
-  if (!client_entry->nickname)
+  if (!client_entry->nickname[0])
     return;
 
   /* Get all clients with same nickname. Do not perform the formatting
@@ -1469,5 +1472,5 @@ void silc_client_nickname_format(SilcClient client,
 
   newnick[off] = 0;
   memcpy(client_entry->nickname, newnick, strlen(newnick));
-  silc_dlist_uninit(clients);
+  silc_client_list_free(client, conn, clients);
 }
index 6c6c56ca22709c1ed5cf710779b075f8c9062f99..ec0e3b8de39a9b8dac782d6d47b42995ba225da1 100644 (file)
@@ -107,7 +107,7 @@ SILC_FSM_STATE(silc_client_private_message)
   SilcPacket packet = state_context;
   SilcMessagePayload payload = NULL;
   SilcClientID remote_id;
-  SilcClientEntry remote_client;
+  SilcClientEntry remote_client = NULL;
   SilcMessageFlags flags;
   unsigned char *message;
   SilcUInt32 message_len;
@@ -122,9 +122,10 @@ SILC_FSM_STATE(silc_client_private_message)
 
   /* Check whether we know this client already */
   remote_client = silc_client_get_client_by_id(client, conn, &remote_id);
-  if (!remote_client || !remote_client->nickname) {
+  if (!remote_client || !remote_client->nickname[0]) {
     /* Resolve the client info.  We return back to packet thread to receive
        other packets while we wait for the resolving to finish. */
+    silc_client_unref_client(client, conn, remote_client);
     silc_client_get_client_by_id_resolve(client, conn, &remote_id, NULL,
                                         silc_client_private_message_resolved,
                                         packet);
@@ -195,6 +196,7 @@ SILC_FSM_STATE(silc_client_private_message)
 
  out:
   /** Packet processed */
+  silc_client_unref_client(client, conn, remote_client);
   if (payload)
     silc_message_payload_free(payload);
   silc_packet_free(packet);
index ce4a03ea546aba268238bb4abc05c13b12b2243c..de95e743720c1c22cfd3ad544a1b161a65a15402 100644 (file)
@@ -925,7 +925,7 @@ SILC_FSM_STATE(silc_client_command_invite)
   SilcChannelEntry channel;
   SilcBuffer clidp, chidp, args = NULL;
   SilcPublicKey pubkey = NULL;
-  SilcDList clients;
+  SilcDList clients = NULL;
   char *nickname = NULL, *name;
   char *invite = NULL;
   unsigned char action[1];
@@ -975,7 +975,6 @@ SILC_FSM_STATE(silc_client_command_invite)
                                      cmd));
 
       client_entry = silc_dlist_get(clients);
-      silc_dlist_uninit(clients);
     } else {
       if (cmd->argv[2][0] == '+')
        action[0] = 0x00;
@@ -1026,6 +1025,7 @@ SILC_FSM_STATE(silc_client_command_invite)
   silc_buffer_free(chidp);
   silc_buffer_free(args);
   silc_free(nickname);
+  silc_client_list_free(client, conn, clients);
 
   /* Notify application */
   COMMAND(SILC_STATUS_OK);
@@ -1123,7 +1123,6 @@ SILC_FSM_STATE(silc_client_command_kill)
                                          cmd));
 
   target = silc_dlist_get(clients);
-  silc_dlist_uninit(clients);
 
   if (cmd->argc >= 3) {
     if (strcasecmp(cmd->argv[2], "-pubkey"))
@@ -1149,6 +1148,7 @@ SILC_FSM_STATE(silc_client_command_kill)
   silc_buffer_free(idp);
   silc_buffer_free(auth);
   silc_free(nickname);
+  silc_client_list_free(client, conn, clients);
 
   /* Notify application */
   COMMAND(SILC_STATUS_OK);
@@ -1836,7 +1836,7 @@ SILC_FSM_STATE(silc_client_command_cumode)
   SilcChannelUser chu;
   SilcClientEntry client_entry;
   SilcBuffer clidp, chidp, auth = NULL;
-  SilcDList clients;
+  SilcDList clients = NULL;
   unsigned char *name, *cp, modebuf[4];
   SilcUInt32 mode = 0, add, len;
   char *nickname = NULL;
@@ -1882,7 +1882,6 @@ SILC_FSM_STATE(silc_client_command_cumode)
                                          cmd));
 
   client_entry = silc_dlist_get(clients);
-  silc_dlist_uninit(clients);
 
   /* Get the current mode */
   chu = silc_client_on_channel(channel, client_entry);
@@ -1997,6 +1996,7 @@ SILC_FSM_STATE(silc_client_command_cumode)
   COMMAND(SILC_STATUS_OK);
 
  out:
+  silc_client_list_free(client, conn, clients);
   silc_free(nickname);
   return SILC_FSM_FINISH;
 }
@@ -2013,7 +2013,7 @@ SILC_FSM_STATE(silc_client_command_kick)
   SilcChannelEntry channel;
   SilcBuffer idp, idp2;
   SilcClientEntry target;
-  SilcDList clients;
+  SilcDList clients = NULL;
   char *name;
   char *nickname = NULL;
 
@@ -2062,7 +2062,6 @@ SILC_FSM_STATE(silc_client_command_kick)
     goto out;
   }
   target = silc_dlist_get(clients);
-  silc_dlist_uninit(clients);
 
   /* Send KICK command to the server */
   idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL);
@@ -2080,6 +2079,7 @@ SILC_FSM_STATE(silc_client_command_kick)
   silc_buffer_free(idp);
   silc_buffer_free(idp2);
   silc_free(nickname);
+  silc_client_list_free(client, conn, clients);
 
   /* Notify application */
   COMMAND(SILC_STATUS_OK);
@@ -2553,7 +2553,7 @@ SILC_FSM_STATE(silc_client_command_getkey)
   } else {
     client_entry = silc_dlist_get(clients);
     idp = silc_id_payload_encode(&client_entry->id, SILC_ID_CLIENT);
-    silc_dlist_uninit(clients);
+    silc_client_list_free(client, conn, clients);
   }
 
   /* Send the commmand */
index 0fd7990366b3d69fb79c74154dc7b6dee2438617..9eea6bf1a53177cbb896377b39304d77b5896524 100644 (file)
@@ -111,8 +111,10 @@ static void silc_client_command_process_error(SilcClientCommandContext cmd,
       return;
 
     client_entry = silc_client_get_client_by_id(client, conn, &id.u.client_id);
-    if (client_entry)
+    if (client_entry) {
+      silc_client_unref_client(client, conn, client_entry);
       silc_client_del_client(client, conn, client_entry);
+    }
   }
 }
 
@@ -438,6 +440,7 @@ SILC_FSM_STATE(silc_client_command_reply_whois)
                               realname, channel_list, mode, idle, fingerprint,
                               umodes, client_entry->attrs);
 
+  silc_client_unref_client(client, conn, client_entry);
   if (has_channels) {
     silc_dlist_uninit(channel_list);
     silc_free(umodes);
@@ -459,7 +462,7 @@ SILC_FSM_STATE(silc_client_command_reply_whowas)
   SilcClient client = conn->client;
   SilcCommandPayload payload = state_context;
   SilcArgumentPayload args = silc_command_get_args(payload);
-  SilcClientEntry client_entry;
+  SilcClientEntry client_entry = NULL;
   SilcID id;
   char *nickname, *username;
   char *realname = NULL;
@@ -491,6 +494,7 @@ SILC_FSM_STATE(silc_client_command_reply_whowas)
                               realname);
 
  out:
+  silc_client_unref_client(client, conn, client_entry);
   silc_fsm_next(fsm, silc_client_command_reply_process);
   return SILC_FSM_CONTINUE;
 }
@@ -548,6 +552,7 @@ SILC_FSM_STATE(silc_client_command_reply_identify)
 
     /* Notify application */
     silc_client_command_callback(cmd, client_entry, name, info);
+    silc_client_unref_client(client, conn, client_entry);
     break;
 
   case SILC_ID_SERVER:
@@ -863,8 +868,10 @@ SILC_FSM_STATE(silc_client_command_reply_kill)
   silc_client_command_callback(cmd, client_entry);
 
   /* Remove the client from all channels and free it */
-  if (client_entry)
+  if (client_entry) {
     silc_client_del_client(client, conn, client_entry);
+    silc_client_unref_client(client, conn, client_entry);
+  }
 
  out:
   silc_fsm_next(fsm, silc_client_command_reply_process);
@@ -1153,17 +1160,22 @@ SILC_FSM_STATE(silc_client_command_reply_join)
     /* Join client to the channel */
     if (!silc_client_on_channel(channel, client_entry)) {
       chu = silc_calloc(1, sizeof(*chu));
-      if (!chu)
+      if (!chu) {
+       silc_client_unref_client(client, conn, client_entry);
        goto out;
+      }
       chu->client = client_entry;
       chu->channel = channel;
       chu->mode = mode;
       silc_hash_table_add(channel->user_list, client_entry, chu);
       silc_hash_table_add(client_entry->channels, channel, chu);
     }
+    silc_client_unref_client(client, conn, client_entry);
 
-    silc_buffer_pull(client_id_list, idp_len);
-    silc_buffer_pull(client_mode_list, 4);
+    if (!silc_buffer_pull(client_id_list, idp_len))
+      goto out;
+    if (!silc_buffer_pull(client_mode_list, 4))
+      goto out;
   }
   silc_buffer_start(client_id_list);
   silc_buffer_start(client_mode_list);
@@ -1443,6 +1455,8 @@ SILC_FSM_STATE(silc_client_command_reply_cumode)
   /* Notify application */
   silc_client_command_callback(cmd, mode, channel, client_entry);
 
+  silc_client_unref_client(client, conn, client_entry);
+
  out:
   silc_fsm_next(fsm, silc_client_command_reply_process);
   return SILC_FSM_CONTINUE;
@@ -1494,6 +1508,8 @@ SILC_FSM_STATE(silc_client_command_reply_kick)
   /* Notify application */
   silc_client_command_callback(cmd, channel, client_entry);
 
+  silc_client_unref_client(client, conn, client_entry);
+
  out:
   silc_fsm_next(fsm, silc_client_command_reply_process);
   return SILC_FSM_CONTINUE;
@@ -1807,14 +1823,17 @@ SILC_FSM_STATE(silc_client_command_reply_users)
     client_entry = silc_client_get_client_by_id(client, conn, &id.u.client_id);
     if (client_entry && !silc_client_on_channel(channel, client_entry)) {
       chu = silc_calloc(1, sizeof(*chu));
-      if (!chu)
+      if (!chu) {
+       silc_client_unref_client(client, conn, client_entry);
        goto out;
+      }
       chu->client = client_entry;
       chu->mode = mode;
       chu->channel = channel;
       silc_hash_table_add(channel->user_list, client_entry, chu);
       silc_hash_table_add(client_entry->channels, channel, chu);
     }
+    silc_client_unref_client(client, conn, client_entry);
 
     if (!silc_buffer_pull(&client_id_list, idp_len))
       goto out;
@@ -1892,6 +1911,7 @@ SILC_FSM_STATE(silc_client_command_reply_getkey)
     /* Notify application */
     silc_client_command_callback(cmd, SILC_ID_CLIENT, client_entry,
                                 client_entry->public_key);
+    silc_client_unref_client(client, conn, client_entry);
   } else if (id.type == SILC_ID_SERVER) {
     /* Received server's public key */
     server_entry = silc_client_get_server_by_id(client, conn, &id.u.server_id);