r1817 - trunk/sysklogd

robert at linuxfromscratch.org robert at linuxfromscratch.org
Fri May 25 01:22:09 PDT 2007


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 <notting at redhat.com> for providing
+  *	a patch.
++ * Wed Dec 1 18:00:00 EST 2004: Jason Vas Dias <jvdias at redhat.com>
++ *      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 <jvdias at redhat.com>
++ *      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 <csm at redhat.com>,
++ * if this happens, syslogd sends log messages to itself until
++ * the /var partition fills up.
++ * Jason Vas Dias <jvdias at redhat.com>
++ */
++
++
++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"




More information about the patches mailing list