Author: robert
Date: 2007-05-25 02:22:09 -0600 (Fri, 25 May 2007)
New Revision: 1817

Added:
   trunk/sysklogd/sysklogd-1.4.1-community_fixes-1.patch
Log:
Added sysklogd community fixes patch

Added: trunk/sysklogd/sysklogd-1.4.1-community_fixes-1.patch
===================================================================
--- trunk/sysklogd/sysklogd-1.4.1-community_fixes-1.patch                       
        (rev 0)
+++ trunk/sysklogd/sysklogd-1.4.1-community_fixes-1.patch       2007-05-25 
08:22:09 UTC (rev 1817)
@@ -0,0 +1,1835 @@
+Submitted By: Robert Connolly <robert at linuxfromscratch dot org> (ashes)
+Date: 2007-05-25
+Initial Package Version: 1.4.1
+Upstream Status: Not Submitted
+Origin:        sysklogd-1.4.2-2.fc7's sysklogd-1.4.2rh.tar.gz
+       sysklogd-1.4.2rh.timezone.patch
+       Parts of sysklogd-1.4.2-rh-alt-warnings.patch
+       sysklogd-1.4.2-owl-syslogd-doexit.patch
+Description: This is over a dozen patches rolled in one. It becomes too
+complicated to keep these patches separate, because eventually they need to
+be installed in order, and then there's no point in keeping them separate.
+This is why Fedora created their own tarball. This patch includes various
+upstream and community bug fixes and enhancements, including sparc and alpha
+fixes. The changelog would double the size of this patch, and most of it has
+very little details, so I didn't include it.
+
+After applying the sysklogd-1.4.2rh.diff I:
+rm kernel.patch
+rm -rf redhat/
+rm sysklogd.spec
+cp ../sysklogd-1.4.1.orig/Makefile Makefile
+
+Then I edited Makefile with -DINET6 and -D_GNU_SOURCE, etc. Use 'make COPTS='
+to set your own cflags.
+I also fixed '#undef *syslog', chdir(2), and write(2), to supress GCC warnings.
+
+diff -Naur sysklogd-1.4.1.orig/Makefile sysklogd-1.4.1/Makefile
+--- sysklogd-1.4.1.orig/Makefile       1998-10-12 20:25:15.000000000 +0000
++++ sysklogd-1.4.1/Makefile    2007-05-25 06:10:06.000000000 +0000
+@@ -1,10 +1,12 @@
+ # Makefile for syslogd and klogd daemons.
+ 
+ CC= gcc
+-#CFLAGS= -g -DSYSV -Wall
+-#LDFLAGS= -g
+-CFLAGS= $(RPM_OPT_FLAGS) -O3 -DSYSV -fomit-frame-pointer -Wall 
-fno-strength-reduce
+-LDFLAGS= -s
++# COPTS_SSP= -fstack-protector-all --param=ssp-buffer-size=4 -Wstack-protector
++# COPTS_EXTRA= -D_FORTIFY_SOURCE=2 -fPIE
++COPTS= -g -O2 -fomit-frame-pointer ${COPTS_SSP} ${COPTS_EXTRA}
++CFLAGS= -DSYSV -DINET6 -D_GNU_SOURCE -std=gnu99 -Wall -Wformat 
-Wformat-security -Werror ${COPTS}
++# LDFLAGS_EXTRA= -pie -z now -z relro -z combreloc
++LDFLAGS= ${LDFLAGS_EXTRA}
+ 
+ # Look where your install program is.
+ INSTALL = /usr/bin/install
+@@ -25,7 +27,7 @@
+ 
+ # Define the following to impart start-up delay in klogd.  This is
+ # useful if klogd is started simultaneously or in close-proximity to syslogd.
+-# KLOGD_START_DELAY = -DKLOGD_DELAY=5
++KLOGD_START_DELAY = -DKLOGD_DELAY=1
+ 
+ # The following define determines whether the package adheres to the
+ # file system standard.
+@@ -44,7 +46,7 @@
+ # ballot below.
+ SYSLOGD_PIDNAME = -DSYSLOGD_PIDNAME=\"syslogd.pid\"
+ 
+-SYSLOGD_FLAGS= -DSYSLOG_INET -DSYSLOG_UNIXAF -DNO_SCCS ${FSSTND} \
++SYSLOGD_FLAGS= -DSYSLOG_INET -DINET6 -DSYSLOG_UNIXAF -DNO_SCCS ${FSSTND} \
+       ${SYSLOGD_PIDNAME}
+ SYSLOG_FLAGS= -DALLOW_KERNEL_LOGGING
+ KLOGD_FLAGS = ${FSSTND} ${KLOGD_START_DELAY}
+@@ -106,14 +108,14 @@
+       ${CC} ${CFLAGS} -DTEST -o ksym_test.o -c ksym.c
+ 
+ clean:
+-      rm -f *.o *.log *~ *.orig
++      rm -f *.o *.log *~ *.orig syslogd klogd
+ 
+ clobber: clean
+       rm -f syslogd klogd ksym syslog_tst oops_test TAGS tsyslogd tklogd
+ 
+ install_exec: syslogd klogd
+-      ${INSTALL} -m 500 -s syslogd ${BINDIR}/syslogd
+-      ${INSTALL} -m 500 -s klogd ${BINDIR}/klogd
++      ${INSTALL} -m 500 syslogd ${BINDIR}/syslogd
++      ${INSTALL} -m 500 klogd ${BINDIR}/klogd
+ 
+ install_man:
+       ${INSTALL} -o ${MAN_OWNER} -g ${MAN_OWNER} -m 644 sysklogd.8 
${MANDIR}/man8/sysklogd.8
+diff -Naur sysklogd-1.4.1.orig/klogd.c sysklogd-1.4.1/klogd.c
+--- sysklogd-1.4.1.orig/klogd.c        2001-03-11 19:40:10.000000000 +0000
++++ sysklogd-1.4.1/klogd.c     2007-05-25 05:59:23.000000000 +0000
+@@ -275,6 +275,10 @@
+ #define ksyslog klogctl
+ #endif
+ 
++#ifndef _PATH_KLOG
++#define _PATH_KLOG  "/proc/kmsg"
++#endif
++
+ #define LOG_BUFFER_SIZE 4096
+ #define LOG_LINE_LENGTH 1000
+ 
+@@ -291,7 +295,7 @@
+               terminate = 0,
+               caught_TSTP = 0,
+               reload_symbols = 0,
+-              console_log_level = -1;
++              console_log_level = 6;
+ 
+ static int    use_syscall = 0,
+               one_shot = 0,
+@@ -509,8 +513,7 @@
+ 
+ 
+       /* Set level of kernel console messaging.. */
+-      if ( (console_log_level != -1)
+-      && (ksyslog(8, NULL, console_log_level) < 0) && \
++      if ( (ksyslog(8, NULL, console_log_level) < 0) && \
+            (errno == EINVAL) )
+       {
+               /*
+@@ -738,7 +741,7 @@
+         switch( parse_state )
+         {
+         case PARSING_TEXT:
+-               delta = copyin( line, space, ptr, len, "\n[%" );
++               delta = copyin( line, space, ptr, len, "\n[" );
+                line  += delta;
+                ptr   += delta;
+                space -= delta;
+@@ -794,30 +797,9 @@
+                      parse_state = PARSING_SYMSTART;      /* at < */
+                   break;
+                }
+-               if( *ptr == '%' )   /* dangerous printf marker */
+-             {
+-                 delta = 0;
+-                 while (len && *ptr == '%')
+-                 {
+-                     *line++ = *ptr++;        /* copy it in */
+-                     space -= 1;
+-                     len   -= 1;
+-                     delta++;
+-                 }
+-                 if (delta % 2)       /* odd amount of %'s */
+-                 {
+-                     if (space)
+-                     {
+-                         *line++ = '%';       /* so simply add one */
+-                         space -= 1;
+-                     }
+-                     else 
+-                     {
+-                         *line++ = '\0';      /* remove the last one / 
terminate the string */
+-                     }
+-
+-                 }
+-             }
++               /* Now that line_buff is no longer fed to *printf as format
++                * string, '%'s are no longer "dangerous".
++              */
+                break;
+         
+         case PARSING_SYMSTART:
+@@ -887,8 +869,7 @@
+                value  = strtoul(sym_start+1, (char **) 0, 16);
+                *(line-1) = '>';  /* put back delim */
+ 
+-               symbol = LookupSymbol(value, &sym);
+-               if ( !symbol_lookup || symbol == (char *) 0 )
++               if ( !symbol_lookup || (symbol = LookupSymbol(value, &sym)) == 
(char *)0 )
+                {
+                   parse_state = PARSING_TEXT;
+                   break;
+@@ -938,7 +919,7 @@
+        * messages into this fresh buffer.
+        */
+       memset(log_buffer, '\0', sizeof(log_buffer));
+-      if ( (rdcnt = ksyslog(2, log_buffer, sizeof(log_buffer))) < 0 )
++      if ( (rdcnt = ksyslog(2, log_buffer, sizeof(log_buffer)-1)) < 0 )
+       {
+               if ( errno == EINTR )
+                       return;
+@@ -965,10 +946,14 @@
+       memset(log_buffer, '\0', sizeof(log_buffer));
+       if ( (rdcnt = read(kmsg, log_buffer, sizeof(log_buffer)-1)) < 0 )
+       {
++              int saved_errno = errno;
++
+               if ( errno == EINTR )
+                       return;
+               Syslog(LOG_ERR, "Cannot read proc file system: %d - %s.", \
+                      errno, strerror(errno));
++              if ( saved_errno == EPERM )
++                      Terminate();
+       }
+       else
+               LogLine(log_buffer, rdcnt);
+@@ -991,7 +976,10 @@
+                       *output = (char *) 0;
+ 
+ #ifndef TESTING
+-      chdir ("/");
++      if (chdir("/") != 0) {
++              fprintf(stderr, "klogd: chdir to / failed: %m");
++              exit (1);
++      }
+ #endif
+       /* Parse the command-line. */
+       while ((ch = getopt(argc, argv, "c:df:iIk:nopsvx2")) != EOF)
+@@ -1143,8 +1131,11 @@
+       if ( one_shot )
+       {
+               if (symbol_lookup) {
+-                      InitKsyms(symfile);
+-                      InitMsyms();
++                      symbol_lookup  = (InitKsyms(symfile) == 1);
++                      symbol_lookup |= InitMsyms();
++                      if (symbol_lookup == 0) {
++                              Syslog(LOG_WARNING, "cannot find any symbols, 
turning off symbol lookups\n");
++                      }
+               }
+               if ( (logsrc = GetKernelLogSrc()) == kernel )
+                       LogKernelLine();
+@@ -1159,8 +1150,11 @@
+ #endif
+       logsrc = GetKernelLogSrc();
+       if (symbol_lookup) {
+-              InitKsyms(symfile);
+-              InitMsyms();
++              symbol_lookup  = (InitKsyms(symfile) == 1);
++              symbol_lookup |= InitMsyms();
++              if (symbol_lookup == 0) {
++                      Syslog(LOG_WARNING, "cannot find any symbols, turning 
off symbol lookups\n");
++              }
+       }
+ 
+         /* The main loop. */
+diff -Naur sysklogd-1.4.1.orig/klogd.h sysklogd-1.4.1/klogd.h
+--- sysklogd-1.4.1.orig/klogd.h        1997-06-13 09:35:54.000000000 +0000
++++ sysklogd-1.4.1/klogd.h     2007-05-25 05:59:23.000000000 +0000
+@@ -31,6 +31,12 @@
+ #include <syslog.h>
+ #include <string.h>
+ 
++#ifdef syslog
++#undef syslog /* Use internal version. */
++#endif
++#ifdef vsyslog
++#undef vsyslog /* Ditto. */
++#endif
+ 
+ /* Function prototypes. */
+ extern int InitKsyms(char *);
+@@ -38,3 +44,6 @@
+ extern char * ExpandKadds(char *, char *);
+ extern void SetParanoiaLevel(int);
+ extern void Syslog(int priority, char *fmt, ...);
++extern void syslog(int pri, const char *fmt, ...);
++extern void vsyslog(int pri, const char *fmt, va_list ap);
++extern void openlog(const char *ident, int logstat, int logfac);
+diff -Naur sysklogd-1.4.1.orig/ksym.c sysklogd-1.4.1/ksym.c
+--- sysklogd-1.4.1.orig/ksym.c 2000-09-12 21:53:31.000000000 +0000
++++ sysklogd-1.4.1/ksym.c      2007-05-25 05:59:23.000000000 +0000
+@@ -112,6 +112,7 @@
+ #include <stdlib.h>
+ #include <malloc.h>
+ #include <sys/utsname.h>
++#include <ctype.h>
+ #include "klogd.h"
+ #include "ksyms.h"
+ 
+@@ -344,6 +345,7 @@
+               if ( (sym_file = fopen(symfile, "r")) != (FILE *) 0 ) {
+                       if (CheckMapVersion(symfile) == 1)
+                               file = symfile;
++                      fclose(sym_file);
+               }
+               if (sym_file == (FILE *) 0 || file == (char *) 0) {
+                       sprintf (symfile, "%s", *mf);
+@@ -352,6 +354,7 @@
+                       if ( (sym_file = fopen(symfile, "r")) != (FILE *) 0 ) {
+                               if (CheckMapVersion(symfile) == 1)
+                                       file = symfile;
++                              fclose(sym_file);
+                       }
+               }
+ 
+@@ -770,6 +773,84 @@
+       if ( (num_syms == 0) ||
+            (kp = strstr(line, "[<")) == (char *) 0 )
+       {
++#ifdef __sparc__
++              if (num_syms) {
++                      /*
++                       * On SPARC, register dumps do not have the [< >] 
characters in it.
++                       */
++                      static struct sparc_tests {
++                              char *str;
++                              int len;
++                      } tests[] = { { "PC: ", 4 },
++                                    { " o7: ", 5 },
++                                    { " ret_pc: ", 9 },
++                                    { " i7: ", 5 },
++                                    { "Caller[", 7 }
++                                  };
++                      int i, j, ndigits;
++                      char *kp2;
++                      for (i = 0; i < 5; i++) {
++                              kp = strstr(line, tests[i].str);
++                              if (!kp) continue;
++                              kp2 = kp + tests[i].len;
++                              if (!isxdigit(*kp2)) continue;
++                              for (ndigits = 1; isxdigit(kp2[ndigits]); 
ndigits++);
++                              if (ndigits != 8 && ndigits != 16) continue;
++                              /* On sparc64, all kernel addresses are in 
first 4GB */
++                              if (ndigits == 16) {
++                                      if (strncmp (kp2, "00000000", 8)) 
continue;
++                                      kp2 += 8;
++                              }
++                              if (!i) {
++                                      char *kp3;
++                                      if (ndigits == 16 && kp > line && 
kp[-1L] != 'T') continue;
++                                      kp3 = kp2 + 8;
++                                      if (ndigits == 16) {
++                                              if (strncmp (kp3, " TNPC: 
00000000", 15) || !isxdigit(kp3[15]))
++                                                      continue;
++                                              kp3 += 15;
++                                      } else {
++                                              if (strncmp (kp3, " NPC: ", 6) 
|| !isxdigit(kp3[6]))
++                                                      continue;
++                                              kp3 += 6;
++                                      }
++                                      for (j = 0; isxdigit(kp3[j]); j++);
++                                      if (j != 8) continue;
++                                      strncpy(elp, line, kp2 + 8 - line);
++                                      elp += kp2 + 8 - line;
++                                      value = strtol(kp2, (char **) 0, 16);
++                                      if ( (symbol = LookupSymbol(value, 
&sym)) ) {
++                                              if (sym.size)
++                                                      elp += sprintf(elp, " 
(%s+%d/%d)", symbol, sym.offset, sym.size);
++                                              else
++                                                      elp += sprintf(elp, " 
(%s)", symbol);
++                                      }
++                                      strncpy(elp, kp2 + 8, kp3 - kp2);
++                                      elp += kp3 - kp2;
++                                      value = strtol(kp3, (char **) 0, 16);
++                                      if ( (symbol = LookupSymbol(value, 
&sym)) ) {
++                                              if (sym.size)
++                                                      elp += sprintf(elp, " 
(%s+%d/%d)", symbol, sym.offset, sym.size);
++                                              else
++                                                      elp += sprintf(elp, " 
(%s)", symbol);
++                                      }
++                                      strcpy(elp, kp3 + 8);
++                              } else {
++                                      strncpy(elp, line, kp2 + 8 - line);
++                                      elp += kp2 + 8 - line;
++                                      value = strtol(kp2, (char **) 0, 16);
++                                      if ( (symbol = LookupSymbol(value, 
&sym)) ) {
++                                              if (sym.size)
++                                                      elp += sprintf(elp, " 
(%s+%d/%d)", symbol, sym.offset, sym.size);
++                                              else
++                                                      elp += sprintf(elp, " 
(%s)", symbol);
++                                      }
++                                      strcpy(elp, kp2 + 8);
++                              }
++                              return el;
++                      }
++              }
++#endif        
+               strcpy(el, line);
+               return(el);
+       }
+diff -Naur sysklogd-1.4.1.orig/ksym_mod.c sysklogd-1.4.1/ksym_mod.c
+--- sysklogd-1.4.1.orig/ksym_mod.c     2000-09-12 21:15:28.000000000 +0000
++++ sysklogd-1.4.1/ksym_mod.c  2007-05-25 05:59:23.000000000 +0000
+@@ -93,7 +93,7 @@
+ #include <linux/time.h>
+ #include <linux/module.h>
+ #else /* __GLIBC__ */
+-#include <linux/module.h>
++#include "module.h"
+ extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence));
+ extern int get_kernel_syms __P ((struct kernel_sym *__table));
+ #endif /* __GLIBC__ */
+diff -Naur sysklogd-1.4.1.orig/module.h sysklogd-1.4.1/module.h
+--- sysklogd-1.4.1.orig/module.h       1970-01-01 00:00:00.000000000 +0000
++++ sysklogd-1.4.1/module.h    2007-05-25 05:59:23.000000000 +0000
+@@ -0,0 +1,62 @@
++
++/* Module definitions for klogd's module support */
++struct kernel_sym
++{
++              unsigned long value;
++              char name[60];
++};
++
++struct module_symbol
++{
++      unsigned long value;
++      const char *name;
++};
++
++struct module_ref
++{
++      struct module *dep;     /* "parent" pointer */
++      struct module *ref;     /* "child" pointer */
++      struct module_ref *next_ref;
++};
++
++struct module_info
++{
++      unsigned long addr;
++      unsigned long size;
++      unsigned long flags;
++      long usecount;
++};
++
++
++typedef struct { volatile int counter; } atomic_t;
++
++struct module
++{
++      unsigned long size_of_struct;   /* == sizeof(module) */
++      struct module *next;
++      const char *name;
++      unsigned long size;
++      
++      union
++      {
++              atomic_t usecount;
++              long pad;
++        } uc;                           /* Needs to keep its size - so says 
rth */
++      
++      unsigned long flags;            /* AUTOCLEAN et al */
++      
++      unsigned nsyms;
++      unsigned ndeps;
++      
++      struct module_symbol *syms;
++      struct module_ref *deps;
++      struct module_ref *refs;
++      int (*init)(void);
++      void (*cleanup)(void);
++      const struct exception_table_entry *ex_table_start;
++      const struct exception_table_entry *ex_table_end;
++#ifdef __alpha__
++      unsigned long gp;
++#endif
++};
++      
+diff -Naur sysklogd-1.4.1.orig/pidfile.c sysklogd-1.4.1/pidfile.c
+--- sysklogd-1.4.1.orig/pidfile.c      1998-02-10 22:37:12.000000000 +0000
++++ sysklogd-1.4.1/pidfile.c   2007-05-25 05:59:23.000000000 +0000
+@@ -25,6 +25,7 @@
+  */
+ 
+ #include <stdio.h>
++#include <stdlib.h>
+ #include <unistd.h>
+ #include <sys/stat.h>
+ #include <sys/file.h>
+@@ -41,11 +42,15 @@
+ int read_pid (char *pidfile)
+ {
+   FILE *f;
+-  int pid;
++  char pidbuf[7]; /* 'kernel.pid_max = 32768', 5 digits. 7 is plenty. */
++  pid_t pid=0;
+ 
+   if (!(f=fopen(pidfile,"r")))
+     return 0;
+-  fscanf(f,"%d", &pid);
++
++  if (fgets(pidbuf, sizeof(pidbuf), f) != NULL) {
++    pid = atol(pidbuf);
++  }
+   fclose(f);
+   return pid;
+ }
+@@ -85,7 +90,8 @@
+ {
+   FILE *f;
+   int fd;
+-  int pid;
++  char pidbuf[7]; /* 'kernel.pid_max = 32768', 5 digits. 7 is plenty. */
++  pid_t pid=0;
+ 
+   if ( ((fd = open(pidfile, O_RDWR|O_CREAT, 0644)) == -1)
+        || ((f = fdopen(fd, "r+")) == NULL) ) {
+@@ -94,7 +100,9 @@
+   }
+ 
+   if (flock(fd, LOCK_EX|LOCK_NB) == -1) {
+-      fscanf(f, "%d", &pid);
++      if (fgets(pidbuf, sizeof(pidbuf), f) != NULL) {
++        pid = atol(pidbuf);
++      }
+       fclose(f);
+       printf("Can't lock, lock is held by pid %d.\n", pid);
+       return 0;
+diff -Naur sysklogd-1.4.1.orig/sysklogd.8 sysklogd-1.4.1/sysklogd.8
+--- sysklogd-1.4.1.orig/sysklogd.8     2001-03-11 19:35:51.000000000 +0000
++++ sysklogd-1.4.1/sysklogd.8  2007-05-25 05:59:23.000000000 +0000
+@@ -7,6 +7,7 @@
+ sysklogd \- Linux system logging utilities.
+ .SH SYNOPSIS
+ .B syslogd
++.RB [ " \-46A " ]
+ .RB [ " \-a "
+ .I socket
+ ]
+@@ -30,6 +31,7 @@
+ .I domainlist
+ ]
+ .RB [ " \-v " ]
++.RB [ " \-x " ]
+ .LP
+ .SH DESCRIPTION
+ .B Sysklogd
+@@ -74,6 +76,26 @@
+ .LP
+ .SH OPTIONS
+ .TP
++.BI "\-4"
++Force 
++.B syslogd 
++to use IPv4 addresses only.
++.TP
++.BI "\-6"
++Force 
++.B syslogd 
++to use IPv6 addresses only.
++.TP
++.BI "\-A"
++Ordinarily, 
++.B syslogd 
++tries to send the message to only one address
++even if the host has more than one A or AAAA record.  If this
++option is specified, 
++.B syslogd 
++tries to send the message to all
++addresses.
++.TP
+ .BI "\-a " "socket"
+ Using this argument you can specify additional sockets from that
+ .B syslogd
+@@ -152,6 +174,11 @@
+ .TP
+ .B "\-v"
+ Print version and exit.
++.TP
++.B "\-x"
++Disable name lookups when receiving remote messages.
++This avoids deadlocks when the nameserver is running on
++the same machine that runs the syslog daemon.
+ .LP
+ .SH SIGNALS
+ .B Syslogd
+diff -Naur sysklogd-1.4.1.orig/syslog.c sysklogd-1.4.1/syslog.c
+--- sysklogd-1.4.1.orig/syslog.c       2001-03-11 19:35:51.000000000 +0000
++++ sysklogd-1.4.1/syslog.c    2007-05-25 05:59:23.000000000 +0000
+@@ -54,11 +54,6 @@
+ #include <sys/file.h>
+ #include <sys/signal.h>
+ #include <sys/syslog.h>
+-#if 0
+-#include "syslog.h"
+-#include "pathnames.h"
+-#endif
+-
+ #include <sys/uio.h>
+ #include <sys/wait.h>
+ #include <netdb.h>
+@@ -70,6 +65,13 @@
+ #include <paths.h>
+ #include <stdio.h>
+ 
++#ifdef syslog
++#undef syslog /* Use internal version. */
++#endif
++#ifdef vsyslog
++#undef vsyslog /* Ditto. */
++#endif
++
+ #define       _PATH_LOGNAME   "/dev/log"
+ 
+ static int    LogFile = -1;           /* fd for log */
+@@ -179,7 +181,10 @@
+       (void)strcat(tbuf, "\r\n");
+       cnt += 2;
+       p = index(tbuf, '>') + 1;
+-      (void)write(fd, p, cnt - (p - tbuf));
++      if (write(fd, p, cnt - (p - tbuf)) == -1) {
++              (void)close(fd);
++              return;
++      }
+       (void)close(fd);
+ }
+ 
+diff -Naur sysklogd-1.4.1.orig/syslog_tst.c sysklogd-1.4.1/syslog_tst.c
+--- sysklogd-1.4.1.orig/syslog_tst.c   1997-06-02 17:21:41.000000000 +0000
++++ sysklogd-1.4.1/syslog_tst.c        2007-05-25 05:59:23.000000000 +0000
+@@ -42,7 +42,7 @@
+                                       if ( (nl = strrchr(bufr, '\n')) != \
+                                           (char *) 0)
+                                               *nl = '\0';
+-                                      syslog(LOG_INFO, bufr);
++                                      syslog(LOG_INFO, "%s", bufr);
+                                       logged += strlen(bufr);
+                                       if ( logged > 1024 )
+                                       {
+@@ -54,7 +54,7 @@
+               }
+               else
+                       while (argc-- > 1)
+-                              syslog(LOG_INFO, argv++[1]);
++                              syslog(LOG_INFO, "%s", argv++[1]);
+       }
+       else
+       {
+diff -Naur sysklogd-1.4.1.orig/syslogd.c sysklogd-1.4.1/syslogd.c
+--- sysklogd-1.4.1.orig/syslogd.c      2001-03-11 19:40:10.000000000 +0000
++++ sysklogd-1.4.1/syslogd.c   2007-05-25 05:59:23.000000000 +0000
+@@ -441,6 +441,15 @@
+  *    Don't return a closed fd if `-a' is called with a wrong path.
+  *    Thanks to Bill Nottingham <[EMAIL PROTECTED]> for providing
+  *    a patch.
++ * Wed Dec 1 18:00:00 EST 2004: Jason Vas Dias <[EMAIL PROTECTED]>
++ *      Use 'siginterrupt(SIGALRM,1)' after each 'signal(SIGALRM,domark)'
++ *      else recvfrom(...) will never be interrupted
++ *      (bugzilla #141983)
++ *
++ * Thu Dec 1 11:00:00 EST 2004: Jason Vas Dias <[EMAIL PROTECTED]>
++ *      Don't allow remote logging host targets like '@localhost'
++ *      (or any name that resolves to the address of a local interface)!!
++ *
+  */
+ 
+ 
+@@ -491,6 +500,8 @@
+ #include <arpa/nameser.h>
+ #include <arpa/inet.h>
+ #include <resolv.h>
++#include <ifaddrs.h>
++
+ #ifndef TESTING
+ #include "pidfile.h"
+ #endif
+@@ -555,10 +566,11 @@
+ 
+ char  **parts;
+ 
+-int inetm = 0;
+ static int debugging_on = 0;
+ static int nlogs = -1;
+ static int restart = 0;
++static int alarm_signal = 0;
++static int exit_on_signal = 0;
+ 
+ #define MAXFUNIX      20
+ 
+@@ -613,22 +625,23 @@
+       short   f_type;                 /* entry type, see below */
+       short   f_file;                 /* file descriptor */
+       time_t  f_time;                 /* time this was last written */
++      char    *f_host;                /* host from which to recd. */
+       u_char  f_pmask[LOG_NFACILITIES+1];     /* priority mask */
+       union {
+               char    f_uname[MAXUNAMES][UNAMESZ+1];
+               struct {
+-                      char    f_hname[MAXHOSTNAMELEN+1];
+-                      struct sockaddr_in      f_addr;
++                      char    f_hname[MAXHOSTNAMELEN];
++                      struct addrinfo *f_addr;
+               } f_forw;               /* forwarding address */
+               char    f_fname[MAXFNAME];
+       } f_un;
+       char    f_prevline[MAXSVLINE];          /* last message logged */
+       char    f_lasttime[16];                 /* time of last occurrence */
+-      char    f_prevhost[MAXHOSTNAMELEN+1];   /* host from which recd. */
++      char    f_prevhost[MAXHOSTNAMELEN];     /* host from which recd. */
+       int     f_prevpri;                      /* pri of f_prevline */
+       int     f_prevlen;                      /* length of f_prevline */
+       int     f_prevcount;                    /* repetition cnt of prevline */
+-      int     f_repeatcount;                  /* number of "repeated" msgs */
++      u_int   f_repeatcount;                  /* number of "repeated" msgs */
+       int     f_flags;                        /* store some additional flags 
*/
+ };
+ 
+@@ -637,8 +650,8 @@
+  * in seconds after previous message is logged.  After each flush,
+  * we move to the next interval until we reach the largest.
+  */
+-int   repeatinterval[] = { 30, 60 };  /* # of secs before flush */
+-#define       MAXREPEAT ((sizeof(repeatinterval) / sizeof(repeatinterval[0])) 
- 1)
++time_t        repeatinterval[] = { 30, 60 };  /* # of secs before flush */
++#define       MAXREPEAT ((int) ((sizeof(repeatinterval) / 
sizeof(repeatinterval[0])) - 1))
+ #define       REPEATTIME(f)   ((f)->f_time + 
repeatinterval[(f)->f_repeatcount])
+ #define       BACKOFF(f)      { if (++(f)->f_repeatcount > MAXREPEAT) \
+                                (f)->f_repeatcount = MAXREPEAT; \
+@@ -721,15 +734,22 @@
+ };
+ 
+ int   Debug;                  /* debug flag */
+-char  LocalHostName[MAXHOSTNAMELEN+1];        /* our hostname */
+-char  *LocalDomain;           /* our local domain name */
++int     resolve = 1;            /* resolve hostname */
++char  LocalHostName[MAXHOSTNAMELEN];  /* our hostname */
++const char    *LocalDomain;           /* our local domain name */
+ int   InetInuse = 0;          /* non-zero if INET sockets are being used */
+-int   finet = -1;             /* Internet datagram socket */
+-int   LogPort;                /* port number for INET connections */
++int   * finet = NULL;         /* Internet datagram socket */
+ int   Initialized = 0;        /* set when we have initialized ourselves */
+ int   MarkInterval = 20 * 60; /* interval between marks in seconds */
++#ifdef INET6
++int     family = PF_UNSPEC;     /* protocol family (IPv4, IPv6 or both) */
++#else
++int     family = PF_INET;       /* protocol family (IPv4 only) */
++#endif
++int     send_to_all = 0;        /* send message to all IPv4/IPv6 addresses */
+ int   MarkSeq = 0;            /* mark sequence number */
+ int   NoFork = 0;             /* don't fork - don't run in daemon mode */
++int     DisableDNS = 0;               /* don't look up IP addresses of 
incoming messages */
+ int   AcceptRemote = 0;       /* receive messages that come via UDP */
+ char  **StripDomains = NULL;  /* these domains may be stripped before writing 
logs */
+ char  **LocalHosts = NULL;    /* these hosts are logged with their hostname */
+@@ -743,7 +763,7 @@
+ char **crunch_list(char *list);
+ int usage(void);
+ void untty(void);
+-void printchopped(const char *hname, char *msg, int len, int fd);
++void printchopped(const char *hname, char *msg, size_t len, int fd);
+ void printline(const char *hname, char *msg);
+ void printsys(char *msg);
+ void logmsg(int pri, char *msg, const char *from, int flags);
+@@ -751,11 +771,14 @@
+ void endtty();
+ void wallmsg(register struct filed *f, struct iovec *iov);
+ void reapchild();
+-const char *cvthname(struct sockaddr_in *f);
++const char *cvthname(struct sockaddr_storage *f);
+ void domark();
++void alarm_handler(int sig);
+ void debug_switch();
+-void logerror(char *type);
++void logerror(const char *type);
+ void die(int sig);
++static void free_host_ai_list( struct addrinfo *ai );
++void exit_signal_handler(int sig);
+ #ifndef TESTING
+ void doexit(int sig);
+ #endif
+@@ -773,9 +796,13 @@
+ static int create_unix_socket(const char *path);
+ #endif
+ #ifdef SYSLOG_INET
+-static int create_inet_socket();
++static int * create_inet_sockets();
+ #endif
+ 
++static struct addrinfo *host_ai_list( char *host );
++static int    hosts_equal(struct addrinfo *ai1, struct addrinfo *ai2);
++static struct addrinfo *not_local_address( char *host );
++
+ int main(argc, argv)
+       int argc;
+       char **argv;
+@@ -786,7 +813,7 @@
+       int len, num_fds;
+ #else /* __GLIBC__ */
+ #ifndef TESTING
+-      size_t len;
++      socklen_t len;
+ #endif
+       int num_fds;
+ #endif /* __GLIBC__ */
+@@ -808,12 +835,13 @@
+ #ifndef TESTING
+       int     fd;
+ #ifdef  SYSLOG_INET
+-      struct sockaddr_in frominet;
+-      char *from;
++      struct sockaddr_storage frominet;
++      const char *from;
+ #endif
+       pid_t ppid = getpid();
+ #endif
+       int ch;
++      int l;
+       struct hostent *hent;
+ 
+       char line[MAXLINE +1];
+@@ -822,15 +850,29 @@
+       int maxfds;
+ 
+ #ifndef TESTING
+-      chdir ("/");
++      if (chdir("/") != 0) {
++              fprintf(stderr, "klogd: chdir to / failed: %m");
++              exit (1);
++      }
+ #endif
+       for (i = 1; i < MAXFUNIX; i++) {
+               funixn[i] = "";
+               funix[i]  = -1;
+       }
+ 
+-      while ((ch = getopt(argc, argv, "a:dhf:l:m:np:rs:v")) != EOF)
++      while ((ch = getopt(argc, argv, "46Aa:dhf:l:m:np:rs:vx")) != EOF)
+               switch((char)ch) {
++                case '4':
++                              family = PF_INET;
++                              break;
++#ifdef INET6
++                case '6':
++                              family = PF_INET6;
++                              break;
++#endif
++                case 'A':
++                              send_to_all++;
++                            break;
+               case 'a':
+                       if (nfunix < MAXFUNIX)
+                               funixn[nfunix++] = optarg;
+@@ -877,6 +919,9 @@
+               case 'v':
+                       printf("syslogd %s.%s\n", VERSION, PATCHLEVEL);
+                       exit (0);
++              case 'x':
++                      DisableDNS = 1;
++                      break;
+               case '?':
+               default:
+                       usage();
+@@ -890,11 +935,11 @@
+               dprintf("Checking pidfile.\n");
+               if (!check_pid(PidFile))
+               {
++                      signal (SIGTERM, doexit);
+                       if (fork()) {
+                               /*
+                                * Parent process
+                                */
+-                              signal (SIGTERM, doexit);
+                               sleep(300);
+                               /*
+                                * Not reached unless something major went 
wrong.  5
+@@ -906,6 +951,7 @@
+                                */
+                               exit(1);
+                       }
++                      signal (SIGTERM, SIG_DFL);
+                       num_fds = getdtablesize();
+                       for (i= 0; i < num_fds; i++)
+                               (void) close(i);
+@@ -986,14 +1032,26 @@
+               if (isupper(*p))
+                       *p = tolower(*p);
+ 
+-      (void) signal(SIGTERM, die);
+-      (void) signal(SIGINT, Debug ? die : SIG_IGN);
+-      (void) signal(SIGQUIT, Debug ? die : SIG_IGN);
++      (void) signal(SIGTERM, exit_signal_handler);
++      (void) signal(SIGINT, Debug ? exit_signal_handler : SIG_IGN);
++      (void) signal(SIGQUIT, Debug ? exit_signal_handler : SIG_IGN);
+       (void) signal(SIGCHLD, reapchild);
+-      (void) signal(SIGALRM, domark);
++      (void) signal(SIGALRM, alarm_handler);
+       (void) signal(SIGUSR1, Debug ? debug_switch : SIG_IGN);
+       (void) alarm(TIMERINTVL);
+-
++      
++      /* By default, signal() now specifies SA_RESTART, so system calls
++       * will NOT now return EINTR when a signal arrives during them.
++       * This makes things like recvfrom potentially hang forever...
++       * Hence we need to add siginterrupt calls:
++       */
++      siginterrupt(SIGTERM,1);
++      siginterrupt(SIGINT, 1);
++      siginterrupt(SIGQUIT,1);
++      siginterrupt(SIGCHLD,1);
++      siginterrupt(SIGALRM,1);
++      siginterrupt(SIGUSR1,1);
++      
+       /* Create a partial message table for all file descriptors. */
+       num_fds = getdtablesize();
+       dprintf("Allocated parts table for %d file descriptors.\n", num_fds);
+@@ -1049,8 +1107,11 @@
+                * descriptors.
+                */
+               if ( InetInuse && AcceptRemote ) {
+-                      FD_SET(inetm, &readfds);
+-                      if (inetm>maxfds) maxfds=inetm;
++                      for (i = 0; i < *finet; i++) {
++                              if (finet[i+1] != -1)
++                                      FD_SET(finet[i+1], &readfds);
++                                      if (finet[i+1]>maxfds) 
maxfds=finet[i+1];
++                      }
+                       dprintf("Listening on syslog UDP port.\n");
+               }
+ #endif
+@@ -1072,17 +1133,32 @@
+               }
+               nfds = select(maxfds+1, (fd_set *) &readfds, (fd_set *) NULL,
+                                 (fd_set *) NULL, (struct timeval *) NULL);
++
++              if ( exit_on_signal )
++              {
++                      die( exit_on_signal );
++                      exit_on_signal = 0;
++              }
++
+               if ( restart )
+               {
++                      restart = 0;
+                       dprintf("\nReceived SIGHUP, reloading syslogd.\n");
+                       init();
+-                      restart = 0;
+                       continue;
+               }
++
++              if ( alarm_signal )
++              {
++                      domark();
++                      alarm_signal = 0;
++              }
++
+               if (nfds == 0) {
+                       dprintf("No select activity.\n");
+                       continue;
+               }
++
+               if (nfds < 0) {
+                       if (errno != EINTR)
+                               logerror("select");
+@@ -1120,34 +1196,30 @@
+ #endif
+ 
+ #ifdef SYSLOG_INET
+-              if (InetInuse && AcceptRemote && FD_ISSET(inetm, &readfds)) {
+-                      len = sizeof(frominet);
+-                      memset(line, '\0', sizeof(line));
+-                      i = recvfrom(finet, line, MAXLINE - 2, 0, \
+-                                   (struct sockaddr *) &frominet, &len);
+-                      dprintf("Message from inetd socket: #%d, host: %s\n",
+-                              inetm, inet_ntoa(frominet.sin_addr));
+-                      if (i > 0) {
+-                              line[i] = line[i+1] = '\0';
+-                              from = (char *)cvthname(&frominet);
+-                              /*
+-                               * Here we could check if the host is permitted
+-                               * to send us syslog messages. We just have to
+-                               * catch the result of cvthname, look for a dot
+-                               * and if that doesn't exist, replace the first
+-                               * '\0' with '.' and we have the fqdn in 
lowercase
+-                               * letters so we could match them against 
whatever.
+-                               *  -Joey
+-                               */
+-                              printchopped(from, line, \
+-                                           i + 2,  finet);
+-                      } else if (i < 0 && errno != EINTR) {
+-                              dprintf("INET socket error: %d = %s.\n", \
+-                                      errno, strerror(errno));
+-                              logerror("recvfrom inet");
+-                              /* should be harmless now that we set
+-                               * BSDCOMPAT on the socket */
+-                              sleep(10);
++              if (InetInuse && AcceptRemote && finet) {
++                      for (i = 0; i < *finet; i++) {
++                              if (FD_ISSET(finet[i+1], &readfds)) {
++                                      len = sizeof(frominet);
++                                      memset(line, '\0', sizeof(line));
++                                      l = recvfrom(finet[i+1], line, MAXLINE 
- 2,
++                                                   0, (struct sockaddr 
*)&frominet,
++                                                   &len);
++                                      if (l > 0) {
++                                              line[l] = line[l+1] = '\0';
++                                              from = cvthname(&frominet);
++                                              printchopped(from, line, l + 2, 
 finet[i+1]);
++                                              dprintf("Message from inetd 
socket: #%d, host: %s\n",
++                                                      finet[i+1], from);
++                                      } 
++                                      else 
++                                              if (l < 0 && errno != EINTR) {
++                                                      dprintf("INET socket 
error: %d = %s.\n",
++                                                                errno, 
strerror(errno));
++                                                      logerror("recvfrom 
inet");
++                                                      /* should be harmless */
++                                                      sleep(10);
++                                              }       
++                              }
+                       }
+               }
+ #endif
+@@ -1174,7 +1246,7 @@
+ 
+ int usage()
+ {
+-      fprintf(stderr, "usage: syslogd [-drvh] [-l hostlist] [-m markinterval] 
[-n] [-p path]\n" \
++      fprintf(stderr, "usage: syslogd [-46Adrvxh] [-l hostlist] [-m 
markinterval] [-n] [-p path]\n" \
+               " [-s domainlist] [-f conffile]\n");
+       exit(1);
+ }
+@@ -1212,41 +1284,71 @@
+ #endif
+ 
+ #ifdef SYSLOG_INET
+-static int create_inet_socket()
++static int * create_inet_sockets()
+ {
+-      int fd, on = 1;
+-      struct sockaddr_in sin;
+-
+-      fd = socket(AF_INET, SOCK_DGRAM, 0);
+-      if (fd < 0) {
+-              logerror("syslog: Unknown protocol, suspending inet service.");
+-              return fd;
+-      }
+-
+-      memset(&sin, 0, sizeof(sin));
+-      sin.sin_family = AF_INET;
+-      sin.sin_port = LogPort;
+-      if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, \
+-                     (char *) &on, sizeof(on)) < 0 ) {
+-              logerror("setsockopt(REUSEADDR), suspending inet");
+-              close(fd);
+-              return -1;
+-      }
+-      /* We need to enable BSD compatibility. Otherwise an attacker
+-       * could flood our log files by sending us tons of ICMP errors.
+-       */
+-      if (setsockopt(fd, SOL_SOCKET, SO_BSDCOMPAT, \
+-                      (char *) &on, sizeof(on)) < 0) {
+-              logerror("setsockopt(BSDCOMPAT), suspending inet");
+-              close(fd);
+-              return -1;
+-      }
+-      if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
+-              logerror("bind, suspending inet");
+-              close(fd);
+-              return -1;
+-      }
+-      return fd;
++      struct addrinfo hints, *res, *r;
++        int error, maxs, *s, *socks;
++      
++        memset(&hints, 0, sizeof(hints));
++        hints.ai_flags = AI_PASSIVE;
++        hints.ai_family = family;
++        hints.ai_socktype = SOCK_DGRAM;
++        error = getaddrinfo(NULL, "syslog", &hints, &res);
++        if (error) {
++              logerror(gai_strerror(error));
++                errno = 0;
++                die(0);
++        }
++      
++        /* Count max number of sockets we may open */
++        for (maxs = 0, r = res; r; r = r->ai_next, maxs++);
++        socks = malloc((maxs+1) * sizeof(int));
++        if (!socks) {
++              logerror("couldn't allocate memory for sockets");
++              die(0);
++        }
++      
++        *socks = 0;   /* num of sockets counter at start of array */
++        s = socks + 1;
++        for (r = res; r; r = r->ai_next) {
++              *s = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
++              if (*s < 0) {
++                      logerror("socket");
++                        continue;
++              }
++
++                if (r->ai_family == AF_INET6) {
++                      int on = 1;
++                              if (setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY,
++                                     (char *)&on, sizeof (on)) < 0) {
++                              logerror("setsockopt");
++                              close(*s);
++                              continue;
++                      }
++              }
++
++                if (bind(*s, r->ai_addr, r->ai_addrlen) < 0) {
++                      close(*s);
++                      logerror("bind");
++                      continue;
++                }
++      
++                (*socks)++;
++                s++;
++      }
++      
++        if (*socks == 0) {
++              free(socks);
++                if (Debug)
++                      return(NULL);
++                else
++                      die(0);
++      }
++
++        if (res)
++              freeaddrinfo(res);
++      
++      return(socks);
+ }
+ #endif
+ 
+@@ -1254,30 +1356,26 @@
+ crunch_list(list)
+       char *list;
+ {
+-      int count, i;
++      int i, m, n;
+       char *p, *q;
+       char **result = NULL;
+ 
+       p = list;
+       
+       /* strip off trailing delimiters */
+-      while (p[strlen(p)-1] == LIST_DELIMITER) {
+-              count--;
++      while (*p && p[strlen(p)-1] == LIST_DELIMITER)
+               p[strlen(p)-1] = '\0';
+-      }
+       /* cut off leading delimiters */
+-      while (p[0] == LIST_DELIMITER) {
+-              count--;
++      while (p[0] == LIST_DELIMITER)
+               p++; 
+-      }
+       
+-      /* count delimiters to calculate elements */
+-      for (count=i=0; p[i]; i++)
+-              if (p[i] == LIST_DELIMITER) count++;
++      /* count delimiters to calculate the number of elements */
++      for (n = i = 0; p[i]; i++)
++              if (p[i] == LIST_DELIMITER) n++;
+       
+-      if ((result = (char **)malloc(sizeof(char *) * count+2)) == NULL) {
++      if ((result = (char **)malloc(sizeof(char *) * (n + 2))) == NULL) {
+               printf ("Sorry, can't get enough memory, exiting.\n");
+-              exit(0);
++              exit(1);
+       }
+       
+       /*
+@@ -1285,30 +1383,28 @@
+        * characters are different from any delimiters,
+        * so we don't have to care about this.
+        */
+-      count = 0;
+-      while ((q=strchr(p, LIST_DELIMITER))) {
+-              result[count] = (char *) malloc((q - p + 1) * sizeof(char));
+-              if (result[count] == NULL) {
++      m = 0;
++      while ((q = strchr(p, LIST_DELIMITER)) && m < n) {
++              result[m] = (char *) malloc((q - p + 1) * sizeof(char));
++              if (result[m] == NULL) {
+                       printf ("Sorry, can't get enough memory, exiting.\n");
+-                      exit(0);
++                      exit(1);
+               }
+-              strncpy(result[count], p, q - p);
+-              result[count][q - p] = '\0';
++              memcpy(result[m], p, q - p);
++              result[m][q - p] = '\0';
+               p = q; p++;
+-              count++;
++              m++;
+       }
+-      if ((result[count] = \
+-           (char *)malloc(sizeof(char) * strlen(p) + 1)) == NULL) {
++      if ((result[m] = strdup(p)) == NULL) {
+               printf ("Sorry, can't get enough memory, exiting.\n");
+-              exit(0);
++              exit(1);
+       }
+-      strcpy(result[count],p);
+-      result[++count] = NULL;
++      result[++m] = NULL;
+ 
+ #if 0
+-      count=0;
+-      while (result[count])
+-              dprintf ("#%d: %s\n", count, StripDomains[count++]);
++      m = 0;
++      while (result[m])
++              dprintf ("#%d: %s\n", m, result[m++]);
+ #endif
+       return result;
+ }
+@@ -1346,7 +1442,7 @@
+ void printchopped(hname, msg, len, fd)
+       const char *hname;
+       char *msg;
+-      int len;
++      size_t len;
+       int fd;
+ {
+       auto int ptlngth;
+@@ -1446,6 +1542,7 @@
+       while ((c = *p++) && q < &line[sizeof(line) - 4]) {
+               if (c == '\n')
+                       *q++ = ' ';
++#if 0
+               else if (c < 040) {
+                       *q++ = '^';
+                       *q++ = c ^ 0100;
+@@ -1454,7 +1551,9 @@
+                       *q++ = '0' + ((c & 0300) >> 6);
+                       *q++ = '0' + ((c & 0070) >> 3);
+                       *q++ = '0' + (c & 0007);
+-              } else
++              }
++#endif
++              else
+                       *q++ = c;
+       }
+       *q = '\0';
+@@ -1550,18 +1649,13 @@
+        * Check to see if msg looks non-standard.
+        */
+       msglen = strlen(msg);
+-      if (msglen < 16 || msg[3] != ' ' || msg[6] != ' ' ||
+-          msg[9] != ':' || msg[12] != ':' || msg[15] != ' ')
+-              flags |= ADDDATE;
+-
+-      (void) time(&now);
+-      if (flags & ADDDATE)
+-              timestamp = ctime(&now) + 4;
+-      else {
+-              timestamp = msg;
++      if (!(msglen < 16 || msg[3] != ' ' || msg[6] != ' ' ||
++          msg[9] != ':' || msg[12] != ':' || msg[15] != ' ')) {
+               msg += 16;
+               msglen -= 16;
+       }
++      (void) time(&now);
++        timestamp = ctime(&now) + 4;
+ 
+       /* extract facility and priority level */
+       if (flags & MARK)
+@@ -1661,13 +1755,15 @@
+       char *msg;
+ {
+       struct iovec iov[6];
++      struct addrinfo *r;
+       register struct iovec *v = iov;
+       char repbuf[80];
+ #ifdef SYSLOG_INET
+       register int l;
++      int i,lsent = 0;
+       char line[MAXLINE + 1];
+       time_t fwd_suspend;
+-      struct hostent *hp;
++      struct addrinfo *saddr;
+ #endif
+ 
+       dprintf("Called fprintlog, ");
+@@ -1736,7 +1832,7 @@
+               fwd_suspend = time((time_t *) 0) - f->f_time;
+               if ( fwd_suspend >= INET_SUSPEND_TIME ) {
+                       dprintf("Forwarding suspension to unknown over, 
retrying\n");
+-                      if ( (hp = gethostbyname(f->f_un.f_forw.f_hname)) == 
NULL ) {
++                      if ( (saddr = 
not_local_address(f->f_un.f_forw.f_hname)) == NULL ) {
+                               dprintf("Failure: %s\n", 
sys_h_errlist[h_errno]);
+                               dprintf("Retries: %d\n", f->f_prevcount);
+                               if ( --f->f_prevcount < 0 ) {
+@@ -1748,7 +1844,7 @@
+                       }
+                       else {
+                               dprintf("%s found, resuming.\n", 
f->f_un.f_forw.f_hname);
+-                              memcpy((char *) 
&f->f_un.f_forw.f_addr.sin_addr, hp->h_addr, hp->h_length);
++                              f->f_un.f_forw.f_addr = saddr;
+                               f->f_prevcount = 0;
+                               f->f_type = F_FORW;
+                               goto f_forw;
+@@ -1776,15 +1872,31 @@
+                       l = strlen(line);
+                       if (l > MAXLINE)
+                               l = MAXLINE;
+-                      if (sendto(finet, line, l, 0, \
+-                                 (struct sockaddr *) &f->f_un.f_forw.f_addr,
+-                                 sizeof(f->f_un.f_forw.f_addr)) != l) {
+-                              int e = errno;
+-                              dprintf("INET sendto error: %d = %s.\n", 
+-                                      e, strerror(e));
+-                              f->f_type = F_FORW_SUSP;
+-                              errno = e;
+-                              logerror("sendto");
++                      if (finet) {
++                              for (r = f->f_un.f_forw.f_addr; r; r = 
r->ai_next) {
++                                      for (i = 0; i < *finet; i++) {
++#if 0
++                                      /*
++                                       * should we check AF first, or just
++                                       * trial and error? FWD
++                                      */ 
++                                      if (r->ai_family == 
address_family_of(finet[i+1]))
++#endif
++                                        lsent = sendto(finet[i+1], line, l, 0,
++                                                       r->ai_addr, 
r->ai_addrlen);
++                                        if (lsent == l)
++                                              break;
++                                      }
++                                      if (lsent == l && !send_to_all)
++                                            break;
++                              }
++                              if (lsent != l) {
++                                      int e = errno;
++                                    dprintf("INET sendto error: %d = %s.\n", 
e, strerror(e));
++                                    f->f_type = F_FORW_SUSP;
++                                      errno = e;
++                                      logerror("sendto");
++                              }
+                       }
+               }
+               break;
+@@ -1839,7 +1951,7 @@
+ #else
+                               && e == EBADF) {
+ #endif
+-                              f->f_file = open(f->f_un.f_fname, 
O_WRONLY|O_APPEND|O_NOCTTY);
++                              f->f_file = open(f->f_un.f_fname, 
O_WRONLY|O_APPEND|O_NOCTTY|O_LARGEFILE);
+                               if (f->f_file < 0) {
+                                       f->f_type = F_UNUSED;
+                                       logerror(f->f_un.f_fname);
+@@ -1914,6 +2026,7 @@
+               (void) signal(SIGTERM, SIG_DFL);
+               (void) alarm(0);
+               (void) signal(SIGALRM, endtty);
++              siginterrupt(SIGALRM,1);
+ #ifndef SYSV
+               (void) signal(SIGTTOU, SIG_IGN);
+               (void) sigsetmask(0);
+@@ -1929,7 +2042,7 @@
+                       /* is this slot used? */
+                       if (ut.ut_name[0] == '\0')
+                               continue;
+-                      if (ut.ut_type == LOGIN_PROCESS)
++                      if (ut.ut_type != USER_PROCESS)
+                               continue;
+                       if (!(strcmp (ut.ut_name,"LOGIN"))) /* paranoia */
+                               continue;
+@@ -2003,27 +2116,48 @@
+  * Return a printable representation of a host address.
+  */
+ const char *cvthname(f)
+-      struct sockaddr_in *f;
++      struct sockaddr_storage *f;
+ {
+-      struct hostent *hp;
++      int error;
+       register char *p;
++      sigset_t omask, nmask;
+       int count;
++      static char hname[NI_MAXHOST], ip[NI_MAXHOST];
++
++      error = getnameinfo((struct sockaddr *)f,
++                            sizeof(*f),
++                            ip, sizeof ip, NULL, 0,
++                            NI_NUMERICHOST);
++        dprintf("cvthname(%s)\n", ip);
+ 
+-      if (f->sin_family != AF_INET) {
+-              dprintf("Malformed from address.\n");
++      if (error) {
++              dprintf("Malformed from address %s\n", gai_strerror(error));
+               return ("???");
+       }
+-      hp = gethostbyaddr((char *) &f->sin_addr, sizeof(struct in_addr), \
+-                         f->sin_family);
+-      if (hp == 0) {
+-              dprintf("Host name for your address (%s) unknown.\n",
+-                      inet_ntoa(f->sin_addr));
+-              return (inet_ntoa(f->sin_addr));
++
++      
++      if (!DisableDNS) {
++              sigemptyset(&nmask);
++              sigaddset(&nmask, SIGHUP);
++              sigprocmask(SIG_BLOCK, &nmask, &omask);
++
++              error = getnameinfo((struct sockaddr *)f,
++                                  sizeof(*f),
++                                    hname, sizeof hname, NULL, 0,
++                                    NI_NAMEREQD);
++
++              sigprocmask(SIG_SETMASK, &omask, NULL);
++      }
++
++      if (error || DisableDNS) {
++              dprintf("Host name for your address (%s) unknown\n", ip);
++              return (ip);
+       }
++
+       /*
+        * Convert to lower case, just like LocalDomain above
+        */
+-      for (p = (char *)hp->h_name; *p ; p++)
++      for (p = (char *) hname; *p ; p++)
+               if (isupper(*p))
+                       *p = tolower(*p);
+ 
+@@ -2031,17 +2165,17 @@
+        * Notice that the string still contains the fqdn, but your
+        * hostname and domain are separated by a '\0'.
+        */
+-      if ((p = strchr(hp->h_name, '.'))) {
++      if ((p = strchr(hname, '.'))) {
+               if (strcmp(p + 1, LocalDomain) == 0) {
+                       *p = '\0';
+-                      return (hp->h_name);
++                      return (hname);
+               } else {
+                       if (StripDomains) {
+                               count=0;
+                               while (StripDomains[count]) {
+                                       if (strcmp(p + 1, StripDomains[count]) 
== 0) {
+                                               *p = '\0';
+-                                              return (hp->h_name);
++                                              return (hname);
+                                       }
+                                       count++;
+                               }
+@@ -2049,9 +2183,9 @@
+                       if (LocalHosts) {
+                               count=0;
+                               while (LocalHosts[count]) {
+-                                      if (!strcmp(hp->h_name, 
LocalHosts[count])) {
++                                      if (!strcmp(hname, LocalHosts[count])) {
+                                               *p = '\0';
+-                                              return (hp->h_name);
++                                              return (hname);
+                                       }
+                                       count++;
+                               }
+@@ -2059,7 +2193,15 @@
+               }
+       }
+ 
+-      return (hp->h_name);
++      return (hname);
++}
++
++void alarm_handler( int sig )
++{
++      alarm_signal = 1;
++      (void) signal(SIGALRM, alarm_handler);  
++      (void) alarm(TIMERINTVL);
++      siginterrupt(SIGALRM,1);
+ }
+ 
+ void domark()
+@@ -2092,8 +2234,6 @@
+               }
+       }
+       }
+-      (void) signal(SIGALRM, domark);
+-      (void) alarm(TIMERINTVL);
+ }
+ 
+ void debug_switch()
+@@ -2109,7 +2249,7 @@
+  * Print syslogd errors some place.
+  */
+ void logerror(type)
+-      char *type;
++      const char *type;
+ {
+       char buf[100];
+ 
+@@ -2157,8 +2297,14 @@
+         for (i = 0; i < nfunix; i++)
+               if (funix[i] != -1)
+                       close(funix[i]);
++
+       /* Close the inet socket. */
+-      if (InetInuse) close(inetm);
++      if (InetInuse && finet)
++              for (i = 0; i < *finet; i++)
++                      if (finet[i+1] != -1) close(finet[i+1]);
++      free(finet);
++        finet = NULL;
++
+ 
+       /* Clean-up files. */
+         for (i = 0; i < nfunix; i++)
+@@ -2170,6 +2316,13 @@
+       exit(0);
+ }
+ 
++void exit_signal_handler(int sig)
++{
++      exit_on_signal = sig;
++      signal(sig, exit_signal_handler);
++      siginterrupt(sig,1);
++}
++
+ /*
+  * Signal handler to terminate the parent process.
+  */
+@@ -2177,7 +2330,7 @@
+ void doexit(sig)
+       int sig;
+ {
+-      exit (0);
++      _exit(0);
+ }
+ #endif
+ 
+@@ -2212,7 +2365,6 @@
+               logerror("see syslogd(8) for details of whether and how to 
enable it.");
+               return;
+       }
+-      LogPort = sp->s_port;
+ 
+       /*
+        *  Close all open log files and free log descriptor array.
+@@ -2237,6 +2389,9 @@
+                               case F_CONSOLE:
+                                       (void) close(f->f_file);
+                               break;
++                              case F_FORW:
++                                      freeaddrinfo(f->f_un.f_forw.f_addr);
++                              break;
+                       }
+               }
+ 
+@@ -2346,21 +2501,22 @@
+ 
+ #ifdef SYSLOG_INET
+       if (Forwarding || AcceptRemote) {
+-              if (finet < 0) {
+-                      finet = create_inet_socket();
+-                      if (finet >= 0) {
++              if (!finet) {
++                      finet = create_inet_sockets();
++                      if (*finet > 0) {
+                               InetInuse = 1;
+                               dprintf("Opened syslog UDP port.\n");
+                       }
+               }
+       }
+       else {
+-              if (finet >= 0)
+-                      close(finet);
+-              finet = -1;
++              if (finet)
++                      for (i = 0; i < *finet; i++)
++                              if (finet[i+1] != -1) close(finet[i+1]);
++              free(finet);
++              finet = NULL;
+               InetInuse = 0;
+       }
+-      inetm = finet;
+ #endif
+ 
+       Initialized = 1;
+@@ -2440,6 +2596,8 @@
+       char *line;
+       register struct filed *f;
+ {
++      struct addrinfo hints, *res;
++      int error;
+       register char *p;
+       register char *q;
+       register int i, i2;
+@@ -2449,7 +2607,7 @@
+       int ignorepri = 0;
+       int syncfile;
+ #ifdef SYSLOG_INET
+-      struct hostent *hp;
++      struct addrinfo *ina;
+ #endif
+       char buf[MAXLINE];
+       char xbuf[200];
+@@ -2605,22 +2763,29 @@
+       {
+       case '@':
+ #ifdef SYSLOG_INET
+-              (void) strcpy(f->f_un.f_forw.f_hname, ++p);
++              (void)strncpy(f->f_un.f_forw.f_hname, ++p,
++                            sizeof(f->f_un.f_forw.f_hname));
+               dprintf("forwarding host: %s\n", p);    /*ASP*/
+-              if ( (hp = gethostbyname(p)) == NULL ) {
++               if ( (ina = not_local_address(p)) == NULL ) {
+                       f->f_type = F_FORW_UNKN;
+                       f->f_prevcount = INET_RETRY_MAX;
+                       f->f_time = time ( (time_t *)0 );
+               } else {
+                       f->f_type = F_FORW;
++                      freeaddrinfo(ina);
+               }
+ 
+-              memset((char *) &f->f_un.f_forw.f_addr, 0,
+-                       sizeof(f->f_un.f_forw.f_addr));
+-              f->f_un.f_forw.f_addr.sin_family = AF_INET;
+-              f->f_un.f_forw.f_addr.sin_port = LogPort;
++              memset(&hints, 0, sizeof(hints));
++              hints.ai_family = family;
++              hints.ai_socktype = SOCK_DGRAM;
++              error = getaddrinfo(f->f_un.f_forw.f_hname, "syslog", &hints,
++                                  &res);
++              if (error) {
++                      logerror(gai_strerror(error));
++                      break;
++              }
+               if ( f->f_type == F_FORW )
+-                      memcpy((char *) &f->f_un.f_forw.f_addr.sin_addr, 
hp->h_addr, hp->h_length);
++                      f->f_un.f_forw.f_addr = res;
+               /*
+                * Otherwise the host might be unknown due to an
+                * inaccessible nameserver (perhaps on the same
+@@ -2640,7 +2805,7 @@
+                       f->f_file = open(++p, O_RDWR|O_NONBLOCK);
+                       f->f_type = F_PIPE;
+               } else {
+-                      f->f_file = open(p, O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY,
++                      f->f_file = open(p, 
O_WRONLY|O_APPEND|O_CREAT|O_NOCTTY|O_LARGEFILE,
+                                        0644);
+                       f->f_type = F_FILE;
+               }
+@@ -2793,6 +2958,206 @@
+       return;
+ }
+ 
++/* These functions are for verifying that a remote logging host
++ * '@name' target does NOT resolve to an address attached to a
++ * local interface; as reported by Chuck Mead <[EMAIL PROTECTED]>,
++ * if this happens, syslogd sends log messages to itself until
++ * the /var partition fills up.
++ * Jason Vas Dias <[EMAIL PROTECTED]>
++ */
++
++
++static void free_host_ai_list( struct addrinfo *ai )
++{ 
++    struct addrinfo *aie=0L, *ain=0L;
++    for(aie = ai; aie != 0L; aie = ain)
++    {
++      ain = aie->ai_next;
++      if(aie->ai_addr != 0L)
++          free(aie->ai_addr);
++      if(aie->ai_canonname != 0L)
++          free(aie->ai_canonname);
++      free(aie);
++    }    
++}
++
++static struct addrinfo *new_host_ai_node( struct addrinfo *ai )
++{
++    struct addrinfo *aie =(struct addrinfo *) malloc( sizeof(struct addrinfo) 
);
++    int len;
++
++    if( aie == 0L )
++      return 0L;
++    if( ai != 0L )
++      memcpy(aie, ai, sizeof(struct addrinfo));
++    aie->ai_addr = 0L;
++    aie->ai_canonname =0L;
++    aie->ai_next = 0L;
++    if( ( ai->ai_addr != 0L ) && (ai->ai_addrlen > 0) )
++    {
++      aie->ai_addr = (struct sockaddr*) malloc( ai->ai_addrlen );
++      if( aie->ai_addr != 0L )
++          memcpy(aie->ai_addr, ai->ai_addr,  ai->ai_addrlen );
++    }
++    if( ( ai->ai_canonname != 0L) && (*(ai->ai_canonname) != '\0') )
++    {
++      len = strlen(ai->ai_canonname);
++      aie->ai_canonname = (char*) malloc( len + 1);
++      if( aie->ai_canonname != 0L )
++      {
++          memcpy( aie->ai_canonname, ai->ai_canonname, len );
++          ai->ai_canonname[len]='\0';
++      }
++    }
++    return aie;
++}
++
++struct addrinfo *host_ai_list( char *host )
++{
++    struct addrinfo *ai=0L, *ail=0L, *aip, *aie, aih;
++    int r;
++    char *n;
++
++    if ( (host == 0L) || (*host == '\0') )
++       return 0L;
++    memset(&aih,'\0',sizeof(struct addrinfo));
++    aih.ai_flags = AI_CANONNAME;
++    aip=0L;
++    if( ((r=getaddrinfo(host, 0L, &aih, &aip)) != 0 ) || (aip == 0L) )
++       return(0L);
++    else
++       for( aie=aip; aie != 0L; aie=aie->ai_next )
++       {
++           if(  (aie->ai_addr == 0L)
++              ||(aie->ai_family == PF_UNSPEC)
++              ||(aie->ai_addrlen <= 0)
++             )
++               continue;
++           if(ai==0L)
++         {    
++             if(aie->ai_canonname == 0L)
++                 continue;
++               ai = new_host_ai_node(aie);
++             ail= ai;
++           }else
++           {
++             n=0L;
++             if( aie->ai_canonname == 0L)
++             {
++                 n = ai->ai_canonname;
++                 aie->ai_canonname = n;
++             }
++               ai->ai_next=new_host_ai_node(aie);
++               ai=ai->ai_next;
++             if(n != 0L)
++                 aie->ai_canonname = 0L;
++           }
++           if (aie == aie->ai_next)
++               break;
++           while
++           (
++                 (aie->ai_next != 0L)
++               &&(
++                    ( aie->ai_next->ai_addr == 0L)
++                  ||( aie->ai_addr == aie->ai_next->ai_addr )
++                  ||(  (aie->ai_next->ai_family == aie->ai_family)
++                     &&(aie->ai_next->ai_addrlen == aie->ai_addrlen)
++                   &&(memcmp( aie->ai_next->ai_addr, aie->ai_addr, 
aie->ai_addrlen)==0)
++                    )
++              )
++            )/* bug: each unique address / name combination is repeated three 
times! */
++                aie = aie->ai_next;
++    }
++    if ( ai != 0L)
++       ai->ai_next=0L;
++    freeaddrinfo(aip);
++    return ail;
++}
++
++int hosts_equal( struct addrinfo *ai1, struct addrinfo *ai2 )
++{
++    struct addrinfo *ai=0;
++    for(; ai1 != 0L; ai1 = ai1->ai_next)
++       if (( ai1->ai_canonname != 0L) || ( ai1->ai_addr != 0L))
++       {
++           for(ai = ai2; ai != 0L; ai = ai->ai_next)
++           {
++               if(  (  ( ai1->ai_canonname != 0L)
++                     &&( ai->ai_canonname != 0L)
++                     &&( strcmp(ai->ai_canonname, ai1->ai_canonname)==0)
++                    )
++                 || (  ( ai1->ai_addr != 0L)
++                     &&( ai->ai_addr != 0L )
++                     &&( ai1->ai_family == ai->ai_family)
++                     &&( ai1->ai_addrlen == ai->ai_addrlen)
++                     &&( memcmp(ai->ai_addr, ai1->ai_addr, ai->ai_addrlen) == 
0)
++                    )
++                 ) break;
++           }
++           if( ai != 0L )
++               break;
++        }
++    return ((ai1 != 0L) && (ai != 0L));
++}
++
++struct addrinfo *not_local_address(char *host)
++{
++    char hostname[1024];
++    struct addrinfo *ai1, *ai2;
++    struct ifaddrs *ifa=0L;
++    if ( host == 0L )
++       return 0L;
++    if(  (strcmp(host,"localhost") == 0)
++       ||(strcmp(host,"localhost.localdomain") == 0)
++       ||(strcmp(host,"127.0.0.1") == 0)
++       ||(strcmp(host,"::1") == 0)
++      ) return 0L;
++    if (gethostname(hostname,1024) == 0)
++      if ( strcmp(host, hostname) == 0 )
++          return 0L;
++    ai1 = host_ai_list(host);
++    ai2 = host_ai_list(hostname);
++    if( hosts_equal(ai1, ai2) ) {
++      free_host_ai_list(ai2);
++      free_host_ai_list(ai1);
++      return 0L;
++    }
++    free_host_ai_list(ai2);
++    ai2=0L;
++    if( getifaddrs(&ifa) == 0)
++    {
++      for(; (ifa != 0L) && (ifa->ifa_addr != 0L); ifa = ifa->ifa_next )
++      {
++          if( inet_ntop( ifa->ifa_addr->sa_family,
++                          ((ifa->ifa_addr->sa_family == PF_INET)
++                           ? (void*)&(((struct 
sockaddr_in*)(ifa->ifa_addr))->sin_addr)
++                           : (ifa->ifa_addr->sa_family == PF_INET6)
++                             ? (void*)&(((struct 
sockaddr_in6*)(ifa->ifa_addr))->sin6_addr)
++                             : (void*)&(ifa->ifa_addr->sa_data[0])
++                           ),
++                           hostname,
++                           sizeof(hostname)
++                   ) != 0L
++              )
++          {
++              ai2=host_ai_list(hostname);
++              if( hosts_equal(ai1, ai2) )
++                  break;
++              free_host_ai_list(ai2);
++              ai2=0L;
++          }
++      }
++    }
++    if( ai2 != 0L )
++    {
++        free_host_ai_list(ai2);
++        free_host_ai_list(ai1);
++        return 0L;
++    }
++
++    return ai1;
++}
++
+ /*
+  * Local variables:
+  *  c-indent-level: 8
+diff -Naur sysklogd-1.4.1.orig/version.h sysklogd-1.4.1/version.h
+--- sysklogd-1.4.1.orig/version.h      2001-03-11 19:40:10.000000000 +0000
++++ sysklogd-1.4.1/version.h   2007-05-25 05:59:23.000000000 +0000
+@@ -1,2 +1,2 @@
+ #define VERSION "1.4"
+-#define PATCHLEVEL "1"
++#define PATCHLEVEL "2-prerelease"

-- 
http://linuxfromscratch.org/mailman/listinfo/patches
FAQ: http://www.linuxfromscratch.org/faq/
Unsubscribe: See the above information page

Reply via email to