aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-10-19 14:54:42 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-10-19 14:55:02 +0100
commit82bb01e1f894af9777625bfbfb9049e5083e0e56 (patch)
tree43fb7b3435dea59fcaf1f88626ead5a687f70968
parente139768a0dae674fa42528fe4297d67e8203eacb (diff)
downloadrspamd-82bb01e1f894af9777625bfbfb9049e5083e0e56.tar.gz
rspamd-82bb01e1f894af9777625bfbfb9049e5083e0e56.zip
[Fix] Another try to deal with posix idiotizm
-rw-r--r--CMakeLists.txt2
-rw-r--r--config.h.in2
-rw-r--r--src/client/rspamc.c44
3 files changed, 40 insertions, 8 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3163e6a94..882d46a8b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -965,6 +965,8 @@ CHECK_SYMBOL_EXISTS(O_ASYNC "sys/types.h;sys/fcntl.h" HAVE_OASYNC)
CHECK_SYMBOL_EXISTS(O_NOFOLLOW "sys/types.h;sys/fcntl.h" HAVE_ONOFOLLOW)
LIST(APPEND CMAKE_REQUIRED_INCLUDES "${LIBSSL_INCLUDE}")
CHECK_SYMBOL_EXISTS(SSL_set_tlsext_host_name "openssl/ssl.h" HAVE_SSL_TLSEXT_HOSTNAME)
+CHECK_SYMBOL_EXISTS(dirfd "sys/types.h;unistd.h;dirent.h" HAVE_DIRFD)
+CHECK_SYMBOL_EXISTS(fpathconf "sys/types.h;unistd.h" HAVE_FPATHCONF)
IF(ENABLE_PCRE2 MATCHES "ON")
IF(HAVE_PCRE_JIT)
diff --git a/config.h.in b/config.h.in
index 90edc1132..bb063b0f0 100644
--- a/config.h.in
+++ b/config.h.in
@@ -21,6 +21,7 @@
#cmakedefine HAVE_CPUID_H 1
#cmakedefine HAVE_CTYPE_H 1
#cmakedefine HAVE_DIRENT_H 1
+#cmakedefine HAVE_DIRFD 1
#cmakedefine HAVE_ENDIAN_H 1
#cmakedefine HAVE_EXP2L 1
#cmakedefine HAVE_EXPL 1
@@ -31,6 +32,7 @@
#cmakedefine HAVE_FDATASYNC 1
#cmakedefine HAVE_FETCH_H 1
#cmakedefine HAVE_FLOCK 1
+#cmakedefine HAVE_FPATHCONF 1
#cmakedefine HAVE_GETPAGESIZE 1
#cmakedefine HAVE_GET_CPUID 1
#cmakedefine HAVE_GLOB_H 1
diff --git a/src/client/rspamc.c b/src/client/rspamc.c
index 400c4c59b..c7068ae8d 100644
--- a/src/client/rspamc.c
+++ b/src/client/rspamc.c
@@ -1411,6 +1411,39 @@ rspamc_process_input (struct event_base *ev_base, struct rspamc_command *cmd,
g_free (hostbuf);
}
+static gsize
+rspamd_dirent_size (DIR * dirp)
+{
+ goffset name_max;
+ gsize name_end;
+
+#if defined(HAVE_FPATHCONF) && defined(HAVE_DIRFD) \
+ && defined(_PC_NAME_MAX)
+ name_max = fpathconf (dirfd (dirp), _PC_NAME_MAX);
+
+
+# if defined(NAME_MAX)
+ if (name_max == -1) {
+ name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
+ }
+# else
+ if (name_max == -1) {
+ return (size_t)(-1);
+ }
+# endif
+#else
+# if defined(NAME_MAX)
+ name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
+# else
+# error "buffer size for readdir_r cannot be determined"
+# endif
+#endif
+
+ name_end = G_STRUCT_OFFSET (struct dirent, d_name) + name_max + 1;
+
+ return (name_end > sizeof (struct dirent) ? name_end : sizeof(struct dirent));
+}
+
static void
rspamc_process_dir (struct event_base *ev_base, struct rspamc_command *cmd,
const gchar *name, GQueue *attrs)
@@ -1422,19 +1455,14 @@ rspamc_process_dir (struct event_base *ev_base, struct rspamc_command *cmd,
FILE *in;
struct stat st;
gboolean is_reg, is_dir;
- gsize name_max, len;
+ gsize len;
d = opendir (name);
if (d != NULL) {
/* Portably allocate struct direntry */
- name_max = pathconf (name, _PC_NAME_MAX);
-
- if (name_max == -1) {
- name_max = PATH_MAX;
- }
-
- len = G_STRUCT_OFFSET (struct dirent, d_name) + name_max + 1;
+ len = rspamd_dirent_size (d);
+ g_assert (len != (gsize)-1);
entry = g_malloc0 (len);
while (readdir_r (d, entry, pentry) == 0) {