updates.
[silc.git] / lib / silcclient / client_notify.c
index a07991736323e7930e1f33c0657609266cffc75c..94e487f173dd92c76e24909c38bc9eaeddd266a8 100644 (file)
@@ -2,7 +2,7 @@
 
   client_notify.c
 
-  Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+  Author: Pekka Riikonen <priikone@silcnet.org>
 
   Copyright (C) 1997 - 2001 Pekka Riikonen
 
 #include "clientlibincludes.h"
 #include "client_internal.h"
 
+typedef struct {
+  SilcPacketContext *packet;
+  void *context;
+  SilcSocketConnection sock;
+} *SilcClientNotifyResolve;
+
 /* Called when notify is received and some async operation (such as command)
    is required before processing the notify message. This calls again the
    silc_client_notify_by_server and reprocesses the original notify packet. */
 
 static void silc_client_notify_by_server_pending(void *context, void *context2)
 {
-  SilcPacketContext *p = (SilcPacketContext *)context;
-  silc_client_notify_by_server(p->context, p->sock, p);
-  silc_socket_free(p->sock);
+  SilcClientNotifyResolve res = (SilcClientNotifyResolve)context;
+  silc_client_notify_by_server(res->context, res->sock, res->packet);
+  silc_socket_free(res->sock);
 }
 
 /* Destructor for the pending command callback */
 
 static void silc_client_notify_by_server_destructor(void *context)
 {
-  silc_packet_context_free((SilcPacketContext *)context);
+  SilcClientNotifyResolve res = (SilcClientNotifyResolve)context;
+  silc_packet_context_free(res->packet);
+  silc_free(res);
 }
 
 /* Resolve client information from server by Client ID. */
@@ -50,17 +58,18 @@ static void silc_client_notify_by_server_resolve(SilcClient client,
                                                 SilcPacketContext *packet,
                                                 SilcClientID *client_id)
 {
-  SilcPacketContext *p = silc_packet_context_dup(packet);
+  SilcClientNotifyResolve res = silc_calloc(1, sizeof(*res));
   SilcBuffer idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
 
-  p->context = (void *)client;
-  p->sock = silc_socket_dup(conn->sock);
+  res->packet = silc_packet_context_dup(packet);
+  res->context = client;
+  res->sock = silc_socket_dup(conn->sock);
 
   silc_client_send_command(client, conn, SILC_COMMAND_WHOIS, ++conn->cmd_ident,
                           1, 3, idp->data, idp->len);
   silc_client_command_pending(conn, SILC_COMMAND_WHOIS, conn->cmd_ident,
                              silc_client_notify_by_server_destructor,
-                             silc_client_notify_by_server_pending, p);
+                             silc_client_notify_by_server_pending, res);
   silc_buffer_free(idp);
 }
 
@@ -123,7 +132,7 @@ void silc_client_notify_by_server(SilcClient client,
     /* Get the channel entry */
     channel = NULL;
     if (silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id,
-                               &id_cache))
+                                   &id_cache))
       channel = (SilcChannelEntry)id_cache->context;
 
     /* Get sender Client ID */
@@ -175,6 +184,9 @@ void silc_client_notify_by_server(SilcClient client,
 
     /* If nickname or username hasn't been resolved, do so */
     if (!client_entry->nickname || !client_entry->username) {
+      if (client_entry->status & SILC_CLIENT_STATUS_RESOLVING)
+       goto out;
+      client_entry->status |= SILC_CLIENT_STATUS_RESOLVING;
       silc_client_notify_by_server_resolve(client, conn, packet, client_id);
       goto out;
     }
@@ -202,9 +214,6 @@ void silc_client_notify_by_server(SilcClient client,
       silc_list_add(channel->clients, chu);
     }
 
-    /* XXX add support for multiple same nicks on same channel. Check
-       for them here */
-
     /* Notify application. The channel entry is sent last as this notify
        is for channel but application don't know it from the arguments
        sent by server. */
@@ -366,6 +375,8 @@ void silc_client_notify_by_server(SilcClient client,
       goto out;
     silc_free(client_id);
 
+    client_entry->valid = FALSE;
+
     /* Get new Client ID */
     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
     if (!tmp)
@@ -479,10 +490,11 @@ void silc_client_notify_by_server(SilcClient client,
       if (!silc_hmac_alloc(tmp, NULL, &channel->hmac))
        goto out;
 
-      silc_hash_make(channel->hmac->hash, channel->key, channel->key_len / 8,
+      silc_hash_make(silc_hmac_get_hash(channel->hmac), 
+                    channel->key, channel->key_len / 8,
                     hash);
       silc_hmac_set_key(channel->hmac, hash, 
-                       silc_hash_len(channel->hmac->hash));
+                       silc_hash_len(silc_hmac_get_hash(channel->hmac)));
       memset(hash, 0, sizeof(hash));
     }
 
@@ -767,8 +779,6 @@ void silc_client_notify_by_server(SilcClient client,
 
  out:
   silc_notify_payload_free(payload);
-  if (client_id)
-    silc_free(client_id);
-  if (channel_id)
-    silc_free(channel_id);
+  silc_free(client_id);
+  silc_free(channel_id);
 }