[Exim] Patch for WishList #38 and more syslog features

Top Page
Delete this message
Reply to this message
Author: Oliver Gorwits
Date:  
To: exim-users
Subject: [Exim] Patch for WishList #38 and more syslog features
--
Folks,

I've put together an Exim-4.14 patch to answer wishlist item #38
and other syslog related features which I was interested in
playing with at our site. Some of you lot may be interested too,
so please try out the patch and give me some feedback.

In particular, (as I've said before) my C is nothing to write
home about so if you spot something sinful or plain stupid then
please do tell.

Thre are *four* new options, two are set in Local/Makefile as
build paramters and the other two are set in your global
runtime configuration file.

i) SYSLOG_LOGS_PID=yes [or commented out in Makefile for 'no']
This activates the LOG_PID flag when calling openlog() in case
you're not interested in such information.

ii) LONG_SYSLOG_LINES=yes [or commented out in Makefile for 'no']
When logging to syslog, this option caters for syslogd
replacements that are able to accept log entries longer than the
1024 characters allowed by RFC3164. It's up to you to make sure
your syslog daemon can handle this datagram. Exim will still break
up its own log lines if they contain newline characters.

iii) $syslog_processname [defaults to 'exim']
     (Exim 4 WishList item #38)
This global configuration option is an unexpanded string that
is given to syslog at openlog() time to label all the entries.
The RFC here states a max 32 characters so that's checked for.


iv) $syslog_facility [defaults to LOG_MAIL]
This global configuration option allows you to choose the facility
that exim logs to. See the manpage for syslog for the choices.
I've allowed you to drop the LOG_ prefix if you like, and to
be case insensitive when specifying the facility. I've also not
allowed you to choose inappropriate facilites such as LOG_KERN
or LOG_LPR and so on.

One last thing is a change of the MAX_SYSLOG_LEN #define in log.c
to a more RFC compliant value (assuming that my math is good :)
which is of course only used if LONG_SYSLOG_LINES isn't enabled.

Attached are two patches, against a stock Exim-4.14 and an
Exiscan patched Exim-4.14 both of which have been briefly tested.
Apply them with the usual 'patch -p1 <patchfile>' in your Exim
source directory.

regards,
oliver.
--
Oliver Gorwits, Network Software Group
Oxford University Computing Services
--
diff -ur exim-4.14/src/EDITME exim-4.14-syslog-patched/src/EDITME
--- exim-4.14/src/EDITME    2003-03-11 12:20:18.000000000 +0000
+++ exim-4.14-syslog-patched/src/EDITME    2003-04-10 13:43:04.000000000 +0000
@@ -436,6 +436,21 @@



 #------------------------------------------------------------------------------
+# When logging to syslog, the following option caters for syslog replacements
+# that are able to accept log entries longer than the 1024 characters allowed
+# by RFC 3164. It is up to you to make sure your syslog daemon can handle this.
+# Non-printable characters are usually unacceptable regardless, so log entries
+# will still be split on newline characters.
+
+# LONG_SYSLOG_LINES=yes
+
+# If you aren't interested in the Process Identifier number of the Exim that is
+# making the call to syslog, then comment out the following line.
+
+# SYSLOG_LOGS_PID=yes
+
+
+#------------------------------------------------------------------------------
 # Cycling log files: this variable specifies the maximum number of old
 # log files that are kept by the exicyclog log-cycling script. You don't have
 # to use exicyclog. If your operating system has other ways of cycling log
diff -ur exim-4.14/src/config.h.defaults exim-4.14-syslog-patched/src/config.h.defaults
--- exim-4.14/src/config.h.defaults    2003-03-11 12:20:19.000000000 +0000
+++ exim-4.14-syslog-patched/src/config.h.defaults    2003-04-10 13:45:51.000000000 +0000
@@ -50,6 +50,8 @@
 #define LOG_DIRECTORY_MODE         0750
 #define LOG_FILE_PATH
 #define LOG_MODE                   0640
+#define LONG_SYSLOG_LINES
+#define SYSLOG_LOGS_PID


 #define LOOKUP_CDB
 #define LOOKUP_DBM
