summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2021-02-05 12:39:25 -0500
committerGlenn Strauss <gstrauss@gluelogic.com>2023-05-03 23:11:34 -0400
commitd7bbd70bd10e429c18df273dd060006a69a91d1e (patch)
treec56167e09c96919abbf8d03e3eabf78a11d76490
parent8e8938a359019c9aa1f2413c0419cd5124d33840 (diff)
downloadlighttpd-git-d7bbd70bd10e429c18df273dd060006a69a91d1e.tar.gz
[multiple] _WIN32 Find*File() sys-dirent.h
_WIN32 FindFirstFile(), FindNextFile(), FindClose()
-rw-r--r--src/Makefile.am2
-rw-r--r--src/mod_dirlisting.c12
-rw-r--r--src/mod_webdav.c16
-rw-r--r--src/sys-dirent.h187
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