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 18:08:46 +0100
commit92dac2f2b6ea5a6e80151c786606fb8c64d9b084 (patch)
tree78375e2912c79c9a40276e8e6923f9c804ff4524
parent152cb5455c4afbb67d8d6782e15173ccc5cbdd78 (diff)
downloadexim4-92dac2f2b6ea5a6e80151c786606fb8c64d9b084.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) (cherry picked from commit dd90c19962a63fe966e17c75b4a36639302d1e67) (cherry picked from commit a4046305716a24dd656c21e1698b0200747b3b59)
-rw-r--r--src/src/environment.c39
-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, 47 insertions, 15 deletions
diff --git a/src/src/environment.c b/src/src/environment.c
index aaa84f817..3af82a673 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,29 +25,44 @@ 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, USS &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)
{
uschar *p;
int sep = 0;
- const uschar* envlist = add_environment;
+ uschar* envlist = add_environment;
while ((p = string_nextinlist(&envlist, &sep, NULL, 0)))
putenv(CS p);
}
diff --git a/src/src/functions.h b/src/src/functions.h
index bb053d314..67a3916d5 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -375,7 +375,7 @@ extern uschar *string_append(uschar *, int *, int *, int, ...);
extern uschar *string_append_listele(uschar *, uschar, const uschar *);
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(uschar *);
extern uschar *string_copylc(uschar *);
diff --git a/src/src/readconf.c b/src/src/readconf.c
index 82a2823ac..6e330348f 100644
--- a/src/src/readconf.c
+++ b/src/src/readconf.c
@@ -11,6 +11,9 @@ implementation of the conditional .ifdef etc. */
#include "exim.h"
+extern char **environ;
+
+
#define CSTATE_STACK_SIZE 10
@@ -2638,7 +2641,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 4b1bcc265..38e498a44 100644
--- a/src/src/string.c
+++ b/src/src/string.c
@@ -1641,9 +1641,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 d6700f1c9..d4194b180 100644
--- a/test/stderr/0002
+++ b/test/stderr/0002
@@ -138,6 +138,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
@@ -203,6 +207,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
@@ -375,6 +383,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