diff -ur exim-4.14/src/exim.c exim-4.14-syslog-patched/src/exim.c
--- exim-4.14/src/exim.c    2003-03-11 12:20:20.000000000 +0000
+++ exim-4.14-syslog-patched/src/exim.c    2003-04-10 13:48:57.000000000 +0000
@@ -2523,6 +2523,13 @@
   log_write(0, LOG_MAIN|LOG_PANIC_DIE,
     "spool_directory is longer than 200 chars: aborting");


+/* Further length check on the processname given to syslog for its TAG field,
+which is only permitted to be 32 characters or less. See RFC 3164 */
+
+if (Ustrlen(syslog_processname) > 32)
+  log_write(0, LOG_MAIN|LOG_PANIC_DIE,
+    "syslog_processname is longer than 32 chars: aborting");
+
 /* Timezone handling. If timezone_string is "utc", set a flag to cause all
 timestamps to be in UTC (gmtime() is used instead of localtime()). Otherwise,
 we may need to get rid of a bogus timezone setting. This can arise when Exim is
diff -ur exim-4.14/src/globals.c exim-4.14-syslog-patched/src/globals.c
--- exim-4.14/src/globals.c    2003-03-11 12:20:20.000000000 +0000
+++ exim-4.14-syslog-patched/src/globals.c    2003-04-10 14:06:53.000000000 +0000
@@ -848,6 +848,8 @@
 BOOL    strip_excess_angle_brackets = FALSE;
 BOOL    strip_trailing_dot     = FALSE;
 BOOL    synchronous_delivery   = FALSE;
+int     syslog_facility        = LOG_MAIL;
+uschar *syslog_processname     = US"exim";
 BOOL    syslog_timestamp       = TRUE;
 uschar *system_filter          = NULL;


diff -ur exim-4.14/src/globals.h exim-4.14-syslog-patched/src/globals.h
--- exim-4.14/src/globals.h    2003-03-11 12:20:20.000000000 +0000
+++ exim-4.14-syslog-patched/src/globals.h    2003-04-10 14:08:28.000000000 +0000
@@ -513,6 +513,8 @@
 extern BOOL    strip_excess_angle_brackets; /* Surrounding route-addrs */
 extern BOOL    strip_trailing_dot;     /* Remove dots at ends of domains */
 extern BOOL    synchronous_delivery;   /* TRUE if -odi is set */
+extern int     syslog_facility;        /* As defined by Syslog.h */
+extern uschar *syslog_processname;     /* 'ident' param to openlog() */
 extern BOOL    syslog_timestamp;       /* TRUE if time on syslogs */
 extern uschar *system_filter;          /* Name of system filter file */


diff -ur exim-4.14/src/log.c exim-4.14-syslog-patched/src/log.c
--- exim-4.14/src/log.c    2003-03-11 12:20:20.000000000 +0000
+++ exim-4.14-syslog-patched/src/log.c    2003-04-10 14:23:04.000000000 +0000
@@ -12,7 +12,7 @@
 #include "exim.h"


#define LOG_NAME_SIZE 256
-#define MAX_SYSLOG_LEN 1000
+#define MAX_SYSLOG_LEN 870

