From d558a844149b8303538a8e7b60f8d5009eaa82d7 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Tue, 26 Apr 2005 19:53:45 +0000 Subject: Solaris compatibility patches --- acsite.m4 | 28 +++++++ common/compat.c | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++++- common/compat.h | 35 ++++++++ common/smtppass.c | 17 ++-- common/spio.c | 2 +- configure.in | 16 +++- src/clamsmtpd.c | 10 ++- 7 files changed, 326 insertions(+), 15 deletions(-) diff --git a/acsite.m4 b/acsite.m4 index e8cdb22..6ade204 100644 --- a/acsite.m4 +++ b/acsite.m4 @@ -198,3 +198,31 @@ fi AC_LANG_RESTORE ])dnl ACX_PTHREAD + +AC_DEFUN(AC_CHECK_GLOBAL, +[ +for ac_global in $1 +do + ac_tr_global=HAVE_`echo $ac_global | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + AC_MSG_CHECKING([for global variable ${ac_global}]) + AC_CACHE_VAL(ac_cv_global_$ac_global, + [ + AC_TRY_LINK(dnl + [/* no includes */], + [ extern long int $ac_global; exit((int)$ac_global)], + eval "ac_cv_global_${ac_global}=yes", + eval "ac_cv_global_${ac_global}=no" + ) + ] + ) + if eval "test \"`echo '$ac_cv_global_'$ac_global`\" = yes"; then + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED($ac_tr_global,1,Define if the global variable $ac_global is available) + else + AC_MSG_RESULT(no) + fi +done +]) + + + diff --git a/common/compat.c b/common/compat.c index 262f94d..23a73d0 100644 --- a/common/compat.c +++ b/common/compat.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Nate Nielsen + * Copyright (c) 2004-2005, Nate Nielsen * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -179,4 +179,235 @@ size_t strlcat(char* dst, const char* src, size_t siz) #endif +#ifndef HAVE_SETENV + +#include + +int setenv(const char* name, const char* value, int overwrite) +{ + char* t; + int r; + if(getenv(name) && !overwrite) + return 0; + t = (char*)malloc((strlen(name) + strlen(value) + 2) * sizeof(char)); + if(!t) return -1; + sprintf(t, "%s=%s", name, value); + r = putenv(t); + free(t); + return r; +} + +#endif + +#ifndef HAVE_DAEMON + +#include +#include +#include +#include +#include + +int daemon(int nochdir, int noclose) +{ + struct sigaction osa, sa; + int oerrno, fd, osa_ok; + pid_t newgrp; + + /* A SIGHUP may be thrown when the parent exits below. */ + sigemptyset(&sa.sa_mask); + sa.sa_handler = SIG_IGN; + sa.sa_flags = 0; + osa_ok = sigaction(SIGHUP, &sa, &osa); + + switch(fork()) + { + case -1: + return -1; + case 0: + break; + default: + _exit(0); + } + + newgrp = setsid(); + oerrno = errno; + if(osa_ok != -1) + sigaction(SIGHUP, &osa, NULL); + if(newgrp == -1) + { + errno = oerrno; + return -1; + } + if(!nochdir) + chdir("/"); + if(!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) + { + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + if(fd > 2) + close(fd); + } + return 0; + +} + +#endif + +#ifndef HAVE_ERR_H + +#include +#include +#include +#include + +extern char** __argv; + +static const char* calc_prog_name() +{ + static char prognamebuf[256]; + static int prepared = 0; + + if(!prepared) + { + const char* beg = strrchr(__argv[0], '\\'); + const char* temp = strrchr(__argv[0], '/'); + beg = (beg > temp) ? beg : temp; + beg = (beg) ? beg + 1 : __argv[0]; + + temp = strrchr(__argv[0], '.'); + temp = (temp > beg) ? temp : __argv[0] + strlen(__argv[0]); + + if((temp - beg) > 255) + temp = beg + 255; + + strncpy(prognamebuf, beg, temp - beg); + prognamebuf[temp - beg] = 0; + prepared = 1; + } + + return prognamebuf; +} + +static FILE* err_file; /* file to use for error output */ + +/* + * This is declared to take a `void *' so that the caller is not required + * to include first. However, it is really a `FILE *', and the + * manual page documents it as such. + */ +void err_set_file(void *fp) +{ + if (fp) + err_file = fp; + else + err_file = stderr; +} + +void err(int eval, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + verrc(eval, errno, fmt, ap); + va_end(ap); +} + +void verr(int eval, const char *fmt, va_list ap) +{ + verrc(eval, errno, fmt, ap); +} + +void errc(int eval, int code, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + verrc(eval, code, fmt, ap); + va_end(ap); +} + +void verrc(int eval, int code, const char *fmt, va_list ap) +{ + if (err_file == 0) + err_set_file((FILE *)0); + fprintf(err_file, "%s: ", calc_prog_name()); + if (fmt != NULL) { + vfprintf(err_file, fmt, ap); + fprintf(err_file, ": "); + } + fprintf(err_file, "%s\n", strerror(code)); + exit(eval); +} + +void errx(int eval, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + verrx(eval, fmt, ap); + va_end(ap); +} + +void verrx(int eval, const char *fmt, va_list ap) +{ + if (err_file == 0) + err_set_file((FILE *)0); + fprintf(err_file, "%s: ", calc_prog_name()); + if (fmt != NULL) + vfprintf(err_file, fmt, ap); + fprintf(err_file, "\n"); + exit(eval); +} + +void warn(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vwarnc(errno, fmt, ap); + va_end(ap); +} + +void vwarn(const char *fmt, va_list ap) +{ + vwarnc(errno, fmt, ap); +} + +void warnc(int code, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vwarnc(code, fmt, ap); + va_end(ap); +} + +void vwarnc(int code, const char *fmt, va_list ap) +{ + if (err_file == 0) + err_set_file((FILE *)0); + fprintf(err_file, "%s: ", calc_prog_name()); + if (fmt != NULL) + { + vfprintf(err_file, fmt, ap); + fprintf(err_file, ": "); + } + fprintf(err_file, "%s\n", strerror(code)); +} + +void warnx(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vwarnx(fmt, ap); + va_end(ap); +} + +void vwarnx(const char *fmt, va_list ap) +{ + if(err_file == 0) + err_set_file((FILE*)0); + fprintf(err_file, "%s: ", calc_prog_name()); + if(fmt != NULL) + vfprintf(err_file, fmt, ap); + fprintf(err_file, "\n"); +} + +#endif diff --git a/common/compat.h b/common/compat.h index 62d37b4..b772f63 100644 --- a/common/compat.h +++ b/common/compat.h @@ -83,4 +83,39 @@ size_t strlcat(char *dst, const char *src, size_t size); size_t strlcpy(char *dst, const char *src, size_t size); #endif +#ifndef HAVE_SETENV +int setenv(const char* name, const char* value, int overwrite); +#endif + +#ifndef HAVE_DAEMON +int daemon(int nochdir, int noclose); +#endif + +#ifdef HAVE_ERR_H +#include +#else +#include +void err_set_file(void *fp); +void err_set_exit(void (*ef)(int)); +void err(int eval, const char *fmt, ...); +void verr(int eval, const char *fmt, va_list ap); +void errc(int eval, int code, const char *fmt, ...); +void verrc(int eval, int code, const char *fmt, va_list ap); +void errx(int eval, const char *fmt, ...); +void verrx(int eval, const char *fmt, va_list ap); +void warn(const char *fmt, ...); +void vwarn(const char *fmt, va_list ap); +void warnc(int code, const char *fmt, ...); +void vwarnc(int code, const char *fmt, va_list ap); +void warnx(const char *fmt, ...); +void vwarnx(const char *fmt, va_list ap); +#endif + +#ifdef HAVE_PATHS_H +#include +#else +#define _PATH_DEVNULL "/dev/null" +#define _PATH_TMP "/tmp" +#endif + #endif /* _COMPAT_H_ */ diff --git a/common/smtppass.c b/common/smtppass.c index e5b88b9..2a312ad 100644 --- a/common/smtppass.c +++ b/common/smtppass.c @@ -45,14 +45,13 @@ #include #include +#include #include #include #include #include #include #include -#include -#include #include #include #include @@ -1328,7 +1327,6 @@ static void make_date(spctx_t* ctx, char* date) { size_t date_len; struct tm t2; - long gmt; time_t t; /* Get a basic date like: 'Wed Jun 30 21:49:08 1993' */ @@ -1341,13 +1339,18 @@ static void make_date(spctx_t* ctx, char* date) return; } - /* Now add the TZ */ trim_end(date); - gmt = t2.tm_gmtoff; date_len = strlen(date); - snprintf(date + date_len, MAX_DATE_LENGTH - date_len, " %+03d%02d (%s)", - (int)(gmt / 3600), (int)(gmt % 3600), t2.tm_zone); + { +#ifdef HAVE_TM_GMTOFF + time_t timezone = t2.tm_gmtoff; + char *tzname[2] = { t2.tm_zone, "" }; +#endif + + snprintf(date + date_len, MAX_DATE_LENGTH - date_len, " %+03d%02d (%s)", + (int)(timezone / 3600), (int)(timezone % 3600), tzname[2]); + } /* Break it off just in case */ date[MAX_DATE_LENGTH - 1] = 0; diff --git a/common/spio.c b/common/spio.c index c26f81a..d0efe05 100644 --- a/common/spio.c +++ b/common/spio.c @@ -56,8 +56,8 @@ #include #include #include -#include +#include "compat.h" #include "usuals.h" #include "sock_any.h" #include "stringx.h" diff --git a/configure.in b/configure.in index 7f59ab4..2527c67 100644 --- a/configure.in +++ b/configure.in @@ -66,12 +66,16 @@ fi ACX_PTHREAD( , [echo "ERROR: Pthread support not found."; exit 1] ) LIBS="$PTHREAD_LIBS $LIBS" -CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +CFLAGS="$CFLAGS $PTHREAD_CFLAGS -D_POSIX_PTHREAD_SEMANTICS" + +# Some checks for Solaris +AC_CHECK_LIB(socket, getsockname) +AC_CHECK_LIB(nsl, getaddrinfo) # Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS(limits.h,,) -AC_CHECK_HEADERS([unistd.h stdio.h stddef.h fcntl.h stdlib.h assert.h errno.h stdarg.h err.h string.h], , +AC_CHECK_HEADERS([limits.h err.h paths.h],,) +AC_CHECK_HEADERS([unistd.h stdio.h stddef.h fcntl.h stdlib.h assert.h errno.h stdarg.h string.h netdb.h], , [echo "ERROR: Required C header missing"; exit 1]) # Check for linux type transparent proxy support @@ -93,10 +97,14 @@ AC_CHECK_DECL(PTHREAD_MUTEX_ERRORCHECK_NP, [AC_DEFINE(HAVE_ERR_MUTEX, 1, "Error [AC_CHECK_DECL(PTHREAD_MUTEX_ERRORCHECK, [AC_DEFINE(HAVE_ERR_MUTEX, 2)], , [ #include ])], [ #include ]) +# Required Variables +AC_CHECK_MEMBER(struct tm.tm_gmtoff,,,[ #include ]) +AC_CHECK_GLOBAL(__argv) + # Required Functions AC_CHECK_FUNCS([memset strerror malloc realloc getopt strchr tolower getaddrinfo], , [echo "ERROR: Required function missing"; exit 1]) -AC_CHECK_FUNCS([strlwr strlcat strlcpy strncat strncpy]) +AC_CHECK_FUNCS([strlwr strlcat strlcpy strncat strncpy setenv daemon]) # Have to resolve this for the path below if test "${prefix}" = "NONE"; then diff --git a/src/clamsmtpd.c b/src/clamsmtpd.c index a0198a5..93d773f 100644 --- a/src/clamsmtpd.c +++ b/src/clamsmtpd.c @@ -39,13 +39,11 @@ #include #include -#include #include #include #include #include #include -#include #include "usuals.h" @@ -153,6 +151,10 @@ static int clam_scan_file(clctx_t* ctx, const char** virus); * STARTUP ETC... */ +#ifndef HAVE___ARGV +char** __argv; +#endif + int main(int argc, char* argv[]) { const char* configfile = DEFAULT_CONFIG; @@ -163,6 +165,10 @@ int main(int argc, char* argv[]) int r; char* t; +#ifndef HAVE___ARGV + __argv = argv; +#endif + /* Configuration defaults */ memset(&g_clstate, 0, sizeof(g_clstate)); g_clstate.directory = _PATH_TMP; -- cgit v1.2.3