• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24 
25 #if !defined(NO_GNU_SOURCE_THIS_TIME)
26 #define NO_GNU_SOURCE_THIS_TIME
27 #endif
28 #if !defined(_DARWIN_C_SOURCE)
29 #define _DARWIN_C_SOURCE
30 #endif
31 
32 #include <libwebsockets.h>
33 #include "private-lib-core.h"
34 #include <string.h>
35 #include <stdio.h>
36 
37 #if defined(LWS_WITH_LIBUV) && UV_VERSION_MAJOR > 0
38 
39 int
lws_dir(const char * dirpath,void * user,lws_dir_callback_function cb)40 lws_dir(const char *dirpath, void *user, lws_dir_callback_function cb)
41 {
42 	struct lws_dir_entry lde;
43 	uv_dirent_t dent;
44 	uv_fs_t req;
45 	int ret = 1, ir;
46 	uv_loop_t loop;
47 
48 	ir = uv_loop_init(&loop);
49 	if (ir) {
50 		lwsl_err("%s: loop init failed %d\n", __func__, ir);
51 		return 1;
52 	}
53 
54 	ir = uv_fs_scandir(&loop, &req, dirpath, 0, NULL);
55 	if (ir < 0) {
56 		lwsl_err("Scandir on %s failed, errno %d\n", dirpath, LWS_ERRNO);
57 		ret = 2;
58 		goto bail;
59 	}
60 
61 	while (uv_fs_scandir_next(&req, &dent) != UV_EOF) {
62 		lde.name = dent.name;
63 		lde.type = (int)dent.type;
64 		if (cb(dirpath, user, &lde))
65 			goto bail1;
66 	}
67 
68 	ret = 0;
69 
70 bail1:
71 	uv_fs_req_cleanup(&req);
72 bail:
73 	while (uv_loop_close(&loop))
74 		;
75 
76 	return ret;
77 }
78 
79 #else
80 
81 #if !defined(_WIN32) && !defined(LWS_PLAT_FREERTOS)
82 
83 #include <dirent.h>
84 
filter(const struct dirent * ent)85 static int filter(const struct dirent *ent)
86 {
87 	if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
88 		return 0;
89 
90 	return 1;
91 }
92 
93 int
lws_dir(const char * dirpath,void * user,lws_dir_callback_function cb)94 lws_dir(const char *dirpath, void *user, lws_dir_callback_function cb)
95 {
96 	struct lws_dir_entry lde;
97 	struct dirent **namelist;
98 	int n, i, ret = 1;
99 
100 	n = scandir((char *)dirpath, &namelist, filter, alphasort);
101 	if (n < 0) {
102 		lwsl_err("Scandir on '%s' failed, errno %d\n", dirpath, LWS_ERRNO);
103 		return 1;
104 	}
105 
106 	for (i = 0; i < n; i++) {
107 		if (strchr(namelist[i]->d_name, '~'))
108 			goto skip;
109 		lde.name = namelist[i]->d_name;
110 
111 		/*
112 		 * some filesystems don't report this (ZFS) and tell that
113 		 * files are LDOT_UNKNOWN
114 		 */
115 
116 #if defined(__sun)
117         struct stat s;
118         stat(namelist[i]->d_name, &s);
119 		switch (s.st_mode) {
120 		case S_IFBLK:
121 			lde.type = LDOT_BLOCK;
122 			break;
123 		case S_IFCHR:
124 			lde.type = LDOT_CHAR;
125 			break;
126 		case S_IFDIR:
127 			lde.type = LDOT_DIR;
128 			break;
129 		case S_IFIFO:
130 			lde.type = LDOT_FIFO;
131 			break;
132 		case S_IFLNK:
133 			lde.type = LDOT_LINK;
134 			break;
135 		case S_IFREG:
136 			lde.type = LDOT_FILE;
137 			break;
138 		default:
139 			lde.type = LDOT_UNKNOWN;
140 			break;
141 		}
142 #else
143 		switch (namelist[i]->d_type) {
144 		case DT_BLK:
145 			lde.type = LDOT_BLOCK;
146 			break;
147 		case DT_CHR:
148 			lde.type = LDOT_CHAR;
149 			break;
150 		case DT_DIR:
151 			lde.type = LDOT_DIR;
152 			break;
153 		case DT_FIFO:
154 			lde.type = LDOT_FIFO;
155 			break;
156 		case DT_LNK:
157 			lde.type = LDOT_LINK;
158 			break;
159 		case DT_REG:
160 			lde.type = LDOT_FILE;
161 			break;
162 		case DT_SOCK:
163 			lde.type = LDOTT_SOCKET;
164 			break;
165 		default:
166 			lde.type = LDOT_UNKNOWN;
167 			break;
168 		}
169 #endif
170 		if (cb(dirpath, user, &lde)) {
171 			while (i++ < n)
172 				free(namelist[i]);
173 			goto bail;
174 		}
175 skip:
176 		free(namelist[i]);
177 	}
178 
179 	ret = 0;
180 
181 bail:
182 	free(namelist);
183 
184 	return ret;
185 }
186 
187 #else
188 #error "If you want lws_dir on windows, you need libuv"
189 #endif
190 #endif
191