Moved generic string and data hashing and comparison functions
[silc.git] / lib / silcutil / silcutil.c
index 0333e6302e2cb9fe545d4bad226490d1edc997de..eb0d989e835791fd78d5e2514e1a2709cd8a3c47 100644 (file)
@@ -40,13 +40,17 @@ int silc_gets(char *dest, int destlen, const char *src, int srclen, int begin)
 
   i = 0;
   for ( ; start <= srclen; i++, start++) {
-    if (i > destlen)
+    if (i > destlen) {
+      silc_set_errno(SILC_ERR_OVERFLOW);
       return -1;
+    }
 
     dest[i] = src[start];
 
-    if (dest[i] == EOF)
+    if (dest[i] == EOF) {
+      silc_set_errno(SILC_ERR_EOF);
       return EOF;
+    }
 
     if (dest[i] == '\n')
       break;
@@ -56,36 +60,16 @@ int silc_gets(char *dest, int destlen, const char *src, int srclen, int begin)
   return start;
 }
 
-/* Checks line for illegal characters. Return -1 when illegal character
-   were found. This is used to check for bad lines when reading data from
-   for example a configuration file. */
-
-int silc_check_line(char *buf)
-{
-  /* Illegal characters in line */
-  if (strchr(buf, '#')) return -1;
-  if (strchr(buf, '\'')) return -1;
-  if (strchr(buf, '\\')) return -1;
-  if (strchr(buf, '\r')) return -1;
-  if (strchr(buf, '\a')) return -1;
-  if (strchr(buf, '\b')) return -1;
-  if (strchr(buf, '\f')) return -1;
-
-  /* Empty line */
-  if (buf[0] == '\n')
-    return -1;
-
-  return 0;
-}
-
 /* Converts string to capital characters. */
 
 SilcBool silc_to_upper(const char *string, char *dest, SilcUInt32 dest_size)
 {
   int i;
 
-  if (strlen(string) > dest_size)
+  if (strlen(string) > dest_size) {
+    silc_set_errno(SILC_ERR_OVERFLOW);
     return FALSE;
+  }
 
   for (i = 0; i < strlen(string); i++)
     dest[i] = (char)toupper((int)string[i]);
@@ -99,8 +83,10 @@ SilcBool silc_to_lower(const char *string, char *dest, SilcUInt32 dest_size)
 {
   int i;
 
-  if (strlen(string) > dest_size)
+  if (strlen(string) > dest_size) {
+    silc_set_errno(SILC_ERR_OVERFLOW);
     return FALSE;
+  }
 
   for (i = 0; i < strlen(string); i++)
     dest[i] = (char)tolower((int)string[i]);
@@ -116,14 +102,18 @@ int silc_parse_userfqdn(const char *string,
 {
   SilcUInt32 tlen;
 
-  if (!user && !fqdn)
+  if (!user && !fqdn) {
+    silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
     return 0;
+  }
 
   memset(user, 0, user_size);
   memset(fqdn, 0, fqdn_size);
 
-  if (!string)
+  if (!string) {
+    silc_set_errno(SILC_ERR_INVALID_ARGUMENT);
     return 0;
+  }
 
   if (string[0] == '@') {
     if (user)
@@ -165,7 +155,7 @@ void silc_parse_command_line(unsigned char *buffer,
 {
   int i, len = 0;
   int argc = 0;
-  const char *cp = buffer;
+  const char *cp = (const char *)buffer;
   char *tmp;
 
   *parsed = silc_calloc(1, sizeof(**parsed));
@@ -239,62 +229,7 @@ char *silc_format(char *fmt, ...)
   silc_vsnprintf(buf, sizeof(buf) - 1, fmt, args);
   va_end(args);
 
-  return strdup(buf);
-}
-
-/* Basic has function to hash strings. May be used with the SilcHashTable.
-   Note that this lowers the characters of the string (with tolower()) so
-   this is used usually with nicknames, channel and server names to provide
-   case insensitive keys. */
-
-SilcUInt32 silc_hash_string(void *key, void *user_context)
-{
-  char *s = (char *)key;
-  SilcUInt32 h = 0, g;
-
-  while (*s != '\0') {
-    h = (h << 4) + tolower((int)*s);
-    if ((g = h & 0xf0000000)) {
-      h = h ^ (g >> 24);
-      h = h ^ g;
-    }
-    s++;
-  }
-
-  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 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 SILC_PTR_TO_32(key);
+  return silc_strdup(buf);
 }
 
 /* Hash a ID. The `user_context' is the ID type. */
@@ -365,29 +300,6 @@ SilcUInt32 silc_hash_client_id_hash(void *key, void *user_context)
   return h;
 }
 
-/* Hash binary data. The `user_context' is the data length. */
-
-SilcUInt32 silc_hash_data(void *key, void *user_context)
-{
-  SilcUInt32 len = SILC_PTR_TO_32(user_context), h = 0;
-  unsigned char *data = (unsigned char *)key;
-  int i;
-
-  h = (data[0] * data[len - 1] + 1) * len;
-  for (i = 0; i < len; i++)
-    h ^= data[i];
-
-  return h;
-}
-
-/* Compares two strings. It may be used as SilcHashTable comparison
-   function. */
-
-SilcBool silc_hash_string_compare(void *key1, void *key2, void *user_context)
-{
-  return !strcasecmp((char *)key1, (char *)key2);
-}
-
 /* Compares two ID's. May be used as SilcHashTable comparison function.
    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. */
@@ -416,25 +328,6 @@ SilcBool silc_hash_client_id_compare(void *key1, void *key2,
   return SILC_ID_COMPARE_TYPE(key1, key2, SILC_ID_CLIENT);
 }
 
-/* Compares binary data. May be used as SilcHashTable comparison function. */
-
-SilcBool silc_hash_data_compare(void *key1, void *key2, void *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)
-    return FALSE;
-  return !memcmp(key1, key2, l2);
-}
-
 /* Creates fingerprint from data, usually used with SHA1 digests */
 
 char *silc_fingerprint(const unsigned char *data, SilcUInt32 data_len)
@@ -460,7 +353,7 @@ char *silc_fingerprint(const unsigned char *data, SilcUInt32 data_len)
   if ((i + 1) % 10 == 0)
     cp[-1] = 0;
 
-  return strdup(fingerprint);
+  return silc_strdup(fingerprint);
 }
 
 /* Return TRUE if the `data' is ASCII string. */
@@ -493,7 +386,7 @@ char *silc_get_input(const char *prompt, SilcBool echo_off)
 
     fd = open("/dev/tty", O_RDONLY);
     if (fd < 0) {
-      fprintf(stderr, "silc: %s\n", strerror(errno));
+      silc_set_errno_posix(errno);
       return NULL;
     }
 
@@ -515,13 +408,14 @@ char *silc_get_input(const char *prompt, SilcBool echo_off)
     fflush(stdout);
 
     if ((read(fd, input, sizeof(input))) < 0) {
-      fprintf(stderr, "silc: %s\n", strerror(errno));
+      silc_set_errno_posix(errno);
       tcsetattr(fd, TCSANOW, &to_old);
       return NULL;
     }
 
     if (strlen(input) <= 1) {
       tcsetattr(fd, TCSANOW, &to_old);
+      silc_set_errno(SILC_ERR_EOF);
       return NULL;
     }
 
@@ -539,7 +433,7 @@ char *silc_get_input(const char *prompt, SilcBool echo_off)
   } else {
     fd = open("/dev/tty", O_RDONLY);
     if (fd < 0) {
-      fprintf(stderr, "silc: %s\n", strerror(errno));
+      silc_set_errno_posix(errno);
       return NULL;
     }
 
@@ -549,17 +443,19 @@ char *silc_get_input(const char *prompt, SilcBool echo_off)
     fflush(stdout);
 
     if ((read(fd, input, sizeof(input))) < 0) {
-      fprintf(stderr, "silc: %s\n", strerror(errno));
+      silc_set_errno_posix(errno);
       return NULL;
     }
 
-    if (strlen(input) <= 1)
+    if (strlen(input) <= 1) {
+      silc_set_errno(SILC_ERR_EOF);
       return NULL;
+    }
 
     if (strchr(input, '\n'))
       *strchr(input, '\n') = '\0';
 
-    return strdup(input);
+    return silc_strdup(input);
   }
 #else
   return NULL;
@@ -640,8 +536,10 @@ SilcBool silc_hex2data(const char *hex, unsigned char *data,
   unsigned char l, h;
   int i;
 
-  if (data_size < strlen(hex) / 2)
+  if (data_size < strlen(hex) / 2) {
+    silc_set_errno(SILC_ERR_OVERFLOW);
     return FALSE;
+  }
 
   for (i = 0; i < strlen(hex) / 2; i++) {
     h = *cp++;
@@ -670,8 +568,10 @@ SilcBool silc_data2hex(const unsigned char *data, SilcUInt32 data_len,
   char *cp = hex;
   int i;
 
-  if (hex_size - 1 < data_len * 2)
+  if (hex_size - 1 < data_len * 2) {
+    silc_set_errno(SILC_ERR_OVERFLOW);
     return FALSE;
+  }
 
   memset(hex, 0, hex_size);