summaryrefslogtreecommitdiffstats
path: root/contrib/dlz/modules/filesystem/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/dlz/modules/filesystem/dir.c')
-rw-r--r--contrib/dlz/modules/filesystem/dir.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/contrib/dlz/modules/filesystem/dir.c b/contrib/dlz/modules/filesystem/dir.c
new file mode 100644
index 0000000..e5f1ac4
--- /dev/null
+++ b/contrib/dlz/modules/filesystem/dir.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "dlz_minimal.h"
+#include "dir.h"
+
+void
+dir_init(dir_t *dir) {
+ dir->entry.name[0] = '\0';
+ dir->entry.length = 0;
+
+ dir->handle = NULL;
+}
+
+isc_result_t
+dir_open(dir_t *dir, const char *dirname) {
+ char *p;
+ isc_result_t result = ISC_R_SUCCESS;
+
+ if (strlen(dirname) + 3 > sizeof(dir->dirname))
+ return (ISC_R_NOSPACE);
+ strcpy(dir->dirname, dirname);
+
+ p = dir->dirname + strlen(dir->dirname);
+ if (dir->dirname < p && *(p - 1) != '/')
+ *p++ = '/';
+ *p++ = '*';
+ *p = '\0';
+
+ dir->handle = opendir(dirname);
+ if (dir->handle == NULL) {
+ switch (errno) {
+ case ENOTDIR:
+ case ELOOP:
+ case EINVAL:
+ case ENAMETOOLONG:
+ case EBADF:
+ result = ISC_R_INVALIDFILE;
+ case ENOENT:
+ result = ISC_R_FILENOTFOUND;
+ case EACCES:
+ case EPERM:
+ result = ISC_R_NOPERM;
+ case ENOMEM:
+ result = ISC_R_NOMEMORY;
+ default:
+ result = ISC_R_UNEXPECTED;
+ }
+ }
+
+ return (result);
+}
+
+/*!
+ * \brief Return previously retrieved file or get next one.
+
+ * Unix's dirent has
+ * separate open and read functions, but the Win32 and DOS interfaces open
+ * the dir stream and reads the first file in one operation.
+ */
+isc_result_t
+dir_read(dir_t *dir) {
+ struct dirent *entry;
+
+ entry = readdir(dir->handle);
+ if (entry == NULL)
+ return (ISC_R_NOMORE);
+
+ if (sizeof(dir->entry.name) <= strlen(entry->d_name))
+ return (ISC_R_UNEXPECTED);
+
+ strcpy(dir->entry.name, entry->d_name);
+
+ dir->entry.length = strlen(entry->d_name);
+ return (ISC_R_SUCCESS);
+}
+
+/*!
+ * \brief Close directory stream.
+ */
+void
+dir_close(dir_t *dir) {
+ (void)closedir(dir->handle);
+ dir->handle = NULL;
+}
+
+/*!
+ * \brief Reposition directory stream at start.
+ */
+isc_result_t
+dir_reset(dir_t *dir) {
+ rewinddir(dir->handle);
+
+ return (ISC_R_SUCCESS);
+}