diff options
author | Glenn Strauss <gstrauss@gluelogic.com> | 2021-02-05 12:39:25 -0500 |
---|---|---|
committer | Glenn Strauss <gstrauss@gluelogic.com> | 2023-05-03 23:11:34 -0400 |
commit | d7bbd70bd10e429c18df273dd060006a69a91d1e (patch) | |
tree | c56167e09c96919abbf8d03e3eabf78a11d76490 | |
parent | 8e8938a359019c9aa1f2413c0419cd5124d33840 (diff) | |
download | lighttpd-git-d7bbd70bd10e429c18df273dd060006a69a91d1e.tar.gz |
[multiple] _WIN32 Find*File() sys-dirent.h
_WIN32 FindFirstFile(), FindNextFile(), FindClose()
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/mod_dirlisting.c | 12 | ||||
-rw-r--r-- | src/mod_webdav.c | 16 | ||||
-rw-r--r-- | src/sys-dirent.h | 187 |
4 files changed, 193 insertions, 24 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 4a3d3042..628ffc48 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -359,7 +359,7 @@ hdr = base64.h buffer.h burl.h network.h log.h http_kv.h keyvalue.h \ sock_addr_cache.h \ configparser.h \ rand.h \ - sys-crypto.h sys-crypto-md.h \ + sys-crypto.h sys-crypto-md.h sys-dirent.h \ sys-endian.h sys-mmap.h sys-setjmp.h \ sys-socket.h sys-stat.h sys-strings.h \ sys-time.h \ diff --git a/src/mod_dirlisting.c b/src/mod_dirlisting.c index a16825fd..8e97acf3 100644 --- a/src/mod_dirlisting.c +++ b/src/mod_dirlisting.c @@ -11,6 +11,7 @@ #include "first.h" +#include "sys-dirent.h" #include "sys-stat.h" #include "sys-time.h" @@ -40,17 +41,6 @@ #endif #endif -#ifndef _WIN32 -#include <dirent.h> -#endif -#ifndef _D_EXACT_NAMLEN -#ifdef _DIRENT_HAVE_D_NAMLEN -#define _D_EXACT_NAMLEN(d) ((d)->d_namlen) -#else -#define _D_EXACT_NAMLEN(d) (strlen ((d)->d_name)) -#endif -#endif - #ifdef _WIN32 #include <windows.h> #include <stringapiset.h> diff --git a/src/mod_webdav.c b/src/mod_webdav.c index 77b6a5dc..095c2e7d 100644 --- a/src/mod_webdav.c +++ b/src/mod_webdav.c @@ -155,7 +155,7 @@ */ -/* linkat() fstatat() unlinkat() fdopendir() NAME_MAX */ +/* linkat() fstatat() unlinkat() fdopendir() */ #if !defined(_XOPEN_SOURCE) || _XOPEN_SOURCE-0 < 700 #undef _XOPEN_SOURCE #define _XOPEN_SOURCE 700 @@ -176,11 +176,11 @@ #endif #include "first.h" /* first */ +#include "sys-dirent.h" #include "sys-mmap.h" #include <sys/types.h> #include "sys-stat.h" #include "sys-time.h" -#include <dirent.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> /* rename() */ @@ -233,14 +233,6 @@ typedef off_t loff_t; #define linkat(odfd,opath,ndfd,npath,flags) -1 #endif -#ifndef _D_EXACT_NAMLEN -#ifdef _DIRENT_HAVE_D_NAMLEN -#define _D_EXACT_NAMLEN(d) ((d)->d_namlen) -#else -#define _D_EXACT_NAMLEN(d) (strlen ((d)->d_name)) -#endif -#endif - #ifndef PATH_MAX #define PATH_MAX 4096 #endif @@ -2518,7 +2510,7 @@ webdav_delete_dir (const plugin_config * const pconf, * so be sure to restore to base each loop iter */ const uint32_t dst_path_used = dst->path.used; const uint32_t dst_rel_path_used = dst->rel_path.used; - int s_isdir; + int s_isdir = 0; struct dirent *de; while (NULL != (de = readdir(dir))) { if (de->d_name[0] == '.' @@ -3219,7 +3211,7 @@ webdav_copymove_dir (const plugin_config * const pconf, webdav_xml_response_status(r, &src->rel_path, 403); return 403; /* Forbidden */ } - mode_t d_type; + mode_t d_type = 0; int multi_status = 0; struct dirent *de; while (NULL != (de = readdir(srcdir))) { diff --git a/src/sys-dirent.h b/src/sys-dirent.h new file mode 100644 index 00000000..213112e7 --- /dev/null +++ b/src/sys-dirent.h @@ -0,0 +1,187 @@ +/* + * sys-dirent.h - <sys/dirent.h> wrapper (selected functions; not complete) + * + * Copyright(c) 2021 Glenn Strauss gstrauss()gluelogic.com All rights reserved + * License: BSD 3-clause (same as lighttpd) + */ +#ifndef INCLUDED_SYS_DIRENT_H +#define INCLUDED_SYS_DIRENT_H +#include "first.h" + +#include <sys/types.h> +#ifndef _WIN32 +#include <dirent.h> +#endif + + +#ifdef _WIN32 + +#include <windows.h> +#include <direct.h> +#include <stdlib.h> +#include <stringapiset.h> + +/*#include <stdlib.h>*/ /* _MAX_PATH */ +/* Windows C Runtime supports path lengths up to 32768 characters in length (_MAX_PATH) + * https://docs.microsoft.com/en-us/cpp/c-runtime-library/path-field-limits?view=msvc-160 + * + * Impose a shorter limit (4k) since using stack below (char path[PATH_MAX+1]) + */ +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + +#ifndef DT_UNKNOWN +#define DT_UNKNOWN 0 +#endif +#ifndef DT_FIFO +#define DT_FIFO 1 +#endif +#ifndef DT_CHR +#define DT_CHR 2 +#endif +#ifndef DT_DIR +#define DT_DIR 4 +#endif +#ifndef DT_BLK +#define DT_BLK 6 +#endif +#ifndef DT_REG +#define DT_REG 8 +#endif +#ifndef DT_LNK +#define DT_LNK 10 +#endif +#ifndef DT_SOCK +#define DT_SOCK 12 +#endif +#ifndef DT_WHT +#define DT_WHT 14 +#endif +#ifndef _DIRENT_HAVE_D_NAMLEN +#define _DIRENT_HAVE_D_NAMLEN 1 +#endif +#ifndef _DIRENT_HAVE_D_TYPE +#define _DIRENT_HAVE_D_TYPE 1 +#endif +#ifndef DTTOIF +#define DTTOIF(d_type) (((mode_t)(d_type)) << 12) +#endif +/* minimal implementation to walk directory */ +struct dirent { + char *d_name; + uint8_t d_type; + uint16_t d_namlen; +}; +struct DIR { + int first; + int last_error; + HANDLE hFind; + struct dirent de; + WIN32_FIND_DATAW ffd; + char fnUTF8[260*4+1]; /* <stdio.h> FILENAME_MAX 260 */ +}; +typedef struct DIR DIR; + +static inline int +closedir (DIR * const dirp); +static inline int +closedir (DIR * const dirp) +{ + if (!dirp) { + errno = EBADF; + return -1; + } + FindClose(dirp->hFind); + free(dirp); + return 0; +} + +static inline DIR * +opendir (const char *name); +static inline DIR * +opendir (const char *name) +{ + WCHAR wbuf[4096]; + int wlen = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, name, -1, + wbuf, (sizeof(wbuf)/sizeof(*wbuf))-2); + if (wlen < 2) return NULL; + --wlen; + if (wbuf[wlen-1] != '/' && wbuf[wlen-1] != '\\') wbuf[wlen++] = '\\'; + wbuf[wlen] = '*'; + wbuf[wlen+1] = '\0'; + DIR * const dirp = calloc(1, sizeof(DIR)); + if (NULL == dirp) return NULL; + dirp->first = 1; + dirp->hFind = FindFirstFileExW(wbuf, FindExInfoBasic, &dirp->ffd, + FindExSearchNameMatch, NULL, + FIND_FIRST_EX_LARGE_FETCH); + if (INVALID_HANDLE_VALUE == dirp->hFind) { + if (GetLastError() != ERROR_FILE_NOT_FOUND) { + free(dirp); + return NULL; + } + dirp->last_error = ERROR_NO_MORE_FILES; + } /* else dirp->last_error = 0 */ + return dirp; +} + +static inline struct dirent * +readdir (DIR * const dirp); +static inline struct dirent * +readdir (DIR * const dirp) +{ + struct dirent * const de = &dirp->de; + WIN32_FIND_DATAW * const ffd = &dirp->ffd; + + do { + if (!dirp->first) { + if (0 == FindNextFileW(dirp->hFind, ffd)) + dirp->last_error = GetLastError(); + } + else + dirp->first = 0; + + if (dirp->last_error) + return NULL; + + const int dsz = + WideCharToMultiByte(CP_UTF8, 0, ffd->cFileName, -1, + dirp->fnUTF8, sizeof(dirp->fnUTF8), NULL, NULL); + if (dsz > 0 && dsz <= UINT16_MAX) { /*(dsz includes '\0' here)*/ + de->d_namlen = (uint16_t)(dsz-1); + de->d_name = dirp->fnUTF8; + if ((ffd->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) + == FILE_ATTRIBUTE_REPARSE_POINT) + de->d_type = DT_LNK; + /* XXX: incomplete; need to check for IO_REPARSE_TAG_SYMLINK */ + else if ((ffd->dwFileAttributes & FILE_ATTRIBUTE_DEVICE) + == FILE_ATTRIBUTE_DEVICE) + de->d_type = DT_CHR; + else if ((ffd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + == FILE_ATTRIBUTE_DIRECTORY) + de->d_type = DT_DIR; + else + de->d_type = DT_REG; + } + else /*(ignore excessively long names)*/ + de->d_namlen = 0; + + } while (0 == de->d_namlen); + + return de; +} + +#endif /* _WIN32 */ + + +#ifndef _D_EXACT_NAMLEN +#ifdef _DIRENT_HAVE_D_NAMLEN +#define _D_EXACT_NAMLEN(d) ((d)->d_namlen) +#else +#define _D_EXACT_NAMLEN(d) (strlen ((d)->d_name)) +#endif +#endif + + +#endif |