bool -> SilcBool.
[silc.git] / lib / silcutil / silcutil.c
index e903eb9f8f3b46916de66bbddeb72f850c57e5ba..b4472bebe38b2a018b7d80aa5a5b51c25b6fa773 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2003 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
    This doesn't remove the newline sign from the destination buffer. The
    argument begin is returned and should be passed again for the function. */
 
-int silc_gets(char *dest, int destlen, const char *src, int srclen,
-             int *begin)
+int silc_gets(char *dest, int destlen, const char *src, int srclen, int begin)
 {
-  int off = *begin;
+  static int start = 0;
   int i;
 
   memset(dest, 0, destlen);
 
+  if (begin != start)
+    start = 0;
+
   i = 0;
-  for ( ; off <= srclen; i++) {
+  for ( ; start <= srclen; i++, start++) {
     if (i > destlen)
       return -1;
 
-    dest[i] = src[off++];
+    dest[i] = src[start];
 
     if (dest[i] == EOF)
       return EOF;
@@ -49,11 +51,9 @@ int silc_gets(char *dest, int destlen, const char *src, int srclen,
     if (dest[i] == '\n')
       break;
   }
-  *begin = off;
-  if (off + 1 >= srclen)
-    return EOF;
+  start++;
 
-  return off;
+  return start;
 }
 
 /* Checks line for illegal characters. Return -1 when illegal character
@@ -99,7 +99,7 @@ const char *silc_get_time(SilcUInt32 timeval)
 
 /* Converts string to capital characters. */
 
-bool silc_to_upper(const char *string, char *dest, SilcUInt32 dest_size)
+SilcBool silc_to_upper(const char *string, char *dest, SilcUInt32 dest_size)
 {
   int i;
 
@@ -114,7 +114,7 @@ bool silc_to_upper(const char *string, char *dest, SilcUInt32 dest_size)
 
 /* Converts string to lower letter characters. */
 
-bool silc_to_lower(const char *string, char *dest, SilcUInt32 dest_size)
+SilcBool silc_to_lower(const char *string, char *dest, SilcUInt32 dest_size)
 {
   int i;
 
@@ -129,7 +129,7 @@ bool silc_to_lower(const char *string, char *dest, SilcUInt32 dest_size)
 
 /* Parse userfqdn string which is in user@fqdn format. */
 
-bool silc_parse_userfqdn(const char *string, char **left, char **right)
+SilcBool silc_parse_userfqdn(const char *string, char **left, char **right)
 {
   SilcUInt32 tlen;
 
@@ -156,7 +156,7 @@ bool silc_parse_userfqdn(const char *string, char **left, char **right)
     }
   } else {
     if (left)
-      *left = strdup(string);
+      *left = silc_memdup(string, strlen(string));
   }
 
   return TRUE;
@@ -467,25 +467,44 @@ SilcUInt32 silc_hash_string(void *key, void *user_context)
   return h;
 }
 
+/* Hash UTF-8 string */
+
+SilcUInt32 silc_hash_utf8_string(void *key, void *user_context)
+{
+  unsigned char *s = (unsigned char *)key;
+  SilcUInt32 h = 0, g;
+
+  while (*s != '\0') {
+    h = (h << 4) + *s;
+    if ((g = h & 0xf0000000)) {
+      h = h ^ (g >> 24);
+      h = h ^ g;
+    }
+    s++;
+  }
+
+  return h;
+}
+
 /* Basic hash function to hash integers. May be used with the SilcHashTable. */
 
 SilcUInt32 silc_hash_uint(void *key, void *user_context)
 {
-  return *(SilcUInt32 *)key;
+  return SILC_PTR_TO_32(key);
 }
 
 /* Basic hash funtion to hash pointers. May be used with the SilcHashTable. */
 
 SilcUInt32 silc_hash_ptr(void *key, void *user_context)
 {
-  return (SilcUInt32)key;
+  return SILC_PTR_TO_32(key);
 }
 
 /* Hash a ID. The `user_context' is the ID type. */
 
 SilcUInt32 silc_hash_id(void *key, void *user_context)
 {
-  SilcIdType id_type = (SilcIdType)(SilcUInt32)user_context;
+  SilcIdType id_type = (SilcIdType)SILC_PTR_TO_32(user_context);
   SilcUInt32 h = 0;
   int i;
 
@@ -553,7 +572,7 @@ SilcUInt32 silc_hash_client_id_hash(void *key, void *user_context)
 
 SilcUInt32 silc_hash_data(void *key, void *user_context)
 {
-  SilcUInt32 len = (SilcUInt32)user_context, h = 0;
+  SilcUInt32 len = SILC_PTR_TO_32(user_context), h = 0;
   unsigned char *data = (unsigned char *)key;
   int i;
 
@@ -569,15 +588,15 @@ SilcUInt32 silc_hash_data(void *key, void *user_context)
 SilcUInt32 silc_hash_public_key(void *key, void *user_context)
 {
   SilcPublicKey pk = (SilcPublicKey)key;
-  return (pk->len + silc_hash_string(pk->name, NULL) +
-         silc_hash_string(pk->identifier, NULL) +
-         silc_hash_data(pk->pk, (void *)pk->pk_len));
+  return (pk->len + (silc_hash_string(pk->name, NULL) ^
+                    silc_hash_string(pk->identifier, NULL) ^
+                    silc_hash_data(pk->pk, SILC_32_TO_PTR(pk->pk_len))));
 }
 
 /* Compares two strings. It may be used as SilcHashTable comparison
    function. */
 
-bool silc_hash_string_compare(void *key1, void *key2, void *user_context)
+SilcBool silc_hash_string_compare(void *key1, void *key2, void *user_context)
 {
   return !strcasecmp((char *)key1, (char *)key2);
 }
@@ -586,9 +605,9 @@ bool silc_hash_string_compare(void *key1, void *key2, void *user_context)
    The Client ID's compares only the hash of the Client ID not any other
    part of the Client ID. Other ID's are fully compared. */
 
-bool silc_hash_id_compare(void *key1, void *key2, void *user_context)
+SilcBool silc_hash_id_compare(void *key1, void *key2, void *user_context)
 {
-  SilcIdType id_type = (SilcIdType)(SilcUInt32)user_context;
+  SilcIdType id_type = (SilcIdType)SILC_PTR_TO_32(user_context);
   return (id_type == SILC_ID_CLIENT ?
          SILC_ID_COMPARE_HASH((SilcClientID *)key1, (SilcClientID *)key2) :
          SILC_ID_COMPARE_TYPE(key1, key2, id_type));
@@ -596,23 +615,34 @@ bool silc_hash_id_compare(void *key1, void *key2, void *user_context)
 
 /* Compare two Client ID's entirely and not just the hash from the ID. */
 
-bool silc_hash_client_id_compare(void *key1, void *key2, void *user_context)
+SilcBool silc_hash_client_id_compare(void *key1, void *key2, void *user_context)
 {
   return SILC_ID_COMPARE_TYPE(key1, key2, SILC_ID_CLIENT);
 }
 
 /* Compares binary data. May be used as SilcHashTable comparison function. */
 
-bool silc_hash_data_compare(void *key1, void *key2, void *user_context)
+SilcBool silc_hash_data_compare(void *key1, void *key2, void *user_context)
 {
-  SilcUInt32 len = (SilcUInt32)user_context;
+  SilcUInt32 len = SILC_PTR_TO_32(user_context);
   return !memcmp(key1, key2, len);
 }
 
+/* Compares UTF-8 string. */
+
+SilcBool silc_hash_utf8_compare(void *key1, void *key2, void *user_context)
+{
+  int l1 = strlen((char *)key1);
+  int l2 = strlen((char *)key2);
+  if (l1 > l2)
+    l2 = l1;
+  return !memcmp(key1, key2, l2);
+}
+
 /* Compares two SILC Public keys. It may be used as SilcHashTable
    comparison function. */
 
-bool silc_hash_public_key_compare(void *key1, void *key2, void *user_context)
+SilcBool silc_hash_public_key_compare(void *key1, void *key2, void *user_context)
 {
   return silc_pkcs_public_key_compare(key1, key2);
 }
@@ -652,6 +682,9 @@ char *silc_client_chmode(SilcUInt32 mode, const char *cipher, const char *hmac)
   if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
     strncat(string, "f", 1);
 
+  if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
+    strncat(string, "C", 1);
+
   if (mode & SILC_CHANNEL_MODE_SILENCE_USERS)
     strncat(string, "m", 1);
 
@@ -768,7 +801,7 @@ char *silc_fingerprint(const unsigned char *data, SilcUInt32 data_len)
 
 /* Return TRUE if the `data' is ASCII string. */
 
-bool silc_string_is_ascii(const unsigned char *data, SilcUInt32 data_len)
+SilcBool silc_string_is_ascii(const unsigned char *data, SilcUInt32 data_len)
 {
   int i;
 
@@ -782,7 +815,7 @@ bool silc_string_is_ascii(const unsigned char *data, SilcUInt32 data_len)
 
 /* Parses SILC protocol style version string. */
 
-bool silc_parse_version_string(const char *version,
+SilcBool silc_parse_version_string(const char *version,
                               SilcUInt32 *protocol_version,
                               char **protocol_version_string,
                               SilcUInt32 *software_version,
@@ -878,7 +911,7 @@ SilcUInt32 silc_version_to_num(const char *version)
 
 /* Displays input prompt on command line and takes input data from user */
 
-char *silc_get_input(const char *prompt, bool echo_off)
+char *silc_get_input(const char *prompt, SilcBool echo_off)
 {
 #ifdef SILC_UNIX
   int fd;
@@ -967,12 +1000,12 @@ char *silc_get_input(const char *prompt, bool echo_off)
 
 /* Return mode list */
 
-bool silc_get_mode_list(SilcBuffer mode_list, SilcUInt32 mode_list_count,
+SilcBool silc_get_mode_list(SilcBuffer mode_list, SilcUInt32 mode_list_count,
                        SilcUInt32 **list)
 {
   int i;
 
-  if (mode_list->len / 4 != mode_list_count)
+  if (silc_buffer_len(mode_list) / 4 != mode_list_count)
     return FALSE;
 
   *list = silc_calloc(mode_list_count, sizeof(**list));
@@ -1043,6 +1076,8 @@ static const SilcStatusMessage silc_status_messages[] = {
   { STAT(TIMEDOUT), "Service timed out" },
   { STAT(UNSUPPORTED_PUBLIC_KEY), "Unsupported public key type" },
   { STAT(OPERATION_ALLOWED), "Operation is not allowed" },
+  { STAT(BAD_SERVER), "Bad server name" },
+  { STAT(BAD_USERNAME), "Bad user name" },
 
   { 0, NULL }
 };
@@ -1155,7 +1190,7 @@ const char *silc_get_command_name(unsigned char command)
 
 /* Return TRUE if `smaller' is smaller than `bigger'. */
 
-bool silc_compare_timeval(struct timeval *smaller,
+SilcBool silc_compare_timeval(struct timeval *smaller,
                          struct timeval *bigger)
 {
   if ((smaller->tv_sec < bigger->tv_sec) ||