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