From 1340d65dcc2378ab24c8bb601dee49fff4971f3a Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Tue, 2 Apr 2002 12:55:03 +0000 Subject: [PATCH] Resolve client info after LEAVE notify. --- lib/silcclient/client_notify.c | 30 ++++++++++++++++++++++++++++-- lib/silcclient/idlist.c | 11 +++++++---- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/lib/silcclient/client_notify.c b/lib/silcclient/client_notify.c index 5e13bf72..1f9d56e1 100644 --- a/lib/silcclient/client_notify.c +++ b/lib/silcclient/client_notify.c @@ -25,12 +25,24 @@ #include "silcclient.h" #include "client_internal.h" +/* Context used for resolving client, channel and server info. */ typedef struct { - SilcPacketContext *packet; + void *packet; void *context; SilcSocketConnection sock; } *SilcClientNotifyResolve; +SILC_TASK_CALLBACK(silc_client_notify_check_client) +{ + SilcClientNotifyResolve res = (SilcClientNotifyResolve)context; + SilcClientConnection conn = res->context; + SilcClient client = conn->client; + SilcClientID *client_id = res->packet; + silc_client_get_client_by_id_resolve(client, conn, client_id, NULL, NULL); + silc_free(client_id); + silc_free(res); +} + /* 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. */ @@ -72,7 +84,7 @@ static void silc_client_notify_by_server_resolve(SilcClient client, res->context = client; res->sock = silc_socket_dup(conn->sock); - /* For client resolving use WHOIS, and oterhwise use IDENTIFY */ + /* For client resolving use WHOIS, and otherwise use IDENTIFY */ if (id_type == SILC_ID_CLIENT) { silc_client_command_register(client, SILC_COMMAND_WHOIS, NULL, NULL, silc_client_command_reply_whois_i, 0, @@ -292,6 +304,20 @@ void silc_client_notify_by_server(SilcClient client, silc_free(chu); } + /* Some client implementations actually quit network by first doing + LEAVE and then immediately SIGNOFF. We'll check for this by doing + check for the client after 15 seconds. If it is not valid after + that we'll remove the client from cache. */ + if (!silc_hash_table_count(client_entry->channels)) { + SilcClientNotifyResolve res = silc_calloc(1, sizeof(*res)); + res->context = conn; + res->packet = silc_id_dup(client_id, SILC_ID_CLIENT); + silc_schedule_task_add(client->schedule, 0, + silc_client_notify_check_client, conn, + 15, 0, SILC_TASK_TIMEOUT, + SILC_TASK_PRI_NORMAL); + } + /* 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. */ diff --git a/lib/silcclient/idlist.c b/lib/silcclient/idlist.c index 15455b69..7549a62d 100644 --- a/lib/silcclient/idlist.c +++ b/lib/silcclient/idlist.c @@ -506,10 +506,13 @@ SILC_CLIENT_CMD_FUNC(get_client_by_id_callback) /* Get the client */ entry = silc_client_get_client_by_id(i->client, i->conn, i->client_id); - if (entry) - i->completion(i->client, i->conn, &entry, 1, i->context); - else - i->completion(i->client, i->conn, NULL, 0, i->context); + if (entry) { + if (i->completion) + i->completion(i->client, i->conn, &entry, 1, i->context); + } else { + if (i->completion) + i->completion(i->client, i->conn, NULL, 0, i->context); + } silc_free(i->client_id); silc_free(i); -- 2.24.0