summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>2016-03-01 21:11:42 +0100
committerHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>2016-03-02 17:52:58 +0100
commitdd90c19962a63fe966e17c75b4a36639302d1e67 (patch)
tree802e397714490cb9f7a4c9651e5b5d7eb1719a21
parent677c582e4da6b30f5467964bbd105c111247df25 (diff)
downloadexim4-dd90c19962a63fe966e17c75b4a36639302d1e67.tar.gz
Fix portability issues on *BSD and MacOS
(cherry picked from commit 2478dbdfba7cf729ddee43a5a77bde8c25ccdede) (cherry picked from commit 84bbb4d8164aae21a8e5418250359637d8aabc29) (cherry picked from commit cdbe36e825ffdeb88da83148a866db0c9c2806e7) (cherry picked from commit de5ba17561e686e5a05c9cc88288c82b563987de) (cherry picked from commit 35a5627dc1afa9c40adc64d215821750d4932a52)
-rw-r--r--src/src/environment.c37
-rw-r--r--src/src/functions.h2
-rw-r--r--src/src/readconf.c5
-rw-r--r--src/src/string.c4
-rw-r--r--test/stderr/000212
5 files changed, 46 insertions, 14 deletions
diff --git a/src/src/environment.c b/src/src/environment.c
index aaa84f817..8542dc0d2 100644
--- a/src/src/environment.c
+++ b/src/src/environment.c
@@ -9,6 +9,8 @@
#include "exim.h"
+extern char **environ;
+
/* The cleanup_environment() function is used during the startup phase
of the Exim process, right after reading the configurations main
part, before any expansions take place. It retains the environment
@@ -23,22 +25,37 @@ BOOL
cleanup_environment()
{
if (!keep_environment || *keep_environment == '\0')
- clearenv();
+ {
+ /* From: https://github.com/dovecot/core/blob/master/src/lib/env-util.c#L55
+ Try to clear the environment.
+ a) environ = NULL crashes on OS X.
+ b) *environ = NULL doesn't work on FreeBSD 7.0.
+ c) environ = emptyenv doesn't work on Haiku OS
+ d) environ = calloc() should work everywhere */
+
+ if (environ) *environ = NULL;
+
+ }
else if (Ustrcmp(keep_environment, "*") != 0)
{
uschar **p;
if (environ) for (p = USS environ; *p; /* see below */)
{
- uschar *name = string_copyn(*p, US Ustrchr(*p, '=') - *p);
-
- if (OK != match_isinlist(name, CUSS &keep_environment,
- 0, NULL, NULL, MCL_NOEXPAND, FALSE, NULL))
- if (unsetenv(CS name) < 0) return FALSE;
- else /* nothing */;
- else
- p++;
+ /* It's considered broken if we do not find the '=', according to
+ Florian Weimer. For now we ignore such strings. unsetenv() would complain,
+ getenv() would complain. */
+ uschar *eqp = Ustrchr(*p, '=');
- store_reset(name);
+ if (eqp)
+ {
+ uschar *name = string_copyn(*p, eqp - *p);
+ if (OK != match_isinlist(name, CUSS &keep_environment,
+ 0, NULL, NULL, MCL_NOEXPAND, FALSE, NULL))
+ if (unsetenv(CS name) < 0) return FALSE;
+ else p = USS environ; /* RESTART from the beginning */
+ else p++;
+ store_reset(name);
+ }
}
}
if (add_environment)
diff --git a/src/src/functions.h b/src/src/functions.h
index 8ddf848f2..fe20b035b 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -409,7 +409,7 @@ extern uschar *string_append_listele(uschar *, uschar, const uschar *);
extern uschar *string_append_listele_n(uschar *, uschar, const uschar *, unsigned);
extern uschar *string_base62(unsigned long int);
extern uschar *string_cat(uschar *, int *, int *, const uschar *, int);
-extern int string_compare_by_pointer(const uschar **, const uschar **);
+extern int string_compare_by_pointer(const void *, const void *);
extern uschar *string_copy_dnsdomain(uschar *);
extern uschar *string_copy_malloc(const uschar *);
extern uschar *string_copylc(const uschar *);
diff --git a/src/src/readconf.c b/src/src/readconf.c
index 9f6954cf0..1de6bd72e 100644
--- a/src/src/readconf.c
+++ b/src/src/readconf.c
@@ -11,9 +11,12 @@ implementation of the conditional .ifdef etc. */
#include "exim.h"
+extern char **environ;
+
static void fn_smtp_receive_timeout(const uschar * name, const uschar * str);
+
#define CSTATE_STACK_SIZE 10
@@ -2674,7 +2677,7 @@ if (type == NULL)
size_t n;
for (p = USS environ; *p; p++) ;
n = p - USS environ;
- qsort(environ, p - USS environ, sizeof(*p), (__compar_fn_t) string_compare_by_pointer);
+ qsort(environ, p - USS environ, sizeof(*p), string_compare_by_pointer);
for (p = USS environ; *p; p++)
{
diff --git a/src/src/string.c b/src/src/string.c
index b7e7db487..461dac56b 100644
--- a/src/src/string.c
+++ b/src/src/string.c
@@ -1712,9 +1712,9 @@ for -bP environment output, needs a function to compare two pointers to string
pointers. Here it is. */
int
-string_compare_by_pointer(const uschar **a, const uschar **b)
+string_compare_by_pointer(const void *a, const void *b)
{
-return Ustrcmp(CUS *a, CUS *b);
+return Ustrcmp(* CUSS a, * CUSS b);
}
#endif /* COMPILE_UTILITY */
diff --git a/test/stderr/0002 b/test/stderr/0002
index c19ce9ce3..d94e3686a 100644
--- a/test/stderr/0002
+++ b/test/stderr/0002
@@ -135,6 +135,10 @@ PWD in keep_environment? no (end of list)
SHELL in keep_environment? no (end of list)
TERM in keep_environment? no (end of list)
USER in keep_environment? yes (matched "USER")
+USER in keep_environment? yes (matched "USER")
+USER in keep_environment? yes (matched "USER")
+USER in keep_environment? yes (matched "USER")
+USER in keep_environment? yes (matched "USER")
configuration file is TESTSUITE/test-config
admin user
changed uid/gid: privilege not needed
@@ -199,6 +203,10 @@ PWD in keep_environment? no (end of list)
SHELL in keep_environment? no (end of list)
TERM in keep_environment? no (end of list)
USER in keep_environment? yes (matched "USER")
+USER in keep_environment? yes (matched "USER")
+USER in keep_environment? yes (matched "USER")
+USER in keep_environment? yes (matched "USER")
+USER in keep_environment? yes (matched "USER")
configuration file is TESTSUITE/test-config
admin user
changed uid/gid: privilege not needed
@@ -388,6 +396,10 @@ PWD in keep_environment? no (end of list)
SHELL in keep_environment? no (end of list)
TERM in keep_environment? no (end of list)
USER in keep_environment? yes (matched "USER")
+USER in keep_environment? yes (matched "USER")
+USER in keep_environment? yes (matched "USER")
+USER in keep_environment? yes (matched "USER")
+USER in keep_environment? yes (matched "USER")
configuration file is TESTSUITE/test-config
admin user
originator: uid=CALLER_UID gid=CALLER_GID login=CALLER name=CALLER_NAME