xref: /minix3/external/bsd/bind/dist/contrib/dlz/modules/filesystem/dir.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1 /*	$NetBSD: dir.c,v 1.1.1.3 2014/12/10 03:34:31 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 
22 #include <ctype.h>
23 #include <errno.h>
24 #include <unistd.h>
25 #include <string.h>
26 
27 #include "dlz_minimal.h"
28 #include "dir.h"
29 
30 void
dir_init(dir_t * dir)31 dir_init(dir_t *dir) {
32 	dir->entry.name[0] = '\0';
33 	dir->entry.length = 0;
34 
35 	dir->handle = NULL;
36 }
37 
38 isc_result_t
dir_open(dir_t * dir,const char * dirname)39 dir_open(dir_t *dir, const char *dirname) {
40 	char *p;
41 	isc_result_t result = ISC_R_SUCCESS;
42 
43 	if (strlen(dirname) + 3 > sizeof(dir->dirname))
44 		return (ISC_R_NOSPACE);
45 	strcpy(dir->dirname, dirname);
46 
47 	p = dir->dirname + strlen(dir->dirname);
48 	if (dir->dirname < p && *(p - 1) != '/')
49 		*p++ = '/';
50 	*p++ = '*';
51 	*p = '\0';
52 
53 	dir->handle = opendir(dirname);
54 	if (dir->handle == NULL) {
55 		switch (errno) {
56 		case ENOTDIR:
57 		case ELOOP:
58 		case EINVAL:
59 		case ENAMETOOLONG:
60 		case EBADF:
61 			result = ISC_R_INVALIDFILE;
62 		case ENOENT:
63 			result = ISC_R_FILENOTFOUND;
64 		case EACCES:
65 		case EPERM:
66 			result = ISC_R_NOPERM;
67 		case ENOMEM:
68 			result = ISC_R_NOMEMORY;
69 		default:
70 			result = ISC_R_UNEXPECTED;
71 		}
72 	}
73 
74 	return (result);
75 }
76 
77 /*!
78  * \brief Return previously retrieved file or get next one.
79 
80  * Unix's dirent has
81  * separate open and read functions, but the Win32 and DOS interfaces open
82  * the dir stream and reads the first file in one operation.
83  */
84 isc_result_t
dir_read(dir_t * dir)85 dir_read(dir_t *dir) {
86 	struct dirent *entry;
87 
88 	entry = readdir(dir->handle);
89 	if (entry == NULL)
90 		return (ISC_R_NOMORE);
91 
92 	if (sizeof(dir->entry.name) <= strlen(entry->d_name))
93 	    return (ISC_R_UNEXPECTED);
94 
95 	strcpy(dir->entry.name, entry->d_name);
96 
97 	dir->entry.length = strlen(entry->d_name);
98 	return (ISC_R_SUCCESS);
99 }
100 
101 /*!
102  * \brief Close directory stream.
103  */
104 void
dir_close(dir_t * dir)105 dir_close(dir_t *dir) {
106        (void)closedir(dir->handle);
107        dir->handle = NULL;
108 }
109 
110 /*!
111  * \brief Reposition directory stream at start.
112  */
113 isc_result_t
dir_reset(dir_t * dir)114 dir_reset(dir_t *dir) {
115 	rewinddir(dir->handle);
116 
117 	return (ISC_R_SUCCESS);
118 }
119