From fbcba64240f0accf54c44249df6b03652bb86dfc Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Thu, 20 Jun 2002 13:56:36 +0000 Subject: [PATCH] Improved UTF-8 encoding and decoding, improved toolkit doc, improved server debug output. For rest, see CHANGES. --- CHANGES | 21 ++++++ TODO | 7 ++ apps/irssi/src/silc/core/client_ops.c | 4 +- apps/irssi/src/silc/core/silc-channels.c | 18 +++-- apps/irssi/src/silc/core/silc-servers.c | 4 +- apps/silcd/command.c | 43 ++++++----- apps/silcd/packet_receive.c | 12 ++- apps/silcd/packet_send.c | 8 +- apps/silcd/server.c | 37 ++------- apps/silcd/server_util.c | 5 +- apps/silcd/serverconfig.c | 5 +- configure.in.pre | 8 +- includes/silcincludes.h | 12 +++ lib/doc/silcclient_using.html | 82 ++++++++++++++++++++ lib/silccore/silccommand.h | 2 + lib/silcutil/Makefile.am | 6 +- lib/silcutil/silclog.h | 5 ++ lib/silcutil/silcstrutil.c | 93 ++++++++++++++++++++++- lib/silcutil/silcstrutil.h | 15 ++-- lib/silcutil/silcutil.c | 95 +++++++++++++++++++++++- lib/silcutil/silcutil.h | 29 +++++++- 21 files changed, 422 insertions(+), 89 deletions(-) diff --git a/CHANGES b/CHANGES index 8d0ca8c7..372a0141 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,24 @@ +Thu Jun 20 13:48:15 EEST 2002 Pekka Riikonen + + * Implemented SILC_STRING_BMP and SILC_STRING_UNIVERSAL for + UTF-8 encoding and decoding. Added also new encodings + SILC_STRING_BMP_LSB and SILC_STRING_UNIVERSAL_LSB. + + Added also SILC_STRING_LANGUAGE which is language and charset + specific encoder and decoer for those platforms that support + iconv(). It can convert the UTF-8 to and from the locale + specific character set. + + Affected file lib/silcutil/silcstrutil.[ch]. + + * Added macro SILC_NOT_IMPLEMENTED to lib/silcutil/silclog.h. + + * Added function silc_get_command_name to the file + lib/silcutil/silcutil.[ch + + * Improved the server debug output a bit. Affected files are + in silcd/. + Wed Jun 19 17:46:31 EEST 2002 Pekka Riikonen * Save the channel passphrase when received succesful JOIN diff --git a/TODO b/TODO index 6748473e..497dea09 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,8 @@ TODO/bugs in Irssi SILC client ============================== + o Do UTF-8 decoding on non-utf terminals with iconv() if available. + o Testing @@ -45,6 +47,11 @@ TODO/bugs In SILC Server TODO/bugs In SILC Libraries =========================== + o Remove ../lib/contrib/ from includes and use relative path instead. + + o Remove default irssi/ silcd/ compilation on toolkit, add maybe + --without-silcd and --without-irssi. + o WIN32 silc_net_create_connection_async does not work the same way than on Unix. Do it with threads on WIN32. The function works but is not actually async currently (Fix this to 0.9.x). diff --git a/apps/irssi/src/silc/core/client_ops.c b/apps/irssi/src/silc/core/client_ops.c index 5c83a211..8b75868c 100644 --- a/apps/irssi/src/silc/core/client_ops.c +++ b/apps/irssi/src/silc/core/client_ops.c @@ -185,7 +185,7 @@ void silc_channel_message(SilcClient client, SilcClientConnection conn, cp = dm; } - silc_utf8_decode(message, message_len, SILC_STRING_ASCII, + silc_utf8_decode(message, message_len, SILC_STRING_LANGUAGE, cp, message_len); signal_emit("message public", 6, server, cp, nick == NULL ? "[]" : nick->nick, @@ -258,7 +258,7 @@ void silc_private_message(SilcClient client, SilcClientConnection conn, cp = dm; } - silc_utf8_decode(message, message_len, SILC_STRING_ASCII, + silc_utf8_decode(message, message_len, SILC_STRING_LANGUAGE, cp, message_len); signal_emit("message private", 4, server, cp, sender->nickname ? sender->nickname : "[]", diff --git a/apps/irssi/src/silc/core/silc-channels.c b/apps/irssi/src/silc/core/silc-channels.c index 38cd2bcc..afff90e6 100644 --- a/apps/irssi/src/silc/core/silc-channels.c +++ b/apps/irssi/src/silc/core/silc-channels.c @@ -200,10 +200,12 @@ static void command_me(const char *data, SILC_SERVER_REC *server, cmd_return_error(CMDERR_CHAN_NOT_FOUND); if (!silc_term_utf8()) { - int len = silc_utf8_encoded_len(argv[1], argv_lens[1], SILC_STRING_ASCII); + int len = silc_utf8_encoded_len(argv[1], argv_lens[1], + SILC_STRING_LANGUAGE); message = silc_calloc(len + 1, sizeof(*message)); g_return_if_fail(message != NULL); - silc_utf8_encode(argv[1], argv_lens[1], SILC_STRING_ASCII, message, len); + silc_utf8_encode(argv[1], argv_lens[1], SILC_STRING_LANGUAGE, + message, len); } /* Send the action message */ @@ -261,10 +263,12 @@ static void command_action(const char *data, SILC_SERVER_REC *server, cmd_return_error(CMDERR_CHAN_NOT_FOUND); if (!silc_term_utf8()) { - int len = silc_utf8_encoded_len(argv[2], argv_lens[2], SILC_STRING_ASCII); + int len = silc_utf8_encoded_len(argv[2], argv_lens[2], + SILC_STRING_LANGUAGE); message = silc_calloc(len + 1, sizeof(*message)); g_return_if_fail(message != NULL); - silc_utf8_encode(argv[2], argv_lens[2], SILC_STRING_ASCII, message, len); + silc_utf8_encode(argv[2], argv_lens[2], SILC_STRING_LANGUAGE, + message, len); } /* Send the action message */ @@ -321,10 +325,12 @@ static void command_notice(const char *data, SILC_SERVER_REC *server, cmd_return_error(CMDERR_CHAN_NOT_FOUND); if (!silc_term_utf8()) { - int len = silc_utf8_encoded_len(argv[1], argv_lens[1], SILC_STRING_ASCII); + int len = silc_utf8_encoded_len(argv[1], argv_lens[1], + SILC_STRING_LANGUAGE); message = silc_calloc(len + 1, sizeof(*message)); g_return_if_fail(message != NULL); - silc_utf8_encode(argv[1], argv_lens[1], SILC_STRING_ASCII, message, len); + silc_utf8_encode(argv[1], argv_lens[1], SILC_STRING_LANGUAGE, + message, len); } /* Send the action message */ diff --git a/apps/irssi/src/silc/core/silc-servers.c b/apps/irssi/src/silc/core/silc-servers.c index ae34c5c7..5b5eb384 100644 --- a/apps/irssi/src/silc/core/silc-servers.c +++ b/apps/irssi/src/silc/core/silc-servers.c @@ -194,10 +194,10 @@ static void send_message(SILC_SERVER_REC *server, char *target, g_return_if_fail(msg != NULL); if (!silc_term_utf8()) { - len = silc_utf8_encoded_len(msg, strlen(msg), SILC_STRING_ASCII); + len = silc_utf8_encoded_len(msg, strlen(msg), SILC_STRING_LANGUAGE); message = silc_calloc(len + 1, sizeof(*message)); g_return_if_fail(message != NULL); - silc_utf8_encode(msg, strlen(msg), SILC_STRING_ASCII, message, len); + silc_utf8_encode(msg, strlen(msg), SILC_STRING_LANGUAGE, message, len); } if (target_type == SEND_TARGET_CHANNEL) diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 116de4fd..1a5c7c5f 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -97,15 +97,15 @@ SilcServerCommand silc_command_list[] = do { \ SilcUInt32 _argc; \ \ - SILC_LOG_DEBUG(("Start")); \ - \ if (silc_server_command_pending_error_check(cmd, context2, command)) { \ + SILC_LOG_DEBUG(("Error occurred in command reply, command not called")); \ silc_server_command_free(cmd); \ return; \ } \ \ _argc = silc_argument_get_arg_num(cmd->args); \ if (_argc < min) { \ + SILC_LOG_DEBUG(("Not enough parameters in command")); \ silc_server_command_send_status_reply(cmd, command, \ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, \ 0); \ @@ -113,6 +113,7 @@ do { \ return; \ } \ if (_argc > max) { \ + SILC_LOG_DEBUG(("Too many parameters in command")); \ silc_server_command_send_status_reply(cmd, command, \ SILC_STATUS_ERR_TOO_MANY_PARAMS, \ 0); \ @@ -157,6 +158,7 @@ SILC_TASK_CALLBACK(silc_server_command_process_timeout) SilcClientEntry client = (SilcClientEntry)timeout->ctx->sock->user_data; if (!client) { + SILC_LOG_DEBUG(("Client entry is invalid")); silc_server_command_free(timeout->ctx); silc_free(timeout); } @@ -164,15 +166,21 @@ SILC_TASK_CALLBACK(silc_server_command_process_timeout) /* Update access time */ client->last_command = time(NULL); - if (!(timeout->cmd->flags & SILC_CF_REG)) + if (!(timeout->cmd->flags & SILC_CF_REG)) { + SILC_LOG_DEBUG(("Calling %s command", + silc_get_command_name(timeout->cmd->cmd))); timeout->cmd->cb(timeout->ctx, NULL); - else if (silc_server_is_registered(timeout->ctx->server, - timeout->ctx->sock, - timeout->ctx, - timeout->cmd->cmd)) + } else if (silc_server_is_registered(timeout->ctx->server, + timeout->ctx->sock, + timeout->ctx, + timeout->cmd->cmd)) { + SILC_LOG_DEBUG(("Calling %s command", + silc_get_command_name(timeout->cmd->cmd))); timeout->cmd->cb(timeout->ctx, NULL); - else + } else { + SILC_LOG_DEBUG(("Client is not registered")); silc_server_command_free(timeout->ctx); + } silc_free(timeout); } @@ -187,8 +195,6 @@ void silc_server_command_process(SilcServer server, SilcServerCommand *cmd; SilcCommand command; - SILC_LOG_DEBUG(("Start")); - /* Allocate command context. This must be free'd by the command routine receiving it. */ ctx = silc_server_command_alloc(); @@ -215,6 +221,7 @@ void silc_server_command_process(SilcServer server, break; if (!cmd || !cmd->cb) { + SILC_LOG_DEBUG(("Unknown command %d", command)); silc_server_command_send_status_reply(ctx, command, SILC_STATUS_ERR_UNKNOWN_COMMAND, 0); silc_server_command_free(ctx); @@ -261,12 +268,16 @@ void silc_server_command_process(SilcServer server, /* Execute for server */ - if (!(cmd->flags & SILC_CF_REG)) + if (!(cmd->flags & SILC_CF_REG)) { + SILC_LOG_DEBUG(("Calling %s command", silc_get_command_name(cmd->cmd))); cmd->cb(ctx, NULL); - else if (silc_server_is_registered(server, sock, ctx, cmd->cmd)) + } else if (silc_server_is_registered(server, sock, ctx, cmd->cmd)) { + SILC_LOG_DEBUG(("Calling %s command", silc_get_command_name(cmd->cmd))); cmd->cb(ctx, NULL); - else + } else { + SILC_LOG_DEBUG(("Server is not registered")); silc_server_command_free(ctx); + } } /* Allocate Command Context */ @@ -3178,7 +3189,7 @@ static void silc_server_command_join_channel(SilcServer server, unsigned char *fkey = NULL; SilcUInt32 fkey_len = 0; - SILC_LOG_DEBUG(("Start")); + SILC_LOG_DEBUG(("Joining client to channel")); if (!channel) return; @@ -4971,8 +4982,6 @@ SILC_TASK_CALLBACK(silc_server_command_detach_timeout) SilcClientID *client_id = (SilcClientID *)q->sock; SilcClientEntry client; - SILC_LOG_DEBUG(("Start")); - client = silc_idlist_find_client_by_id(q->server->local_list, client_id, FALSE, NULL); @@ -5695,8 +5704,6 @@ SILC_SERVER_CMD_FUNC(getkey) SilcIdType id_type; SilcPublicKey public_key; - SILC_LOG_DEBUG(("Start")); - tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len); if (!tmp) { silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY, diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index ac06a7d2..f91d0aa1 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -2681,7 +2681,6 @@ void silc_server_new_channel(SilcServer server, SilcUInt32 name_len; unsigned char *id; SilcUInt32 id_len; - SilcUInt32 mode; SilcServerEntry server_entry; SilcChannelEntry channel; @@ -3033,10 +3032,10 @@ void silc_server_connection_auth_request(SilcServer server, int ret; SilcAuthMethod auth_meth = SILC_AUTH_NONE; - SILC_LOG_DEBUG(("Start")); - - if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT) + if (packet->src_id_type && packet->src_id_type != SILC_ID_CLIENT) { + SILC_LOG_DEBUG(("Request not from client")); return; + } /* Parse the payload */ ret = silc_buffer_unformat(packet->buffer, @@ -3064,6 +3063,11 @@ void silc_server_connection_auth_request(SilcServer server, auth_meth = SILC_AUTH_PUBLIC_KEY; } + SILC_LOG_DEBUG(("Authentication method is [%s]", + (auth_meth == SILC_AUTH_NONE ? "None" : + auth_meth == SILC_AUTH_PASSWORD ? "Passphrase" : + "Digital signatures"))); + /* Send it back to the client */ silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth); } diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index 2d41ebcc..8e947fd7 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -156,7 +156,7 @@ void silc_server_packet_send_dest(SilcServer server, if (idata && idata->status & SILC_IDLIST_STATUS_DISABLED) return; - SILC_LOG_DEBUG(("Sending packet, type %d", type)); + SILC_LOG_DEBUG(("Sending %s packet", silc_get_packet_name(type))); if (dst_id) { dst_id_data = silc_id_id2str(dst_id, dst_id_type); @@ -241,7 +241,7 @@ void silc_server_packet_send_srcdest(SilcServer server, SilcUInt32 src_id_len = 0; int block_len = 0; - SILC_LOG_DEBUG(("Sending packet, type %d", type)); + SILC_LOG_DEBUG(("Sending %s packet", silc_get_packet_name(type))); /* Get data used in the packet sending, keys and stuff */ idata = (SilcIDListData)sock->user_data; @@ -1651,7 +1651,7 @@ void silc_server_send_new_id(SilcServer server, { SilcBuffer idp; - SILC_LOG_DEBUG(("Start")); + SILC_LOG_DEBUG(("Sending new ID")); idp = silc_id_payload_encode(id, id_type); silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, @@ -1676,7 +1676,7 @@ void silc_server_send_new_channel(SilcServer server, unsigned char *cid; SilcUInt32 name_len = strlen(channel_name); - SILC_LOG_DEBUG(("Start")); + SILC_LOG_DEBUG(("Sending new channel")); cid = silc_id_id2str(channel_id, SILC_ID_CHANNEL); if (!cid) diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 4ec15a82..1cd96bbb 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -1929,8 +1929,6 @@ SILC_TASK_CALLBACK(silc_server_packet_parse_real) SilcIDListData idata = (SilcIDListData)sock->user_data; int ret; - SILC_LOG_DEBUG(("Parsing packet")); - /* Parse the packet */ if (parse_ctx->normal) ret = silc_packet_parse(packet, idata ? idata->receive_key : NULL); @@ -1944,8 +1942,10 @@ SILC_TASK_CALLBACK(silc_server_packet_parse_real) goto out; } - if (ret == SILC_PACKET_NONE) + if (ret == SILC_PACKET_NONE) { + SILC_LOG_DEBUG(("Error parsing packet")); goto out; + } /* Check that the the current client ID is same as in the client's packet. */ if (sock->type == SILC_SOCKET_TYPE_CLIENT) { @@ -1955,6 +1955,7 @@ SILC_TASK_CALLBACK(silc_server_packet_parse_real) packet->src_id_type); if (!id || !SILC_ID_CLIENT_COMPARE(client->id, id)) { silc_free(id); + SILC_LOG_DEBUG(("Packet source is not same as sender")); goto out; } silc_free(id); @@ -2079,6 +2080,9 @@ void silc_server_packet_parse_type(SilcServer server, SilcPacketType type = packet->type; SilcIDListData idata = (SilcIDListData)sock->user_data; + SILC_LOG_DEBUG(("Received %s packet [flags %d]", + silc_get_packet_name(type), packet->flags)); + /* Parse the packet type */ switch (type) { case SILC_PACKET_DISCONNECT: @@ -2086,8 +2090,6 @@ void silc_server_packet_parse_type(SilcServer server, SilcStatus status; char *message = NULL; - SILC_LOG_DEBUG(("Disconnect packet")); - if (packet->flags & SILC_PACKET_FLAG_LIST) break; if (packet->buffer->len < 1) @@ -2113,7 +2115,6 @@ void silc_server_packet_parse_type(SilcServer server, * one protocol for connection executing at once hence this * success message is for whatever protocol is executing currently. */ - SILC_LOG_DEBUG(("Success packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; if (sock->protocol) @@ -2126,7 +2127,6 @@ void silc_server_packet_parse_type(SilcServer server, * one protocol for connection executing at once hence this * failure message is for whatever protocol is executing currently. */ - SILC_LOG_DEBUG(("Failure packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; if (sock->protocol) { @@ -2143,7 +2143,6 @@ void silc_server_packet_parse_type(SilcServer server, break; case SILC_PACKET_REJECT: - SILC_LOG_DEBUG(("Reject packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; return; @@ -2154,7 +2153,6 @@ void silc_server_packet_parse_type(SilcServer server, * Received notify packet. Server can receive notify packets from * router. Server then relays the notify messages to clients if needed. */ - SILC_LOG_DEBUG(("Notify packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) silc_server_notify_list(server, sock, packet); else @@ -2170,7 +2168,6 @@ void silc_server_packet_parse_type(SilcServer server, * (although probably most common ones) thus they are handled * specially. */ - SILC_LOG_DEBUG(("Channel Message packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; idata->last_receive = time(NULL); @@ -2184,7 +2181,6 @@ void silc_server_packet_parse_type(SilcServer server, * locally connected clients on the particular channel. Router * never receives this channel and thus is ignored. */ - SILC_LOG_DEBUG(("Channel Key packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; silc_server_channel_key(server, sock, packet); @@ -2198,7 +2194,6 @@ void silc_server_packet_parse_type(SilcServer server, * Recived command. Processes the command request and allocates the * command context and calls the command. */ - SILC_LOG_DEBUG(("Command packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; silc_server_command_process(server, sock, packet); @@ -2210,7 +2205,6 @@ void silc_server_packet_parse_type(SilcServer server, * may be reply to command sent by us or reply to command sent by client * that we've routed further. */ - SILC_LOG_DEBUG(("Command Reply packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; silc_server_command_reply(server, sock, packet); @@ -2224,7 +2218,6 @@ void silc_server_packet_parse_type(SilcServer server, * Received private message packet. The packet is coming from either * client or server. */ - SILC_LOG_DEBUG(("Private Message packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; idata->last_receive = time(NULL); @@ -2244,7 +2237,6 @@ void silc_server_packet_parse_type(SilcServer server, * Key Exchange protocol packets */ case SILC_PACKET_KEY_EXCHANGE: - SILC_LOG_DEBUG(("KE packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; @@ -2264,7 +2256,6 @@ void silc_server_packet_parse_type(SilcServer server, break; case SILC_PACKET_KEY_EXCHANGE_1: - SILC_LOG_DEBUG(("KE 1 packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; @@ -2308,7 +2299,6 @@ void silc_server_packet_parse_type(SilcServer server, break; case SILC_PACKET_KEY_EXCHANGE_2: - SILC_LOG_DEBUG(("KE 2 packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; @@ -2358,7 +2348,6 @@ void silc_server_packet_parse_type(SilcServer server, * authentication method for the connection. This packet maybe received * at any time. */ - SILC_LOG_DEBUG(("Connection authentication request packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; silc_server_connection_auth_request(server, sock, packet); @@ -2370,7 +2359,6 @@ void silc_server_packet_parse_type(SilcServer server, case SILC_PACKET_CONNECTION_AUTH: /* Start of the authentication protocol. We receive here the authentication data and will verify it. */ - SILC_LOG_DEBUG(("Connection auth packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; @@ -2397,7 +2385,6 @@ void silc_server_packet_parse_type(SilcServer server, * to distribute information about new registered entities in the * SILC network. */ - SILC_LOG_DEBUG(("New ID packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) silc_server_new_id_list(server, sock, packet); else @@ -2410,7 +2397,6 @@ void silc_server_packet_parse_type(SilcServer server, * we will use to create initial client ID. After creating new * ID we will send it to the client. */ - SILC_LOG_DEBUG(("New Client packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; silc_server_new_client(server, sock, packet); @@ -2422,7 +2408,6 @@ void silc_server_packet_parse_type(SilcServer server, * information that we may save. This is received after server has * connected to us. */ - SILC_LOG_DEBUG(("New Server packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; silc_server_new_server(server, sock, packet); @@ -2433,7 +2418,6 @@ void silc_server_packet_parse_type(SilcServer server, * Received new channel packet. Information about new channel in the * network are distributed using this packet. */ - SILC_LOG_DEBUG(("New Channel packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) silc_server_new_channel_list(server, sock, packet); else @@ -2444,7 +2428,6 @@ void silc_server_packet_parse_type(SilcServer server, /* * Received heartbeat. */ - SILC_LOG_DEBUG(("Heartbeat packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; break; @@ -2453,7 +2436,6 @@ void silc_server_packet_parse_type(SilcServer server, /* * Received heartbeat. */ - SILC_LOG_DEBUG(("Key agreement packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; silc_server_key_agreement(server, sock, packet); @@ -2464,7 +2446,6 @@ void silc_server_packet_parse_type(SilcServer server, * Received re-key packet. The sender wants to regenerate the session * keys. */ - SILC_LOG_DEBUG(("Re-key packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; silc_server_rekey(server, sock, packet); @@ -2474,7 +2455,6 @@ void silc_server_packet_parse_type(SilcServer server, /* * The re-key is done. */ - SILC_LOG_DEBUG(("Re-key done packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; @@ -2499,7 +2479,6 @@ void silc_server_packet_parse_type(SilcServer server, case SILC_PACKET_FTP: /* FTP packet */ - SILC_LOG_DEBUG(("FTP packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; silc_server_ftp(server, sock, packet); @@ -2507,7 +2486,6 @@ void silc_server_packet_parse_type(SilcServer server, case SILC_PACKET_RESUME_CLIENT: /* Resume client */ - SILC_LOG_DEBUG(("Resume Client packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; silc_server_resume_client(server, sock, packet); @@ -2516,7 +2494,6 @@ void silc_server_packet_parse_type(SilcServer server, case SILC_PACKET_RESUME_ROUTER: /* Resume router packet received. This packet is received for backup router resuming protocol. */ - SILC_LOG_DEBUG(("Resume router packet")); if (packet->flags & SILC_PACKET_FLAG_LIST) break; silc_server_backup_resume_router(server, sock, packet); diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index c041ffb0..fbb0c7fd 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -1173,6 +1173,8 @@ void silc_server_send_connect_notifys(SilcServer server, { SilcIDListData idata = (SilcIDListData)client; + SILC_LOG_DEBUG(("Send welcome notifys")); + /* Send some nice info to the client */ SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE, ("Welcome to the SILC Network %s", @@ -1366,7 +1368,8 @@ bool silc_server_check_watcher_list(SilcServer server, unsigned char hash[16]; WatcherNotifyContext n; - SILC_LOG_DEBUG(("Start")); + SILC_LOG_DEBUG(("Checking watcher list %s", + client->nickname ? client->nickname : "")); /* If the watching is rejected by the client do nothing */ if (client->mode & SILC_UMODE_REJECT_WATCHING) diff --git a/apps/silcd/serverconfig.c b/apps/silcd/serverconfig.c index 177f5826..4c576383 100644 --- a/apps/silcd/serverconfig.c +++ b/apps/silcd/serverconfig.c @@ -122,9 +122,10 @@ static bool my_parse_authdata(SilcAuthMethod auth_meth, char *p, /* p is a plain text password */ if (auth_data && auth_data_len) { if (!silc_utf8_valid(p, strlen(p))) { - *auth_data_len = silc_utf8_encoded_len(p, strlen(p), 0); + *auth_data_len = silc_utf8_encoded_len(p, strlen(p), + SILC_STRING_LANGUAGE); *auth_data = silc_calloc(*auth_data_len, sizeof(unsigned char)); - silc_utf8_encode(p, strlen(p), SILC_STRING_ASCII, *auth_data, + silc_utf8_encode(p, strlen(p), SILC_STRING_LANGUAGE, *auth_data, *auth_data_len); } else { *auth_data = (void *) strdup(p); diff --git a/configure.in.pre b/configure.in.pre index 10d3d993..3c670af8 100644 --- a/configure.in.pre +++ b/configure.in.pre @@ -70,8 +70,8 @@ AC_CHECK_HEADERS(unistd.h string.h getopt.h errno.h fcntl.h assert.h) AC_CHECK_HEADERS(sys/types.h sys/stat.h sys/time.h stddef.h) AC_CHECK_HEADERS(netinet/in.h netinet/tcp.h xti.h netdb.h) AC_CHECK_HEADERS(pwd.h grp.h termcap.h paths.h) -AC_CHECK_HEADERS(ncurses.h signal.h ctype.h regex.h utime.h) -AC_CHECK_HEADERS(arpa/inet.h sys/mman.h limits.h termios.h) +AC_CHECK_HEADERS(ncurses.h signal.h ctype.h regex.h utime.h iconv.h) +AC_CHECK_HEADERS(arpa/inet.h sys/mman.h limits.h termios.h locale.h langinfo.h) # Data type checking AC_TYPE_SIGNAL @@ -293,8 +293,8 @@ AC_CHECK_FUNCS(fcntl setsockopt) AC_CHECK_FUNCS(getopt_long time) AC_CHECK_FUNCS(chmod stat fstat getenv putenv strerror ctime gettimeofday) AC_CHECK_FUNCS(getpid getgid getsid getpgid getpgrp getuid setgroups initgroups) -AC_CHECK_FUNCS(strchr strstr strcpy strncpy memcpy memset memmove utime) -AC_CHECK_FUNCS(pthread_create) +AC_CHECK_FUNCS(strchr strstr strcpy strncpy memcpy memset memmove utime iconv) +AC_CHECK_FUNCS(pthread_create nl_langinfo) # SIM support checking # XXX These needs to be changed as more supported platforms appear. diff --git a/includes/silcincludes.h b/includes/silcincludes.h index 8fe2ccfe..ca741639 100644 --- a/includes/silcincludes.h +++ b/includes/silcincludes.h @@ -201,6 +201,18 @@ extern "C" { #include #endif +#ifdef HAVE_ICONV_H +#include +#endif + +#ifdef HAVE_LOCALE_H +#include +#endif + +#ifdef HAVE_LANGINFO_H +#include +#endif + #endif /* !SILC_WIN32 */ #ifndef HAVE_GETOPT_LONG diff --git a/lib/doc/silcclient_using.html b/lib/doc/silcclient_using.html index d31a7f37..82cf3901 100644 --- a/lib/doc/silcclient_using.html +++ b/lib/doc/silcclient_using.html @@ -303,6 +303,86 @@ silc_client_connect_to_server function, but performed the connecting process manually. +
 
 
+Debugging + +
 
+Being able to debug what you have coded is important when troubles occurs +during coding, and they always do. SILC supports extensive debugging +capabilities which are also available for client library user. You should +have compiled the Toolkit with --enable-debug option so that run-time +debugging is enabled. + +
 
+To turn on the run-time debugging set the global variable "silc_debug" to +TRUE. To see packet hexdumps you can set also "silc_debug_hexdump" to TRUE. +Hexdumps can create more debug log so not setting it to TRUE by default is +probably best. To get debug messages out of specific modules you can set +a debug string with silc_log_set_debug_string function. The function takes +regex string as argument, for example: + +
 
+ +  silc_debug = TRUE;
+  silc_log_set_debug_string("*");
+
+ +
 
+This piece of code turns on the debugging and sets "*" as debug string. This +means that all debug messages are printed. To get debugging out of only +for example SILC Client Library the debug string could be "silc_client*". +The debug string matches to function names and filenames so it is possible +to get debugging out of specific files, and specific functions. Other +examples could be: + +
 
+ +  silc_log_set_debug_string("silc_client*,*socket*,*ske*");
+
+ +
 
+By default, all debug messages are printed to standard error output (stderr). +If you want to redirect the debug messages somewhere else you can set your +own debug callback with silc_log_set_debug_callbacks function: + +
 
+ +  silc_log_set_debug_callbacks(my_debug_callback, my_context, my_hexdump_callback, my_context);
+
+ +
 
+See the lib/silcutil/silclog.h for definition of the callbacks. See the +same file for other logging and debugging information. + +
 
+You can also use SILC debugging capabilities in your own application. To +produce debug messages you can use SILC_LOG_DEBUG and SILC_LOG_HEXDUMP +macros in your application. The SILC_LOG_DEBUG can print out normal debug +messages with variable argument list, for example: + +
 
+ +  SILC_LOG_DEBUG(("Start"));
+  SILC_LOG_DEBUG(("Packet length %d", packet_len));
+  SILC_LOG_DEBUG(("The remote is %s on %d", sock->ip, sock->port)); +
+ +
 
+The SILC_LOG_HEXDUMP macro can be used dump data which couldn't be printed +out otherwise, for example binary data. + +
 
+ +  SILC_LOG_HEXDUMP(("Packet"), packet->data, packet->len);
+  SILC_LOG_HEXDUMP(("Packet, size=%d", size), packet->data, packet->len); +
+ +
 
+Note that the variable arguments in SILC_LOG_HEXDUMP are before the second +last parenthesis, and the last two arguments are the data, and its length that +are hexdumped. + +
 
 
Example Client @@ -333,6 +413,8 @@ int main() silc_ask_passphrase, silc_failure, silc_key_agreement, + silc_ftp, + silc_detach }; SilcClient client; diff --git a/lib/silccore/silccommand.h b/lib/silccore/silccommand.h index e0357b72..3fbda03a 100644 --- a/lib/silccore/silccommand.h +++ b/lib/silccore/silccommand.h @@ -153,6 +153,8 @@ typedef unsigned char SilcCommand; #define SILC_COMMAND_SERVICE 27 /* Private range start */ +#define SILC_COMMAND_PRIVATE 200 + #define SILC_COMMAND_PRIV_CONNECT 200 #define SILC_COMMAND_PRIV_CLOSE 201 #define SILC_COMMAND_PRIV_SHUTDOWN 202 diff --git a/lib/silcutil/Makefile.am b/lib/silcutil/Makefile.am index eeea6a09..93979c86 100644 --- a/lib/silcutil/Makefile.am +++ b/lib/silcutil/Makefile.am @@ -37,10 +37,10 @@ endif if SILC_DIST_TOOLKIT SILC_DIST_SOURCE = stacktrace.c -SILC_DIST_HEADERS = stacktrace.h +SILC_DIST_HEADER = stacktrace.h else SILC_DIST_SOURCE = -SILC_DIST_HEADERS = +SILC_DIST_HEADER = endif noinst_LIBRARIES = libsilcutil.a @@ -62,7 +62,7 @@ libsilcutil_a_SOURCES = \ if SILC_DIST_TOOLKIT include_HEADERS = \ - $(SILC_DIST_SOURCE) \ + $(SILC_DIST_HEADER) \ silcbuffer.h \ silcbuffmt.h \ silcconfig.h \ diff --git a/lib/silcutil/silclog.h b/lib/silcutil/silclog.h index b91ab5cb..26a1ca85 100644 --- a/lib/silcutil/silclog.h +++ b/lib/silcutil/silclog.h @@ -221,8 +221,10 @@ extern DLLAPI bool silc_debug_hexdump; /* Macros */ #ifdef SILC_WIN32 +#ifndef __FUNCTION__ #define __FUNCTION__ "" #endif +#endif /****d* silcutil/SilcLogAPI/SILC_LOG_INFO * @@ -330,8 +332,11 @@ extern DLLAPI bool silc_debug_hexdump; __FUNCTION__, \ __LINE__, \ silc_format fmt) +#define SILC_NOT_IMPLEMENTED(string) \ + SILC_LOG_DEBUG(("*********** %s: NOT IMPLEMENTED YET", string)); #else #define SILC_LOG_DEBUG(fmt) +#define SILC_NOT_IMPLEMENTED(string) #endif /* SILC_DEBUG */ /***/ diff --git a/lib/silcutil/silcstrutil.c b/lib/silcutil/silcstrutil.c index 5e6a592b..0e2398ae 100644 --- a/lib/silcutil/silcstrutil.c +++ b/lib/silcutil/silcstrutil.c @@ -192,16 +192,62 @@ SilcUInt32 silc_utf8_encode(const unsigned char *bin, SilcUInt32 bin_len, return bin_len; } + if (bin_encoding == SILC_STRING_LANGUAGE) { +#if defined(HAVE_ICONV) && defined(HAVE_NL_LANGINFO) && defined(CODESET) + char *fromconv, *icp, *ocp; + iconv_t icd; + size_t inlen, outlen; + + setlocale(LC_CTYPE, ""); + fromconv = nl_langinfo(CODESET); + if (fromconv && strlen(fromconv)) { + icd = iconv_open("UTF-8", fromconv); + icp = (char *)bin; + ocp = (char *)utf8; + inlen = bin_len; + outlen = utf8_size; + if (icd != (iconv_t)-1 && + (iconv(icd, &icp, &inlen, &ocp, &outlen) != -1)) { + utf8_size -= outlen; + iconv_close(icd); + return utf8_size; + } else { + if (icd != (iconv_t)-1) + iconv_close(icd); + } + } +#endif + + /* Fallback to 8-bit ASCII */ + bin_encoding = SILC_STRING_ASCII; + } + for (i = 0; i < bin_len; i++) { switch (bin_encoding) { case SILC_STRING_ASCII: charval = bin[i]; break; case SILC_STRING_ASCII_ESC: + SILC_NOT_IMPLEMENTED("SILC_STRING_ASCII_ESC"); + return 0; break; case SILC_STRING_BMP: + SILC_GET16_MSB(charval, bin + i); + i += 1; + break; + case SILC_STRING_BMP_LSB: + SILC_GET16_LSB(charval, bin + i); + i += 1; break; case SILC_STRING_UNIVERSAL: + SILC_GET32_MSB(charval, bin + i); + i += 3; + break; + case SILC_STRING_UNIVERSAL_LSB: + SILC_GET32_LSB(charval, bin + i); + i += 3; + break; + case SILC_STRING_LANGUAGE: break; } @@ -290,6 +336,36 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, if (!utf8 || !utf8_len) return 0; + if (bin_encoding == SILC_STRING_LANGUAGE) { +#if defined(HAVE_ICONV) && defined(HAVE_NL_LANGINFO) && defined(CODESET) + char *toconv, *icp, *ocp; + iconv_t icd; + size_t inlen, outlen; + + setlocale(LC_CTYPE, ""); + toconv = nl_langinfo(CODESET); + if (toconv && strlen(toconv)) { + icd = iconv_open(toconv, "UTF-8"); + icp = (char *)utf8; + ocp = (char *)bin; + inlen = utf8_len; + outlen = bin_size; + if (icd != (iconv_t)-1 && + (iconv(icd, &icp, &inlen, &ocp, &outlen) != -1)) { + bin_size -= outlen; + iconv_close(icd); + return bin_size; + } else { + if (icd != (iconv_t)-1) + iconv_close(icd); + } + } +#endif + + /* Fallback to 8-bit ASCII */ + bin_encoding = SILC_STRING_ASCII; + } + for (i = 0; i < utf8_len; i++) { if ((utf8[i] & 0x80) == 0x00) { charval = utf8[i] & 0x7f; @@ -383,13 +459,26 @@ SilcUInt32 silc_utf8_decode(const unsigned char *utf8, SilcUInt32 utf8_len, enclen++; break; case SILC_STRING_ASCII_ESC: + SILC_NOT_IMPLEMENTED("SILC_STRING_ASCII_ESC"); return 0; break; case SILC_STRING_BMP: - return 0; + SILC_PUT16_MSB(charval, bin + enclen); + enclen += 2; + break; + case SILC_STRING_BMP_LSB: + SILC_PUT16_LSB(charval, bin + enclen); + enclen += 2; break; case SILC_STRING_UNIVERSAL: - return 0; + SILC_PUT32_MSB(charval, bin + enclen); + enclen += 4; + break; + case SILC_STRING_UNIVERSAL_LSB: + SILC_PUT32_LSB(charval, bin + enclen); + enclen += 4; + break; + case SILC_STRING_LANGUAGE: break; } } diff --git a/lib/silcutil/silcstrutil.h b/lib/silcutil/silcstrutil.h index e72b4d44..1f0608cf 100644 --- a/lib/silcutil/silcstrutil.h +++ b/lib/silcutil/silcstrutil.h @@ -88,12 +88,15 @@ unsigned char *silc_pem_decode(unsigned char *pem, SilcUInt32 pem_len, * SOURCE */ typedef enum { - SILC_STRING_ASCII = 0, /* Any 8 bit ASCII encoding (default) */ - - /* Rest are not implemented yet */ - SILC_STRING_ASCII_ESC = 1, /* 7 bit ASCII (>0x7f escaped) */ - SILC_STRING_BMP = 2, /* 16 bit, UCS-2, BMP, ISO/IEC 10646 */ - SILC_STRING_UNIVERSAL = 3, /* 32 bit, UCS-4, Universal, ISO/IEC 10646 */ + SILC_STRING_ASCII = 0, /* Any 8 bit ASCII encoding (default) */ + SILC_STRING_ASCII_ESC = 1, /* 7 bit ASCII (>0x7f escaped) */ + SILC_STRING_BMP = 2, /* 16 bit, UCS-2, BMP, ISO/IEC 10646 */ + SILC_STRING_BMP_LSB = 3, /* BMP, least significant byte first */ + SILC_STRING_UNIVERSAL = 4, /* 32 bit, UCS-4, Universal, ISO/IEC 10646 */ + SILC_STRING_UNIVERSAL_LSB = 5, /* Universal, least significant byte first */ + SILC_STRING_LANGUAGE = 6, /* Language and charset specific conversion + on those platforms that support iconv(). + Fallback is SILC_STRING_ASCII. */ } SilcStringEncoding; /***/ diff --git a/lib/silcutil/silcutil.c b/lib/silcutil/silcutil.c index bb10741b..bcfa80de 100644 --- a/lib/silcutil/silcutil.c +++ b/lib/silcutil/silcutil.c @@ -967,11 +967,11 @@ bool silc_get_mode_list(SilcBuffer mode_list, SilcUInt32 mode_list_count, /* Status message structure. Messages are defined below. */ typedef struct { SilcStatus status; - char *message; + const char *message; } SilcStatusMessage; #define STAT(x) SILC_STATUS_ERR_##x -const SilcStatusMessage silc_status_messages[] = { +static const SilcStatusMessage silc_status_messages[] = { { STAT(NO_SUCH_NICK), "There was no such nickname" }, { STAT(NO_SUCH_CHANNEL), "There was no such channel" }, @@ -1023,7 +1023,7 @@ const SilcStatusMessage silc_status_messages[] = { /* Returns status message string */ -char *silc_get_status_message(unsigned char status) +const char *silc_get_status_message(unsigned char status) { int i; @@ -1037,3 +1037,92 @@ char *silc_get_status_message(unsigned char status) return silc_status_messages[i].message; } + +static const char *packet_name[] = { + "NONE", + "DISCONNECT", + "SUCCESS", + "FAILURE", + "REJECT", + "NOTIFY", + "ERROR", + "CHANNEL MESSAGE", + "CHANNEL KEY", + "PRIVATE MESSAGE", + "PRIVATE MESSAGE KEY", + "COMMAND", + "COMMAND REPLY", + "KEY EXCHANGE", + "KEY EXCHANGE 1", + "KEY EXCHANGE 2", + "CONNECTION AUTH REQUEST", + "CONNECTION AUTH", + "NEW ID", + "NEW CLIENT", + "NEW SERVER", + "NEW CHANNEL", + "REKEY", + "REKEY_DONE", + "HEARTBEAT", + "KEY AGREEMENT", + "RESUME ROUTER", + "FTP", + "RESUME CLIENT", +}; + +/* Returns packet type name */ + +const char *silc_get_packet_name(unsigned char type) +{ + if (type >= SILC_PACKET_MAX) + return "RESERVED"; + if (type >= SILC_PACKET_PRIVATE) + return "PRIVATE RANGE"; + if (type > (sizeof(packet_name) / sizeof(*packet_name))) + return "UNKNOWN"; + return packet_name[type]; +} + +static const char *command_name[] = { + "NONE", + "WHOIS", + "WHOWAS", + "IDENTIFY", + "NICK", + "LIST", + "TOPIC", + "INVITE", + "QUIT", + "KILL", + "INFO", + "STATS", + "PING", + "OPER", + "JOIN", + "MOTD", + "UMODE", + "CMODE", + "CUMODE", + "KICK", + "BAN", + "DETACH", + "WATCH", + "SILCOPER", + "LEAVE", + "USERS", + "GETKEY", + "SERVICE", +}; + +/* Returns command name */ + +const char *silc_get_command_name(unsigned char command) +{ + if (command >= SILC_COMMAND_RESERVED) + return "RESERVED"; + if (command >= SILC_COMMAND_PRIVATE) + return "PRIVATE RANGE"; + if (command > (sizeof(command_name) / sizeof(*command_name))) + return "UNKNOWN"; + return command_name[command]; +} diff --git a/lib/silcutil/silcutil.h b/lib/silcutil/silcutil.h index 2c0230fc..d92ae48f 100644 --- a/lib/silcutil/silcutil.h +++ b/lib/silcutil/silcutil.h @@ -573,7 +573,6 @@ char *silc_get_real_name(); bool silc_get_mode_list(SilcBuffer mode_list, SilcUInt32 mode_list_count, SilcUInt32 **list); - /****f* silcutil/SilcUtilAPI/silc_get_status_message * * SYNOPSIS @@ -585,6 +584,32 @@ bool silc_get_mode_list(SilcBuffer mode_list, SilcUInt32 mode_list_count, * Returns status message string * ***/ -char *silc_get_status_message(unsigned char status); +const char *silc_get_status_message(unsigned char status); + +/****f* silcutil/SilcUtilAPI/silc_get_packet_name + * + * SYNOPSIS + * + * char *silc_get_packet_name(SilcPacketType type); + * + * DESCRIPTION + * + * Returns the name corresponding packet type `type'. + * + ***/ +const char *silc_get_packet_name(unsigned char type); + +/****f* silcutil/SilcUtilAPI/silc_get_command_name + * + * SYNOPSIS + * + * char *silc_get_packet_name(SilcCommand command); + * + * DESCRIPTION + * + * Returns the name corresponding SILC command `command'. + * + ***/ +const char *silc_get_command_name(unsigned char command); #endif /* !SILCUTIL_H */ -- 2.24.0