1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | /* $NetBSD: dir.c,v 1.5 2022/09/23 12:15:27 christos Exp $ */ /* * 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); } |