You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
191 lines
4.0 KiB
191 lines
4.0 KiB
/*
|
|
* libwebsockets - small server side websockets and web server implementation
|
|
*
|
|
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to
|
|
* deal in the Software without restriction, including without limitation the
|
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
* sell copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
* IN THE SOFTWARE.
|
|
*/
|
|
|
|
#if !defined(NO_GNU_SOURCE_THIS_TIME)
|
|
#define NO_GNU_SOURCE_THIS_TIME
|
|
#endif
|
|
#if !defined(_DARWIN_C_SOURCE)
|
|
#define _DARWIN_C_SOURCE
|
|
#endif
|
|
|
|
#include <libwebsockets.h>
|
|
#include "private-lib-core.h"
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
#if defined(LWS_WITH_LIBUV) && UV_VERSION_MAJOR > 0
|
|
|
|
int
|
|
lws_dir(const char *dirpath, void *user, lws_dir_callback_function cb)
|
|
{
|
|
struct lws_dir_entry lde;
|
|
uv_dirent_t dent;
|
|
uv_fs_t req;
|
|
int ret = 1, ir;
|
|
uv_loop_t loop;
|
|
|
|
ir = uv_loop_init(&loop);
|
|
if (ir) {
|
|
lwsl_err("%s: loop init failed %d\n", __func__, ir);
|
|
return 1;
|
|
}
|
|
|
|
ir = uv_fs_scandir(&loop, &req, dirpath, 0, NULL);
|
|
if (ir < 0) {
|
|
lwsl_err("Scandir on %s failed, errno %d\n", dirpath, LWS_ERRNO);
|
|
ret = 2;
|
|
goto bail;
|
|
}
|
|
|
|
while (uv_fs_scandir_next(&req, &dent) != UV_EOF) {
|
|
lde.name = dent.name;
|
|
lde.type = (int)dent.type;
|
|
if (cb(dirpath, user, &lde))
|
|
goto bail1;
|
|
}
|
|
|
|
ret = 0;
|
|
|
|
bail1:
|
|
uv_fs_req_cleanup(&req);
|
|
bail:
|
|
while (uv_loop_close(&loop))
|
|
;
|
|
|
|
return ret;
|
|
}
|
|
|
|
#else
|
|
|
|
#if !defined(_WIN32) && !defined(LWS_PLAT_FREERTOS)
|
|
|
|
#include <dirent.h>
|
|
|
|
static int filter(const struct dirent *ent)
|
|
{
|
|
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
int
|
|
lws_dir(const char *dirpath, void *user, lws_dir_callback_function cb)
|
|
{
|
|
struct lws_dir_entry lde;
|
|
struct dirent **namelist;
|
|
int n, i, ret = 1;
|
|
|
|
n = scandir((char *)dirpath, &namelist, filter, alphasort);
|
|
if (n < 0) {
|
|
lwsl_err("Scandir on '%s' failed, errno %d\n", dirpath, LWS_ERRNO);
|
|
return 1;
|
|
}
|
|
|
|
for (i = 0; i < n; i++) {
|
|
if (strchr(namelist[i]->d_name, '~'))
|
|
goto skip;
|
|
lde.name = namelist[i]->d_name;
|
|
|
|
/*
|
|
* some filesystems don't report this (ZFS) and tell that
|
|
* files are LDOT_UNKNOWN
|
|
*/
|
|
|
|
#if defined(__sun)
|
|
struct stat s;
|
|
stat(namelist[i]->d_name, &s);
|
|
switch (s.st_mode) {
|
|
case S_IFBLK:
|
|
lde.type = LDOT_BLOCK;
|
|
break;
|
|
case S_IFCHR:
|
|
lde.type = LDOT_CHAR;
|
|
break;
|
|
case S_IFDIR:
|
|
lde.type = LDOT_DIR;
|
|
break;
|
|
case S_IFIFO:
|
|
lde.type = LDOT_FIFO;
|
|
break;
|
|
case S_IFLNK:
|
|
lde.type = LDOT_LINK;
|
|
break;
|
|
case S_IFREG:
|
|
lde.type = LDOT_FILE;
|
|
break;
|
|
default:
|
|
lde.type = LDOT_UNKNOWN;
|
|
break;
|
|
}
|
|
#else
|
|
switch (namelist[i]->d_type) {
|
|
case DT_BLK:
|
|
lde.type = LDOT_BLOCK;
|
|
break;
|
|
case DT_CHR:
|
|
lde.type = LDOT_CHAR;
|
|
break;
|
|
case DT_DIR:
|
|
lde.type = LDOT_DIR;
|
|
break;
|
|
case DT_FIFO:
|
|
lde.type = LDOT_FIFO;
|
|
break;
|
|
case DT_LNK:
|
|
lde.type = LDOT_LINK;
|
|
break;
|
|
case DT_REG:
|
|
lde.type = LDOT_FILE;
|
|
break;
|
|
case DT_SOCK:
|
|
lde.type = LDOTT_SOCKET;
|
|
break;
|
|
default:
|
|
lde.type = LDOT_UNKNOWN;
|
|
break;
|
|
}
|
|
#endif
|
|
if (cb(dirpath, user, &lde)) {
|
|
while (i++ < n)
|
|
free(namelist[i]);
|
|
goto bail;
|
|
}
|
|
skip:
|
|
free(namelist[i]);
|
|
}
|
|
|
|
ret = 0;
|
|
|
|
bail:
|
|
free(namelist);
|
|
|
|
return ret;
|
|
}
|
|
|
|
#else
|
|
#error "If you want lws_dir on windows, you need libuv"
|
|
#endif
|
|
#endif
|