diff options
author | Linus Nordberg <linus@nordberg.se> | 2013-01-22 11:01:59 +0100 |
---|---|---|
committer | Linus Nordberg <linus@nordberg.se> | 2013-01-22 11:39:52 +0100 |
commit | 95c4d4a42f2b4457c64a87c45c7c170dfba6a7c4 (patch) | |
tree | 2db13956be8e5c2152b2b472185e295938fc347d /lib/radsecproxy/hash.c | |
parent | 0be487506195d069c468fa71c32dc2cd50450363 (diff) |
Revive radsecproxy.h and hostport_types.h and move rsp_* into radsecproxy/.
Diffstat (limited to 'lib/radsecproxy/hash.c')
-rw-r--r-- | lib/radsecproxy/hash.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/lib/radsecproxy/hash.c b/lib/radsecproxy/hash.c new file mode 100644 index 0000000..ab17433 --- /dev/null +++ b/lib/radsecproxy/hash.c @@ -0,0 +1,131 @@ +/* Copyright (c) 2008, UNINETT AS */ +/* See LICENSE for licensing information. */ + +#include <stdlib.h> +#include <string.h> +#include <pthread.h> +#include "list.h" +#include "hash.h" + +/* allocates and initialises hash structure; returns NULL if malloc fails */ +struct hash *hash_create() { + struct hash *h = malloc(sizeof(struct hash)); + if (!h) + return NULL; + h->hashlist = list_create(); + if (!h->hashlist) { + free(h); + return NULL; + } + pthread_mutex_init(&h->mutex, NULL); + return h; +} + +/* frees all memory associated with the hash */ +void hash_destroy(struct hash *h) { + struct list_node *ln; + + if (!h) + return; + for (ln = list_first(h->hashlist); ln; ln = list_next(ln)) { + free(((struct hash_entry *)ln->data)->key); + free(((struct hash_entry *)ln->data)->data); + } + list_destroy(h->hashlist); + pthread_mutex_destroy(&h->mutex); +} + +/* insert entry in hash; returns 1 if ok, 0 if malloc fails */ +int hash_insert(struct hash *h, void *key, uint32_t keylen, void *data) { + struct hash_entry *e; + + if (!h) + return 0; + e = malloc(sizeof(struct hash_entry)); + if (!e) + return 0; + memset(e, 0, sizeof(struct hash_entry)); + e->key = malloc(keylen); + if (!e->key) { + free(e); + return 0; + } + memcpy(e->key, key, keylen); + e->keylen = keylen; + e->data = data; + pthread_mutex_lock(&h->mutex); + if (!list_push(h->hashlist, e)) { + pthread_mutex_unlock(&h->mutex); + free(e->key); + free(e); + return 0; + } + pthread_mutex_unlock(&h->mutex); + return 1; +} + +/* reads entry from hash */ +void *hash_read(struct hash *h, void *key, uint32_t keylen) { + struct list_node *ln; + struct hash_entry *e; + + if (!h) + return 0; + pthread_mutex_lock(&h->mutex); + for (ln = list_first(h->hashlist); ln; ln = list_next(ln)) { + e = (struct hash_entry *)ln->data; + if (e->keylen == keylen && !memcmp(e->key, key, keylen)) { + pthread_mutex_unlock(&h->mutex); + return e->data; + } + } + pthread_mutex_unlock(&h->mutex); + return NULL; +} + +/* extracts entry from hash */ +void *hash_extract(struct hash *h, void *key, uint32_t keylen) { + struct list_node *ln; + struct hash_entry *e; + + if (!h) + return 0; + pthread_mutex_lock(&h->mutex); + for (ln = list_first(h->hashlist); ln; ln = list_next(ln)) { + e = (struct hash_entry *)ln->data; + if (e->keylen == keylen && !memcmp(e->key, key, keylen)) { + free(e->key); + list_removedata(h->hashlist, e); + free(e); + pthread_mutex_unlock(&h->mutex); + return e->data; + } + } + pthread_mutex_unlock(&h->mutex); + return NULL; +} + +/* returns first entry */ +struct hash_entry *hash_first(struct hash *hash) { + struct list_node *ln; + struct hash_entry *e; + if (!hash || !((ln = list_first(hash->hashlist)))) + return NULL; + e = (struct hash_entry *)ln->data; + e->next = ln->next; + return e; +} + +/* returns the next node after the argument */ +struct hash_entry *hash_next(struct hash_entry *entry) { + struct hash_entry *e; + if (!entry || !entry->next) + return NULL; + e = (struct hash_entry *)entry->next->data; + e->next = (struct list_node *)entry->next->next; + return e; +} + +/* Local Variables: */ +/* c-file-style: "stroustrup" */ +/* End: */ |