#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
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)
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 *);
#include "exim.h"
+extern char **environ;
+
static void fn_smtp_receive_timeout(const uschar * name, const uschar * str);
+
#define CSTATE_STACK_SIZE 10
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++)
{
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 */
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
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
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