#define LOG_MODE_FILE 1
#define LOG_MODE_SYSLOG 2
@@ -68,51 +68,107 @@
static void
write_syslog(int priority, uschar *s)
{
-int len, pass;
-int linecount = 0;
-
-if (!syslog_timestamp) s += log_timezone? 26 : 20;
-
-len = Ustrlen(s);
+int tlen, plen;

#ifndef NO_OPENLOG
if (!syslog_open)
{
- openlog("exim", LOG_PID|LOG_CONS, LOG_MAIL);
+#ifdef SYSLOG_LOGS_PID
+ openlog(syslog_processname, LOG_PID|LOG_CONS, syslog_facility);
+#else
+ openlog(syslog_processname, LOG_CONS, syslog_facility);
+#endif
syslog_open = TRUE;
}
#endif

-/* First do a scan through the message in order to determine how many lines
-it is going to end up as. Then rescan to output it. */
+if (!syslog_timestamp) s += log_timezone? 26 : 20;
+plen = tlen = Ustrlen(s);
+uschar *ss = s;

-for (pass = 0; pass < 2; pass++)
-  {
-  int i;
-  int tlen;
-  uschar *ss = s;
-  for (i = 1, tlen = len; tlen > 0; i++)
-    {
-    int plen = tlen;
-    uschar *nlptr = Ustrchr(ss, '\n');
-    if (nlptr != NULL) plen = nlptr - ss;
-    if (plen > MAX_SYSLOG_LEN) plen = MAX_SYSLOG_LEN;
+/* find the first newline in message */
+uschar *nlptr = Ustrchr(ss, '\n');


-    tlen -= plen;
-    if (ss[plen] == '\n') tlen--;    /* chars left */
+/* plen becomes length of valid log message chunk */
+if (nlptr != NULL) plen = nlptr - ss;
+#ifndef LONG_SYSLOG_LINES
+if (plen > MAX_SYSLOG_LEN) plen = MAX_SYSLOG_LEN;
+#endif
+
+/* tlen becomes length of remaining message chunk */
+tlen -= plen;
+if (ss[plen] == '\n') tlen--;
+
+if (tlen == 0) /* can fit this message into one syslog call */
+  syslog(priority, "%.*s", plen, ss);
+
+else
+  {
+  int i = 1;
+  BOOL tmp_msgid = FALSE;


-    if (pass == 0) linecount++; else
+  if (message_id[0] == 0)
+    {
+    /* generate a syslog_id. This works in exactly the same way as when
+    receive.c generates a message_id except that it's used here to give log
+    messages that don't relate to an email message a unique identifier, when
+    splitting them over several syslog calls. */
+    int    resolution;
+    struct timeval now_tv;
+
+    (void)gettimeofday(&now_tv, NULL);
+
+    Ustrncpy(message_id, string_base62((long int)(now_tv.tv_sec)), 6);
+    message_id[6] = '-';
+    Ustrncpy(message_id + 7, string_base62((long int)getpid()), 6);
+
+    if (host_number_string != NULL)
+      {
+      resolution = (BASE_62 == 62)? 5000 : 10000;
+      sprintf(CS(message_id + MESSAGE_ID_LENGTH - 3), "-%2s",
+        string_base62((long int)(
+          host_number * (1000000/resolution) +
+            now_tv.tv_usec/resolution)) + 4);
+      }
+    else
       {
-      if (linecount == 1)
-        syslog(priority, "%.*s", plen, ss);
-      else
-        syslog(priority, "[%d%c%d] %.*s", i,
-          (ss[plen] == '\n' && tlen != 0)? '\\' : '/',
-          linecount, plen, ss);
+      resolution = (BASE_62 == 62)? 500 : 1000;
+      sprintf(CS(message_id + MESSAGE_ID_LENGTH - 3), "-%2s",
+        string_base62((long int)(now_tv.tv_usec/resolution)) + 4);
       }
+
+    now_tv.tv_usec = (now_tv.tv_usec/resolution) * resolution;
+    exim_wait_tick(&now_tv, resolution);
+
+    /* take a note that we used message_id storage for the syslog_id */
+    tmp_msgid = TRUE;
+    }
+
+  /* now write all the syslog lines with [x/y] prepended */
+  while (tlen > 0)
+    {
+    syslog(priority, "[%d%c%s] %.*s", i,
+      (ss[plen] == '\n')? '\\' : '/',
+      message_id, plen, ss);
+
     ss += plen;
     if (*ss == '\n') ss++;
+    i++;
+
+    /* locate the next valid message chunk */
+    plen = tlen;
+    nlptr = Ustrchr(ss, '\n');
+    if (nlptr != NULL) plen = nlptr - ss;
+#ifndef LONG_SYSLOG_LINES
+    if (plen > MAX_SYSLOG_LEN) plen = MAX_SYSLOG_LEN;
+#endif
+    tlen -= plen;
+    if (ss[plen] == '\n') tlen--;
     }
+
+  syslog(priority, "[%d/%s] %.*s", i, message_id, plen, ss);
+
+  if (tmp_msgid) message_id[0] = 0; /* reset message_id */
   }
 }


diff -ur exim-4.14/src/readconf.c exim-4.14-syslog-patched/src/readconf.c
--- exim-4.14/src/readconf.c    2003-03-11 12:20:22.000000000 +0000
+++ exim-4.14-syslog-patched/src/readconf.c    2003-04-10 14:16:04.000000000 +0000
@@ -38,6 +38,7 @@


static config_file_item *config_file_stack = NULL; /* For includes */

+static uschar *syslog_facility_str  = NULL;
 static uschar *configured_smtp_port = NULL;
 static uschar next_section[24];
 static uschar time_buffer[24];
@@ -271,6 +272,8 @@
   { "spool_directory",          opt_stringptr,   &spool_directory },
   { "strip_excess_angle_brackets", opt_bool,     &strip_excess_angle_brackets },
   { "strip_trailing_dot",       opt_bool,        &strip_trailing_dot },
+  { "syslog_facility",          opt_stringptr,   &syslog_facility_str },
+  { "syslog_processname",       opt_stringptr,   &syslog_processname },
   { "syslog_timestamp",         opt_bool,        &syslog_timestamp },
   { "system_filter",            opt_stringptr,   &system_filter },
   { "system_filter_directory_transport", opt_stringptr,&system_filter_directory_transport },
@@ -2651,6 +2654,47 @@
   log_file_path = s;
   }


+/* Interpret syslog_facility into an acceptable integer argument for
+'ident' param to openlog(). Default is LOG_MAIL set in globals.c */
+
+if (syslog_facility_str != NULL)
+  {
+  uschar *s = syslog_facility_str;
+  syslog_facility = LOG_KERN;
+    /* For error detection: should never log under that facility from exim. */
+
+  if ((Ustrlen(syslog_facility_str) >= 8) &&
+        (strncmpic(syslog_facility_str, US"log_", 4) == 0))
+    s += 4;
+
+  if (Ustrlen(s) == 4)
+    {
+    if      (strcmpic(s, US"mail")   == 0) syslog_facility = LOG_MAIL;
+    else if (strcmpic(s, US"user")   == 0) syslog_facility = LOG_USER;
+    else if (strcmpic(s, US"news")   == 0) syslog_facility = LOG_NEWS;
+    else if (strcmpic(s, US"uucp")   == 0) syslog_facility = LOG_UUCP;
+    }
+  else if (Ustrlen(s) == 6)
+    {
+    if      (strcmpic(s, US"local0") == 0) syslog_facility = LOG_LOCAL0;
+    else if (strcmpic(s, US"local1") == 0) syslog_facility = LOG_LOCAL1;
+    else if (strcmpic(s, US"local2") == 0) syslog_facility = LOG_LOCAL2;
+    else if (strcmpic(s, US"local3") == 0) syslog_facility = LOG_LOCAL3;
+    else if (strcmpic(s, US"local4") == 0) syslog_facility = LOG_LOCAL4;
+    else if (strcmpic(s, US"local5") == 0) syslog_facility = LOG_LOCAL5;
+    else if (strcmpic(s, US"local6") == 0) syslog_facility = LOG_LOCAL6;
+    else if (strcmpic(s, US"local7") == 0) syslog_facility = LOG_LOCAL7;
+    else if (strcmpic(s, US"daemon") == 0) syslog_facility = LOG_DAEMON;
+    }
+
+  if (syslog_facility == LOG_KERN)
+    {
+    syslog_facility = LOG_MAIL;
+    log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
+      "failed to interpret syslog_facility \"%s\"", syslog_facility_str);
+    }
+  }
+
 /* Expand pid_file_path */


 if (*pid_file_path != 0)
