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.c118
1 files changed, 118 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..f2b3a4e
--- /dev/null
+++ b/contrib/dlz/modules/filesystem/dir.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * SPDX-License-Identifier: MPL-2.0
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, you can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+#include "dir.h"
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "dlz_minimal.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;
+ break;
+ case ENOENT:
+ result = ISC_R_FILENOTFOUND;
+ break;
+ case EACCES:
+ case EPERM:
+ result = ISC_R_NOPERM;
+ break;
+ case ENOMEM:
+ result = ISC_R_NOMEMORY;
+ break;
+ default:
+ result = ISC_R_UNEXPECTED;
+ break;
+ }
+ }
+
+ 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);
+}