Use silc_str[n]casecmp instead of strcmp routines with
authorPekka Riikonen <priikone@silcnet.org>
Wed, 30 Mar 2005 20:19:31 +0000 (20:19 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Wed, 30 Mar 2005 20:19:31 +0000 (20:19 +0000)
identifier strings.
Convert nickname to UTF-8 in /mgs and /smsg.

CHANGES
apps/irssi/src/silc/core/silc-servers.c
lib/doc/silcclient_unicode.html [new file with mode: 0644]
lib/silcclient/DIRECTORY
lib/silcclient/client.c
lib/silcclient/client_keyagr.c
lib/silcclient/client_notify.c
lib/silcclient/command.c
lib/silcclient/idlist.c
lib/silcclient/silcclient.h

diff --git a/CHANGES b/CHANGES
index 11c5600ca4ce666997bb8a0aacfec050b19d3660..c543fa5b3568ee3177ef5fe0f98cfa5cc3ddf9f1 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,15 @@
+Wed Mar 30 22:16:35 EEST 2005  Pekka Riikonen <priikone@silcnet.org>
+
+       * Added silc_utf8_str[n]casecmp into lib/silcutil/silcutf8.[ch].
+
+       * Use silc_utf8_str[n]casecmp instead of strcmp routines
+         in library and in SILC Client when dealing with nicknames
+         and other identifier strings.  Affected file in client lib
+         and irssi.
+
+       * Convert nickname to UTF-8 in /msg and /smsg.  Affected file
+         irssi/src/silc/core/silc-servers.c.
+
 Wed Mar 30 10:50:02 EEST 2005  Pekka Riikonen <priikone@silcnet.org>
 
        * Fixed idcache to work with the new identifier strings.
index 2ba621c682a03a6b78aa9619fa7971f0625c8c51..476205d450e0cfcf3c00b81e9f4da307873bf1b2 100644 (file)
@@ -1,7 +1,7 @@
 /*
   silc-server.c : irssi
 
-  Copyright (C) 2000 - 2004 Timo Sirainen
+  Copyright (C) 2000 - 2005 Timo Sirainen
                             Pekka Riikonen <priikone@silcnet.org>
 
   This program is free software; you can redistribute it and/or modify
@@ -117,7 +117,7 @@ static void silc_send_msg_clients(SilcClient client,
        real (formatted) nickname and the nick (maybe formatted) that
        use gave. This is to assure that `nick' does not match
        `nick@host'. */
-    if (strcasecmp(rec->nick, clients[0]->nickname)) {
+    if (!silc_utf8_strcasecmp(rec->nick, clients[0]->nickname)) {
       printtext(NULL, NULL, MSGLEVEL_CLIENTERROR,
                "%s: There is no such client", rec->nick);
       goto out;
@@ -237,7 +237,7 @@ const char *get_nick_flags(void)
 static void send_message(SILC_SERVER_REC *server, char *target,
                         char *msg, int target_type)
 {
-  char *message = NULL;
+  char *message = NULL, *t = NULL;
   int len;
 
   g_return_if_fail(server != NULL);
@@ -254,12 +254,21 @@ static void send_message(SILC_SERVER_REC *server, char *target,
   if (target_type == SEND_TARGET_CHANNEL)
     silc_send_channel(server, target, message ? message : msg,
                      SILC_MESSAGE_FLAG_UTF8);
-  else
-    silc_send_msg(server, target, message ? message : msg,
+  else {
+    if (!silc_term_utf8()) {
+      len = silc_utf8_encoded_len(target, strlen(target), SILC_STRING_LOCALE);
+      t = silc_calloc(len + 1, sizeof(*t));
+      g_return_if_fail(t != NULL);
+      silc_utf8_encode(target, strlen(target), SILC_STRING_LOCALE, t, len);
+    }
+
+    silc_send_msg(server, t ? t : target, message ? message : msg,
                  message ? strlen(message) : strlen(msg),
                  SILC_MESSAGE_FLAG_UTF8);
+  }
 
   silc_free(message);
+  silc_free(t);
 }
 
 void silc_send_heartbeat(SilcSocketConnection sock,
@@ -537,7 +546,7 @@ static void command_smsg(const char *data, SILC_SERVER_REC *server,
   }
 
   if (target != NULL) {
-    char *message = NULL;
+    char *message = NULL, *t = NULL;
     int len, result;
 
     if (!silc_term_utf8()) {
@@ -551,12 +560,21 @@ static void command_smsg(const char *data, SILC_SERVER_REC *server,
       result = silc_send_channel(server, target, message ? message : msg,
                                 SILC_MESSAGE_FLAG_UTF8 |
                                 SILC_MESSAGE_FLAG_SIGNED);
-    else
-      result = silc_send_msg(server, target, message ? message : msg,
+    else {
+      if (!silc_term_utf8()) {
+       len = silc_utf8_encoded_len(target, strlen(target),
+                                   SILC_STRING_LOCALE);
+       t = silc_calloc(len + 1, sizeof(*t));
+       g_return_if_fail(t != NULL);
+       silc_utf8_encode(target, strlen(target), SILC_STRING_LOCALE, t, len);
+      }
+      result = silc_send_msg(server, t ? t : target, message ? message : msg,
                             message ? strlen(message) : strlen(msg),
                             SILC_MESSAGE_FLAG_UTF8 |
                             SILC_MESSAGE_FLAG_SIGNED);
+    }
     silc_free(message);
+    silc_free(t);
     if (!result)
       goto out;
   }
diff --git a/lib/doc/silcclient_unicode.html b/lib/doc/silcclient_unicode.html
new file mode 100644 (file)
index 0000000..3d6ec56
--- /dev/null
@@ -0,0 +1,40 @@
+<big><b>Unicode and UTF-8 Strings in Client Library</b></big>
+
+<br />&nbsp;<br />
+This document describes how the client library handles UTF-8 encoded
+strings.  By default all strings in the SILC protocol are UTF-8 encoded.
+All strings that are sent to server and strings that are received from the
+server are always UTF-8 encoded.  It is application's responsibility to
+render the strings as well as possible on the user interface.
+
+<br />&nbsp;<br />
+Exception to these strings are messages sent and received in
+<a href="silcmessage-SilcMessagePayload.html">Message Payload</a>, which
+can include practically any kind of strings with any kind of character
+encodings, and binary data also.  If UTF-8 encoded message is sent
+or received it is indicated with the SILC_MESSAGE_FLAG_UTF8, and
+application can render the messages accordingly.
+
+<br />&nbsp;<br />
+Other strings are always UTF-8 encoded and application needs to decode
+the strings to other character encoding if application does not support
+UTF-8 rendering on user interface.  Also strings application sends to
+library, such as, nicknames, channel names, server names, host names,
+topic srings, any command argument, etc. must always be UTF-8 encoded
+before they are sent to the library.  The <a href="silcutf8.h">UTF-8
+routines</a> help the application developer to encode and decode
+UTF-8 strings.
+
+<br />&nbsp;<br />
+The client library does not ever encode or decode strings to or from the
+current locale.  The library always expects that all strings it receives
+from application are already UTF-8 encoded.  The library may validate
+certain UTF-8 strings and return error if needed.  Server may also
+send errors in command reply if strings are not encoded properly.
+
+<br />&nbsp;<br />
+Nicknames and channel names in SILC are also UTF-8 encoded and can
+include practically any kind of letters, numbers and punctuation
+marks.  Control characters and other special characters are not allowed
+in nickname strings, and application never receives such nicknames
+or channel names from the library.
index d61bcfe7a4e4752daf2832585500ff9b88269244..a4fad88df39d8f60f23e4afd8314a82a9f1d6823 100644 (file)
@@ -5,6 +5,7 @@
 @LINK=command_reply_args.html:Arguments for <b>command_reply</b> Client Operation
 @LINK=silcstatus_args.html:SilcStatus Error Arguments in <b>command_reply</b> Client Operation
 @LINK=notifyargs.html:Arguments for <b>notify</b> Client Operation
+@LINK=silcclient_unicode.html:Unicode and UTF-8 Strings in Client Library
 @LINK=silcclient.html:Client Library Interface Reference
 -->
 
@@ -17,7 +18,7 @@
 <b>Introduction</b>
 
 <br /><br />
-SILC Client Library is SILC Client implementation without the actual user 
+SILC Client Library is SILC Client implementation without the actual user
 interface. The library uses common and core components of SILC protocol from
 lib/silccore library and normal utility routines from lib/silcutil library.
 The library has been designed to be complete SILC Client implementation
index a43a52afd1d0075ab5ddb5da70a8a0970e4c0f23..33a975496864aadfe251a29323790ece27454dd4 100644 (file)
@@ -120,6 +120,28 @@ bool silc_client_init(SilcClient client)
   assert(client->hostname);
   assert(client->realname);
 
+  /* Validate essential strings */
+  if (client->nickname)
+    if (!silc_identifier_verify(client->nickname, strlen(client->nickname),
+                               SILC_STRING_UTF8, 128)) {
+      SILC_LOG_ERROR(("Malformed nickname '%s'", client->nickname));
+      return FALSE;
+    }
+  if (!silc_identifier_verify(client->username, strlen(client->username),
+                             SILC_STRING_UTF8, 128)) {
+    SILC_LOG_ERROR(("Malformed username '%s'", client->username));
+    return FALSE;
+  }
+  if (!silc_identifier_verify(client->hostname, strlen(client->hostname),
+                             SILC_STRING_UTF8, 256)) {
+    SILC_LOG_ERROR(("Malformed hostname '%s'", client->hostname));
+    return FALSE;
+  }
+  if (!silc_utf8_valid(client->realname, strlen(client->realname))) {
+    SILC_LOG_ERROR(("Malformed realname '%s'", client->realname));
+    return FALSE;
+  }
+
   if (!client->internal->params->dont_register_crypto_library) {
     /* Initialize the crypto library.  If application has done this already
        this has no effect.  Also, we will not be overriding something
@@ -1786,7 +1808,8 @@ void silc_client_receive_new_id(SilcClient client,
     if (!conn->internal->params.detach_data) {
       /* Send NICK command if the nickname was set by the application (and is
         not same as the username). Send this with little timeout. */
-      if (client->nickname && strcmp(client->nickname, client->username))
+      if (client->nickname &&
+         !silc_utf8_strcasecmp(client->nickname, client->username))
        silc_schedule_task_add(client->schedule, 0,
                               silc_client_send_auto_nick, conn,
                               1, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
index 305c4b4bc7ef3c78ceee420f3f0845e2f7c9b1fb..8027bb3c93b5b0e6a17620b678d14962001bfe36 100644 (file)
@@ -2,15 +2,14 @@
 
   client_keyagr.c
 
-  Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+  Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2001 Pekka Riikonen
+  Copyright (C) 2001 - 2005 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
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
-  
+  the Free Software Foundation; version 2 of the License.
+
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@@ -21,7 +20,7 @@
 /* This file includes the Key Agreement packet processing and actual
    key agreement routines. This file has nothing to do with the actual
    connection key exchange protocol, it is implemented in the client.c
-   and in protocol.c. This file implements the client-to-client key 
+   and in protocol.c. This file implements the client-to-client key
    agreement as defined by the SILC protocol. */
 
 #include "silcincludes.h"
@@ -54,7 +53,7 @@ static void silc_client_key_agreement_send_packet(SilcSKE ske,
                                                  void *context)
 {
   SilcProtocol protocol = (SilcProtocol)context;
-  SilcClientKEInternalContext *ctx = 
+  SilcClientKEInternalContext *ctx =
     (SilcClientKEInternalContext *)protocol->context;
   void *tmp;
 
@@ -92,7 +91,7 @@ SILC_TASK_CALLBACK(silc_client_key_agreement_close)
 SILC_TASK_CALLBACK(silc_client_key_agreement_final)
 {
   SilcProtocol protocol = (SilcProtocol)context;
-  SilcClientKEInternalContext *ctx = 
+  SilcClientKEInternalContext *ctx =
     (SilcClientKEInternalContext *)protocol->context;
   SilcClient client = (SilcClient)ctx->client;
   SilcClientKeyAgreement ke = (SilcClientKeyAgreement)ctx->context;
@@ -103,7 +102,7 @@ SILC_TASK_CALLBACK(silc_client_key_agreement_final)
       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
     /* Error occured during protocol */
     ke->client_entry->ke = NULL;
-    ke->completion(ke->client, ke->conn, ke->client_entry, 
+    ke->completion(ke->client, ke->conn, ke->client_entry,
                   SILC_KEY_AGREEMENT_ERROR, NULL, ke->context);
     silc_ske_free_key_material(ctx->keymat);
     goto out;
@@ -112,7 +111,7 @@ SILC_TASK_CALLBACK(silc_client_key_agreement_final)
   /* Pass the negotiated key material to the application. The application
      is responsible of freeing the key material. */
   ke->client_entry->ke = NULL;
-  ke->completion(ke->client, ke->conn, ke->client_entry, 
+  ke->completion(ke->client, ke->conn, ke->client_entry,
                 SILC_KEY_AGREEMENT_OK, ctx->keymat, ke->context);
 
  out:
@@ -128,9 +127,9 @@ SILC_TASK_CALLBACK(silc_client_key_agreement_final)
     silc_schedule_task_del(client->schedule, ke->timeout);
   silc_client_del_socket(ke->client, ke->sock);
 
-  silc_schedule_task_add(client->schedule, 0, 
+  silc_schedule_task_add(client->schedule, 0,
                     silc_client_key_agreement_close,
-                    (void *)ke, 0, 1, 
+                    (void *)ke, 0, 1,
                     SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
 
   silc_free(ctx);
@@ -154,10 +153,10 @@ SILC_TASK_CALLBACK(silc_client_process_key_agreement)
   sock = silc_net_accept_connection(ke->fd);
   if (sock < 0) {
     client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
-                              "Could not accept key agreement connection: ", 
+                              "Could not accept key agreement connection: ",
                               strerror(errno));
     ke->client_entry->ke = NULL;
-    ke->completion(ke->client, ke->conn, ke->client_entry, 
+    ke->completion(ke->client, ke->conn, ke->client_entry,
                   SILC_KEY_AGREEMENT_ERROR, NULL, ke->context);
     silc_schedule_task_del_by_fd(client->schedule, ke->fd);
     silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
@@ -181,10 +180,10 @@ SILC_TASK_CALLBACK(silc_client_process_key_agreement)
   /* Perform name and address lookups for the remote host. */
   silc_net_check_host_by_sock(sock, &newsocket->hostname, &newsocket->ip);
   if (!newsocket->hostname && !newsocket->ip) {
-    client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT, 
+    client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
                               "Could not resolve the remote IP or hostname");
     ke->client_entry->ke = NULL;
-    ke->completion(ke->client, ke->conn, ke->client_entry, 
+    ke->completion(ke->client, ke->conn, ke->client_entry,
                   SILC_KEY_AGREEMENT_ERROR, NULL, ke->context);
     silc_schedule_task_del_by_fd(client->schedule, ke->fd);
     silc_schedule_unset_listen_fd(ke->client->schedule, ke->fd);
@@ -213,14 +212,14 @@ SILC_TASK_CALLBACK(silc_client_process_key_agreement)
 
   /* Prepare the connection for key exchange protocol. We allocate the
      protocol but will not start it yet. The connector will be the
-     initiator of the protocol thus we will wait for initiation from 
+     initiator of the protocol thus we will wait for initiation from
      there before we start the protocol. */
-  silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE, 
-                     &newsocket->protocol, proto_ctx, 
+  silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
+                     &newsocket->protocol, proto_ctx,
                      silc_client_key_agreement_final);
 
   /* Register the connection for network input and output. This sets
-     that scheduler will listen for incoming packets for this connection 
+     that scheduler will listen for incoming packets for this connection
      and sets that outgoing packets may be sent to this connection as well.
      However, this doesn't set the scheduler for outgoing traffic, it
      will be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
@@ -230,7 +229,7 @@ SILC_TASK_CALLBACK(silc_client_process_key_agreement)
 }
 
 /* Timeout occured during key agreement. This means that the key agreement
-   protocol was not completed in the specified timeout. We will call the 
+   protocol was not completed in the specified timeout. We will call the
    completion callback. */
 
 SILC_TASK_CALLBACK(silc_client_key_agreement_timeout)
@@ -238,7 +237,7 @@ SILC_TASK_CALLBACK(silc_client_key_agreement_timeout)
   SilcClientKeyAgreement ke = (SilcClientKeyAgreement)context;
 
   ke->client_entry->ke = NULL;
-  ke->completion(ke->client, ke->conn, ke->client_entry, 
+  ke->completion(ke->client, ke->conn, ke->client_entry,
                 SILC_KEY_AGREEMENT_TIMEOUT, NULL, ke->context);
 
   if (ke->sock) {
@@ -269,9 +268,9 @@ SILC_TASK_CALLBACK(silc_client_key_agreement_timeout)
    the same packet including its hostname and port. If the library receives
    the reply from the remote client the `key_agreement' client operation
    callback will be called to verify whether the user wants to perform the
-   key agreement or not. 
+   key agreement or not.
 
-   NOTE: If the application provided the `hostname' and the `port' and the 
+   NOTE: If the application provided the `hostname' and the `port' and the
    remote side initiates the key agreement protocol it is not verified
    from the user anymore whether the protocol should be executed or not.
    By setting the `hostname' and `port' the user gives permission to
@@ -282,7 +281,7 @@ SILC_TASK_CALLBACK(silc_client_key_agreement_timeout)
    perform the key agreement at all. If the key agreement protocol is
    performed the `completion' callback with the `context' will be called.
    If remote side decides to ignore the request the `completion' will be
-   called after the specified timeout, `timeout_secs'. 
+   called after the specified timeout, `timeout_secs'.
 
    NOTE: If the `hostname' and the `port' was not provided the `completion'
    will not be called at all since this does nothing more than sending
@@ -290,7 +289,7 @@ SILC_TASK_CALLBACK(silc_client_key_agreement_timeout)
 
    NOTE: There can be only one active key agreement for one client entry.
    Before setting new one, the old one must be finished (it is finished
-   after calling the completion callback) or the function 
+   after calling the completion callback) or the function
    silc_client_abort_key_agreement must be called. */
 
 void silc_client_send_key_agreement(SilcClient client,
@@ -325,10 +324,10 @@ void silc_client_send_key_agreement(SilcClient client,
   /* Create the listener if hostname and port was provided.
    * also, use bindhost if it was specified.
    */
-   
+
   if (hostname) {
     ke = silc_calloc(1, sizeof(*ke));
-    
+
     if (bindhost)
       ke->fd = silc_net_create_server(port, bindhost);
     else
@@ -336,8 +335,8 @@ void silc_client_send_key_agreement(SilcClient client,
 
     if (ke->fd < 0) {
       client->internal->ops->say(
-                    client, conn, SILC_CLIENT_MESSAGE_ERROR, 
-                    "Cannot create listener on %s on port %d: %s", 
+                    client, conn, SILC_CLIENT_MESSAGE_ERROR,
+                    "Cannot create listener on %s on port %d: %s",
                     (bindhost) ? bindhost:hostname, port, strerror(errno));
       completion(client, conn, client_entry, SILC_KEY_AGREEMENT_FAILURE,
                 NULL, context);
@@ -351,26 +350,26 @@ void silc_client_send_key_agreement(SilcClient client,
     ke->completion = completion;
     ke->context = context;
 
-    /* Add listener task to the scheduler. This task receives the key 
+    /* Add listener task to the scheduler. This task receives the key
        negotiations. */
     silc_schedule_task_add(client->schedule, ke->fd,
                           silc_client_process_key_agreement,
-                          (void *)ke, 0, 0, 
+                          (void *)ke, 0, 0,
                           SILC_TASK_FD,
                           SILC_TASK_PRI_NORMAL);
 
     /* Register a timeout task that will be executed if the connector
-       will not start the key exchange protocol within the specified 
+       will not start the key exchange protocol within the specified
        timeout. */
-    ke->timeout = silc_schedule_task_add(client->schedule, 0, 
+    ke->timeout = silc_schedule_task_add(client->schedule, 0,
                                         silc_client_key_agreement_timeout,
-                                        (void *)ke, timeout_secs, 0, 
+                                        (void *)ke, timeout_secs, 0,
                                         SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
   }
 
   /* Encode the key agreement payload */
-  buffer = silc_key_agreement_payload_encode(hostname, 
-                                            !ke ? port : 
+  buffer = silc_key_agreement_payload_encode(hostname,
+                                            !ke ? port :
                                             silc_net_get_local_port(ke->fd));
 
   /* Send the key agreement packet to the client */
@@ -380,7 +379,7 @@ void silc_client_send_key_agreement(SilcClient client,
   silc_buffer_free(buffer);
 }
 
-static int 
+static int
 silc_client_connect_to_client_internal(SilcClientInternalConnectContext *ctx)
 {
   int sock;
@@ -392,9 +391,9 @@ silc_client_connect_to_client_internal(SilcClientInternalConnectContext *ctx)
 
   /* Register task that will receive the async connect and will
      read the result. */
-  ctx->task = silc_schedule_task_add(ctx->client->schedule, sock, 
+  ctx->task = silc_schedule_task_add(ctx->client->schedule, sock,
                                     silc_client_perform_key_agreement_start,
-                                    (void *)ctx, 0, 0, 
+                                    (void *)ctx, 0, 0,
                                     SILC_TASK_FD,
                                     SILC_TASK_PRI_NORMAL);
   silc_schedule_set_listen_fd(ctx->client->schedule, sock, SILC_TASK_WRITE,
@@ -409,7 +408,7 @@ silc_client_connect_to_client_internal(SilcClientInternalConnectContext *ctx)
    to the remote client on specified port. */
 
 static int
-silc_client_connect_to_client(SilcClient client, 
+silc_client_connect_to_client(SilcClient client,
                              SilcClientConnection conn, int port,
                              char *host, void *context)
 {
@@ -451,8 +450,8 @@ SILC_TASK_CALLBACK(silc_client_perform_key_agreement_start)
       client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_ERROR,
                                 "Could not connect to client %s: %s",
                                 ctx->host, strerror(opt));
-      client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT, 
-                                "Connecting to port %d of client %s resumed", 
+      client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
+                                "Connecting to port %d of client %s resumed",
                                 ctx->port, ctx->host);
 
       /* Unregister old connection try */
@@ -475,7 +474,7 @@ SILC_TASK_CALLBACK(silc_client_perform_key_agreement_start)
       silc_free(ctx);
 
       /* Call the completion callback */
-      ke->completion(ke->client, ke->conn, ke->client_entry, 
+      ke->completion(ke->client, ke->conn, ke->client_entry,
                     SILC_KEY_AGREEMENT_FAILURE, NULL, ke->context);
       silc_free(ke);
     }
@@ -504,7 +503,7 @@ SILC_TASK_CALLBACK(silc_client_perform_key_agreement_start)
    The `hostname' is the remote hostname (or IP address) and the `port'
    is the remote port. The `completion' callback with the `context' will
    be called after the key agreement protocol.
-   
+
    NOTE: If the application returns TRUE in the `key_agreement' client
    operation the library will automatically start the key agreement. In this
    case the application must not call this function. However, application
@@ -560,8 +559,8 @@ void silc_client_perform_key_agreement(SilcClient client,
   }
 }
 
-/* Same as above but application has created already the connection to 
-   the remote host. The `sock' is the socket to the remote connection. 
+/* Same as above but application has created already the connection to
+   the remote host. The `sock' is the socket to the remote connection.
    Application can use this function if it does not want the client library
    to create the connection. */
 
@@ -615,15 +614,15 @@ void silc_client_perform_key_agreement_fd(SilcClient client,
   ke->proto_ctx = proto_ctx;
 
   /* Perform key exchange protocol. */
-  silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE, 
+  silc_protocol_alloc(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
                      &protocol, (void *)proto_ctx,
                      silc_client_key_agreement_final);
   ke->sock->protocol = protocol;
 
   /* Register the connection for network input and output. This sets
-     that scheduler will listen for incoming packets for this connection 
+     that scheduler will listen for incoming packets for this connection
      and sets that outgoing packets may be sent to this connection as well.
-     However, this doesn't set the scheduler for outgoing traffic, it will 
+     However, this doesn't set the scheduler for outgoing traffic, it will
      be set separately by calling SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT,
      later when outgoing data is available. */
   context = (void *)client;
@@ -634,10 +633,10 @@ void silc_client_perform_key_agreement_fd(SilcClient client,
 }
 
 /* This function can be called to unbind the hostname and the port for
-   the key agreement protocol. However, this function has effect only 
+   the key agreement protocol. However, this function has effect only
    before the key agreement protocol has been performed. After it has
-   been performed the library will automatically unbind the port. The 
-   `client_entry' is the client to which we sent the key agreement 
+   been performed the library will automatically unbind the port. The
+   `client_entry' is the client to which we sent the key agreement
    request. */
 
 void silc_client_abort_key_agreement(SilcClient client,
@@ -656,21 +655,21 @@ void silc_client_abort_key_agreement(SilcClient client,
     }
     silc_schedule_task_del_by_fd(client->schedule, client_entry->ke->fd);
     if (client_entry->ke->timeout)
-      silc_schedule_task_del(client->schedule, 
+      silc_schedule_task_del(client->schedule,
                             client_entry->ke->timeout);
     ke = client_entry->ke;
     client_entry->ke = NULL;
-    ke->completion(client, conn, client_entry, 
+    ke->completion(client, conn, client_entry,
                   SILC_KEY_AGREEMENT_ABORTED, NULL, ke->context);
     silc_free(ke);
   }
 }
 
-/* Callback function that is called after we've resolved the client 
+/* Callback function that is called after we've resolved the client
    information who sent us the key agreement packet from the server.
    We actually call the key_agreement client operation now. */
 
-static void 
+static void
 silc_client_key_agreement_resolve_cb(SilcClient client,
                                     SilcClientConnection conn,
                                     SilcClientEntry *clients,
@@ -694,7 +693,7 @@ silc_client_key_agreement_resolve_cb(SilcClient client,
 
   /* Call the key_agreement client operation */
   ret = client->internal->ops->key_agreement(
-                                  client, conn, clients[0], 
+                                  client, conn, clients[0],
                                   silc_key_agreement_get_hostname(payload),
                                   silc_key_agreement_get_port(payload),
                                   &completion, &completion_context);
@@ -715,7 +714,7 @@ silc_client_key_agreement_resolve_cb(SilcClient client,
 
 /* Received Key Agreement packet from remote client. Process the packet
    and resolve the client information from the server before actually
-   letting the application know that we've received this packet.  Then 
+   letting the application know that we've received this packet.  Then
    call the key_agreement client operation and let the user decide
    whether we perform the key agreement protocol now or not. */
 
@@ -728,7 +727,7 @@ void silc_client_key_agreement(SilcClient client,
   if (packet->src_id_type != SILC_ID_CLIENT)
     return;
 
-  remote_id = silc_id_str2id(packet->src_id, packet->src_id_len, 
+  remote_id = silc_id_str2id(packet->src_id, packet->src_id_len,
                             SILC_ID_CLIENT);
   if (!remote_id)
     return;
index cd4fea9d921c6719754f3abc4a5cf851bcc0b4ee..a56d4b8b54702cb72154da9cc80527c61d39898c 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2004 Pekka Riikonen
+  Copyright (C) 1997 - 2005 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
@@ -632,7 +632,7 @@ void silc_client_notify_by_server(SilcClient client,
        ID changes.  Check whether the hashes in the Client ID match, if
        they do nickname didn't change. */
     if (SILC_ID_COMPARE_HASH(client_entry->id, client_id) &&
-       !strcmp(tmp, client_entry->nickname)) {
+       silc_utf8_strcasecmp(tmp, client_entry->nickname)) {
       /* Nickname didn't change.  Update only Client ID. */
       silc_idcache_del_by_context(conn->internal->client_cache,
                                  client_entry);
@@ -1411,7 +1411,7 @@ void silc_client_notify_by_server(SilcClient client,
 
        /* If same nick, the client was new to us and has become "present"
           to network.  Send NULL as nick to application. */
-       if (tmp_nick && !strcmp(tmp, tmp_nick))
+       if (tmp_nick && silc_utf8_strcasecmp(tmp, tmp_nick))
          tmp = NULL;
 
        silc_free(tmp_nick);
index b40908faa60078eb932de3fa500502ef7305cd4d..a7f59aba217b56b2e92501b1855885e396b933c8 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2004 Pekka Riikonen
+  Copyright (C) 1997 - 2005 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
@@ -505,7 +505,7 @@ SILC_CLIENT_CMD_FUNC(nick)
     goto out;
   }
 
-  if (!strcmp(conn->nickname, cmd->argv[1]))
+  if (silc_utf8_strcasecmp(conn->nickname, cmd->argv[1]))
     goto out;
 
   /* Show current nickname */
index c6dbd425db380ecda3f7da15a70d6358bf6179ae..8b69f6d48c7626bb1df9aeea323cac2e84ba7616 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2001 - 2004 Pekka Riikonen
+  Copyright (C) 2001 - 2005 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
@@ -80,7 +80,7 @@ SilcClientEntry *silc_client_get_clients_local(SilcClient client,
     silc_idcache_list_first(list, &id_cache);
     while (id_cache) {
       entry = (SilcClientEntry)id_cache->context;
-      if (strcasecmp(entry->nickname, format)) {
+      if (!silc_utf8_strcasecmp(entry->nickname, format)) {
        if (!silc_idcache_list_next(list, &id_cache)) {
          break;
        } else {
@@ -422,7 +422,7 @@ SilcClientEntry silc_idlist_get_client(SilcClient client,
     while (id_cache) {
       entry = (SilcClientEntry)id_cache->context;
 
-      if (strcasecmp(entry->nickname, format)) {
+      if (!silc_utf8_strcasecmp(entry->nickname, format)) {
        if (!silc_idcache_list_next(list, &id_cache)) {
          entry = NULL;
          break;
@@ -1465,8 +1465,9 @@ void silc_client_update_server(SilcClient client,
 {
   SILC_LOG_DEBUG(("Start"));
 
-  if (server_name && (!server_entry->server_name ||
-                     strcmp(server_entry->server_name, server_name))) {
+  if (server_name &&
+      (!server_entry->server_name ||
+       !silc_utf8_strcasecmp(server_entry->server_name, server_name))) {
 
     silc_idcache_del_by_context(conn->internal->server_cache, server_entry);
     silc_free(server_entry->server_name);
@@ -1476,8 +1477,9 @@ void silc_client_update_server(SilcClient client,
                     server_entry, 0, NULL);
   }
 
-  if (server_info && (!server_entry->server_info ||
-                     strcmp(server_entry->server_info, server_info))) {
+  if (server_info &&
+      (!server_entry->server_info ||
+       !silc_utf8_strcasecmp(server_entry->server_info, server_info))) {
     silc_free(server_entry->server_info);
     server_entry->server_info = strdup(server_info);
   }
@@ -1523,7 +1525,7 @@ void silc_client_nickname_format(SilcClient client,
     if (clients[i]->valid && clients[i] != client_entry)
       len++;
     if (clients[i]->valid && clients[i] != client_entry &&
-       !strcasecmp(clients[i]->nickname, client_entry->nickname))
+       silc_utf8_strcasecmp(clients[i]->nickname, client_entry->nickname))
       freebase = FALSE;
   }
   if (!len || freebase)
@@ -1533,8 +1535,8 @@ void silc_client_nickname_format(SilcClient client,
     unformatted = clients[0];
   else
     for (i = 0; i < clients_count; i++)
-      if (!strncasecmp(clients[i]->nickname, client_entry->nickname,
-                      strlen(clients[i]->nickname)))
+      if (silc_utf8_strncasecmp(clients[i]->nickname, client_entry->nickname,
+                               strlen(clients[i]->nickname)))
        unformatted = clients[i];
 
   /* If we are changing nickname of our local entry we'll enforce
@@ -1609,7 +1611,7 @@ void silc_client_nickname_format(SilcClient client,
          break;
 
        for (i = 0; i < clients_count; i++) {
-         if (strncasecmp(clients[i]->nickname, newnick, off))
+         if (!silc_utf8_strncasecmp(clients[i]->nickname, newnick, off))
            continue;
          if (strlen(clients[i]->nickname) <= off)
            continue;
index 8a02c2a6ea9e6a118163639b4bfae6ff40a2fa6f..a819389688367d837a29aa6e1aae473d964a72de 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2000 - 2004 Pekka Riikonen
+  Copyright (C) 2000 - 2005 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
@@ -73,7 +73,8 @@ extern "C" {
  */
 struct SilcClientStruct {
   /*
-   * The following fields are set by application
+   * The following fields are set by application. Strings MUST be UTF-8
+   * encoded strings.
    */
   char *nickname;               /* Nickname, MAY be set by application  */
   char *username;               /* Username, MUST be set by application */
@@ -123,7 +124,7 @@ struct SilcClientStruct {
  *    to server this is context is returned to the application in the
  *    "connected" client operation.  It includes all the important
  *    data for the session, such as nickname, local and remote IDs, and
- *    other information.
+ *    other information.  All strings in the structure are UTF-8 encoded.
  *
  * SOURCE
  */
@@ -140,7 +141,7 @@ struct SilcClientConnectionStruct {
   /*
    * Remote data
    */
-  char *remote_host;             /* Remote host name */
+  char *remote_host;             /* Remote host name, UTF-8 encoded */
   int remote_port;               /* Remote port */
   SilcServerID *remote_id;       /* Remote Server ID */
   unsigned char *remote_id_data;  /* Remote Server ID decoded */
@@ -190,7 +191,7 @@ struct SilcClientConnectionStruct {
  *    that are accessed using the Client Library routines will have their
  *    own SilcClientEntry structure.  For example, when finding users by
  *    their nickname the Client Library returns this structure back to
- *    the application.
+ *    the application.  All strings in the structure are UTF-8 encoded.
  *
  * SOURCE
  */
@@ -246,7 +247,7 @@ struct SilcClientEntryStruct {
  *    This structure represents a channel in the SILC network.  All
  *    channels that the client are aware of or have joined in will be
  *    represented as SilcChannelEntry.  The structure includes information
- *    about the channel.
+ *    about the channel.  All strings in the structure are UTF-8 encoded.
  *
  * SOURCE
  */
@@ -320,6 +321,7 @@ struct SilcChannelUserStruct {
  *    This structure represents a server in the SILC network.  All servers
  *    that the client is aware of and have for example resolved with
  *    SILC_COMMAND_INFO command have their on SilcServerEntry structure.
+ *    All strings in the structure are UTF-8 encoded.
  *
  * SOURCE
  */
@@ -850,8 +852,8 @@ typedef struct {
      not want to use them set this to TRUE.  See SilcAttribute and
      silc_client_attribute_add for more information on attributes. */
   bool ignore_requested_attributes;
-  
-  /* If this is set to TRUE, the silcclient library will not register and 
+
+  /* If this is set to TRUE, the silcclient library will not register and
      deregister the cipher, pkcs, hash and hmac algorithms. The application
      itself will need to handle that. */
   bool dont_register_crypto_library;