--
diff -Nur exim-4.14/Local/Makefile exim-4.14-patched/Local/Makefile
--- exim-4.14/Local/Makefile    2003-04-10 13:28:30.230028000 +0100
+++ exim-4.14-patched/Local/Makefile    2003-04-07 16:18:19.322163000 +0100
@@ -435,6 +435,8 @@
 # the building process.


LOG_FILE_PATH=:syslog
+SPLIT_LONG_SYSLOG_LINES=yes
+# SYSLOG_LOGS_PID=yes


 #------------------------------------------------------------------------------
diff -Nur exim-4.14/src/config.h.defaults exim-4.14-patched/src/config.h.defaults
--- exim-4.14/src/config.h.defaults    2003-03-11 12:20:19.000000000 +0000
+++ exim-4.14-patched/src/config.h.defaults    2003-04-07 15:52:59.254299000 +0100
@@ -50,6 +50,8 @@
 #define LOG_DIRECTORY_MODE         0750
 #define LOG_FILE_PATH
 #define LOG_MODE                   0640
+#define SPLIT_LONG_SYSLOG_LINES
+#define SYSLOG_LOGS_PID


 #define LOOKUP_CDB
 #define LOOKUP_DBM
diff -Nur exim-4.14/src/exim.c exim-4.14-patched/src/exim.c
--- exim-4.14/src/exim.c    2003-04-10 13:51:11.389224000 +0100
+++ exim-4.14-patched/src/exim.c    2003-04-09 17:57:16.192947000 +0100
@@ -2524,6 +2524,13 @@
   log_write(0, LOG_MAIN|LOG_PANIC_DIE,
     "spool_directory is longer than 200 chars: aborting");


+/* Further length check on the processname given to syslog for its TAG field,
+which is only permitted to be 32 characters or less. See RFC 3164 */
+
+if (Ustrlen(syslog_processname) > 32)
+  log_write(0, LOG_MAIN|LOG_PANIC_DIE,
+    "syslog_processname is longer than 32 chars: aborting");
+
 /* Timezone handling. If timezone_string is "utc", set a flag to cause all
 timestamps to be in UTC (gmtime() is used instead of localtime()). Otherwise,
 we may need to get rid of a bogus timezone setting. This can arise when Exim is
diff -Nur exim-4.14/src/globals.c exim-4.14-patched/src/globals.c
--- exim-4.14/src/globals.c    2003-04-10 13:51:11.506863000 +0100
+++ exim-4.14-patched/src/globals.c    2003-04-09 15:06:36.421975000 +0100
@@ -889,6 +889,8 @@
 BOOL    strip_excess_angle_brackets = FALSE;
 BOOL    strip_trailing_dot     = FALSE;
 BOOL    synchronous_delivery   = FALSE;
+int     syslog_facility        = LOG_MAIL;
+uschar *syslog_processname     = US"exim";
 BOOL    syslog_timestamp       = TRUE;
 uschar *system_filter          = NULL;


diff -Nur exim-4.14/src/globals.h exim-4.14-patched/src/globals.h
--- exim-4.14/src/globals.h    2003-04-10 13:51:11.514788000 +0100
+++ exim-4.14-patched/src/globals.h    2003-04-08 16:51:32.455316000 +0100
@@ -557,6 +557,8 @@
 extern BOOL    strip_excess_angle_brackets; /* Surrounding route-addrs */
 extern BOOL    strip_trailing_dot;     /* Remove dots at ends of domains */
 extern BOOL    synchronous_delivery;   /* TRUE if -odi is set */
+extern int     syslog_facility;        /* As defined by Syslog.h */
+extern uschar *syslog_processname;     /* 'ident' param to openlog() */
 extern BOOL    syslog_timestamp;       /* TRUE if time on syslogs */
 extern uschar *system_filter;          /* Name of system filter file */


diff -Nur exim-4.14/src/log.c exim-4.14-patched/src/log.c
--- exim-4.14/src/log.c    2003-03-11 12:20:20.000000000 +0000
+++ exim-4.14-patched/src/log.c    2003-04-10 14:25:47.727236000 +0100
@@ -12,7 +12,7 @@
 #include "exim.h"


#define LOG_NAME_SIZE 256
-#define MAX_SYSLOG_LEN 1000
+#define MAX_SYSLOG_LEN 700

#define LOG_MODE_FILE 1
#define LOG_MODE_SYSLOG 2
@@ -49,7 +49,6 @@



-
 /*************************************************
 *              Write to syslog                   *
 *************************************************/
@@ -68,53 +67,110 @@
 static void
 write_syslog(int priority, uschar *s)
 {
-int len, pass;
-int linecount = 0;
-
-if (!syslog_timestamp) s += log_timezone? 26 : 20;
-
-len = Ustrlen(s);
+int tlen, plen;


#ifndef NO_OPENLOG
if (!syslog_open)
{
- openlog("exim", LOG_PID|LOG_CONS, LOG_MAIL);
+#ifdef SYSLOG_LOGS_PID
+ openlog(syslog_processname, LOG_PID|LOG_CONS, syslog_facility);
+#else
+ openlog(syslog_processname, LOG_CONS, syslog_facility);
+#endif
syslog_open = TRUE;
}
#endif

-/* First do a scan through the message in order to determine how many lines
-it is going to end up as. Then rescan to output it. */
+if (!syslog_timestamp) s += log_timezone? 26 : 20;
+plen = tlen = Ustrlen(s);
+uschar *ss = s;

-for (pass = 0; pass < 2; pass++)
-  {
-  int i;
-  int tlen;
-  uschar *ss = s;
-  for (i = 1, tlen = len; tlen > 0; i++)
-    {
-    int plen = tlen;
-    uschar *nlptr = Ustrchr(ss, '\n');
-    if (nlptr != NULL) plen = nlptr - ss;
-    if (plen > MAX_SYSLOG_LEN) plen = MAX_SYSLOG_LEN;
+/* find the first newline in message */
+uschar *nlptr = Ustrchr(ss, '\n');


-    tlen -= plen;
-    if (ss[plen] == '\n') tlen--;    /* chars left */
+/* plen becomes length of valid log message chunk */
+if (nlptr != NULL) plen = nlptr - ss;
+#ifdef SPLIT_LONG_SYSLOG_LINES
+if (plen > MAX_SYSLOG_LEN) plen = MAX_SYSLOG_LEN;
+#endif
+
+/* tlen becomes length of remaining message chunk */
+tlen -= plen;
+if (ss[plen] == '\n') tlen--;
+
+if (tlen == 0) /* can fit this message into one syslog call */
+  syslog(priority, "%.*s", plen, ss);
+
+else
+  {
+  int i = 1;
+  BOOL tmp_msgid = FALSE;


-    if (pass == 0) linecount++; else
+  if (message_id[0] == 0)
+    {
+    /* generate a syslog_id. This works in exactly the same way as when
+    receive.c generates a message_id except that it's used here to give log
+    messages that don't relate to an email message a unique identifier, when
+    splitting them over several syslog calls. */
+    int    resolution;
+    struct timeval now_tv;
+
+    (void)gettimeofday(&now_tv, NULL);
+
+    Ustrncpy(message_id, string_base62((long int)(now_tv.tv_sec)), 6);
+    message_id[6] = '-';
+    Ustrncpy(message_id + 7, string_base62((long int)getpid()), 6);
+
+    if (host_number_string != NULL)
+      {
+      resolution = (BASE_62 == 62)? 5000 : 10000;
+      sprintf(CS(message_id + MESSAGE_ID_LENGTH - 3), "-%2s",
+        string_base62((long int)(
+          host_number * (1000000/resolution) +
+            now_tv.tv_usec/resolution)) + 4);
+      }
+    else
       {
-      if (linecount == 1)
-        syslog(priority, "%.*s", plen, ss);
-      else
-        syslog(priority, "[%d%c%d] %.*s", i,
-          (ss[plen] == '\n' && tlen != 0)? '\\' : '/',
-          linecount, plen, ss);
+      resolution = (BASE_62 == 62)? 500 : 1000;
+      sprintf(CS(message_id + MESSAGE_ID_LENGTH - 3), "-%2s",
+        string_base62((long int)(now_tv.tv_usec/resolution)) + 4);
       }
+
+    now_tv.tv_usec = (now_tv.tv_usec/resolution) * resolution;
+    exim_wait_tick(&now_tv, resolution);
+
+    /* take a note that we used message_id storage for the syslog_id */
+    tmp_msgid = TRUE;
+    }
+
+  /* now write all the syslog lines with [x/y] prepended */
+  while (tlen > 0)
+    {
+    syslog(priority, "[%d%c%s] %.*s", i,
+      (ss[plen] == '\n')? '\\' : '/',
+      message_id, plen, ss);
+
     ss += plen;
     if (*ss == '\n') ss++;
+    i++;
+
+    /* locate the next valid message chunk */
+    plen = tlen;
+    nlptr = Ustrchr(ss, '\n');
+    if (nlptr != NULL) plen = nlptr - ss;
+#ifdef SPLIT_LONG_SYSLOG_LINES
+    if (plen > MAX_SYSLOG_LEN) plen = MAX_SYSLOG_LEN;
+#endif
+    tlen -= plen;
+    if (ss[plen] == '\n') tlen--;
     }
+
+  syslog(priority, "[%d/%s] %.*s", i, message_id, plen, ss);
+
+  if (tmp_msgid) message_id[0] = 0; /* reset message_id */
   }
-}
+
+} /* end write_syslog */




@@ -193,7 +249,6 @@



-
 /*************************************************
 *                Open a log file                 *
 *************************************************/
diff -Nur exim-4.14/src/readconf.c exim-4.14-patched/src/readconf.c
--- exim-4.14/src/readconf.c    2003-04-10 13:51:11.528565000 +0100
+++ exim-4.14-patched/src/readconf.c    2003-04-10 12:06:51.060620000 +0100
@@ -38,6 +38,7 @@


static config_file_item *config_file_stack = NULL; /* For includes */

+static uschar *syslog_facility_str  = NULL;
 static uschar *configured_smtp_port = NULL;
 static uschar next_section[24];
 static uschar time_buffer[24];
@@ -309,6 +310,8 @@
   { "spool_directory",          opt_stringptr,   &spool_directory },
   { "strip_excess_angle_brackets", opt_bool,     &strip_excess_angle_brackets },
   { "strip_trailing_dot",       opt_bool,        &strip_trailing_dot },
+  { "syslog_facility",          opt_stringptr,   &syslog_facility_str },
+  { "syslog_processname",       opt_stringptr,   &syslog_processname },
   { "syslog_timestamp",         opt_bool,        &syslog_timestamp },
   { "system_filter",            opt_stringptr,   &system_filter },
   { "system_filter_directory_transport", opt_stringptr,&system_filter_directory_transport },
@@ -2689,6 +2692,47 @@
   log_file_path = s;
   }


+/* Interpret syslog_facility into an acceptable integer argument for
+'ident' param to openlog(). Default is LOG_MAIL set in globals.c */
+
+if (syslog_facility_str != NULL)
+  {
+  uschar *s = syslog_facility_str;
+  syslog_facility = LOG_KERN;
+    /* For error detection: should never log under that facility from exim. */
+
+  if ((Ustrlen(syslog_facility_str) >= 8) &&
+        (strncmpic(syslog_facility_str, US"log_", 4) == 0))
+    s += 4;
+
+  if (Ustrlen(s) == 4)
+    {
+    if      (strcmpic(s, US"mail")   == 0) syslog_facility = LOG_MAIL;
+    else if (strcmpic(s, US"user")   == 0) syslog_facility = LOG_USER;
+    else if (strcmpic(s, US"news")   == 0) syslog_facility = LOG_NEWS;
+    else if (strcmpic(s, US"uucp")   == 0) syslog_facility = LOG_UUCP;
+    }
+  else if (Ustrlen(s) == 6)
+    {
+    if      (strcmpic(s, US"local0") == 0) syslog_facility = LOG_LOCAL0;
+    else if (strcmpic(s, US"local1") == 0) syslog_facility = LOG_LOCAL1;
+    else if (strcmpic(s, US"local2") == 0) syslog_facility = LOG_LOCAL2;
+    else if (strcmpic(s, US"local3") == 0) syslog_facility = LOG_LOCAL3;
+    else if (strcmpic(s, US"local4") == 0) syslog_facility = LOG_LOCAL4;
+    else if (strcmpic(s, US"local5") == 0) syslog_facility = LOG_LOCAL5;
+    else if (strcmpic(s, US"local6") == 0) syslog_facility = LOG_LOCAL6;
+    else if (strcmpic(s, US"local7") == 0) syslog_facility = LOG_LOCAL7;
+    else if (strcmpic(s, US"daemon") == 0) syslog_facility = LOG_DAEMON;
+    }
+
+  if (syslog_facility == LOG_KERN)
+    {
+    syslog_facility = LOG_MAIL;
+    log_write(0, LOG_PANIC_DIE|LOG_CONFIG,
+      "failed to interpret syslog_facility \"%s\"", syslog_facility_str);
+    }
+  }
+
 /* Expand pid_file_path */


if (*pid_file_path != 0)
--