Add error messages in case of signature error
[oweals/opkg-lede.git] / libopkg / hash_table.c
index 41877c2f3e60993a00324b6ddf93ffba62ba4126..713ecff605889eb349222319a9087002da5b7cdd 100644 (file)
@@ -78,7 +78,27 @@ int hash_table_init(const char *name, hash_table_t *hash, int len)
 
 void hash_table_deinit(hash_table_t *hash)
 {
-    free(hash->entries);
+    int i;
+    if (!hash)
+        return;
+
+    /* free the reminaing entries */
+    for (i = 0; i < hash->n_entries; i++) {
+       hash_entry_t *hash_entry = (hash->entries + i);
+       free (hash_entry->key);
+       /* skip the first entry as this is part of the array */
+       hash_entry = hash_entry->next;
+        while (hash_entry)
+       {
+         hash_entry_t *old = hash_entry;
+         hash_entry = hash_entry->next;
+         free (old->key);
+         free (old);
+       }
+    }
+
+    free (hash->entries);
+
     hash->entries = NULL;
     hash->n_entries = 0;
 }
@@ -119,9 +139,14 @@ int hash_table_insert(hash_table_t *hash, const char *key, void *value)
                * before we can hook up the value
                */
                if (0) opkg_message(NULL, OPKG_DEBUG2, "Function: %s. Value already in hash by collision for '%s' \n", __FUNCTION__, key);
-              while (hash_entry->next)
+              while (hash_entry->next) {
                    hash_entry = hash_entry->next;
-              hash_entry->next = (hash_entry_t *)malloc(sizeof(hash_entry_t));
+                    if (strcmp(hash_entry->key, key) == 0) {
+                        hash_entry->data = value;
+                        return 0;
+                    }
+               }
+              hash_entry->next = (hash_entry_t *)calloc(1, sizeof(hash_entry_t));
               if (!hash_entry->next) {
                    return -ENOMEM;
               }
@@ -136,6 +161,37 @@ int hash_table_insert(hash_table_t *hash, const char *key, void *value)
      return 0;
 }
 
+int hash_table_remove(hash_table_t *hash, const char *key)
+{
+    int ndx= hash_index(hash, key);
+    hash_entry_t *hash_entry = hash->entries + ndx;
+    hash_entry_t *next_entry=NULL, *last_entry=NULL;
+    while (hash_entry) 
+    {
+        if (hash_entry->key) 
+        {
+            if (strcmp(key, hash_entry->key) == 0) {
+                free(hash_entry->key);
+                if (last_entry) {
+                    last_entry->next = hash_entry->next;
+                    free(hash_entry);
+                } else {
+                    next_entry = hash_entry->next;
+                    if (next_entry) {
+                        memmove(hash_entry, next_entry, sizeof(hash_entry_t));
+                        free(next_entry);
+                    } else {
+                        memset(hash_entry, 0 , sizeof(hash_entry_t));
+                    }
+                }
+                return 1;
+            }
+        }
+        last_entry = hash_entry;
+        hash_entry = hash_entry->next;
+    }
+    return 0;
+}
 
 void hash_table_foreach(hash_table_t *hash, void (*f)(const char *key, void *entry, void *data), void *data)
 {