mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
lws_dir: add rm -rf and glob filter callbacks
Bring over two general-purpose callbacks for lws_dir from Sai
This commit is contained in:
parent
cb0ea63ef1
commit
cced12822b
2 changed files with 143 additions and 44 deletions
|
@ -577,6 +577,53 @@ lws_dir_callback_function(const char *dirpath, void *user,
|
|||
*/
|
||||
LWS_VISIBLE LWS_EXTERN int
|
||||
lws_dir(const char *dirpath, void *user, lws_dir_callback_function cb);
|
||||
|
||||
/**
|
||||
* lws_dir_rm_rf_cb() - callback for lws_dir that performs recursive rm -rf
|
||||
*
|
||||
* \param dirpath: directory we are at in lws_dir
|
||||
* \param user: ignored
|
||||
* \param lde: lws_dir info on the file or directory we are at
|
||||
*
|
||||
* This is a readymade rm -rf callback for use with lws_dir. It recursively
|
||||
* removes everything below the starting dir and then the starting dir itself.
|
||||
* Works on linux, OSX and Windows at least.
|
||||
*/
|
||||
LWS_VISIBLE LWS_EXTERN int
|
||||
lws_dir_rm_rf_cb(const char *dirpath, void *user, struct lws_dir_entry *lde);
|
||||
|
||||
/*
|
||||
* We pass every file in the base dir through a filter, and call back on the
|
||||
* ones that match. Directories are ignored.
|
||||
*
|
||||
* The original path filter string may look like, eg, "sai-*.deb" or "*.txt"
|
||||
*/
|
||||
|
||||
typedef int (*lws_dir_glob_cb_t)(void *data, const char *path);
|
||||
|
||||
typedef struct lws_dir_glob {
|
||||
const char *filter;
|
||||
lws_dir_glob_cb_t cb;
|
||||
void *user;
|
||||
} lws_dir_glob_t;
|
||||
|
||||
/**
|
||||
* lws_dir_glob_cb() - callback for lws_dir that performs filename globbing
|
||||
*
|
||||
* \param dirpath: directory we are at in lws_dir
|
||||
* \param user: pointer to your prepared lws_dir_glob_cb_t
|
||||
* \param lde: lws_dir info on the file or directory we are at
|
||||
*
|
||||
* \p user is prepared with an `lws_dir_glob_t` containing a callback for paths
|
||||
* that pass the filtering, a user pointer to pass to that callback, and a
|
||||
* glob string like "*.txt". It may not contain directories, the lws_dir musr
|
||||
* be started at the correct dir.
|
||||
*
|
||||
* Only the base path passed to lws_dir is scanned, it does not look in subdirs.
|
||||
*/
|
||||
LWS_VISIBLE LWS_EXTERN int
|
||||
lws_dir_glob_cb(const char *dirpath, void *user, struct lws_dir_entry *lde);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
140
lib/misc/dir.c
140
lib/misc/dir.c
|
@ -34,52 +34,24 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#if defined(WIN32)
|
||||
#include <direct.h>
|
||||
#define read _read
|
||||
#define open _open
|
||||
#define close _close
|
||||
#define write _write
|
||||
#define mkdir(x,y) _mkdir(x)
|
||||
#define rmdir _rmdir
|
||||
#define unlink _unlink
|
||||
#define HAVE_STRUCT_TIMESPEC
|
||||
#if defined(pid_t)
|
||||
#undef pid_t
|
||||
#endif
|
||||
#endif /* win32 */
|
||||
|
||||
#define COMBO_SIZEOF 256
|
||||
|
||||
#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(LWS_PLAT_FREERTOS)
|
||||
|
||||
#if defined(WIN32)
|
||||
|
@ -232,5 +204,85 @@ bail:
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check filename against one globby filter
|
||||
*
|
||||
* We can support things like "*.rpm"
|
||||
*/
|
||||
|
||||
static int
|
||||
lws_dir_glob_check(const char *nm, const char *filt)
|
||||
{
|
||||
while (*nm) {
|
||||
if (*filt == '*') {
|
||||
if (!strcmp(nm, filt + 1))
|
||||
return 1;
|
||||
} else {
|
||||
if (*nm != *filt)
|
||||
return 0;
|
||||
filt++;
|
||||
}
|
||||
nm++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We get passed a single filter string, like "*.txt" or "mydir/\*.rpm" or so.
|
||||
*/
|
||||
|
||||
int
|
||||
lws_dir_glob_cb(const char *dirpath, void *user, struct lws_dir_entry *lde)
|
||||
{
|
||||
lws_dir_glob_t *filter = (lws_dir_glob_t*)user;
|
||||
char path[384];
|
||||
|
||||
if (!strcmp(lde->name, ".") || !strcmp(lde->name, ".."))
|
||||
return 0;
|
||||
|
||||
if (lde->type == LDOT_DIR)
|
||||
return 0;
|
||||
|
||||
if (lws_dir_glob_check(lde->name, filter->filter)) {
|
||||
lws_snprintf(path, sizeof(path), "%s%c%s", dirpath, csep,
|
||||
lde->name);
|
||||
filter->cb(filter->user, path);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
lws_dir_rm_rf_cb(const char *dirpath, void *user, struct lws_dir_entry *lde)
|
||||
{
|
||||
char path[384];
|
||||
|
||||
if (!strcmp(lde->name, ".") || !strcmp(lde->name, ".."))
|
||||
return 0;
|
||||
|
||||
lws_snprintf(path, sizeof(path), "%s%c%s", dirpath, csep, lde->name);
|
||||
|
||||
if (lde->type == LDOT_DIR) {
|
||||
lws_dir(path, NULL, lws_dir_rm_rf_cb);
|
||||
if (rmdir(path))
|
||||
lwsl_warn("%s: rmdir %s failed %d\n", __func__, path, errno);
|
||||
} else {
|
||||
if (unlink(path)) {
|
||||
#if defined(WIN32)
|
||||
SetFileAttributesA(path, FILE_ATTRIBUTE_NORMAL);
|
||||
if (unlink(path))
|
||||
#else
|
||||
if (rmdir(path))
|
||||
#endif
|
||||
lwsl_warn("%s: unlink %s failed %d (type %d)\n",
|
||||
__func__, path, errno, lde->type);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue