improved server debug output. For rest, see CHANGES.
+Thu Jun 20 13:48:15 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
+
+ * 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 <priikone@silcnet.org>
* Save the channel passphrase when received succesful JOIN
TODO/bugs in Irssi SILC client
==============================
+ o Do UTF-8 decoding on non-utf terminals with iconv() if available.
+
o Testing
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).
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 ? "[<unknown>]" : nick->nick,
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 : "[<unknown>]",
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 */
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 */
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 */
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)
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); \
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); \
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);
}
/* 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);
}
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();
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);
/* 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 */
unsigned char *fkey = NULL;
SilcUInt32 fkey_len = 0;
- SILC_LOG_DEBUG(("Start"));
+ SILC_LOG_DEBUG(("Joining client to channel"));
if (!channel)
return;
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);
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,
SilcUInt32 name_len;
unsigned char *id;
SilcUInt32 id_len;
- SilcUInt32 mode;
SilcServerEntry server_entry;
SilcChannelEntry channel;
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,
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);
}
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);
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;
{
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,
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)
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);
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) {
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);
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:
SilcStatus status;
char *message = NULL;
- SILC_LOG_DEBUG(("Disconnect packet"));
-
if (packet->flags & SILC_PACKET_FLAG_LIST)
break;
if (packet->buffer->len < 1)
* 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)
* 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) {
break;
case SILC_PACKET_REJECT:
- SILC_LOG_DEBUG(("Reject packet"));
if (packet->flags & SILC_PACKET_FLAG_LIST)
break;
return;
* 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
* (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);
* 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);
* 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);
* 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);
* 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);
* Key Exchange protocol packets
*/
case SILC_PACKET_KEY_EXCHANGE:
- SILC_LOG_DEBUG(("KE packet"));
if (packet->flags & SILC_PACKET_FLAG_LIST)
break;
break;
case SILC_PACKET_KEY_EXCHANGE_1:
- SILC_LOG_DEBUG(("KE 1 packet"));
if (packet->flags & SILC_PACKET_FLAG_LIST)
break;
break;
case SILC_PACKET_KEY_EXCHANGE_2:
- SILC_LOG_DEBUG(("KE 2 packet"));
if (packet->flags & SILC_PACKET_FLAG_LIST)
break;
* 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);
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;
* 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
* 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);
* 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);
* 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
/*
* Received heartbeat.
*/
- SILC_LOG_DEBUG(("Heartbeat packet"));
if (packet->flags & SILC_PACKET_FLAG_LIST)
break;
break;
/*
* Received heartbeat.
*/
- SILC_LOG_DEBUG(("Key agreement packet"));
if (packet->flags & SILC_PACKET_FLAG_LIST)
break;
silc_server_key_agreement(server, sock, packet);
* 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);
/*
* The re-key is done.
*/
- SILC_LOG_DEBUG(("Re-key done packet"));
if (packet->flags & SILC_PACKET_FLAG_LIST)
break;
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);
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);
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);
{
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",
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)
/* 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);
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
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.
#include <utime.h>
#endif
+#ifdef HAVE_ICONV_H
+#include <iconv.h>
+#endif
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
+
#endif /* !SILC_WIN32 */
#ifndef HAVE_GETOPT_LONG
process manually.
+<br /> <br /> <br />
+<b>Debugging</b>
+
+<br /> <br />
+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.
+
+<br /> <br />
+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:
+
+<br /> <br />
+<tt>
+ silc_debug = TRUE;<br />
+ silc_log_set_debug_string("*");<br />
+</tt>
+
+<br /> <br />
+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:
+
+<br /> <br />
+<tt>
+ silc_log_set_debug_string("silc_client*,*socket*,*ske*");<br />
+</tt>
+
+<br /> <br />
+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:
+
+<br /> <br />
+<tt>
+ silc_log_set_debug_callbacks(my_debug_callback, my_context, my_hexdump_callback, my_context);<br />
+</tt>
+
+<br /> <br />
+See the lib/silcutil/silclog.h for definition of the callbacks. See the
+same file for other logging and debugging information.
+
+<br /> <br />
+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:
+
+<br /> <br />
+<tt>
+ SILC_LOG_DEBUG(("Start"));<br />
+ SILC_LOG_DEBUG(("Packet length %d", packet_len));<br />
+ SILC_LOG_DEBUG(("The remote is %s on %d", sock->ip, sock->port));
+</tt>
+
+<br /> <br />
+The SILC_LOG_HEXDUMP macro can be used dump data which couldn't be printed
+out otherwise, for example binary data.
+
+<br /> <br />
+<tt>
+ SILC_LOG_HEXDUMP(("Packet"), packet->data, packet->len);<br />
+ SILC_LOG_HEXDUMP(("Packet, size=%d", size), packet->data, packet->len);
+</tt>
+
+<br /> <br />
+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.
+
+
<br /> <br /> <br />
<b>Example Client</b>
silc_ask_passphrase,
silc_failure,
silc_key_agreement,
+ silc_ftp,
+ silc_detach
};
SilcClient client;
#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
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
if SILC_DIST_TOOLKIT
include_HEADERS = \
- $(SILC_DIST_SOURCE) \
+ $(SILC_DIST_HEADER) \
silcbuffer.h \
silcbuffmt.h \
silcconfig.h \
/* Macros */
#ifdef SILC_WIN32
+#ifndef __FUNCTION__
#define __FUNCTION__ ""
#endif
+#endif
/****d* silcutil/SilcLogAPI/SILC_LOG_INFO
*
__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 */
/***/
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;
}
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;
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;
}
}
* 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;
/***/
/* 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" },
/* Returns status message string */
-char *silc_get_status_message(unsigned char status)
+const char *silc_get_status_message(unsigned char status)
{
int i;
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];
+}
bool silc_get_mode_list(SilcBuffer mode_list, SilcUInt32 mode_list_count,
SilcUInt32 **list);
-
/****f* silcutil/SilcUtilAPI/silc_get_status_message
*
* SYNOPSIS
* 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 */