1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker * libwebsockets - small server side websockets and web server implementation
3*1c60b9acSAndroid Build Coastguard Worker *
4*1c60b9acSAndroid Build Coastguard Worker * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker *
6*1c60b9acSAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker *
13*1c60b9acSAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker *
16*1c60b9acSAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker */
24*1c60b9acSAndroid Build Coastguard Worker
25*1c60b9acSAndroid Build Coastguard Worker #if !defined(NO_GNU_SOURCE_THIS_TIME)
26*1c60b9acSAndroid Build Coastguard Worker #define NO_GNU_SOURCE_THIS_TIME
27*1c60b9acSAndroid Build Coastguard Worker #endif
28*1c60b9acSAndroid Build Coastguard Worker #if !defined(_DARWIN_C_SOURCE)
29*1c60b9acSAndroid Build Coastguard Worker #define _DARWIN_C_SOURCE
30*1c60b9acSAndroid Build Coastguard Worker #endif
31*1c60b9acSAndroid Build Coastguard Worker
32*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-core.h"
33*1c60b9acSAndroid Build Coastguard Worker #include <string.h>
34*1c60b9acSAndroid Build Coastguard Worker #include <stdio.h>
35*1c60b9acSAndroid Build Coastguard Worker
36*1c60b9acSAndroid Build Coastguard Worker #include <sys/stat.h>
37*1c60b9acSAndroid Build Coastguard Worker #if defined(WIN32)
38*1c60b9acSAndroid Build Coastguard Worker #include <direct.h>
39*1c60b9acSAndroid Build Coastguard Worker #define read _read
40*1c60b9acSAndroid Build Coastguard Worker #define open _open
41*1c60b9acSAndroid Build Coastguard Worker #define close _close
42*1c60b9acSAndroid Build Coastguard Worker #define write _write
43*1c60b9acSAndroid Build Coastguard Worker #define mkdir(x,y) _mkdir(x)
44*1c60b9acSAndroid Build Coastguard Worker #define rmdir _rmdir
45*1c60b9acSAndroid Build Coastguard Worker #define unlink _unlink
46*1c60b9acSAndroid Build Coastguard Worker #define HAVE_STRUCT_TIMESPEC
47*1c60b9acSAndroid Build Coastguard Worker #if defined(pid_t)
48*1c60b9acSAndroid Build Coastguard Worker #undef pid_t
49*1c60b9acSAndroid Build Coastguard Worker #endif
50*1c60b9acSAndroid Build Coastguard Worker #endif /* win32 */
51*1c60b9acSAndroid Build Coastguard Worker
52*1c60b9acSAndroid Build Coastguard Worker #define COMBO_SIZEOF 512
53*1c60b9acSAndroid Build Coastguard Worker
54*1c60b9acSAndroid Build Coastguard Worker #if !defined(LWS_PLAT_FREERTOS)
55*1c60b9acSAndroid Build Coastguard Worker
56*1c60b9acSAndroid Build Coastguard Worker #if defined(WIN32)
57*1c60b9acSAndroid Build Coastguard Worker #include "../../win32port/dirent/dirent-win32.h"
58*1c60b9acSAndroid Build Coastguard Worker #else
59*1c60b9acSAndroid Build Coastguard Worker #include <dirent.h>
60*1c60b9acSAndroid Build Coastguard Worker #endif
61*1c60b9acSAndroid Build Coastguard Worker
filter(const struct dirent * ent)62*1c60b9acSAndroid Build Coastguard Worker static int filter(const struct dirent *ent)
63*1c60b9acSAndroid Build Coastguard Worker {
64*1c60b9acSAndroid Build Coastguard Worker if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
65*1c60b9acSAndroid Build Coastguard Worker return 0;
66*1c60b9acSAndroid Build Coastguard Worker
67*1c60b9acSAndroid Build Coastguard Worker return 1;
68*1c60b9acSAndroid Build Coastguard Worker }
69*1c60b9acSAndroid Build Coastguard Worker
70*1c60b9acSAndroid Build Coastguard Worker
71*1c60b9acSAndroid Build Coastguard Worker #if !defined(WIN32)
72*1c60b9acSAndroid Build Coastguard Worker static char csep = '/';
73*1c60b9acSAndroid Build Coastguard Worker #else
74*1c60b9acSAndroid Build Coastguard Worker static char csep = '\\';
75*1c60b9acSAndroid Build Coastguard Worker #endif
76*1c60b9acSAndroid Build Coastguard Worker
77*1c60b9acSAndroid Build Coastguard Worker static void
lws_dir_via_stat(char * combo,size_t l,const char * path,struct lws_dir_entry * lde)78*1c60b9acSAndroid Build Coastguard Worker lws_dir_via_stat(char *combo, size_t l, const char *path, struct lws_dir_entry *lde)
79*1c60b9acSAndroid Build Coastguard Worker {
80*1c60b9acSAndroid Build Coastguard Worker struct stat s;
81*1c60b9acSAndroid Build Coastguard Worker
82*1c60b9acSAndroid Build Coastguard Worker lws_strncpy(combo + l, path, COMBO_SIZEOF - l);
83*1c60b9acSAndroid Build Coastguard Worker
84*1c60b9acSAndroid Build Coastguard Worker lde->type = LDOT_UNKNOWN;
85*1c60b9acSAndroid Build Coastguard Worker
86*1c60b9acSAndroid Build Coastguard Worker if (!stat(combo, &s)) {
87*1c60b9acSAndroid Build Coastguard Worker switch (s.st_mode & S_IFMT) {
88*1c60b9acSAndroid Build Coastguard Worker case S_IFBLK:
89*1c60b9acSAndroid Build Coastguard Worker lde->type = LDOT_BLOCK;
90*1c60b9acSAndroid Build Coastguard Worker break;
91*1c60b9acSAndroid Build Coastguard Worker case S_IFCHR:
92*1c60b9acSAndroid Build Coastguard Worker lde->type = LDOT_CHAR;
93*1c60b9acSAndroid Build Coastguard Worker break;
94*1c60b9acSAndroid Build Coastguard Worker case S_IFDIR:
95*1c60b9acSAndroid Build Coastguard Worker lde->type = LDOT_DIR;
96*1c60b9acSAndroid Build Coastguard Worker break;
97*1c60b9acSAndroid Build Coastguard Worker case S_IFIFO:
98*1c60b9acSAndroid Build Coastguard Worker lde->type = LDOT_FIFO;
99*1c60b9acSAndroid Build Coastguard Worker break;
100*1c60b9acSAndroid Build Coastguard Worker #if !defined(WIN32)
101*1c60b9acSAndroid Build Coastguard Worker case S_IFLNK:
102*1c60b9acSAndroid Build Coastguard Worker lde->type = LDOT_LINK;
103*1c60b9acSAndroid Build Coastguard Worker break;
104*1c60b9acSAndroid Build Coastguard Worker #endif
105*1c60b9acSAndroid Build Coastguard Worker case S_IFREG:
106*1c60b9acSAndroid Build Coastguard Worker lde->type = LDOT_FILE;
107*1c60b9acSAndroid Build Coastguard Worker break;
108*1c60b9acSAndroid Build Coastguard Worker default:
109*1c60b9acSAndroid Build Coastguard Worker break;
110*1c60b9acSAndroid Build Coastguard Worker }
111*1c60b9acSAndroid Build Coastguard Worker }
112*1c60b9acSAndroid Build Coastguard Worker }
113*1c60b9acSAndroid Build Coastguard Worker
114*1c60b9acSAndroid Build Coastguard Worker int
lws_dir(const char * dirpath,void * user,lws_dir_callback_function cb)115*1c60b9acSAndroid Build Coastguard Worker lws_dir(const char *dirpath, void *user, lws_dir_callback_function cb)
116*1c60b9acSAndroid Build Coastguard Worker {
117*1c60b9acSAndroid Build Coastguard Worker struct lws_dir_entry lde;
118*1c60b9acSAndroid Build Coastguard Worker struct dirent **namelist;
119*1c60b9acSAndroid Build Coastguard Worker int n, i, ret = 1;
120*1c60b9acSAndroid Build Coastguard Worker char combo[COMBO_SIZEOF];
121*1c60b9acSAndroid Build Coastguard Worker size_t l;
122*1c60b9acSAndroid Build Coastguard Worker
123*1c60b9acSAndroid Build Coastguard Worker l = (size_t)(ssize_t)lws_snprintf(combo, COMBO_SIZEOF - 2, "%s", dirpath);
124*1c60b9acSAndroid Build Coastguard Worker combo[l++] = csep;
125*1c60b9acSAndroid Build Coastguard Worker combo[l] = '\0';
126*1c60b9acSAndroid Build Coastguard Worker
127*1c60b9acSAndroid Build Coastguard Worker n = scandir((char *)dirpath, &namelist, filter, alphasort);
128*1c60b9acSAndroid Build Coastguard Worker if (n < 0) {
129*1c60b9acSAndroid Build Coastguard Worker lwsl_err("Scandir on '%s' failed, errno %d\n", dirpath, LWS_ERRNO);
130*1c60b9acSAndroid Build Coastguard Worker return 1;
131*1c60b9acSAndroid Build Coastguard Worker }
132*1c60b9acSAndroid Build Coastguard Worker
133*1c60b9acSAndroid Build Coastguard Worker for (i = 0; i < n; i++) {
134*1c60b9acSAndroid Build Coastguard Worker #if !defined(__sun)
135*1c60b9acSAndroid Build Coastguard Worker unsigned int type = namelist[i]->d_type;
136*1c60b9acSAndroid Build Coastguard Worker #endif
137*1c60b9acSAndroid Build Coastguard Worker if (strchr(namelist[i]->d_name, '~'))
138*1c60b9acSAndroid Build Coastguard Worker goto skip;
139*1c60b9acSAndroid Build Coastguard Worker lde.name = namelist[i]->d_name;
140*1c60b9acSAndroid Build Coastguard Worker
141*1c60b9acSAndroid Build Coastguard Worker /*
142*1c60b9acSAndroid Build Coastguard Worker * some filesystems don't report this (ZFS) and tell that
143*1c60b9acSAndroid Build Coastguard Worker * files are LDOT_UNKNOWN
144*1c60b9acSAndroid Build Coastguard Worker */
145*1c60b9acSAndroid Build Coastguard Worker
146*1c60b9acSAndroid Build Coastguard Worker #if defined(__sun)
147*1c60b9acSAndroid Build Coastguard Worker lws_dir_via_stat(combo, l, namelist[i]->d_name, &lde);
148*1c60b9acSAndroid Build Coastguard Worker #else
149*1c60b9acSAndroid Build Coastguard Worker /*
150*1c60b9acSAndroid Build Coastguard Worker * XFS on Linux doesn't fill in d_type at all, always zero.
151*1c60b9acSAndroid Build Coastguard Worker */
152*1c60b9acSAndroid Build Coastguard Worker
153*1c60b9acSAndroid Build Coastguard Worker if (DT_BLK != DT_UNKNOWN && type == DT_BLK)
154*1c60b9acSAndroid Build Coastguard Worker lde.type = LDOT_BLOCK;
155*1c60b9acSAndroid Build Coastguard Worker else if (DT_CHR != DT_UNKNOWN && type == DT_CHR)
156*1c60b9acSAndroid Build Coastguard Worker lde.type = LDOT_CHAR;
157*1c60b9acSAndroid Build Coastguard Worker else if (DT_DIR != DT_UNKNOWN && type == DT_DIR)
158*1c60b9acSAndroid Build Coastguard Worker lde.type = LDOT_DIR;
159*1c60b9acSAndroid Build Coastguard Worker else if (DT_FIFO != DT_UNKNOWN && type == DT_FIFO)
160*1c60b9acSAndroid Build Coastguard Worker lde.type = LDOT_FIFO;
161*1c60b9acSAndroid Build Coastguard Worker else if (DT_LNK != DT_UNKNOWN && type == DT_LNK)
162*1c60b9acSAndroid Build Coastguard Worker lde.type = LDOT_LINK;
163*1c60b9acSAndroid Build Coastguard Worker else if (DT_REG != DT_UNKNOWN && type == DT_REG)
164*1c60b9acSAndroid Build Coastguard Worker lde.type = LDOT_FILE;
165*1c60b9acSAndroid Build Coastguard Worker else if (DT_SOCK != DT_UNKNOWN && type == DT_SOCK)
166*1c60b9acSAndroid Build Coastguard Worker lde.type = LDOTT_SOCKET;
167*1c60b9acSAndroid Build Coastguard Worker else {
168*1c60b9acSAndroid Build Coastguard Worker lde.type = LDOT_UNKNOWN;
169*1c60b9acSAndroid Build Coastguard Worker lws_dir_via_stat(combo, l, namelist[i]->d_name, &lde);
170*1c60b9acSAndroid Build Coastguard Worker }
171*1c60b9acSAndroid Build Coastguard Worker #endif
172*1c60b9acSAndroid Build Coastguard Worker if (cb(dirpath, user, &lde)) {
173*1c60b9acSAndroid Build Coastguard Worker while (i < n)
174*1c60b9acSAndroid Build Coastguard Worker free(namelist[i++]);
175*1c60b9acSAndroid Build Coastguard Worker ret = 0; /* told to stop by cb */
176*1c60b9acSAndroid Build Coastguard Worker goto bail;
177*1c60b9acSAndroid Build Coastguard Worker }
178*1c60b9acSAndroid Build Coastguard Worker skip:
179*1c60b9acSAndroid Build Coastguard Worker free(namelist[i]);
180*1c60b9acSAndroid Build Coastguard Worker }
181*1c60b9acSAndroid Build Coastguard Worker
182*1c60b9acSAndroid Build Coastguard Worker bail:
183*1c60b9acSAndroid Build Coastguard Worker free(namelist);
184*1c60b9acSAndroid Build Coastguard Worker
185*1c60b9acSAndroid Build Coastguard Worker return ret;
186*1c60b9acSAndroid Build Coastguard Worker }
187*1c60b9acSAndroid Build Coastguard Worker
188*1c60b9acSAndroid Build Coastguard Worker /*
189*1c60b9acSAndroid Build Coastguard Worker * Check filename against one globby filter
190*1c60b9acSAndroid Build Coastguard Worker *
191*1c60b9acSAndroid Build Coastguard Worker * We can support things like "*.rpm"
192*1c60b9acSAndroid Build Coastguard Worker */
193*1c60b9acSAndroid Build Coastguard Worker
194*1c60b9acSAndroid Build Coastguard Worker static int
lws_dir_glob_check(const char * nm,const char * filt)195*1c60b9acSAndroid Build Coastguard Worker lws_dir_glob_check(const char *nm, const char *filt)
196*1c60b9acSAndroid Build Coastguard Worker {
197*1c60b9acSAndroid Build Coastguard Worker while (*nm) {
198*1c60b9acSAndroid Build Coastguard Worker if (*filt == '*') {
199*1c60b9acSAndroid Build Coastguard Worker if (!strcmp(nm, filt + 1))
200*1c60b9acSAndroid Build Coastguard Worker return 1;
201*1c60b9acSAndroid Build Coastguard Worker } else {
202*1c60b9acSAndroid Build Coastguard Worker if (*nm != *filt)
203*1c60b9acSAndroid Build Coastguard Worker return 0;
204*1c60b9acSAndroid Build Coastguard Worker filt++;
205*1c60b9acSAndroid Build Coastguard Worker }
206*1c60b9acSAndroid Build Coastguard Worker nm++;
207*1c60b9acSAndroid Build Coastguard Worker }
208*1c60b9acSAndroid Build Coastguard Worker
209*1c60b9acSAndroid Build Coastguard Worker return 0;
210*1c60b9acSAndroid Build Coastguard Worker }
211*1c60b9acSAndroid Build Coastguard Worker
212*1c60b9acSAndroid Build Coastguard Worker /*
213*1c60b9acSAndroid Build Coastguard Worker * We get passed a single filter string, like "*.txt" or "mydir/\*.rpm" or so.
214*1c60b9acSAndroid Build Coastguard Worker */
215*1c60b9acSAndroid Build Coastguard Worker
216*1c60b9acSAndroid Build Coastguard Worker int
lws_dir_glob_cb(const char * dirpath,void * user,struct lws_dir_entry * lde)217*1c60b9acSAndroid Build Coastguard Worker lws_dir_glob_cb(const char *dirpath, void *user, struct lws_dir_entry *lde)
218*1c60b9acSAndroid Build Coastguard Worker {
219*1c60b9acSAndroid Build Coastguard Worker lws_dir_glob_t *filter = (lws_dir_glob_t*)user;
220*1c60b9acSAndroid Build Coastguard Worker char path[384];
221*1c60b9acSAndroid Build Coastguard Worker
222*1c60b9acSAndroid Build Coastguard Worker if (!strcmp(lde->name, ".") || !strcmp(lde->name, ".."))
223*1c60b9acSAndroid Build Coastguard Worker return 0;
224*1c60b9acSAndroid Build Coastguard Worker
225*1c60b9acSAndroid Build Coastguard Worker if (lde->type == LDOT_DIR)
226*1c60b9acSAndroid Build Coastguard Worker return 0;
227*1c60b9acSAndroid Build Coastguard Worker
228*1c60b9acSAndroid Build Coastguard Worker if (lws_dir_glob_check(lde->name, filter->filter)) {
229*1c60b9acSAndroid Build Coastguard Worker lws_snprintf(path, sizeof(path), "%s%c%s", dirpath, csep,
230*1c60b9acSAndroid Build Coastguard Worker lde->name);
231*1c60b9acSAndroid Build Coastguard Worker filter->cb(filter->user, path);
232*1c60b9acSAndroid Build Coastguard Worker }
233*1c60b9acSAndroid Build Coastguard Worker
234*1c60b9acSAndroid Build Coastguard Worker return 0;
235*1c60b9acSAndroid Build Coastguard Worker }
236*1c60b9acSAndroid Build Coastguard Worker
237*1c60b9acSAndroid Build Coastguard Worker int
lws_dir_rm_rf_cb(const char * dirpath,void * user,struct lws_dir_entry * lde)238*1c60b9acSAndroid Build Coastguard Worker lws_dir_rm_rf_cb(const char *dirpath, void *user, struct lws_dir_entry *lde)
239*1c60b9acSAndroid Build Coastguard Worker {
240*1c60b9acSAndroid Build Coastguard Worker char path[384];
241*1c60b9acSAndroid Build Coastguard Worker
242*1c60b9acSAndroid Build Coastguard Worker if (!strcmp(lde->name, ".") || !strcmp(lde->name, ".."))
243*1c60b9acSAndroid Build Coastguard Worker return 0;
244*1c60b9acSAndroid Build Coastguard Worker
245*1c60b9acSAndroid Build Coastguard Worker lws_snprintf(path, sizeof(path), "%s%c%s", dirpath, csep, lde->name);
246*1c60b9acSAndroid Build Coastguard Worker
247*1c60b9acSAndroid Build Coastguard Worker if (lde->type == LDOT_DIR) {
248*1c60b9acSAndroid Build Coastguard Worker #if !defined(WIN32) && !defined(_WIN32) && !defined(__COVERITY__)
249*1c60b9acSAndroid Build Coastguard Worker char dummy[8];
250*1c60b9acSAndroid Build Coastguard Worker /*
251*1c60b9acSAndroid Build Coastguard Worker * hm... eg, recursive dir symlinks can show up a LDOT_DIR
252*1c60b9acSAndroid Build Coastguard Worker * here. If it's a symlink, don't recurse into it.
253*1c60b9acSAndroid Build Coastguard Worker *
254*1c60b9acSAndroid Build Coastguard Worker * Notice we immediately discard dummy without looking in it.
255*1c60b9acSAndroid Build Coastguard Worker * There is no way to get into trouble from its lack of NUL
256*1c60b9acSAndroid Build Coastguard Worker * termination in dummy[]. We just wanted to know if it was
257*1c60b9acSAndroid Build Coastguard Worker * a symlink at all.
258*1c60b9acSAndroid Build Coastguard Worker *
259*1c60b9acSAndroid Build Coastguard Worker * Hide this from Coverity since it flags any use of readlink()
260*1c60b9acSAndroid Build Coastguard Worker * even if safe.
261*1c60b9acSAndroid Build Coastguard Worker */
262*1c60b9acSAndroid Build Coastguard Worker if (readlink(path, dummy, sizeof(dummy)) < 0)
263*1c60b9acSAndroid Build Coastguard Worker #endif
264*1c60b9acSAndroid Build Coastguard Worker lws_dir(path, NULL, lws_dir_rm_rf_cb);
265*1c60b9acSAndroid Build Coastguard Worker
266*1c60b9acSAndroid Build Coastguard Worker if (rmdir(path))
267*1c60b9acSAndroid Build Coastguard Worker lwsl_warn("%s: rmdir %s failed %d\n", __func__, path, errno);
268*1c60b9acSAndroid Build Coastguard Worker } else {
269*1c60b9acSAndroid Build Coastguard Worker if (unlink(path)) {
270*1c60b9acSAndroid Build Coastguard Worker #if defined(WIN32)
271*1c60b9acSAndroid Build Coastguard Worker SetFileAttributesA(path, FILE_ATTRIBUTE_NORMAL);
272*1c60b9acSAndroid Build Coastguard Worker if (unlink(path))
273*1c60b9acSAndroid Build Coastguard Worker #else
274*1c60b9acSAndroid Build Coastguard Worker if (rmdir(path))
275*1c60b9acSAndroid Build Coastguard Worker #endif
276*1c60b9acSAndroid Build Coastguard Worker lwsl_warn("%s: unlink %s failed %d (type %d)\n",
277*1c60b9acSAndroid Build Coastguard Worker __func__, path, errno, lde->type);
278*1c60b9acSAndroid Build Coastguard Worker }
279*1c60b9acSAndroid Build Coastguard Worker }
280*1c60b9acSAndroid Build Coastguard Worker
281*1c60b9acSAndroid Build Coastguard Worker return 0;
282*1c60b9acSAndroid Build Coastguard Worker }
283*1c60b9acSAndroid Build Coastguard Worker
284*1c60b9acSAndroid Build Coastguard Worker
285*1c60b9acSAndroid Build Coastguard Worker #endif
286*1c60b9acSAndroid Build Coastguard Worker
287*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_PLUGINS_API)
288*1c60b9acSAndroid Build Coastguard Worker
289*1c60b9acSAndroid Build Coastguard Worker struct lws_plugins_args {
290*1c60b9acSAndroid Build Coastguard Worker struct lws_plugin **pplugin;
291*1c60b9acSAndroid Build Coastguard Worker const char *_class;
292*1c60b9acSAndroid Build Coastguard Worker const char *filter;
293*1c60b9acSAndroid Build Coastguard Worker each_plugin_cb_t each;
294*1c60b9acSAndroid Build Coastguard Worker void *each_user;
295*1c60b9acSAndroid Build Coastguard Worker };
296*1c60b9acSAndroid Build Coastguard Worker
297*1c60b9acSAndroid Build Coastguard Worker static int
lws_plugins_dir_cb(const char * dirpath,void * user,struct lws_dir_entry * lde)298*1c60b9acSAndroid Build Coastguard Worker lws_plugins_dir_cb(const char *dirpath, void *user, struct lws_dir_entry *lde)
299*1c60b9acSAndroid Build Coastguard Worker {
300*1c60b9acSAndroid Build Coastguard Worker struct lws_plugins_args *pa = (struct lws_plugins_args *)user;
301*1c60b9acSAndroid Build Coastguard Worker char path[256], base[64], *q = base;
302*1c60b9acSAndroid Build Coastguard Worker const lws_plugin_header_t *pl;
303*1c60b9acSAndroid Build Coastguard Worker const char *p;
304*1c60b9acSAndroid Build Coastguard Worker
305*1c60b9acSAndroid Build Coastguard Worker if (strlen(lde->name) < 7)
306*1c60b9acSAndroid Build Coastguard Worker return 0; /* keep going */
307*1c60b9acSAndroid Build Coastguard Worker
308*1c60b9acSAndroid Build Coastguard Worker /*
309*1c60b9acSAndroid Build Coastguard Worker * The actual plugin names for protocol plugins look like
310*1c60b9acSAndroid Build Coastguard Worker * "libprotocol_lws_ssh_base.so" and for event libs
311*1c60b9acSAndroid Build Coastguard Worker * "libwebsockets-evlib_ev.so"... to recover the base name of
312*1c60b9acSAndroid Build Coastguard Worker * "lws_ssh_base" and "evlib_ev" we strip from the left to after the
313*1c60b9acSAndroid Build Coastguard Worker * first _ or -, and then truncate at the first .
314*1c60b9acSAndroid Build Coastguard Worker */
315*1c60b9acSAndroid Build Coastguard Worker
316*1c60b9acSAndroid Build Coastguard Worker p = lde->name;
317*1c60b9acSAndroid Build Coastguard Worker while (*p && *p != '_' && *p != '-')
318*1c60b9acSAndroid Build Coastguard Worker p++;
319*1c60b9acSAndroid Build Coastguard Worker if (!*p)
320*1c60b9acSAndroid Build Coastguard Worker return 0;
321*1c60b9acSAndroid Build Coastguard Worker p++;
322*1c60b9acSAndroid Build Coastguard Worker while (*p && *p != '.' && lws_ptr_diff(q, base) < (int)sizeof(base) - 1)
323*1c60b9acSAndroid Build Coastguard Worker *q++ = *p++;
324*1c60b9acSAndroid Build Coastguard Worker *q = '\0';
325*1c60b9acSAndroid Build Coastguard Worker
326*1c60b9acSAndroid Build Coastguard Worker /* if he's given a filter, only match if base matches it */
327*1c60b9acSAndroid Build Coastguard Worker if (pa->filter && strcmp(base, pa->filter))
328*1c60b9acSAndroid Build Coastguard Worker return 0; /* keep going */
329*1c60b9acSAndroid Build Coastguard Worker
330*1c60b9acSAndroid Build Coastguard Worker lws_snprintf(path, sizeof(path) - 1, "%s/%s", dirpath, lde->name);
331*1c60b9acSAndroid Build Coastguard Worker
332*1c60b9acSAndroid Build Coastguard Worker pl = lws_plat_dlopen(pa->pplugin, path, base, pa->_class,
333*1c60b9acSAndroid Build Coastguard Worker pa->each, pa->each_user);
334*1c60b9acSAndroid Build Coastguard Worker
335*1c60b9acSAndroid Build Coastguard Worker /*
336*1c60b9acSAndroid Build Coastguard Worker * If we were looking for a specific plugin, finding it should make
337*1c60b9acSAndroid Build Coastguard Worker * us stop looking (eg, to account for directory precedence of the
338*1c60b9acSAndroid Build Coastguard Worker * same plugin). If scanning for plugins in a dir, we always keep
339*1c60b9acSAndroid Build Coastguard Worker * going.
340*1c60b9acSAndroid Build Coastguard Worker */
341*1c60b9acSAndroid Build Coastguard Worker
342*1c60b9acSAndroid Build Coastguard Worker return pa->filter && pl;
343*1c60b9acSAndroid Build Coastguard Worker }
344*1c60b9acSAndroid Build Coastguard Worker
345*1c60b9acSAndroid Build Coastguard Worker int
lws_plugins_init(struct lws_plugin ** pplugin,const char * const * d,const char * _class,const char * filter,each_plugin_cb_t each,void * each_user)346*1c60b9acSAndroid Build Coastguard Worker lws_plugins_init(struct lws_plugin **pplugin, const char * const *d,
347*1c60b9acSAndroid Build Coastguard Worker const char *_class, const char *filter,
348*1c60b9acSAndroid Build Coastguard Worker each_plugin_cb_t each, void *each_user)
349*1c60b9acSAndroid Build Coastguard Worker {
350*1c60b9acSAndroid Build Coastguard Worker struct lws_plugins_args pa;
351*1c60b9acSAndroid Build Coastguard Worker char *ld_env;
352*1c60b9acSAndroid Build Coastguard Worker int ret = 1;
353*1c60b9acSAndroid Build Coastguard Worker
354*1c60b9acSAndroid Build Coastguard Worker pa.pplugin = pplugin;
355*1c60b9acSAndroid Build Coastguard Worker pa._class = _class;
356*1c60b9acSAndroid Build Coastguard Worker pa.each = each;
357*1c60b9acSAndroid Build Coastguard Worker pa.each_user = each_user;
358*1c60b9acSAndroid Build Coastguard Worker pa.filter = filter;
359*1c60b9acSAndroid Build Coastguard Worker
360*1c60b9acSAndroid Build Coastguard Worker /*
361*1c60b9acSAndroid Build Coastguard Worker * Check LD_LIBRARY_PATH override path first if present
362*1c60b9acSAndroid Build Coastguard Worker */
363*1c60b9acSAndroid Build Coastguard Worker
364*1c60b9acSAndroid Build Coastguard Worker ld_env = getenv("LD_LIBRARY_PATH");
365*1c60b9acSAndroid Build Coastguard Worker if (ld_env) {
366*1c60b9acSAndroid Build Coastguard Worker char temp[128];
367*1c60b9acSAndroid Build Coastguard Worker struct lws_tokenize ts;
368*1c60b9acSAndroid Build Coastguard Worker
369*1c60b9acSAndroid Build Coastguard Worker memset(&ts, 0, sizeof(ts));
370*1c60b9acSAndroid Build Coastguard Worker ts.start = ld_env;
371*1c60b9acSAndroid Build Coastguard Worker ts.len = strlen(ld_env);
372*1c60b9acSAndroid Build Coastguard Worker ts.flags = LWS_TOKENIZE_F_SLASH_NONTERM |
373*1c60b9acSAndroid Build Coastguard Worker LWS_TOKENIZE_F_DOT_NONTERM |
374*1c60b9acSAndroid Build Coastguard Worker LWS_TOKENIZE_F_MINUS_NONTERM |
375*1c60b9acSAndroid Build Coastguard Worker LWS_TOKENIZE_F_NO_INTEGERS |
376*1c60b9acSAndroid Build Coastguard Worker LWS_TOKENIZE_F_NO_FLOATS;
377*1c60b9acSAndroid Build Coastguard Worker
378*1c60b9acSAndroid Build Coastguard Worker do {
379*1c60b9acSAndroid Build Coastguard Worker ts.e = (int8_t)lws_tokenize(&ts);
380*1c60b9acSAndroid Build Coastguard Worker if (ts.e != LWS_TOKZE_TOKEN)
381*1c60b9acSAndroid Build Coastguard Worker continue;
382*1c60b9acSAndroid Build Coastguard Worker
383*1c60b9acSAndroid Build Coastguard Worker lws_strnncpy(temp, ts.token,
384*1c60b9acSAndroid Build Coastguard Worker ts.token_len,
385*1c60b9acSAndroid Build Coastguard Worker sizeof(temp));
386*1c60b9acSAndroid Build Coastguard Worker
387*1c60b9acSAndroid Build Coastguard Worker lwsl_info("%s: trying %s\n", __func__, temp);
388*1c60b9acSAndroid Build Coastguard Worker if (!lws_dir(temp, &pa, lws_plugins_dir_cb))
389*1c60b9acSAndroid Build Coastguard Worker ret = 0;
390*1c60b9acSAndroid Build Coastguard Worker
391*1c60b9acSAndroid Build Coastguard Worker } while (ts.e > 0);
392*1c60b9acSAndroid Build Coastguard Worker }
393*1c60b9acSAndroid Build Coastguard Worker
394*1c60b9acSAndroid Build Coastguard Worker while (d && *d) {
395*1c60b9acSAndroid Build Coastguard Worker lwsl_info("%s: trying %s\n", __func__, *d);
396*1c60b9acSAndroid Build Coastguard Worker if (!lws_dir(*d, &pa, lws_plugins_dir_cb))
397*1c60b9acSAndroid Build Coastguard Worker ret = 0;
398*1c60b9acSAndroid Build Coastguard Worker
399*1c60b9acSAndroid Build Coastguard Worker d++;
400*1c60b9acSAndroid Build Coastguard Worker }
401*1c60b9acSAndroid Build Coastguard Worker
402*1c60b9acSAndroid Build Coastguard Worker return ret;
403*1c60b9acSAndroid Build Coastguard Worker }
404*1c60b9acSAndroid Build Coastguard Worker
405*1c60b9acSAndroid Build Coastguard Worker int
lws_plugins_destroy(struct lws_plugin ** pplugin,each_plugin_cb_t each,void * each_user)406*1c60b9acSAndroid Build Coastguard Worker lws_plugins_destroy(struct lws_plugin **pplugin, each_plugin_cb_t each,
407*1c60b9acSAndroid Build Coastguard Worker void *each_user)
408*1c60b9acSAndroid Build Coastguard Worker {
409*1c60b9acSAndroid Build Coastguard Worker struct lws_plugin *p = *pplugin, *p1;
410*1c60b9acSAndroid Build Coastguard Worker
411*1c60b9acSAndroid Build Coastguard Worker while (p) {
412*1c60b9acSAndroid Build Coastguard Worker if (each)
413*1c60b9acSAndroid Build Coastguard Worker each(p, each_user);
414*1c60b9acSAndroid Build Coastguard Worker lws_plat_destroy_dl(p);
415*1c60b9acSAndroid Build Coastguard Worker p1 = p->list;
416*1c60b9acSAndroid Build Coastguard Worker p->list = NULL;
417*1c60b9acSAndroid Build Coastguard Worker lws_free(p);
418*1c60b9acSAndroid Build Coastguard Worker p = p1;
419*1c60b9acSAndroid Build Coastguard Worker }
420*1c60b9acSAndroid Build Coastguard Worker
421*1c60b9acSAndroid Build Coastguard Worker *pplugin = NULL;
422*1c60b9acSAndroid Build Coastguard Worker
423*1c60b9acSAndroid Build Coastguard Worker return 0;
424*1c60b9acSAndroid Build Coastguard Worker }
425*1c60b9acSAndroid Build Coastguard Worker #endif
426