summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2005-04-26 19:53:45 +0000
committerStef Walter <stef@memberwebs.com>2005-04-26 19:53:45 +0000
commitd558a844149b8303538a8e7b60f8d5009eaa82d7 (patch)
treeaefd84d482034c71761a39f1b3b7470c953faeeb
parent1226811e4aead186d1c94dd190c6a40ea4ec4c2d (diff)
Solaris compatibility patches
-rw-r--r--acsite.m428
-rw-r--r--common/compat.c233
-rw-r--r--common/compat.h35
-rw-r--r--common/smtppass.c17
-rw-r--r--common/spio.c2
-rw-r--r--configure.in16
-rw-r--r--src/clamsmtpd.c10
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 <stdio.h>
+
+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 <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <fcntl.h>
+
+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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+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 <stdio.h> 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 <err.h>
+#else
+#include <stdarg.h>
+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 <paths.h>
+#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 <sys/stat.h>
#include <ctype.h>
+#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <syslog.h>
#include <signal.h>
#include <errno.h>
-#include <err.h>
-#include <paths.h>
#include <stdarg.h>
#include <pwd.h>
#include <time.h>
@@ -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 <stdarg.h>
#include <unistd.h>
#include <errno.h>
-#include <err.h>
+#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 <pthread.h> ])], [ #include <pthread.h> ])
+# Required Variables
+AC_CHECK_MEMBER(struct tm.tm_gmtoff,,,[ #include <time.h> ])
+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 <sys/param.h>
#include <sys/wait.h>
-#include <paths.h>
#include <ctype.h>
#include <stdio.h>
#include <unistd.h>
#include <syslog.h>
#include <errno.h>
-#include <err.h>
#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;