diff options
Diffstat (limited to 'src/libstrongswan/collections')
-rw-r--r-- | src/libstrongswan/collections/array.c | 2 | ||||
-rw-r--r-- | src/libstrongswan/collections/dictionary.h | 55 | ||||
-rw-r--r-- | src/libstrongswan/collections/enumerator.c | 103 | ||||
-rw-r--r-- | src/libstrongswan/collections/enumerator.h | 37 | ||||
-rw-r--r-- | src/libstrongswan/collections/hashtable.c | 39 | ||||
-rw-r--r-- | src/libstrongswan/collections/hashtable.h | 9 |
6 files changed, 230 insertions, 15 deletions
diff --git a/src/libstrongswan/collections/array.c b/src/libstrongswan/collections/array.c index 75efb85bf..8d619116a 100644 --- a/src/libstrongswan/collections/array.c +++ b/src/libstrongswan/collections/array.c @@ -168,7 +168,7 @@ array_t *array_create(u_int esize, u_int8_t reserve) ); if (array->tail) { - array->data = malloc(array->tail * array->esize); + array->data = malloc(get_size(array, array->tail)); } return array; } diff --git a/src/libstrongswan/collections/dictionary.h b/src/libstrongswan/collections/dictionary.h new file mode 100644 index 000000000..679e41d2d --- /dev/null +++ b/src/libstrongswan/collections/dictionary.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2014 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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 GNU General Public License + * for more details. + */ + +/** + * @defgroup dictionary dictionary + * @{ @ingroup collections + */ + +#ifndef DICTIONARY_H_ +#define DICTIONARY_H_ + +#include <collections/enumerator.h> + +typedef struct dictionary_t dictionary_t; + +/** + * Interface for read-only dictionaries. + */ +struct dictionary_t { + + /** + * Create an enumerator over the key/value pairs in the dictionary. + * + * @return enumerator over (const void *key, void *value) + */ + enumerator_t *(*create_enumerator)(dictionary_t *this); + + /** + * Returns the value with the given key, if the dictionary contains such an + * entry, otherwise NULL is returned. + * + * @param key the key of the requested value + * @return the value, NULL if not found + */ + void *(*get)(dictionary_t *this, const void *key); + + /** + * Destroys a dictionary object. + */ + void (*destroy)(dictionary_t *this); +}; + +#endif /** DICTIONARY_H_ @}*/ diff --git a/src/libstrongswan/collections/enumerator.c b/src/libstrongswan/collections/enumerator.c index 8049ac016..fa277e7c8 100644 --- a/src/libstrongswan/collections/enumerator.c +++ b/src/libstrongswan/collections/enumerator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Tobias Brunner + * Copyright (C) 2008-2013 Tobias Brunner * Copyright (C) 2007 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -25,6 +25,10 @@ #include <errno.h> #include <string.h> +#ifdef HAVE_GLOB_H +#include <glob.h> +#endif /* HAVE_GLOB_H */ + #include <utils/debug.h> /** @@ -157,8 +161,103 @@ enumerator_t* enumerator_create_directory(const char *path) return &this->public; } +#ifdef HAVE_GLOB_H + /** - * Enumerator implementation for directory enumerator + * Enumerator implementation for glob enumerator + */ +typedef struct { + /** implements enumerator_t */ + enumerator_t public; + /** glob data */ + glob_t glob; + /** iteration count */ + u_int pos; + /** absolute path of current file */ + char full[PATH_MAX]; +} glob_enum_t; + +/** + * Implementation of enumerator_create_glob().destroy + */ +static void destroy_glob_enum(glob_enum_t *this) +{ + globfree(&this->glob); + free(this); +} + +/** + * Implementation of enumerator_create_glob().enumerate + */ +static bool enumerate_glob_enum(glob_enum_t *this, char **file, struct stat *st) +{ + char *match; + + if (this->pos >= this->glob.gl_pathc) + { + return FALSE; + } + match = this->glob.gl_pathv[this->pos++]; + if (file) + { + *file = match; + } + if (st) + { + if (stat(match, st)) + { + DBG1(DBG_LIB, "stat() on '%s' failed: %s", match, + strerror(errno)); + return FALSE; + } + } + return TRUE; +} + +/** + * See header + */ +enumerator_t* enumerator_create_glob(const char *pattern) +{ + glob_enum_t *this; + int status; + + if (!pattern) + { + return enumerator_create_empty(); + } + + INIT(this, + .public = { + .enumerate = (void*)enumerate_glob_enum, + .destroy = (void*)destroy_glob_enum, + }, + ); + + status = glob(pattern, GLOB_ERR, NULL, &this->glob); + if (status == GLOB_NOMATCH) + { + DBG1(DBG_LIB, "no files found matching '%s'", pattern); + } + else if (status != 0) + { + DBG1(DBG_LIB, "expanding file pattern '%s' failed: %s", pattern, + strerror(errno)); + } + return &this->public; +} + +#else /* HAVE_GLOB_H */ + +enumerator_t* enumerator_create_glob(const char *pattern) +{ + return NULL; +} + +#endif /* HAVE_GLOB_H */ + +/** + * Enumerator implementation for token enumerator */ typedef struct { /** implements enumerator_t */ diff --git a/src/libstrongswan/collections/enumerator.h b/src/libstrongswan/collections/enumerator.h index 299373a3e..55f8d83e6 100644 --- a/src/libstrongswan/collections/enumerator.h +++ b/src/libstrongswan/collections/enumerator.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2013 Tobias Brunner * Copyright (C) 2007 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -69,7 +70,9 @@ enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item)); * This enumerator_t.enumerate() function returns a (to the directory) relative * filename (as a char*), an absolute filename (as a char*) and a file status * (to a struct stat), which all may be NULL. "." and ".." entries are - * skipped. Example: + * skipped. + * + * Example: * * @code char *rel, *abs; @@ -96,6 +99,38 @@ enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item)); enumerator_t* enumerator_create_directory(const char *path); /** + * Create an enumerator over files/directories matching a file pattern. + * + * This enumerator_t.enumerate() function returns the filename (as a char*), + * and a file status (to a struct stat), which both may be NULL. + * + * Example: + * + * @code + char *file; + struct stat st; + enumerator_t *e; + + e = enumerator_create_glob("/etc/ipsec.*.conf"); + if (e) + { + while (e->enumerate(e, &file, &st)) + { + if (S_ISREG(st.st_mode)) + { + printf("%s\n", file); + } + } + e->destroy(e); + } + @endcode + * + * @param pattern file pattern to match + * @return the enumerator, NULL if not supported + */ +enumerator_t* enumerator_create_glob(const char *pattern); + +/** * Create an enumerator over tokens of a string. * * Tokens are separated by one of the characters in sep and trimmed by the diff --git a/src/libstrongswan/collections/hashtable.c b/src/libstrongswan/collections/hashtable.c index ca31d8361..2b77a37cc 100644 --- a/src/libstrongswan/collections/hashtable.c +++ b/src/libstrongswan/collections/hashtable.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2012 Tobias Brunner + * Copyright (C) 2008-2014 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -250,7 +250,7 @@ static void rehash(private_hashtable_t *this) } METHOD(hashtable_t, put, void*, - private_hashtable_t *this, const void *key, void *value) + private_hashtable_t *this, const void *key, void *value) { void *old_value = NULL; pair_t *pair; @@ -309,19 +309,19 @@ static void *get_internal(private_hashtable_t *this, const void *key, } METHOD(hashtable_t, get, void*, - private_hashtable_t *this, const void *key) + private_hashtable_t *this, const void *key) { return get_internal(this, key, this->equals); } METHOD(hashtable_t, get_match, void*, - private_hashtable_t *this, const void *key, hashtable_equals_t match) + private_hashtable_t *this, const void *key, hashtable_equals_t match) { return get_internal(this, key, match); } METHOD(hashtable_t, remove_, void*, - private_hashtable_t *this, const void *key) + private_hashtable_t *this, const void *key) { void *value = NULL; pair_t *pair, *prev = NULL; @@ -353,7 +353,7 @@ METHOD(hashtable_t, remove_, void*, } METHOD(hashtable_t, remove_at, void, - private_hashtable_t *this, private_enumerator_t *enumerator) + private_hashtable_t *this, private_enumerator_t *enumerator) { if (enumerator->table == this && enumerator->current) { @@ -373,13 +373,13 @@ METHOD(hashtable_t, remove_at, void, } METHOD(hashtable_t, get_count, u_int, - private_hashtable_t *this) + private_hashtable_t *this) { return this->count; } METHOD(enumerator_t, enumerate, bool, - private_enumerator_t *this, const void **key, void **value) + private_enumerator_t *this, const void **key, void **value) { while (this->count && this->row < this->table->capacity) { @@ -411,7 +411,7 @@ METHOD(enumerator_t, enumerate, bool, } METHOD(hashtable_t, create_enumerator, enumerator_t*, - private_hashtable_t *this) + private_hashtable_t *this) { private_enumerator_t *enumerator; @@ -427,8 +427,8 @@ METHOD(hashtable_t, create_enumerator, enumerator_t*, return &enumerator->enumerator; } -METHOD(hashtable_t, destroy, void, - private_hashtable_t *this) +static void destroy_internal(private_hashtable_t *this, + void (*fn)(void*,const void*)) { pair_t *pair, *next; u_int row; @@ -438,6 +438,10 @@ METHOD(hashtable_t, destroy, void, pair = this->table[row]; while (pair) { + if (fn) + { + fn(pair->value, pair->key); + } next = pair->next; free(pair); pair = next; @@ -447,6 +451,18 @@ METHOD(hashtable_t, destroy, void, free(this); } +METHOD(hashtable_t, destroy, void, + private_hashtable_t *this) +{ + destroy_internal(this, NULL); +} + +METHOD(hashtable_t, destroy_function, void, + private_hashtable_t *this, void (*fn)(void*,const void*)) +{ + destroy_internal(this, fn); +} + /* * Described in header. */ @@ -465,6 +481,7 @@ hashtable_t *hashtable_create(hashtable_hash_t hash, hashtable_equals_t equals, .get_count = _get_count, .create_enumerator = _create_enumerator, .destroy = _destroy, + .destroy_function = _destroy_function, }, .hash = hash, .equals = equals, diff --git a/src/libstrongswan/collections/hashtable.h b/src/libstrongswan/collections/hashtable.h index 0a7ebeb65..f60564a42 100644 --- a/src/libstrongswan/collections/hashtable.h +++ b/src/libstrongswan/collections/hashtable.h @@ -156,6 +156,15 @@ struct hashtable_t { * Destroys a hash table object. */ void (*destroy) (hashtable_t *this); + + /** + * Destroys a hash table object and calls the given function for each + * item and its key in the hash table. + * + * @param function function to call on each item and key + */ + void (*destroy_function)(hashtable_t *this, + void (*)(void *val, const void *key)); }; /** |