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