From 7ba30123577540d59575c8f020bad86c52c21f59 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Mon, 28 Apr 2014 21:47:58 +0300 Subject: [PATCH] Targeted say-operation messages Add support for including the client, channel or server with the say() client operation library can generate. This allows application to better target the message to correct window or recipient. --- lib/silcclient/client.c | 2 +- lib/silcclient/client_channel.c | 20 ++++++++++++++++---- lib/silcclient/client_ftp.c | 14 +++++++++++++- lib/silcclient/silcclient.h | 18 ++++++++++++++++-- 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index 25533994..38afc453 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -452,7 +452,7 @@ SILC_FSM_STATE(silc_client_error) msg = silc_memdup(silc_buffer_data(&packet->buffer), silc_buffer_len(&packet->buffer)); if (msg) - client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT, msg); + client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR, msg); silc_free(msg); silc_packet_free(packet); diff --git a/lib/silcclient/client_channel.c b/lib/silcclient/client_channel.c index 4120695d..3b020c5d 100644 --- a/lib/silcclient/client_channel.c +++ b/lib/silcclient/client_channel.c @@ -53,9 +53,12 @@ SilcBool silc_client_send_channel_message(SilcClient client, chu = silc_client_on_channel(channel, conn->local_entry); if (silc_unlikely(!chu)) { + conn->context_type = SILC_ID_CHANNEL; + conn->channel_entry = channel; client->internal->ops->say(conn->client, conn, - SILC_CLIENT_MESSAGE_AUDIT, + SILC_CLIENT_MESSAGE_ERROR, "Cannot talk to channel: not joined"); + conn->context_type = SILC_ID_NONE; return FALSE; } @@ -423,21 +426,27 @@ SilcBool silc_client_save_channel_key(SilcClient client, /* Get channel cipher */ cipher = silc_channel_key_get_cipher(payload, NULL); if (!silc_cipher_alloc(cipher, &channel->internal.send_key)) { + conn->context_type = SILC_ID_CHANNEL; + conn->channel_entry = channel; client->internal->ops->say( conn->client, conn, - SILC_CLIENT_MESSAGE_AUDIT, + SILC_CLIENT_MESSAGE_ERROR, "Cannot talk to channel: unsupported cipher %s", cipher); + conn->context_type = SILC_ID_NONE; silc_client_unref_channel(client, conn, channel); silc_channel_key_payload_free(payload); return FALSE; } if (!silc_cipher_alloc(cipher, &channel->internal.receive_key)) { + conn->context_type = SILC_ID_CHANNEL; + conn->channel_entry = channel; client->internal->ops->say( conn->client, conn, - SILC_CLIENT_MESSAGE_AUDIT, + SILC_CLIENT_MESSAGE_ERROR, "Cannot talk to channel: unsupported cipher %s", cipher); + conn->context_type = SILC_ID_NONE; silc_client_unref_channel(client, conn, channel); silc_channel_key_payload_free(payload); return FALSE; @@ -453,11 +462,14 @@ SilcBool silc_client_save_channel_key(SilcClient client, (char *)silc_hmac_get_name(channel->internal.hmac) : SILC_DEFAULT_HMAC); if (!silc_hmac_alloc(hmac, NULL, &channel->internal.hmac)) { + conn->context_type = SILC_ID_CHANNEL; + conn->channel_entry = channel; client->internal->ops->say( conn->client, conn, - SILC_CLIENT_MESSAGE_AUDIT, + SILC_CLIENT_MESSAGE_ERROR, "Cannot talk to channel: unsupported HMAC %s", hmac); + conn->context_type = SILC_ID_NONE; silc_client_unref_channel(client, conn, channel); silc_channel_key_payload_free(payload); return FALSE; diff --git a/lib/silcclient/client_ftp.c b/lib/silcclient/client_ftp.c index a38d03c0..ac53a0c5 100644 --- a/lib/silcclient/client_ftp.c +++ b/lib/silcclient/client_ftp.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2001 - 2007 Pekka Riikonen + Copyright (C) 2001 - 2014 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 @@ -189,11 +189,14 @@ static void silc_client_ftp_open_handle(SilcSFTP sftp, session->fd = silc_file_open(path, O_RDWR | O_CREAT | O_EXCL); if (session->fd < 0) { /* Call monitor callback */ + session->conn->context_type = SILC_ID_CLIENT; + session->conn->client_entry = session->client_entry; session->client->internal->ops->say(session->client, session->conn, SILC_CLIENT_MESSAGE_ERROR, "File `%s' open failed: %s", session->filepath, strerror(errno)); + session->conn->context_type = SILC_ID_NONE; if (session->monitor) (*session->monitor)(session->client, session->conn, @@ -736,9 +739,12 @@ silc_client_file_send(SilcClient client, silc_client_ftp_connect_completion, session); if (!session->listener) { + conn->context_type = SILC_ID_CLIENT; + conn->client_entry = session->client_entry; client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR, "Cannot create listener for file transfer: " "%s", strerror(errno)); + conn->context_type = SILC_ID_NONE; silc_free(session); return SILC_CLIENT_FILE_NO_MEMORY; } @@ -855,11 +861,14 @@ silc_client_file_receive(SilcClient client, /* Add the listener for the key agreement */ SILC_LOG_DEBUG(("Creating listener for file transfer")); if (!params || (!params->local_ip && !params->bind_ip)) { + session->conn->context_type = SILC_ID_CLIENT; + session->conn->client_entry = session->client_entry; session->client->internal->ops->say(session->client, session->conn, SILC_CLIENT_MESSAGE_ERROR, "Cannot create listener for file " "transfer; IP address and/or port " "not provided"); + session->conn->context_type = SILC_ID_NONE; silc_free(session); return SILC_CLIENT_FILE_ERROR; } @@ -869,9 +878,12 @@ silc_client_file_receive(SilcClient client, silc_client_ftp_connect_completion, session); if (!session->listener) { + session->conn->context_type = SILC_ID_CLIENT; + session->conn->client_entry = session->client_entry; client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR, "Cannot create listener for file transfer: " "%s", strerror(errno)); + session->conn->context_type = SILC_ID_NONE; silc_free(session); return SILC_CLIENT_FILE_NO_MEMORY; } diff --git a/lib/silcclient/silcclient.h b/lib/silcclient/silcclient.h index 00d0b5e5..0d07b938 100644 --- a/lib/silcclient/silcclient.h +++ b/lib/silcclient/silcclient.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2000 - 2008 Pekka Riikonen + Copyright (C) 2000 - 2014 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 @@ -232,6 +232,18 @@ struct SilcClientConnectionStruct { void *callback_context; /* Connection context */ SilcClient client; /* Pointer back to SilcClient */ + /* Current say() operation associated context, identifies the client, + channel or server the message is related to. Application can use + this information to target the message better. */ + union { + SilcClientEntry client_entry; + SilcChannelEntry channel_entry; + SilcServerEntry server_entry; + }; + SilcIdType context_type; /* Defines which pointer is set + in the union. If SILC_ID_NONE + pointer is NULL. */ + /* Application specific data. Application may set here whatever it wants. */ void *context; @@ -506,7 +518,9 @@ typedef struct SilcClientOperationsStruct { The `type' indicates the type of the message sent by the library. The application can for example filter the message according the type. The variable argument list is arguments to the formatted - message that `msg' may be. */ + message `msg'. A SilcClientEntry, SilcChannelEntry or SilcServerEntry + can be associated with the message inside the `conn' by the library, + and application may use it to better target the message. */ void (*say)(SilcClient client, SilcClientConnection conn, SilcClientMessageType type, char *msg, ...); -- 2.24.0