From 06cf6fdcb4b33f3751ec8d121c98e00553c8b069 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sun, 27 Dec 2015 13:18:42 +0000 Subject: [PATCH] Provide setenv/unsetenv for environments lacking them. Bug 1578 Currently this covers HP-UX and older Solaris. --- src/OS/Makefile-Base | 4 +++- src/OS/os.h-HP-UX | 1 + src/OS/os.h-SunOS5 | 6 +++++ src/scripts/MakeLinks | 1 + src/src/setenv.c | 55 +++++++++++++++++++++++++++++++++++++++++++ src/src/tls.c | 14 +++++++---- 6 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 src/src/setenv.c diff --git a/src/OS/Makefile-Base b/src/OS/Makefile-Base index 9c713f0a1..960c9afd6 100644 --- a/src/OS/Makefile-Base +++ b/src/OS/Makefile-Base @@ -620,7 +620,9 @@ spool_out.o: $(HDRS) spool_out.c std-crypto.o: $(HDRS) std-crypto.c store.o: $(HDRS) store.c string.o: $(HDRS) string.c -tls.o: $(HDRS) tls.c tls-gnu.c tlscert-gnu.c tls-openssl.c tlscert-openssl.c +tls.o: $(HDRS) tls.c setenv.c \ + tls-gnu.c tlscert-gnu.c \ + tls-openssl.c tlscert-openssl.c tod.o: $(HDRS) tod.c transport.o: $(HDRS) transport.c tree.o: $(HDRS) tree.c diff --git a/src/OS/os.h-HP-UX b/src/OS/os.h-HP-UX index 4998734f6..1b599231d 100644 --- a/src/OS/os.h-HP-UX +++ b/src/OS/os.h-HP-UX @@ -10,6 +10,7 @@ #define FSCALE 1.0 #define HAVE_SYS_STATVFS_H +#define MISSING_UNSETENV_3 #define F_FREESP O_TRUNC #define NEED_H_ERRNO 1 diff --git a/src/OS/os.h-SunOS5 b/src/OS/os.h-SunOS5 index dd14f25c8..bb1d77fe9 100644 --- a/src/OS/os.h-SunOS5 +++ b/src/OS/os.h-SunOS5 @@ -28,7 +28,13 @@ it seems. */ #define PAM_CONVERSE_ARG2_TYPE struct pam_message + /* default is non-const */ #define ICONV_ARG2_TYPE const char ** +#if _POSIX_C_SOURCE < 200112L +# define MISSING_UNSETENV_3 +#endof + + /* End */ diff --git a/src/scripts/MakeLinks b/src/scripts/MakeLinks index b7e0fabbd..e011c3ca1 100755 --- a/src/scripts/MakeLinks +++ b/src/scripts/MakeLinks @@ -106,6 +106,7 @@ for f in dbfunctions.h dbstuff.h exim.h functions.h globals.h local_scan.h \ exim_dbutil.c exim_lock.c expand.c filter.c filtertest.c globals.c \ header.c host.c ip.c log.c lss.c match.c moan.c parse.c perl.c queue.c \ rda.c readconf.c receive.c retry.c rewrite.c rfc2047.c route.c search.c \ + setenv.c \ sieve.c smtp_in.c smtp_out.c spool_in.c spool_out.c std-crypto.c store.c \ string.c tls.c tlscert-gnu.c tlscert-openssl.c tls-gnu.c tls-openssl.c \ tod.c transport.c tree.c verify.c version.c dkim.c dkim.h dmarc.c dmarc.h \ diff --git a/src/src/setenv.c b/src/src/setenv.c new file mode 100644 index 000000000..6da56d58d --- /dev/null +++ b/src/src/setenv.c @@ -0,0 +1,55 @@ +/************************************************* +* Exim - an Internet mail transport agent * +*************************************************/ + +/* Copyright (c) Michael Haardt 2015 */ +/* Copyright (c) Jeremy Harris 2015 */ +/* See the file NOTICE for conditions of use and distribution. */ + +/* This module provides (un)setenv routines for those environments +lacking them in libraries. */ + + +static int +setenv(const char * name, const char * val, int overwrite) +{ +uschar * s; +if (Ustrchr(name, '=')) return -1; +if (overwrite || !getenv(name)) + putenv(CS string_copy_malloc(string_sprintf("%s=%s", name, val))); +return 0; +} + +static int +unsetenv(const char *name) +{ +size_t len; +const char * end; +char ** e; +extern char ** environ; + +if (!name) + { + errno = EINVAL; + return -1; + } + +for (end = name; *end != '=' && *end; ) end++; +len = end - name; + +/* Find name in environment and move remaining variables down. +Do not early-out in case there are duplicate names. */ + +for (e = environ; *e; e++) + if (strncmp(*e, name, len) == 0 && (*e)[len] == '=') + { + char ** sp = e; + do *sp = sp[1]; while (*++sp); + } + +return 0; +} + +/* vi: aw ai sw=2 +*/ +/* End of setenv.c */ diff --git a/src/src/tls.c b/src/src/tls.c index a3658276f..5958dfc1c 100644 --- a/src/src/tls.c +++ b/src/src/tls.c @@ -84,22 +84,26 @@ return TRUE; * Timezone environment flipping * *************************************************/ +#ifdef MISSING_UNSETENV_3 +# include "setenv.c" +#endif + static uschar * to_tz(uschar * tz) { uschar * old = US getenv("TZ"); - setenv("TZ", CS tz, 1); - tzset(); + (void) setenv("TZ", CCS tz, 1); + tzset(); return old; } static void restore_tz(uschar * tz) { if (tz) - setenv("TZ", CS tz, 1); + (void) setenv("TZ", CCS tz, 1); else - unsetenv("TZ"); - tzset(); + (void) unsetenv("TZ"); + tzset(); } /************************************************* -- 2.30.2