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. */
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);
}
/* 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 */
/* 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;
}
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. */
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)
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));
}
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);
}