/*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2013 Tobias Brunner
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
*
#include <errno.h>
#include <string.h>
+#ifdef HAVE_GLOB_H
+#include <glob.h>
+#endif /* HAVE_GLOB_H */
+
#include <utils/debug.h>
/**
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;
+ /** current match */
+ char **match;
+ /** 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 = *(++this->match);
+
+ if (!match)
+ {
+ return FALSE;
+ }
+ 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,
+ },
+ .glob = {
+ .gl_offs = 1, /* reserve one slot so we can enumerate easily */
+ }
+ );
+
+ status = glob(pattern, GLOB_DOOFFS | 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));
+ }
+ this->match = this->glob.gl_pathv;
+ 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 */
/*
+ * Copyright (C) 2013 Tobias Brunner
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* 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;
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