diff options
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | NEWS | 16 | ||||
-rw-r--r-- | configure.ac | 31 | ||||
-rw-r--r-- | doc/mailfromd.texi | 38 | ||||
-rw-r--r-- | gacopyz/gacopyz.c | 18 | ||||
-rw-r--r-- | gacopyz/server.c | 18 | ||||
-rw-r--r-- | src/Makefile.am | 13 | ||||
-rw-r--r-- | src/main.c | 26 | ||||
-rw-r--r-- | src/syslog_async.c | 43 |
9 files changed, 162 insertions, 60 deletions
@@ -1,6 +1,25 @@ +2007-12-12 Sergey Poznyakoff <gray@gnu.org.ua> + + * src/syslog_async.c: Include config.h, netinet/in.h and signal.h + Conditionally include paths.h, provide replacements for _PATH_LOG + and _PATH_CONSOLE if it is absent. + Provide dummy replacement for MSG_NOSIGNAL and LOG_PERROR. + (log_write_async): Ignore SIGPIPE if MSG_NOSIGNAL is not defined. + * src/main.c: Conditionally compile syslog-async stuff. + * src/Makefile.am: Likewise. + * configure.ac: Check for paths.h. + Restore previous meaning of --enable-syslog-async. + (DEFAULT_SYSLOG_ASYNC): New variable. + Raise version number to 4.2.1. + + * doc/mailfromd.texi: Reflect above-mentioned changes. + * gacopyz/server.c, gacopyz/gacopyz.c: Rename all sun to s_un and + sin to s_in, to avoid name clashes. + * NEWS (4.2.1): New entry. + 2007-10-23 Sergey Poznyakoff <gray@gnu.org.ua> * doc/mailfromd.texi: Do not use subheading commands inside of deffn. * doc/Makefile.am * doc/gendocs.sh: New file. A customized version. @@ -1,21 +1,31 @@ -Mailfromd NEWS -- history of user-visible changes. 2007-10-23 +Mailfromd NEWS -- history of user-visible changes. 2007-12-12 Copyright (C) 2005, 2006, 2007 Sergey Poznyakoff See the end of file for copying conditions. Please send mailfromd bug reports to <bug-mailfromd@gnu.org.ua> -Version 4.2 (SVN) +Version 4.2.1 + +* Restore previous meaning of --enable-syslog-async. + +Unless this option is given to ./configure, asynchronous syslog +implementation will not be compiled. + +* Fix compilation on Sun. + + +Version 4.2, 2007-10-23 * Licensed under the GPLv3 * New command line options --syslog-async and --no-syslog-async These options allow to select the implementation of syslog to use -at run time. +at run time. * RFC 2821 compatibility The sender verification engine used to send whitespace character between `MAIL FROM:' and `RCPT TO:' commands and their argument. This violated RFC 2821, which requires the argument to follow the diff --git a/configure.ac b/configure.ac index e49a654a..492f9487 100644 --- a/configure.ac +++ b/configure.ac @@ -14,13 +14,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. AC_PREREQ(2.59) m4_define([MF_VERSION_MAJOR], 4) m4_define([MF_VERSION_MINOR], 2) -dnl m4_define([MF_VERSION_PATCH], 0) +m4_define([MF_VERSION_PATCH], 1) AC_INIT([mailfromd], MF_VERSION_MAJOR.MF_VERSION_MINOR[]m4_ifdef([MF_VERSION_PATCH],.MF_VERSION_PATCH), [bug-mailfromd@gnu.org.ua]) AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_HEADERS([config.h]) @@ -44,13 +44,13 @@ AC_PROG_LEX # Checks for libraries. AC_CHECK_LIB(resolv, res_query) # Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS([stdlib.h unistd.h sysexits.h]) +AC_CHECK_HEADERS([stdlib.h unistd.h sysexits.h paths.h]) # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_SIGNAL AC_TYPE_SIZE_T AC_CHECK_SIZEOF(uint32_t) AC_CHECK_SIZEOF(unsigned long) @@ -93,13 +93,14 @@ fi AC_SUBST(MAILUTILS_VERSION) AC_SUBST(MAILUTILS_INCLUDES) AC_SUBST(MAILUTILS_LIBS) MAILUTILS_VERSION=`$MU_CONFIG --info version|sed 's/VERSION=//'` case $MAILUTILS_VERSION in 0.*) AC_MSG_ERROR([Mailutils version too old; at least 1.0 is required]);; -1.1*) MAILUTILS_LIBS=`$MU_CONFIG --link auth`;; +1.1|1.1.*) MAILUTILS_LIBS=`$MU_CONFIG --link auth`;; +1.2) MAILUTILS_LIBS=`$MU_CONFIG --link auth`;; *) MAILUTILS_LIBS=`$MU_CONFIG --link auth mailer`;; esac MAILUTILS_INCLUDES=`$MU_CONFIG --compile` save_LIBS=$LIBS LIBS="$LIBS $MAILUTILS_LIBS" @@ -124,25 +125,29 @@ AC_SUBST(lisp_LISP) AM_GNU_GETTEXT([external], [need-formatstring-macros]) AM_GNU_GETTEXT_VERSION([0.16]) # Syslog AC_ARG_ENABLE([syslog-async], AC_HELP_STRING([--enable-syslog-async], - [use non-blocking version of syslog by default]), + [compile non-blocking version of syslog]), [case "${enableval}" in yes) syslog_async=yes ;; no) syslog_async=no ;; *) AC_MSG_ERROR([bad value ${enableval} for --enable-syslog-async]) ;; esac],[syslog_async=no]) -AH_TEMPLATE([DEFAULT_SYSLOG_ASYNC], - [Define to 1 if syslog-async is being used by default]) if test $syslog_async = "yes"; then - AC_DEFINE([DEFAULT_SYSLOG_ASYNC], [1]) -else - AC_DEFINE([DEFAULT_SYSLOG_ASYNC], [0]) + AC_ARG_VAR([DEFAULT_SYSLOG_ASYNC], + [Define to 1 if syslog-async is being used by default]) + if test -z "$DEFAULT_SYSLOG_ASYNC"; then + DEFAULT_SYSLOG_ASYNC=0 + fi + AC_DEFINE_UNQUOTED([DEFAULT_SYSLOG_ASYNC],$DEFAULT_SYSLOG_ASYNC, + [Define to 1 to use syslog_async by default]) + AC_SUBST([BUILD_SYSLOG_ASYNC], '$(SYSLOG_ASYNC_O)') + AC_DEFINE([USE_SYSLOG_ASYNC], [1], [Define if syslog-async is being used]) fi # Check for DBM flavor AH_TEMPLATE(BDB2_CURSOR_LASTARG, [Last argument to the cursor member of Berkeley 2 DB structure]) @@ -570,13 +575,13 @@ DBM version............................... $status_dbm Default user.............................. $user State directory........................... $stat_dir Socket.................................... $socket Expiration interval....................... $expire Negative DNS answer expiration interval... $negative_dns_expire Rates expire interval..................... $rates_expire -Default syslog implementation............. $syslog_flavor +Compile asynchronous syslog............... $syslog_async Readline (for mtasim)..................... $usereadline Documentation rendition type.............. $rendition ******************************************************************* EOF ], @@ -591,17 +596,13 @@ socket='$DEFAULT_SOCKET' user=$DEFAULT_USER expire=$DEFAULT_EXPIRE_INTERVAL negative_dns_expire=$DEFAULT_DNS_NEGATIVE_EXPIRE_INTERVAL rates_expire=$DEFAULT_EXPIRE_RATES_INTERVAL usereadline=$usereadline rendition=$RENDITION -if test "$syslog_async" = "yes"; then - syslog_flavor="non-blocking" -else - syslog_flavor="standard" -fi +syslog_async=$syslog_async ]) AC_CONFIG_FILES([Makefile lib/Makefile gacopyz/Makefile src/Makefile diff --git a/doc/mailfromd.texi b/doc/mailfromd.texi index 33d6b208..ec4e45b5 100644 --- a/doc/mailfromd.texi +++ b/doc/mailfromd.texi @@ -128,12 +128,13 @@ Introduction to @command{mailfromd} Sender Address Verification. * Limitations:: Building the Package +* 420-421:: Upgrading from 4.2 to 4.2.1 * 410-420:: Upgrading from 4.1 to 4.2 * 400-410:: Upgrading from 4.0 to 4.1 * 31x-400:: Upgrading from 3.1.x to 4.0 * 30x-31x:: Upgrading from 3.0.x to 3.1 * 2x-30x:: Upgrading from 2.x to 3.0.x * 1x-2x:: Upgrading from 1.x to 2.x @@ -906,23 +907,32 @@ overflows, some lines are lost, but the daemon continues to run. When lines are lost, this fact is logged with a message of the form: @smallexample async_syslog overflow: 5 log entries lost @end smallexample - You can select which implementation to run when starting -@command{mailfromd}, by using @option{--syslog-async} or -@option{--no-syslog-async} command line options -(@pxref{Logging and Debugging}). When configuring, you can set -the asynchronous syslog as the @emph{default} syslog implementation, -using the @option{--enable-syslog-async} command line option: + To enable this implementation, configure the package with +@option{--enable-syslog-async} option, e.g.: @smallexample ./configure --enable-syslog-async @end smallexample +@cindex @code{DEFAULT_SYSLOG_ASYNC}, @command{configure} variable + Additionally, you can instruct @command{mailfromd} to use +asynchronous syslog by default. To do so, set +@code{DEFAULT_SYSLOG_ASYNC} to 1, as shown in example below: + +@smallexample +./configure --enable-syslog-async DEFAULT_SYSLOG_ASYNC=1 +@end smallexample + + You will be able to override these defaults at run-time by using +@option{--syslog-async} or @option{--no-syslog-async} command line options +(@pxref{Logging and Debugging}). + @item Run @command{configure} with all the desired options. For example, the following command: @smallexample ./configure DEFAULT_SOCKET=inet:999@@localhost --with-berkeley-db=3 @@ -971,24 +981,38 @@ and mode. (@file{@var{sysconfdir}/mailfromd.etc}) and edit it, if necessary. If you are upgrading from an older version of @command{mailfromd}, see the corresponding section below. @end enumerate @menu +* 420-421:: Upgrading from 4.2 to 4.2.1 * 410-420:: Upgrading from 4.1 to 4.2 * 400-410:: Upgrading from 4.0 to 4.1 * 31x-400:: Upgrading from 3.1.x to 4.0 * 30x-31x:: Upgrading from 3.0.x to 3.1 * 2x-30x:: Upgrading from 2.x to 3.0.x * 1x-2x:: Upgrading from 1.x to 2.x @end menu +@node 420-421 +@section Upgrading from 4.2 to 4.2.1 +@cindex Upgrading from 4.2 to 4.2.1 +@cindex @code{DEFAULT_SYSLOG_ASYNC}, @command{configure} variable + + The asynchronous syslog implementation was reported to malfunction +on some systems (notably on Solaris), so this release does not enable +it by default. The previous meaning of the @option{--enable-syslog-async} +configuration option is also restored. Use this option in order to +enable asynchronous syslog feature. To set default syslog +implemetation, use @code{DEFAULT_SYSLOG_ASYNC} configuration variable +(@pxref{syslog-async}). + @node 410-420 @section Upgrading from 4.1 to 4.2 @cindex Upgrading from 4.1 to 4.2 -@UNREVISED{} + Upgrading to this version does not require any special efforts. You can use your configuration files and filter scripts without any changes. The only difference worth noticing is that starting from this version @command{mailfromd} is always compiled with asynchronous syslog implementation. The @option{--enable-syslog-async} configuration file option is still available, but its meaning has diff --git a/gacopyz/gacopyz.c b/gacopyz/gacopyz.c index 1fff7edb..24f694e8 100644 --- a/gacopyz/gacopyz.c +++ b/gacopyz/gacopyz.c @@ -149,14 +149,14 @@ static int do_connect(gacopyz_conn_t conn, const char *cstr, char *proto, char *port, char *path, int backlog, int rmsocket) { union { struct sockaddr sa; - struct sockaddr_in sin; - struct sockaddr_un sun; + struct sockaddr_in s_in; + struct sockaddr_un s_un; } addr; int socklen; int fd, flags; int yes = 1; if (!proto @@ -168,23 +168,23 @@ do_connect(gacopyz_conn_t conn, _("%s: invalid connection type: %s; " "port is meaningless for UNIX sockets"), conn->desc.xxfi_name, cstr); return -1; } - if (strlen(path) > sizeof addr.sun.sun_path) { + if (strlen(path) > sizeof addr.s_un.sun_path) { errno = EINVAL; gacopyz_log(conn, SMI_LOG_ERR, _("%s: %s: UNIX socket name too long"), conn->desc.xxfi_name, path); return -1; } addr.sa.sa_family = PF_UNIX; - socklen = sizeof(addr.sun); - strcpy(addr.sun.sun_path, path); + socklen = sizeof(addr.s_un); + strcpy(addr.s_un.sun_path, path); if (stat(path, &st)) { if (errno == ENOENT) { conn->cleanup = cleanup_unix_socket; conn->cleanup_data = strdup(path); } else { @@ -214,13 +214,13 @@ do_connect(gacopyz_conn_t conn, } else if (strcmp(proto, "inet") == 0) { short pnum; long num; char *p; addr.sa.sa_family = PF_INET; - socklen = sizeof(addr.sin); + socklen = sizeof(addr.s_in); if (!port) { gacopyz_log(conn, SMI_LOG_ERR, _("%s: invalid connection type: %s; " "missing port number"), conn->desc.xxfi_name, cstr); @@ -247,26 +247,26 @@ do_connect(gacopyz_conn_t conn, return -1; } pnum = sp->s_port; } if (!path) - addr.sin.sin_addr.s_addr = INADDR_ANY; + addr.s_in.sin_addr.s_addr = INADDR_ANY; else { struct hostent *hp = gethostbyname(path); if (!hp) { gacopyz_log(conn, SMI_LOG_ERR, _("%s: Unknown host name %s"), conn->desc.xxfi_name, path); return -1; } addr.sa.sa_family = hp->h_addrtype; switch (hp->h_addrtype) { case AF_INET: - memmove(&addr.sin.sin_addr, hp->h_addr, 4); - addr.sin.sin_port = pnum; + memmove(&addr.s_in.sin_addr, hp->h_addr, 4); + addr.s_in.sin_port = pnum; break; default: gacopyz_log(conn, SMI_LOG_ERR, _("%s: invalid connection type: %s; " "unsupported address family"), diff --git a/gacopyz/server.c b/gacopyz/server.c index 401854b2..a4a05e49 100644 --- a/gacopyz/server.c +++ b/gacopyz/server.c @@ -645,14 +645,14 @@ gacopyz_srv_destroy(gacopyz_srv_t *p) static int srv_connect(gacopyz_srv_t srv, char *proto, char *port, char *path) { union { struct sockaddr sa; - struct sockaddr_in sin; - struct sockaddr_un sun; + struct sockaddr_in s_in; + struct sockaddr_un s_un; } addr; int socklen; int fd = -1; if (!proto || strcmp(proto, "unix") == 0 || strcmp(proto, "local") == 0) { @@ -663,23 +663,23 @@ srv_connect(gacopyz_srv_t srv, char *proto, char *port, char *path) _("Invalid connection type: %s; " "port is meaningless for UNIX sockets"), srv->portspec); return -1; } - if (strlen(path) > sizeof addr.sun.sun_path) { + if (strlen(path) > sizeof addr.s_un.sun_path) { errno = EINVAL; gacopyz_io_log(&srv->iod, SMI_LOG_ERR, _("%s: UNIX socket name too long"), path); return -1; } addr.sa.sa_family = PF_UNIX; - socklen = sizeof(addr.sun); - strcpy(addr.sun.sun_path, path); + socklen = sizeof(addr.s_un); + strcpy(addr.s_un.sun_path, path); if (stat(path, &st)) { gacopyz_io_log(&srv->iod, SMI_LOG_ERR, _("%s: cannot stat socket: %s"), path, strerror(errno)); return -1; @@ -696,13 +696,13 @@ srv_connect(gacopyz_srv_t srv, char *proto, char *port, char *path) } else if (strcmp(proto, "inet") == 0) { short pnum; long num; char *p; addr.sa.sa_family = PF_INET; - socklen = sizeof(addr.sin); + socklen = sizeof(addr.s_in); if (!port) { gacopyz_io_log(&srv->iod, SMI_LOG_ERR, _("Invalid connection type: %s; " "missing port number"), srv->portspec); @@ -729,26 +729,26 @@ srv_connect(gacopyz_srv_t srv, char *proto, char *port, char *path) return -1; } pnum = sp->s_port; } if (!path) - addr.sin.sin_addr.s_addr = INADDR_ANY; + addr.s_in.sin_addr.s_addr = INADDR_ANY; else { struct hostent *hp = gethostbyname(path); if (!hp) { gacopyz_io_log(&srv->iod, SMI_LOG_ERR, _("Unknown host name %s"), path); return -1; } addr.sa.sa_family = hp->h_addrtype; switch (hp->h_addrtype) { case AF_INET: - memmove(&addr.sin.sin_addr, hp->h_addr, 4); - addr.sin.sin_port = pnum; + memmove(&addr.s_in.sin_addr, hp->h_addr, 4); + addr.s_in.sin_port = pnum; break; default: gacopyz_io_log(&srv->iod, SMI_LOG_ERR, _("Invalid connection type: %s; " "unsupported address family"), diff --git a/src/Makefile.am b/src/Makefile.am index ea504d53..1aa7fdb5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -59,25 +59,27 @@ mailfromd_SOURCES = \ symtab.c\ rate.c\ $(M4_FILES:.m4=.c) noinst_LIBRARIES=libmf.a +SYSLOG_ASYNC_O=syslog_async.o + libmf_a_SOURCES=\ - syslog_async.c\ - syslog_async.h\ version.c -libmf_a_LIBADD=$(LIBOBJS) +libmf_a_LIBADD=$(LIBOBJS) $(BUILD_SYSLOG_ASYNC) mailfromd_LDADD = ./libmf.a $(LDADD) mtasim_SOURCES = mtasim.c openat-die.c mtasim_LDADD = ./libmf.a $(LDADD) $(READLINE_LIBS) -noinst_HEADERS = mailfromd.h mu_dbm.h builtin.h dns.h spf.h drivers.c debug.h +noinst_HEADERS = mailfromd.h mu_dbm.h builtin.h dns.h spf.h drivers.c debug.h \ + syslog_async.h + EXTRA_DIST = \ $(M4_FILES)\ builtin.def\ builtin.h\ daemon.c\ debug.cin\ @@ -93,13 +95,14 @@ EXTRA_DIST = \ opcode.awk\ opcodes\ optab.opc\ optab.oph\ snarf.m4\ status.mfh\ - status.mfi + status.mfi\ + syslog_async.c BUILT_SOURCES=\ $(M4_FILES:.m4=.c)\ builtin.h\ debug.c\ debug.h\ @@ -36,14 +36,12 @@ #include <mailutils/mailutils.h> #include <mailutils/argp.h> #include "mailfromd.h" -#include "syslog_async.h" - /* Configurable options */ int mode = MAILFROMD_DAEMON; /* Default operation mode */ enum smtp_state test_state = smtp_state_envfrom; /* State for --test mode */ int need_config = 1;/* Set if the current mode requires reading the @@ -75,14 +73,17 @@ char *portspec; /* Communication socket specification. int force_remove; /* Remove local communication socket if it already exists */ int foreground; /* Stay in foreground */ int single_process_option; /* Run in single process mode. */ unsigned long source_address = INADDR_ANY; /* Source address for TCP connections */ +#ifdef USE_SYSLOG_ASYNC int use_syslog_async = DEFAULT_SYSLOG_ASYNC; - /* Use asynchronous syslog implementation */ + /* Use asynchronous syslog implementation */ +#endif + char *syslog_tag; /* Tag to mark syslog entries with. */ char *mailfromd_state_dir; /* see init_names() */ char *pidfile; /* see init_names() */ char *user = DEFAULT_USER; /* Switch to this user privileges after startup */ mu_list_t retain_groups; /* List of group IDs to retain when switching @@ -122,26 +123,30 @@ time_t response_timeout = 30; /* Logging & debugging */ int syslog_printer (int prio, const char *fmt, va_list ap) { +#ifdef USE_SYSLOG_ASYNC if (use_syslog_async) { vsyslog_async (prio, fmt, ap); - } else { + } else +#endif + { #if HAVE_VSYSLOG vsyslog (prio, fmt, ap); #else char buf[128]; vsnprintf (buf, sizeof buf, fmt, ap); syslog (prio, "%s", buf); #endif } return 0; } +#ifdef USE_SYSLOG_ASYNC void mf_gacopyz_syslog_async_log_printer(int level, char *fmt, va_list ap) { switch (level) { case SMI_LOG_DEBUG: level = LOG_DEBUG; @@ -159,12 +164,13 @@ mf_gacopyz_syslog_async_log_printer(int level, char *fmt, va_list ap) case SMI_LOG_FATAL: default: level = LOG_EMERG; } vsyslog_async(level, fmt, ap); } +#endif int syslog_error_printer (const char *fmt, va_list ap) { return syslog_printer(LOG_ERR, fmt, ap); } @@ -975,16 +981,18 @@ static struct argp_option options[] = { { "gacopyz-log", OPTION_GACOPYZ_LOG, N_("LEVEL"), 0, N_("Set Gacopyz log level"), GRP+1 }, { "stderr", 's', NULL, 0, N_("Log to stderr"), GRP+1 }, { "syslog", OPTION_SYSLOG, NULL, 0, N_("Log to syslog (default)"), GRP+1 }, +#ifdef USE_SYSLOG_ASYNC { "syslog-async", OPTION_SYSLOG_ASYNC, NULL, 0, N_("Use asynchronous syslog"), GRP+1 }, { "no-syslog-async", OPTION_NO_SYSLOG_ASYNC, NULL, 0, N_("Use system syslog"), GRP+1 }, +#endif { "log-tag", OPTION_LOG_TAG, N_("STRING"), 0, N_("Set the identifier used in syslog messages to STRING"), GRP+1 }, { "source-info", OPTION_SOURCE_INFO, NULL, 0, N_("Debug messages include source information"), GRP+1 }, { "stack-trace", OPTION_STACK_TRACE, NULL, 0, N_("Enable stack traces on runtime errors"), GRP+1 }, @@ -1298,20 +1306,21 @@ parse_opt (int key, char *arg, struct argp_state *state) break; case OPTION_SYSLOG: log_to_stderr = 0; break; +#ifdef USE_SYSLOG_ASYNC case OPTION_SYSLOG_ASYNC: use_syslog_async = 1; break; case OPTION_NO_SYSLOG_ASYNC: use_syslog_async = 0; break; - +#endif case OPTION_TIMEOUT: set_option("timeout", arg, 1); break; case OPTION_TRACE: do_trace = 1; @@ -1699,17 +1708,19 @@ mailfromd_show_defaults() printf("script file: %s\n", script_file); printf("preprocessor: %s\n", ext_pp ? ext_pp : "none"); printf("user: %s\n", user); printf("statedir: %s\n", mailfromd_state_dir); printf("socket: %s\n", portspec); printf("pidfile: %s\n", pidfile); +#ifdef USE_SYSLOG_ASYNC #if DEFAULT_SYSLOG_ASYNC == 1 printf("default syslog: non-blocking\n"); #else printf("default syslog: blocking\n"); #endif +#endif printf("database format: "); #if defined WITH_GDBM printf("GDBM"); #elif defined WITH_BDB printf("Berkeley DB %d.x", WITH_BDB); #endif @@ -1720,16 +1731,19 @@ mailfromd_show_defaults() void log_setup(int want_stderr) { /* Set up logging */ if (!want_stderr) { +#ifdef USE_SYSLOG_ASYNC if (use_syslog_async) { openlog_async(syslog_tag, LOG_PID, log_facility); gacopyz_set_logger(mf_gacopyz_syslog_async_log_printer); - } else { + } else +#endif + { openlog(syslog_tag, LOG_PID, log_facility); gacopyz_set_logger(gacopyz_syslog_log_printer); } mu_error_set_print(syslog_error_printer); } else { gacopyz_set_logger(gacopyz_stderr_log_printer); diff --git a/src/syslog_async.c b/src/syslog_async.c index a168eac9..006cf16e 100644 --- a/src/syslog_async.c +++ b/src/syslog_async.c @@ -11,33 +11,55 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include <sys/file.h> #include <sys/syslog.h> +#include <netinet/in.h> +#include <signal.h> #include <sys/uio.h> #include <sys/wait.h> #include <netdb.h> #include <string.h> #include <time.h> #include <unistd.h> #include <errno.h> #include <stdarg.h> #include <stdlib.h> -#include <paths.h> +#ifdef HAVE_PATHS_H +# include <paths.h> +#else +# define _PATH_LOG "/dev/log" +# define _PATH_CONSOLE "/dev/console" +#endif #include <stdio.h> #include <ctype.h> #include "syslog_async.h" +#ifndef MSG_NOSIGNAL +# define MSG_NOSIGNAL 0 +#endif + +#ifndef LOG_PERROR +# define LOG_PERROR 0 +#endif + +#ifndef LOG_PRI +# define LOG_PRI(x) ((x) & LOG_PRIMASK) +#endif + /* From RFC 3164 */ #define MAX_MESSAGE 1024 #define DEF_BACKLOG 5 #define DEF_DELAY 1000 /* doesn't come into effect until backlog > 10 */ @@ -163,12 +185,16 @@ int log_fd_async(void) void log_write_async(void) { ssize_t rc; int fd, tried_stream = 0; struct log_entry *tmp; + +#if MSG_NOSIGNAL == 0 + RETSIGTYPE (*sigfun) (int sig) = signal (SIGPIPE, SIG_IGN); +#endif while (entries) { if (log_fd == -1 && (log_fd = mksock(SOCK_DGRAM)) == -1) goto fail; @@ -191,19 +217,19 @@ void log_write_async(void) } if (errno == EINTR) continue; if (errno == EAGAIN) - return; + break; /* *BSD, returns this instead of blocking? */ if (errno == ENOBUFS) { connection_good = 0; - return; + break; } /* A stream socket closed at the other end goes into EPIPE forever, close and re-open. */ if (errno == EPIPE) goto reopen_stream; @@ -218,30 +244,31 @@ void log_write_async(void) ECONNREFUSED -> connection went down ENOTCONN -> nobody listening (ECONNRESET, EDESTADDRREQ are *BSD equivalents) */ struct sockaddr_un logaddr; - logaddr.sun_family = AF_LOCAL; + logaddr.sun_family = AF_UNIX; strncpy(logaddr.sun_path, _PATH_LOG, sizeof(logaddr.sun_path)); /* Got connection back? try again. */ - if (connect(log_fd, (struct sockaddr *)&logaddr, sizeof(logaddr)) != -1) + if (connect(log_fd, (struct sockaddr *)&logaddr, + sizeof(logaddr)) != -1) continue; /* errors from connect which mean we should keep trying */ if (errno == ENOENT || errno == EALREADY || errno == ECONNREFUSED || errno == EISCONN || errno == EINTR || errno == EAGAIN) { /* try again on next syslog() call */ connection_good = 0; - return; + break; } /* we start with a SOCK_DGRAM socket, but syslog may want SOCK_STREAM */ if (!tried_stream && errno == EPROTOTYPE) { reopen_stream: @@ -286,12 +313,16 @@ void log_write_async(void) int e = entries_lost; entries_lost = 0; /* avoid wild recursion */ syslog_async(LOG_WARNING, "async_syslog overflow: %d log entries lost", e); } continue; } + +#if MSG_NOSIGNAL == 0 + signal (SIGPIPE, sigfun); +#endif } void syslog_async(int priority, const char *format, ...) { va_list ap; |