summaryrefslogtreecommitdiff
path: root/src/libstrongswan/collections
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/collections')
-rw-r--r--src/libstrongswan/collections/array.c2
-rw-r--r--src/libstrongswan/collections/dictionary.h55
-rw-r--r--src/libstrongswan/collections/enumerator.c103
-rw-r--r--src/libstrongswan/collections/enumerator.h37
-rw-r--r--src/libstrongswan/collections/hashtable.c39
-rw-r--r--src/libstrongswan/collections/hashtable.h9
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));
};
/**