Compare commits

...
15 Commits
Author SHA1 Message Date
Mattias Walström e3fe203005 Minor changes in changelog 2025-04-11 16:27:01 +02:00
Mattias Walström 18f7c779c9 Changelog: Prepare for release 25.03.01 2025-04-11 14:09:57 +02:00
Mattias Walström 454207c185 Fix migration when SSH server settings exist
This fix #1015
2025-04-11 14:05:53 +02:00
Richard AlpeandMattias Walström d877806e2b confd: remove prefix from version leaf in migrate
Signed-off-by: Richard Alpe <richard@bit42.se>
2025-04-11 14:04:38 +02:00
Richard AlpeandMattias Walström 5ed7182361 confd: fix indentation of bin/migrate
Don't mix tabs and spaces.

Signed-off-by: Richard Alpe <richard@bit42.se>
2025-04-11 14:04:24 +02:00
Mattias Walström 3f695b6c62 Fix symlink in release packages
Fix #1002
2025-04-11 14:03:57 +02:00
Mattias Walström 4f3605a5f7 migrate: Fix typo resulting in not logging correctly 2025-04-11 14:03:42 +02:00
Joachim WibergandMattias Walström e89dde0d25 confd: set correct file version of migrated files in backup
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-04-11 14:03:28 +02:00
Joachim WibergandMattias Walström e1ecf6b71d board/common: set wheel group on /cfg/backup dir
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-04-11 14:03:16 +02:00
Mattias WalströmandGitHub 10f62f679b Merge pull request #1000 from kernelkit/logging-fixes
Misc. fixes related to logging found in -rc1
2025-03-31 15:08:10 +02:00
Joachim Wiberg fa4f7c6532 doc: update ChangeLog with fixes for -rc1 issues
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-03-31 13:49:34 +02:00
Joachim Wiberg 0647541988 patches/sysklogd: sync with latest version in Buildroot 2025.02
Buildroot 2025.02 currently has sysklogd v2.7.0, which has new features,
but also a few bugs.  This commit drops all patches for v2.5.2 and adds
all patches for sysklogd v2.7.2

For more information, see:

 - https://github.com/troglobit/sysklogd/releases/tag/v2.7.1
 - https://github.com/troglobit/sysklogd/releases/tag/v2.7.2

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-03-31 13:43:19 +02:00
Joachim Wiberg 2602ddc0b8 board/common: skip product init if no product specific dir
This silences a bogus warning in the log when runparts is called with no
argument.  I.e., when there is no product specific init files available.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-03-31 13:35:44 +02:00
Joachim Wiberg 3886b284d3 confd: fix invalid priority argument to logger
There is no such loglevel 'critical', only 'crit' is defined.

For some reason this issue has not been spotted until the upgrade to
Buildroot 2025.02, which includes sysklogd v2.7.0, and Finit v4.11.

Introduced in 3e48af6, when the concept of failure-config was added.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-03-31 13:14:34 +02:00
Joachim Wiberg 22a9405d1e confd: shellcheck fixes to load script
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
2025-03-31 13:13:43 +02:00
41 changed files with 1114 additions and 2040 deletions
+1 -1
View File
@@ -90,7 +90,7 @@ if [ "$BR2_TARGET_ROOTFS_SQUASHFS" = "y" ]; then
rel=$(ver)
ln -sf rootfs.squashfs "$BINARIES_DIR/${NAME}${rel}.img"
if [ -n "$rel" ]; then
ln -sf "$BINARIES_DIR/${NAME}${rel}.img" "$BINARIES_DIR/${NAME}.img"
ln -sf "${NAME}${rel}.img" "$BINARIES_DIR/${NAME}.img"
fi
fi
@@ -39,8 +39,10 @@ fi
# init scripts to prevent select services from starting.
initctl -nbq cond set led
note "Calling runparts $PRODUCT_INIT/S[0-9]+.* start"
/usr/libexec/finit/runparts -bsp "$PRODUCT_INIT"
if [ -d "$PRODUCT_INIT" ]; then
note "Calling runparts $PRODUCT_INIT/S[0-9]+.* start"
/usr/libexec/finit/runparts -bsp "$PRODUCT_INIT"
fi
# Product specific init done.
initctl -nbq cond set product
@@ -4,10 +4,14 @@
# the migrate tool inserts old version in name before .cfg extension.
CONFIG_FILE="/cfg/startup-config.cfg"
BACKUP_FILE="/cfg/backup/startup-config.cfg"
mkdir -p "$(dirname "$BACKUP_FILE")"
BACKUP_DIR="$(dirname "$BACKUP_FILE")"
mkdir -p "$BACKUP_DIR"
chown root:wheel "$BACKUP_DIR"
chmod 0770 "$BACKUP_DIR"
if [ ! -f "$CONFIG_FILE" ]; then
note "No $(basename "$CONFIG_FILE" .cfg) yet, likely factory reset."
logger -I $$ -k -p user.notice -t $(basename "$0") "No $(basename "$CONFIG_FILE" .cfg) yet, likely factory reset."
exit 0
elif migrate -cq "$CONFIG_FILE"; then
exit 0
+13
View File
@@ -3,6 +3,12 @@ Change Log
All notable changes to the project are documented in this file.
[v25.03.1][] - 2025-04-11
-------------------------
### Fixes
- Fix configuration migration issues when upgrading
[v25.03.0][] - 2025-03-31
-------------------------
@@ -21,6 +27,12 @@ All notable changes to the project are documented in this file.
- Fix #990: web console, ttyd service, stopped working after upgrade to
Buildroot 2025.02, caused by new (missing) option `--writable`
- Fix TCAM memory corruption in `mvpp2` Ethernet controller
- Fix annoying (but harmless) usage message from the logger tool when
`startup-config` fails to load and the system reverts to failure mode
- Fix harmless log warning for product specific init when no product
specific init scripts are found
- Backport fixes for sysklogd, affecting hostname filtering and periods
in TAG names, pending official backport in Buildroot
[v25.02.0][] - 2025-03-04
@@ -1524,6 +1536,7 @@ Supported YANG models in addition to those used by sysrepo and netopeer:
[buildroot]: https://buildroot.org/
[UNRELEASED]: https://github.com/kernelkit/infix/compare/v25.03.0...HEAD
[v25.03.1]: https://github.com/kernelkit/infix/compare/v25.03.0...v25.03.1
[v25.03.0]: https://github.com/kernelkit/infix/compare/v25.02.0...v25.03.0
[v25.02.0]: https://github.com/kernelkit/infix/compare/v25.01.0...v25.02.0
[v25.01.0]: https://github.com/kernelkit/infix/compare/v24.11.0...v25.01.0
+1 -1
View File
@@ -17,7 +17,7 @@ run name:startup log:prio:user.notice norestart <pid/confd> env:/etc/default/con
-- Loading startup-config
# Run if loading startup-config fails for some reason
run name:failure log:prio:user.critical norestart env:/etc/default/confd \
run name:failure log:prio:user.crit norestart env:/etc/default/confd \
if:<run/startup/failure> \
[S] <pid/confd> /usr/libexec/confd/load -t $CONFD_TIMEOUT failure-config \
-- Loading failure-config
@@ -1,117 +0,0 @@
From ad9a464806fe27fe65d403f56f1dc701f7d0a10a Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Wed, 24 Apr 2024 13:19:09 +0200
Subject: [PATCH 01/17] Fix #72: loss of raw kernel log messages to console
Organization: Addiva Elektronik
This patch adds a command line flag `-l` to keep kernel logs to console.
A feature requested by embedded Linux users which often navigate issues
by console output.
With properly configured kernel logging, e.g., `quiet`, only error and
above in severity is logged by the kernel directly to the console. So
for most users this would be a useful behavior.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
man/syslogd.8 | 18 +++++++++++++++++-
src/syslogd.c | 10 +++++++++-
src/syslogd.h | 4 ++--
3 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/man/syslogd.8 b/man/syslogd.8
index dcfb564..70f1b8b 100644
--- a/man/syslogd.8
+++ b/man/syslogd.8
@@ -38,7 +38,7 @@
.Nd log systems messages
.Sh SYNOPSIS
.Nm
-.Op Fl ?468AcdFHKknsTtv
+.Op Fl ?468AcdFHKklnsTtv
.Op Fl a Ar addr[/len][:port]
.Op Fl a Ar name[:port]
.Op Fl b Ar addr[:port]
@@ -292,6 +292,22 @@ Usually the
.Dq kern
facility is reserved for messages read directly from
.Pa /dev/kmsg .
+.It Fl l
+Keep kernel console logging. By default
+.Nm
+call
+.Xr klogctl 2
+to disable the kernel's logging to console after having opened
+.Pa /dev/kmsg .
+With this option the kernel's log level can be adjusted using
+.Xr sysctl 8 ,
+or the kernel command line, to suit your logging needs to the console.
+.Pp
+Please note, this does not affect logging of kernel messages, see
+.Fl K ,
+only what the kernel logs to
+.Pa /dev/console .
+Also, this is only applicable to Linux.
.It Fl m Ar interval
Select the number of minutes between
.Dq mark
diff --git a/src/syslogd.c b/src/syslogd.c
index c02d064..c9ea7fd 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -154,6 +154,7 @@ static int RemoteHostname; /* Log remote hostname from the message */
static int KernLog = 1; /* Track kernel logs by default */
static int KeepKernFac; /* Keep remotely logged kernel facility */
static int KeepKernTime; /* Keep kernel timestamp, evern after initial read */
+static int KeepKernConsole; /* Keep kernel logging to console */
static off_t RotateSz = 0; /* Max file size (bytes) before rotating, disabled by default */
static int RotateCnt = 5; /* Max number (count) of log files to keep, set with -c <NUM> */
@@ -363,6 +364,9 @@ int usage(int code)
" -H Use hostname from message instead of address for remote messages\n"
" -K Disable kernel logging, useful in container use-cases\n"
" -k Allow logging with facility 'kernel', otherwise remapped to 'user'\n"
+#ifdef __linux__
+ " -l Keep kernel logging to console, use sysctl to adjust kernel.printk\n"
+#endif
" -m MINS Interval between MARK messages, 0 to disable, default: 20 min\n"
" -n Disable DNS query for every request\n"
" -P FILE File to store the process ID, default: %s\n"
@@ -397,7 +401,7 @@ int main(int argc, char *argv[])
char *ptr;
int ch;
- while ((ch = getopt(argc, argv, "468Aa:b:C:cdHFf:Kkm:nP:p:r:sTtv?")) != EOF) {
+ while ((ch = getopt(argc, argv, "468Aa:b:C:cdHFf:Kklm:nP:p:r:sTtv?")) != EOF) {
switch ((char)ch) {
case '4':
family = PF_INET;
@@ -464,6 +468,10 @@ int main(int argc, char *argv[])
KeepKernFac = 1;
break;
+ case 'l':
+ KeepKernConsole = 1;
+ break;
+
case 'm': /* mark interval */
MarkInterval = atoi(optarg) * 60;
break;
diff --git a/src/syslogd.h b/src/syslogd.h
index 68ceafb..1703df2 100644
--- a/src/syslogd.h
+++ b/src/syslogd.h
@@ -169,8 +169,8 @@
#define SYSLOG_ACTION_CONSOLE_ON 7
#ifdef __linux__
-#define kern_console_off() klogctl(SYSLOG_ACTION_CONSOLE_OFF, NULL, 0)
-#define kern_console_on() klogctl(SYSLOG_ACTION_CONSOLE_ON, NULL, 0)
+#define kern_console_off() if (!KeepKernConsole) klogctl(SYSLOG_ACTION_CONSOLE_OFF, NULL, 0)
+#define kern_console_on() if (!KeepKernConsole) klogctl(SYSLOG_ACTION_CONSOLE_ON, NULL, 0)
#else
#define kern_console_off() do { } while (0)
#define kern_console_on() do { } while (0)
--
2.43.0
@@ -1,177 +0,0 @@
From 7e0882688b0ea459c850e6e0ace66cca7100fd0a Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Fri, 12 Jul 2024 22:54:51 +0200
Subject: [PATCH 02/17] Fix #80: add global log rotation options to .conf file
Organization: Addiva Elektronik
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
man/syslog.conf.5 | 20 ++++++++++++++++----
src/syslogd.c | 36 ++++++++++++++++++++++++++++++++++--
syslog.conf | 14 +++++++++++---
3 files changed, 61 insertions(+), 9 deletions(-)
diff --git a/man/syslog.conf.5 b/man/syslog.conf.5
index 73c11e1..030c377 100644
--- a/man/syslog.conf.5
+++ b/man/syslog.conf.5
@@ -71,6 +71,9 @@ OPTION := [OPTION,]
secure_mode [0,1,2]
+rotate_size SIZE
+rotate_count NUMBER
+
include /etc/syslog.d/*.conf
notify /path/to/script-on-rotate
.Ed
@@ -107,6 +110,15 @@ a file can reach before it is rotated, and later compressed. This
feature is mostly intended for embedded systems that do not want to have
cron or a separate log rotate daemon.
.Pp
+The
+.Ql rotate_size SIZE
+and
+.Ql rotate_count COUNT
+are the same as the
+.Nm syslogd Fl r Ar SIZE:COUNT
+command line option. Remember, command line options take precedence
+over .conf file settings.
+.Pp
.Sy Note:
the permissions of the rotated files are kept. Meaning the
administrator can create all log files, before starting
@@ -120,13 +132,13 @@ permissions.
Comments, lines starting with a hash mark ('#'), and empty lines are
ignored. If an error occurs during parsing the whole line is ignored.
.Pp
-Additional options include
+The
.Ql secure_mode <0-2>
-which is the same as the
+option is the same as the
.Nm syslogd Fl s
-commandline option.
+command line option.
.Sy Note:
-command line option always wins, so you need to drop
+again, command line option always wins, so you need to drop
.Fl s
from the command line to use this .conf file option instead.
.Pp
diff --git a/src/syslogd.c b/src/syslogd.c
index c9ea7fd..5061376 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -156,6 +156,7 @@ static int KeepKernFac; /* Keep remotely logged kernel facility */
static int KeepKernTime; /* Keep kernel timestamp, evern after initial read */
static int KeepKernConsole; /* Keep kernel logging to console */
+static int rotate_opt; /* Set if command line option has been given (wins) */
static off_t RotateSz = 0; /* Max file size (bytes) before rotating, disabled by default */
static int RotateCnt = 5; /* Max number (count) of log files to keep, set with -c <NUM> */
@@ -180,13 +181,17 @@ static SIMPLEQ_HEAD(, allowedpeer) aphead = SIMPLEQ_HEAD_INITIALIZER(aphead);
* parser moves the argument to the beginning of the parsed line.
*/
char *secure_str; /* string value of secure_mode */
+char *rotate_sz_str; /* string value of RotateSz */
+char *rotate_cnt_str; /* string value of RotateCnt */
const struct cfkey {
const char *key;
char **var;
} cfkey[] = {
- { "notify", NULL },
- { "secure_mode", &secure_str },
+ { "notify", NULL },
+ { "secure_mode", &secure_str },
+ { "rotate_size", &rotate_sz_str },
+ { "rotate_count", &rotate_cnt_str },
};
/* Function prototypes. */
@@ -499,6 +504,7 @@ int main(int argc, char *argv[])
case 'r':
parse_rotation(optarg, &RotateSz, &RotateCnt);
+ rotate_opt++;
break;
case 's':
@@ -3296,6 +3302,32 @@ static int cfparse(FILE *fp, struct files *newf, struct notifiers *newn)
secure_str = NULL;
}
+ if (rotate_sz_str) {
+ if (rotate_opt) {
+ logit("Skipping 'rotate_size', already set on command line.");
+ } else {
+ int val = strtobytes(rotate_sz_str);
+ if (val > 0)
+ RotateSz = val;
+ }
+
+ free(rotate_sz_str);
+ rotate_sz_str = NULL;
+ }
+
+ if (rotate_cnt_str) {
+ if (rotate_opt) {
+ logit("Skipping 'rotate_count', already set on command line.");
+ } else {
+ int val = atoi(rotate_cnt_str);
+ if (val > 0)
+ RotateCnt = val;
+ }
+
+ free(rotate_cnt_str);
+ rotate_cnt_str = NULL;
+ }
+
return 0;
}
diff --git a/syslog.conf b/syslog.conf
index c4c7525..52161a1 100644
--- a/syslog.conf
+++ b/syslog.conf
@@ -42,9 +42,11 @@ mail.err /var/log/mail.err
cron,daemon.none;\
mail,news.none -/var/log/messages
-# Store all critical eventes, except kernel logs in critical
#
-#*.=crit;kern.none /var/log/critical
+# Store all critical events, except kernel logs, in critical RFC5424 format.
+# Overide global log rotation settings, rotate every 10MiB, keep 5 old logs,
+#
+#*.=crit;kern.none /var/log/critical ;rotate=10M:5,RFC5424
# Example of sending events to remote syslog server.
# All events from notice and above, except auth, authpriv
@@ -60,7 +62,7 @@ mail.err /var/log/mail.err
# Priority alert and above are sent to the operator
#
-#*.alert root,joey
+#*.alert root,joey
#
# Secure mode, same as -s, none(0), on(1), full(2). When enabled
@@ -70,6 +72,12 @@ mail.err /var/log/mail.err
#
secure_mode 1
+#
+# Global log rotation, same as -r SIZE:COUNT, command line wins.
+#
+#rotate_size 1M
+#rotate_count 5
+
#
# Include all config files in /etc/syslog.d/
#
--
2.43.0
@@ -1,102 +0,0 @@
From a2c47f81bf3d358dddb475cbaa8125f2cb776587 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Sun, 14 Jul 2024 09:19:01 +0200
Subject: [PATCH 03/17] Refactor, rely on global file rotation if not set
per-file
Organization: Addiva Elektronik
Instead of initializing per-file rotation with global values, leave them
unset to allow global settings to be changed from config file.
This changes the semantics so that it is no longer possible to disable
log rotation on a per-file basis.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslogd.c | 37 +++++++++++++++++++++++++------------
1 file changed, 25 insertions(+), 12 deletions(-)
diff --git a/src/syslogd.c b/src/syslogd.c
index 5061376..fa8964b 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -1732,21 +1732,34 @@ static void logmsg(struct buf_msg *buffer)
static void logrotate(struct filed *f)
{
struct stat statf;
+ off_t sz;
- if (!f->f_rotatesz)
+ if (!f->f_rotatesz && !RotateSz)
return;
+ if (f->f_rotatesz)
+ sz = f->f_rotatesz;
+ else
+ sz = RotateSz;
+
if (fstat(f->f_file, &statf))
return;
/* bug (mostly harmless): can wrap around if file > 4gb */
- if (S_ISREG(statf.st_mode) && statf.st_size > f->f_rotatesz)
+ if (S_ISREG(statf.st_mode) && statf.st_size > sz)
rotate_file(f, &statf);
}
static void rotate_file(struct filed *f, struct stat *stp_or_null)
{
- if (f->f_rotatecount > 0) { /* always 0..999 */
+ int cnt;
+
+ if (f->f_rotatecount)
+ cnt = f->f_rotatecount;
+ else
+ cnt = RotateCnt;
+
+ if (cnt > 0) { /* always 0..999 */
struct stat st_stack;
int len = strlen(f->f_un.f_fname) + 10 + 5;
int i;
@@ -1754,7 +1767,7 @@ static void rotate_file(struct filed *f, struct stat *stp_or_null)
char newFile[len];
/* First age zipped log files */
- for (i = f->f_rotatecount; i > 1; i--) {
+ for (i = cnt; i > 1; i--) {
snprintf(oldFile, len, "%s.%d.gz", f->f_un.f_fname, i - 1);
snprintf(newFile, len, "%s.%d.gz", f->f_un.f_fname, i);
@@ -1808,7 +1821,14 @@ static void rotate_all_files(void)
struct filed *f;
SIMPLEQ_FOREACH(f, &fhead, f_link) {
- if (f->f_type == F_FILE && f->f_rotatesz)
+ off_t sz;
+
+ if (f->f_rotatesz)
+ sz = f->f_rotatesz;
+ else
+ sz = RotateSz;
+
+ if (f->f_type == F_FILE && sz)
rotate_file(f, NULL);
}
}
@@ -3140,13 +3160,6 @@ static struct filed *cfline(char *line)
break;
case F_FILE:
- /* default rotate from command line */
- if (f->f_rotatesz == 0) {
- f->f_rotatecount = RotateCnt;
- f->f_rotatesz = RotateSz;
- }
- /* fallthrough */
-
default:
/* All other targets default to RFC3164 */
if (f->f_flags & (RFC3164 | RFC5424))
--
2.43.0
@@ -1,67 +0,0 @@
From 0366909927cebecdf6c35b83a976a25c529043e1 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Sun, 14 Jul 2024 09:26:50 +0200
Subject: [PATCH 04/17] Allow per-file rotation settings to set only one value
Organization: Addiva Elektronik
This change makes it possible to set rotate=2M, or rotate=:5, and then
rely on the global settings for the other.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
man/syslog.conf.5 | 10 ++++++++--
src/syslogd.c | 7 +++----
2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/man/syslog.conf.5 b/man/syslog.conf.5
index 030c377..f436dc3 100644
--- a/man/syslog.conf.5
+++ b/man/syslog.conf.5
@@ -67,7 +67,10 @@ ACTION := /path/to/file
OPTION := [OPTION,]
|= RFC3164
|= RFC5424
- |= rotate=SIZE:COUNT
+ |= rotate=ROT
+ROT := SIZE:COUNT
+ |= SIZE
+ |= :COUNT
secure_mode [0,1,2]
@@ -108,7 +111,10 @@ The log rotation, which is only relevant for files, details the max
.Ar SIZE:COUNT
a file can reach before it is rotated, and later compressed. This
feature is mostly intended for embedded systems that do not want to have
-cron or a separate log rotate daemon.
+cron or a separate log rotate daemon. It is possible to specify only
+size or count, in which case the global setting covers the other. E.g.,
+to set only the rotation count, use:
+.Ar rotate=:COUNT .
.Pp
The
.Ql rotate_size SIZE
diff --git a/src/syslogd.c b/src/syslogd.c
index fa8964b..2264a75 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -2876,13 +2876,12 @@ static void cfrot(char *ptr, struct filed *f)
*c++ = 0;
cnt = atoi(c);
}
+ if (cnt > 0)
+ f->f_rotatecount = cnt;
sz = strtobytes(ptr);
- if (sz > 0 && cnt > 0) {
- logit("Set rotate size %d bytes, %d rotations\n", sz, cnt);
- f->f_rotatecount = cnt;
+ if (sz > 0)
f->f_rotatesz = sz;
- }
}
static int cfopt(char **ptr, const char *opt)
--
2.43.0
@@ -1,150 +0,0 @@
From a1dc835fd5d11ce0dd6d9983c1aa2ca188460ac9 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Sun, 14 Jul 2024 17:46:41 +0200
Subject: [PATCH 05/17] Fix #81: blocking delay for unreachable remote
Organization: Addiva Elektronik
This patch fixes a blocking delay when a named remote action is set up.
On GLIBC systems, with the default resolver setup, this may be as long
as 10 seconds, meaning syslogd retried nslookup() every log message,
which in turn lead to snail speed on logging to other targets.
Additionally it re-enables the warning for failure to resolve the DNS
name -- a user is likely very interested in why they are not seeing any
logs on their remote server. Logs age out, so logging in to a device
which may have logged this once is not very useful.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
configure.ac | 12 ++++++++++++
src/syslogd.c | 27 ++++++++++++++++-----------
src/syslogd.h | 5 ++++-
3 files changed, 32 insertions(+), 12 deletions(-)
diff --git a/configure.ac b/configure.ac
index c370877..cf2488a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -67,6 +67,10 @@ AC_CHECK_FUNCS([setsid])
AC_CHECK_FUNCS([getprogname strtobytes])
# Command line options
+AC_ARG_WITH(dns-delay,
+ AS_HELP_STRING([--with-dns-delay=SEC], [Retry delay resolving DNS names, default: 60]),
+ [dns_delay=$withval], [dns_delay='no'])
+
AC_ARG_WITH(suspend-time,
AS_HELP_STRING([--with-suspend-time=SEC], [Retry delay for sending to remote, default: 180]),
[suspend_time=$withval], [suspend_time='no'])
@@ -82,6 +86,13 @@ AC_ARG_WITH(logger,
AS_IF([test "x$logger" != "xno"], with_logger="yes", with_logger="no")
AM_CONDITIONAL([ENABLE_LOGGER], [test "x$with_logger" != "xno"])
+AS_IF([test "x$dns_delay" != "xno"],[
+ AS_IF([test "x$dns_delay" = "xyes"],[
+ AC_MSG_ERROR([Must supply argument])])
+ ]
+ AC_DEFINE_UNQUOTED(INET_DNS_DELAY, $dns_delay, [Retry delay for resolving DNS names, default: 60]),
+ dns_delay=60)
+
AS_IF([test "x$suspend_time" != "xno"],[
AS_IF([test "x$suspend_time" = "xyes"],[
AC_MSG_ERROR([Must supply argument])])
@@ -134,6 +145,7 @@ cat <<EOF
Optional features:
logger.........: $with_logger
+ dns retry delay: $dns_delay sec
suspend time...: $suspend_time sec
systemd........: $with_systemd
diff --git a/src/syslogd.c b/src/syslogd.c
index 2264a75..c838c36 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -837,6 +837,11 @@ static void inet_cb(int sd, void *arg)
parsemsg(hname, msg);
}
+/*
+ * Depending on the setup of /etc/resolv.conf, and the system resolver,
+ * a call to this function may be blocked for 10 seconds, or even more,
+ * waiting for a response. See https://serverfault.com/a/562108/122484
+ */
static int nslookup(const char *host, const char *service, struct addrinfo **ai)
{
struct addrinfo hints;
@@ -2405,8 +2410,8 @@ static void forw_lookup(struct filed *f)
char *host = f->f_un.f_forw.f_hname;
char *serv = f->f_un.f_forw.f_serv;
struct addrinfo *ai;
+ time_t now, diff;
int err, first;
- time_t diff;
if (SecureMode > 1) {
if (f->f_un.f_forw.f_addr)
@@ -2419,27 +2424,27 @@ static void forw_lookup(struct filed *f)
/* Called from cfline() for initial lookup? */
first = f->f_type == F_UNUSED ? 1 : 0;
+ now = timer_now();
+ diff = now - f->f_time;
+
/*
- * Not INET_SUSPEND_TIME, but back off a few seconds at least
- * to prevent syslogd from hammering the resolver for every
- * little message that is logged. E.g., at boot when we read
- * the kernel ring buffer.
+ * Back off a minute to prevent unnecessary delays on other log
+ * targets due to being blockd in nslookup(). This means bootup
+ * log messages may not be logged for named remote targets since
+ * networking may not be available until later.
*/
- diff = timer_now() - f->f_time;
- if (!first && diff < 5)
+ if (!first && diff < INET_DNS_DELAY)
return;
err = nslookup(host, serv, &ai);
if (err) {
f->f_type = F_FORW_UNKN;
- f->f_time = timer_now();
- if (!first && !(f->f_flags & SUSP_RETR))
+ f->f_time = now;
+ if (!first)
WARN("Failed resolving '%s:%s': %s", host, serv, gai_strerror(err));
- f->f_flags |= SUSP_RETR; /* Retry silently */
return;
}
- f->f_flags &= ~SUSP_RETR;
f->f_type = F_FORW;
f->f_un.f_forw.f_addr = ai;
f->f_prevcount = 0;
diff --git a/src/syslogd.h b/src/syslogd.h
index 1703df2..a14b6a0 100644
--- a/src/syslogd.h
+++ b/src/syslogd.h
@@ -119,6 +119,10 @@
#define MAXUNAMES 20 /* maximum number of user names */
#define MAXFNAME 200 /* max file pathname length */
+#ifndef INET_DNS_DELAY
+#define INET_DNS_DELAY 60
+#endif
+
#ifndef INET_SUSPEND_TIME
#define INET_SUSPEND_TIME 180 /* equal to 3 minutes */
#endif
@@ -185,7 +189,6 @@
#define MARK 0x008 /* this message is a mark */
#define RFC3164 0x010 /* format log message according to RFC 3164 */
#define RFC5424 0x020 /* format log message according to RFC 5424 */
-#define SUSP_RETR 0x040 /* suspend/forw_unkn, retrying nslookup */
/* Syslog timestamp formats. */
#define BSDFMT_DATELEN 0
--
2.43.0
@@ -1,40 +0,0 @@
From 2d626af27e8f3115175749d183a8b7f91849bf10 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Sun, 14 Jul 2024 17:43:39 +0200
Subject: [PATCH 06/17] Fix annoying gcc warning in rotate_file()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Organization: Addiva Elektronik
syslogd.c: In function rotate_file:
syslogd.c:1787:69: warning: %s directive output between 0 and 2147483646 bytes may cause result to exceed INT_MAX [-Wformat-truncation=]
1787 | snprintf(cmd, sizeof(cmd), "gzip -f %s", newFile);
| ^~
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslogd.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/syslogd.c b/src/syslogd.c
index c838c36..461bbb1 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -1786,10 +1786,11 @@ static void rotate_file(struct filed *f, struct stat *stp_or_null)
snprintf(newFile, len, "%s.%d", f->f_un.f_fname, i);
if (!rename(oldFile, newFile) && i > 0) {
- size_t clen = 18 + strlen(newFile) + 1;
+ const char *gzip = "gzip -f";
+ size_t clen = strlen(gzip) + len + 1;
char cmd[clen];
- snprintf(cmd, sizeof(cmd), "gzip -f %s", newFile);
+ snprintf(cmd, clen, "%s %s", gzip, newFile);
system(cmd);
}
}
--
2.43.0
@@ -1,239 +0,0 @@
From 2aa73f85580614b9162aaaa74b2a9e817c6396bd Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 15 Jul 2024 10:46:50 +0200
Subject: [PATCH 07/17] Refactor cfparse() to add a per-keyword parser
Organization: Addiva Elektronik
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslogd.c | 74 +++++++++++++++++++++++++++------------------------
src/syslogd.h | 2 +-
2 files changed, 40 insertions(+), 36 deletions(-)
diff --git a/src/syslogd.c b/src/syslogd.c
index 461bbb1..452513f 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -163,7 +163,7 @@ static int RotateCnt = 5; /* Max number (count) of log files to keep, set wi
/*
* List of notifiers
*/
-static SIMPLEQ_HEAD(notifiers, notifier) nothead = SIMPLEQ_HEAD_INITIALIZER(nothead);
+static TAILQ_HEAD(notifiers, notifier) nothead = TAILQ_HEAD_INITIALIZER(nothead);
/*
* List of peers and sockets for binding.
@@ -184,16 +184,6 @@ char *secure_str; /* string value of secure_mode */
char *rotate_sz_str; /* string value of RotateSz */
char *rotate_cnt_str; /* string value of RotateCnt */
-const struct cfkey {
- const char *key;
- char **var;
-} cfkey[] = {
- { "notify", NULL },
- { "secure_mode", &secure_str },
- { "rotate_size", &rotate_sz_str },
- { "rotate_count", &rotate_cnt_str },
-};
-
/* Function prototypes. */
static int allowaddr(char *s);
void untty(void);
@@ -221,10 +211,10 @@ static void signal_init(void);
static void boot_time_init(void);
static void init(void);
static int strtobytes(char *arg);
-static int cfparse(FILE *fp, struct files *newf, struct notifiers *newn);
+static int cfparse(FILE *fp, struct files *newf);
int decode(char *name, struct _code *codetab);
static void logit(char *, ...);
-static void notifier_add(struct notifiers *newn, const char *program);
+static void notifier_add(char *program, void *arg);
static void notifier_invoke(const char *logfile);
static void notifier_free_all(void);
void reload(int);
@@ -233,6 +223,20 @@ static int validate(struct sockaddr *sa, const char *hname);
static int waitdaemon(int);
static void timedout(int);
+/*
+ * Configuration file keywords, variables, and optional callbacks
+ */
+const struct cfkey {
+ const char *key;
+ char **var;
+ void (*cb)(char *, void *);
+ void *arg;
+} cfkey[] = {
+ { "notify", NULL, notifier_add, &nothead },
+ { "rotate_size", &rotate_sz_str, NULL, NULL },
+ { "rotate_count", &rotate_cnt_str, NULL, NULL },
+ { "secure_mode", &secure_str, NULL, NULL },
+};
/*
* Very basic, and incomplete, check if we're running in a container.
@@ -1816,7 +1820,7 @@ static void rotate_file(struct filed *f, struct stat *stp_or_null)
return;
}
- if (!SIMPLEQ_EMPTY(&nothead))
+ if (!TAILQ_EMPTY(&nothead))
notifier_invoke(f->f_un.f_fname);
}
ftruncate(f->f_file, 0);
@@ -2708,7 +2712,6 @@ static void boot_time_init(void)
*/
static void init(void)
{
- struct notifiers newn = SIMPLEQ_HEAD_INITIALIZER(newn);
struct files newf = SIMPLEQ_HEAD_INITIALIZER(newf);
struct filed *f;
struct peer *pe;
@@ -2762,6 +2765,11 @@ static void init(void)
*/
tzset();
+ /*
+ * Free all notifiers
+ */
+ notifier_free_all();
+
/*
* Read configuration file(s)
*/
@@ -2776,7 +2784,7 @@ static void init(void)
}
}
- if (cfparse(fp, &newf, &newn)) {
+ if (cfparse(fp, &newf)) {
fclose(fp);
return;
}
@@ -2789,13 +2797,6 @@ static void init(void)
fhead = newf;
- /*
- * Free all notifiers
- */
- notifier_free_all();
-
- nothead = newn;
-
/*
* Open or close sockets for local and remote communication
*/
@@ -2815,11 +2816,12 @@ static void init(void)
Initialized = 1;
if (Debug) {
- if (!SIMPLEQ_EMPTY(&nothead)) {
+ if (!TAILQ_EMPTY(&nothead)) {
struct notifier *np;
- SIMPLEQ_FOREACH(np, &nothead, n_link)
+ TAILQ_FOREACH(np, &nothead, n_link) {
printf("notify %s\n", np->n_program);
+ }
printf("\n");
}
@@ -3208,6 +3210,8 @@ const struct cfkey *cfkey_match(char *cline)
if (cfk->var)
*cfk->var = strdup(p);
+ else if (cfk->cb)
+ cfk->cb(p, cfk->arg);
else
memmove(cline, p, strlen(p) + 1);
@@ -3220,7 +3224,7 @@ const struct cfkey *cfkey_match(char *cline)
/*
* Parse .conf file and append to list
*/
-static int cfparse(FILE *fp, struct files *newf, struct notifiers *newn)
+static int cfparse(FILE *fp, struct files *newf)
{
const struct cfkey *cfk;
struct filed *f;
@@ -3286,7 +3290,7 @@ static int cfparse(FILE *fp, struct files *newf, struct notifiers *newn)
}
logit("Parsing %s ...\n", gl.gl_pathv[i]);
- cfparse(fpi, newf, newn);
+ cfparse(fpi, newf);
fclose(fpi);
}
globfree(&gl);
@@ -3294,11 +3298,8 @@ static int cfparse(FILE *fp, struct files *newf, struct notifiers *newn)
}
cfk = cfkey_match(cline);
- if (cfk) {
- if (!strcmp(cfk->key, "notify"))
- notifier_add(newn, cline);
+ if (cfk)
continue;
- }
f = cfline(cline);
if (!f)
@@ -3681,8 +3682,10 @@ static void logit(char *fmt, ...)
fflush(stdout);
}
-static void notifier_add(struct notifiers *newn, const char *program)
+static void notifier_add(char *program, void *arg)
{
+ struct notifiers *newn = (struct notifiers *)arg;
+
while (*program && isspace(*program))
++program;
@@ -3701,7 +3704,7 @@ static void notifier_add(struct notifiers *newn, const char *program)
ERR("Cannot allocate memory for a notify program");
return;
}
- SIMPLEQ_INSERT_TAIL(newn, np, n_link);
+ TAILQ_INSERT_TAIL(newn, np, n_link);
} else
logit("notify: non-existing, or not executable program\n");
}
@@ -3714,7 +3717,7 @@ static void notifier_invoke(const char *logfile)
logit("notify: rotated %s, invoking hooks\n", logfile);
- SIMPLEQ_FOREACH(np, &nothead, n_link) {
+ TAILQ_FOREACH(np, &nothead, n_link) {
childpid = fork();
switch (childpid) {
@@ -3739,7 +3742,8 @@ static void notifier_free_all(void)
{
struct notifier *np, *npnext;
- SIMPLEQ_FOREACH_SAFE(np, &nothead, n_link, npnext) {
+ TAILQ_FOREACH_SAFE(np, &nothead, n_link, npnext) {
+ TAILQ_REMOVE(&nothead, np, n_link);
free(np->n_program);
free(np);
}
diff --git a/src/syslogd.h b/src/syslogd.h
index a14b6a0..14c66a7 100644
--- a/src/syslogd.h
+++ b/src/syslogd.h
@@ -314,7 +314,7 @@ struct filed {
* Log rotation notifiers
*/
struct notifier {
- SIMPLEQ_ENTRY(notifier) n_link;
+ TAILQ_ENTRY(notifier) n_link;
char *n_program;
};
--
2.43.0
@@ -1,42 +0,0 @@
From c15bb6208cdd0e0629a28c10cb448a11aa7a1624 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 15 Jul 2024 14:24:08 +0200
Subject: [PATCH 08/17] Fix gcc warning in vsyslogp_r()
Organization: Addiva Elektronik
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslog.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/syslog.c b/src/syslog.c
index 1510258..fbbdfdf 100644
--- a/src/syslog.c
+++ b/src/syslog.c
@@ -267,7 +267,7 @@ vsyslogp_r(int pri, struct syslog_data *data, const char *msgid,
/* Default log format is RFC5424, continues below BSD format */
if (data->log_stat & LOG_RFC3164) {
const char *tag = data->log_tag;
- char tmp[33];
+ char tmp[256];
if (!(data->log_stat & LOG_NLOG)) {
prlen = snprintf(p, tbuf_left, "<%d>", pri);
@@ -303,12 +303,12 @@ vsyslogp_r(int pri, struct syslog_data *data, const char *msgid,
/*
* When sending remote we MUST follow RFC3164 sec 4.1.3,
- * otherwise we "cheat" and allow max lenght hostname,
+ * otherwise we "cheat" and allow max length hostname,
* for either log file or local syslogd -- it is up to
* the local syslogd then to fulfill RFC req. on output
*/
if (data->log_host) {
- strlcpy(tmp, data->log_tag, sizeof(tbuf));
+ strlcpy(tmp, data->log_tag, sizeof(tmp));
tag = tmp;
}
--
2.43.0
@@ -1,285 +0,0 @@
From f5fae387b92e81cc1f1f9e8f6656b20bb9e2e929 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 15 Jul 2024 14:57:54 +0200
Subject: [PATCH 09/17] Fix #83: add support for listen addr:port to .conf file
Organization: Addiva Elektronik
This complements the command line '-b addr:port' support with a 'listen'
directive in the .conf file. The command line listen directives are in
this implementation treated as "static" and cannot be removed using the
.conf file.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslogd.c | 104 +++++++++++++++++++++++++++++++++++++++++---------
src/syslogd.h | 3 +-
2 files changed, 88 insertions(+), 19 deletions(-)
diff --git a/src/syslogd.c b/src/syslogd.c
index 452513f..8ad5109 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -168,12 +168,12 @@ static TAILQ_HEAD(notifiers, notifier) nothead = TAILQ_HEAD_INITIALIZER(nothead)
/*
* List of peers and sockets for binding.
*/
-static SIMPLEQ_HEAD(, peer) pqueue = SIMPLEQ_HEAD_INITIALIZER(pqueue);
+static TAILQ_HEAD(peers, peer) pqueue = TAILQ_HEAD_INITIALIZER(pqueue);
/*
* List fo peers allowed to log to us.
*/
-static SIMPLEQ_HEAD(, allowedpeer) aphead = SIMPLEQ_HEAD_INITIALIZER(aphead);
+static SIMPLEQ_HEAD(allowed, allowedpeer) aphead = SIMPLEQ_HEAD_INITIALIZER(aphead);
/*
* central list of recognized configuration keywords with an optional
@@ -211,6 +211,7 @@ static void signal_init(void);
static void boot_time_init(void);
static void init(void);
static int strtobytes(char *arg);
+static void cflisten(char *ptr, void *arg);
static int cfparse(FILE *fp, struct files *newf);
int decode(char *name, struct _code *codetab);
static void logit(char *, ...);
@@ -232,6 +233,7 @@ const struct cfkey {
void (*cb)(char *, void *);
void *arg;
} cfkey[] = {
+ { "listen", NULL, cflisten, NULL },
{ "notify", NULL, notifier_add, &nothead },
{ "rotate_size", &rotate_sz_str, NULL, NULL },
{ "rotate_count", &rotate_cnt_str, NULL, NULL },
@@ -276,11 +278,24 @@ static int addpeer(struct peer *pe0)
{
struct peer *pe;
+ TAILQ_FOREACH(pe, &pqueue, pe_link) {
+ if (((pe->pe_name == NULL && pe0->pe_name == NULL) ||
+ (pe->pe_name != NULL && pe0->pe_name != NULL && strcmp(pe->pe_name, pe0->pe_name) == 0)) &&
+ ((pe->pe_serv == NULL && pe0->pe_serv == NULL) ||
+ (pe->pe_serv != NULL && pe0->pe_serv != NULL && strcmp(pe->pe_serv, pe0->pe_serv) == 0))) {
+ /* update flags */
+ pe->pe_mark = pe0->pe_mark;
+ pe->pe_mode = pe0->pe_mode;
+
+ return 0;
+ }
+ }
+
pe = calloc(1, sizeof(*pe));
if (pe == NULL)
err(1, "malloc failed");
*pe = *pe0;
- SIMPLEQ_INSERT_TAIL(&pqueue, pe, pe_link);
+ TAILQ_INSERT_TAIL(&pqueue, pe, pe_link);
return 0;
}
@@ -406,7 +421,6 @@ int main(int argc, char *argv[])
pid_t ppid = 1;
int no_sys = 0;
int pflag = 0;
- int bflag = 0;
char *ptr;
int ch;
@@ -434,13 +448,13 @@ int main(int argc, char *argv[])
break;
case 'b':
- bflag = 1;
ptr = strchr(optarg, ':');
if (ptr)
*ptr++ = 0;
addpeer(&(struct peer) {
.pe_name = optarg,
.pe_serv = ptr,
+ .pe_mark = -1,
});
break;
@@ -503,6 +517,7 @@ int main(int argc, char *argv[])
addpeer(&(struct peer) {
.pe_name = optarg,
.pe_mode = 0666,
+ .pe_mark = -1,
});
break;
@@ -538,13 +553,6 @@ int main(int argc, char *argv[])
if ((argc -= optind))
return usage(1);
- /* Default to listen to :514 (syslog/udp) */
- if (!bflag)
- addpeer(&(struct peer) {
- .pe_name = NULL,
- .pe_serv = "syslog",
- });
-
/* Figure out where to read system log messages from */
if (!pflag) {
/* Do we run under systemd-journald (Requires=syslog.socket)? */
@@ -556,6 +564,7 @@ int main(int argc, char *argv[])
addpeer(&(struct peer) {
.pe_name = _PATH_LOG,
.pe_mode = 0666,
+ .pe_mark = -1,
});
}
}
@@ -2545,7 +2554,9 @@ void die(int signo)
/*
* Close all UNIX and inet sockets
*/
- SIMPLEQ_FOREACH_SAFE(pe, &pqueue, pe_link, next) {
+ TAILQ_FOREACH_SAFE(pe, &pqueue, pe_link, next) {
+ TAILQ_REMOVE(&pqueue, pe, pe_link);
+
for (size_t i = 0; i < pe->pe_socknum; i++) {
logit("Closing socket %d ...\n", pe->pe_sock[i]);
socket_close(pe->pe_sock[i]);
@@ -2713,8 +2724,9 @@ static void boot_time_init(void)
static void init(void)
{
struct files newf = SIMPLEQ_HEAD_INITIALIZER(newf);
+ struct peer *pe, *penext;
struct filed *f;
- struct peer *pe;
+ int bflag = 0;
FILE *fp;
char *p;
@@ -2765,6 +2777,16 @@ static void init(void)
*/
tzset();
+ /*
+ * mark
+ */
+ TAILQ_FOREACH(pe, &pqueue, pe_link) {
+ if (pe->pe_mark == -1)
+ continue;
+
+ pe->pe_mark = 1;
+ }
+
/*
* Free all notifiers
*/
@@ -2797,10 +2819,31 @@ static void init(void)
fhead = newf;
+ /*
+ * Ensure a default listen *:514 exists (compat)
+ */
+ TAILQ_FOREACH(pe, &pqueue, pe_link) {
+ if (pe->pe_mark == 1)
+ continue; /* marked for deletion */
+ if (pe->pe_name && pe->pe_name[0] == '/')
+ continue; /* named pipe */
+ if (pe->pe_name || pe->pe_serv) {
+ bflag = 1;
+ break; /* static or from .conf */
+ }
+ }
+ if (!bflag) {
+ /* Default to listen to :514 (syslog/udp) */
+ addpeer(&(struct peer) {
+ .pe_name = NULL,
+ .pe_serv = "514",
+ });
+ }
+
/*
* Open or close sockets for local and remote communication
*/
- SIMPLEQ_FOREACH(pe, &pqueue, pe_link) {
+ TAILQ_FOREACH(pe, &pqueue, pe_link) {
if (pe->pe_name && pe->pe_name[0] == '/') {
create_unix_socket(pe);
} else {
@@ -2808,11 +2851,23 @@ static void init(void)
socket_close(pe->pe_sock[i]);
pe->pe_socknum = 0;
- if (SecureMode < 2)
+ /* skip any marked for deletion */
+ if (SecureMode < 2 && pe->pe_mark <= 0)
create_inet_socket(pe);
}
}
+ /*
+ * Sweep
+ */
+ TAILQ_FOREACH_SAFE(pe, &pqueue, pe_link, penext) {
+ if (pe->pe_mark <= 0)
+ continue;
+
+ TAILQ_REMOVE(&pqueue, pe, pe_link);
+ free(pe);
+ }
+
Initialized = 1;
if (Debug) {
@@ -2874,6 +2929,19 @@ static void init(void)
logit("syslogd: restarted.\n");
}
+static void cflisten(char *ptr, void *arg)
+{
+ char *peer = ptr;
+
+ ptr = strchr(peer, ':');
+ if (ptr)
+ *ptr++ = 0;
+ addpeer(&(struct peer) {
+ .pe_name = peer,
+ .pe_serv = ptr,
+ });
+}
+
static void cfrot(char *ptr, struct filed *f)
{
char *c;
@@ -3096,7 +3164,7 @@ static struct filed *cfline(char *line)
if (bp)
*bp++ = 0;
else
- bp = "syslog"; /* default: 514/udp */
+ bp = "514"; /* default: 514/udp */
strlcpy(f->f_un.f_forw.f_hname, p, sizeof(f->f_un.f_forw.f_hname));
strlcpy(f->f_un.f_forw.f_serv, bp, sizeof(f->f_un.f_forw.f_serv));
@@ -3426,7 +3494,7 @@ static int allowaddr(char *s)
goto err;
}
} else {
- if ((se = getservbyname("syslog", "udp")))
+ if ((se = getservbyname("514", "udp")))
ap->port = ntohs(se->s_port);
else
/* sanity, should not happen */
diff --git a/src/syslogd.h b/src/syslogd.h
index 14c66a7..d74c0ed 100644
--- a/src/syslogd.h
+++ b/src/syslogd.h
@@ -225,9 +225,10 @@
* Struct to hold records of peers and sockets
*/
struct peer {
- SIMPLEQ_ENTRY(peer) pe_link;
+ TAILQ_ENTRY(peer) pe_link;
const char *pe_name;
const char *pe_serv;
+ int pe_mark;
mode_t pe_mode;
int pe_sock[16];
size_t pe_socknum;
--
2.43.0
@@ -1,346 +0,0 @@
From ad8dedd04a979279d245b53a60311ad91acaaf14 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 15 Jul 2024 15:02:32 +0200
Subject: [PATCH 10/17] Fix #82: retry creating UNIX and network sockets on
failure
Organization: Addiva Elektronik
When starting up, or on SIGHUP, syslogd may fail to create a UNIX socket
or (bind) an Internet socket. The latter may be because the system is
in bootstrap and the interface and/or address syslogd tries to bind() to
does not yet exist.
This commit adds a very basic retry loop every five seconds.
Also, with the new retry logic it was deemed worth it to increase the
logging from syslogd itself. I.e., when failing to create a socket,
or when retrying and succeeding, as well as when closing sockets. In
particular when opening and closing Internet facing ports.
Since startup, or reconfiguration, is not failure to send() the we do
not want to inadvertedly trigger F_FORW_SUSP for remote log actions.
This is the reason for the ENONET error code from socket_ffs(), to
ensure we retry sending to remote on the next log message instead of
waiting 180 sec. Ordering at boot, or reconf, is also the reason for
setting Initialized earlier -- this prevents inadvertedly logging to the
console instead of to a file that actually is open. We can usually log
to file but maybe not yet to a remote.
To not terrify casual readers of the logs, messages for opening and
closing Inet (Internet) sockets are tracked from what context they were
opened in. Context, in this context, is the secure_mode switch in which
syslogd only opens UDP sockets for sending messages to other syslog
servers, i.e., without binding to a server port.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/socket.c | 1 +
src/syslogd.c | 145 +++++++++++++++++++++++++++++++++++---------------
2 files changed, 102 insertions(+), 44 deletions(-)
diff --git a/src/socket.c b/src/socket.c
index 4b64888..8c32dac 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -217,6 +217,7 @@ int socket_ffs(int family)
return entry->sd;
}
+ errno = ENONET;
return -1;
}
diff --git a/src/syslogd.c b/src/syslogd.c
index 8ad5109..402a85e 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -160,6 +160,9 @@ static int rotate_opt; /* Set if command line option has been given
static off_t RotateSz = 0; /* Max file size (bytes) before rotating, disabled by default */
static int RotateCnt = 5; /* Max number (count) of log files to keep, set with -c <NUM> */
+struct timeval *retry = NULL; /* Set by init() to &init_tv whenever retry jobs exist */
+struct timeval init_tv = { 5, 0 }; /* Retry every 5 seconds. */
+
/*
* List of notifiers
*/
@@ -209,6 +212,7 @@ void debug_switch();
void die(int sig);
static void signal_init(void);
static void boot_time_init(void);
+static void retry_init(void);
static void init(void);
static int strtobytes(char *arg);
static void cflisten(char *ptr, void *arg);
@@ -642,7 +646,7 @@ no_klogd:
for (;;) {
int rc;
- rc = socket_poll(NULL);
+ rc = socket_poll(retry);
if (restart > 0) {
restart--;
logit("\nReceived SIGHUP, reloading syslogd.\n");
@@ -660,8 +664,11 @@ no_klogd:
rotate_all_files();
}
- if (rc < 0 && errno != EINTR)
- ERR("select()");
+ if (rc < 0) {
+ if (errno != EINTR)
+ ERR("select()");
+ } else if (rc == 0)
+ retry_init();
if (KernLog)
sys_seqno_save();
@@ -769,14 +776,14 @@ static void unix_cb(int sd, void *arg)
parsemsg(LocalHostName, msg);
}
-static void create_unix_socket(struct peer *pe)
+static int create_unix_socket(struct peer *pe)
{
struct sockaddr_un sun;
struct addrinfo ai;
int sd = -1;
if (pe->pe_socknum)
- return; /* Already set up */
+ return 0; /* Already set up */
memset(&ai, 0, sizeof(ai));
ai.ai_addr = (struct sockaddr *)&sun;
@@ -790,11 +797,12 @@ static void create_unix_socket(struct peer *pe)
if (sd < 0)
goto err;
- logit("Created UNIX socket %d ...\n", sd);
+ NOTE("Created UNIX socket %s", sun.sun_path);
pe->pe_sock[pe->pe_socknum++] = sd;
- return;
+ return 0;
err:
ERR("cannot create %s", pe->pe_name);
+ return 1;
}
static void unmapped(struct sockaddr *sa)
@@ -866,7 +874,7 @@ static int nslookup(const char *host, const char *service, struct addrinfo **ai)
/* Reset resolver cache and retry name lookup */
res_init();
- logit("nslookup '%s:%s'\n", node ?: "none", service);
+ logit("nslookup '%s:%s'\n", node ?: "*", service);
memset(&hints, 0, sizeof(hints));
hints.ai_flags = !node ? AI_PASSIVE : 0;
hints.ai_family = family;
@@ -875,22 +883,25 @@ static int nslookup(const char *host, const char *service, struct addrinfo **ai)
return getaddrinfo(node, service, &hints, ai);
}
-static void create_inet_socket(struct peer *pe)
+static int create_inet_socket(struct peer *pe)
{
struct addrinfo *ai, *res;
- int sd, err;
+ int err, rc = 0;
+
+ if (pe->pe_socknum)
+ return 0; /* Already set up */
err = nslookup(pe->pe_name, pe->pe_serv, &res);
if (err) {
- ERRX("%s/udp service unknown: %s", pe->pe_serv,
- gai_strerror(err));
- return;
+ ERRX("%s:%s/udp service unknown: %s", pe->pe_name ?: "*", pe->pe_serv, gai_strerror(err));
+ return 1;
}
for (ai = res; ai; ai = ai->ai_next) {
+ int sd;
+
if (pe->pe_socknum + 1 >= NELEMS(pe->pe_sock)) {
- WARN("Only %zd IP addresses per socket supported.",
- NELEMS(pe->pe_sock));
+ WARN("Only %zd IP addresses per socket supported.", NELEMS(pe->pe_sock));
break;
}
@@ -900,15 +911,35 @@ static void create_inet_socket(struct peer *pe)
ai->ai_flags &= ~AI_SECURE;
sd = socket_create(ai, inet_cb, NULL);
- if (sd < 0)
+ if (sd < 0) {
+ WARN("Failed creating socket for %s:%s: %s", pe->pe_name ?: "*",
+ pe->pe_serv, strerror(errno));
+ rc = 1;
continue;
+ }
- logit("Created inet socket %d for %s:%s ...\n", sd,
- pe->pe_name, pe->pe_serv);
+ if (!SecureMode) {
+ pe->pe_mode |= 01000;
+ NOTE("Opened inet socket %s:%s", pe->pe_name ?: "*", pe->pe_serv);
+ }
pe->pe_sock[pe->pe_socknum++] = sd;
}
freeaddrinfo(res);
+ if (rc && pe->pe_socknum == 0)
+ return rc;
+
+ return 0;
+}
+
+static void close_socket(struct peer *pe)
+{
+ for (size_t i = 0; i < pe->pe_socknum; i++) {
+ if (pe->pe_mode & 01000)
+ NOTE("Closing inet socket %s:%s", pe->pe_name ?: "*", pe->pe_serv);
+ socket_close(pe->pe_sock[i]);
+ }
+ pe->pe_socknum = 0;
}
void untty(void)
@@ -1947,6 +1978,7 @@ void fprintlog_write(struct filed *f, struct iovec *iov, int iovcnt, int flags)
if (lsent != len) {
switch (errno) {
case ENOBUFS:
+ case ENONET: /* returned by socket_ffs() */
case ENETDOWN:
case ENETUNREACH:
case EHOSTUNREACH:
@@ -2556,11 +2588,7 @@ void die(int signo)
*/
TAILQ_FOREACH_SAFE(pe, &pqueue, pe_link, next) {
TAILQ_REMOVE(&pqueue, pe, pe_link);
-
- for (size_t i = 0; i < pe->pe_socknum; i++) {
- logit("Closing socket %d ...\n", pe->pe_sock[i]);
- socket_close(pe->pe_sock[i]);
- }
+ close_socket(pe);
free(pe);
}
@@ -2718,6 +2746,31 @@ static void boot_time_init(void)
#endif
}
+/*
+ * Used by init() to trigger retries of, e.g., binding to interfaces.
+ */
+static void retry_init(void)
+{
+ struct peer *pe;
+ int fail = 0;
+
+ logit("Retrying socket init ...\n");
+ TAILQ_FOREACH(pe, &pqueue, pe_link) {
+ if (pe->pe_name && pe->pe_name[0] == '/') {
+ fail |= create_unix_socket(pe);
+ } else {
+ /* skip any marked for deletion */
+ if (SecureMode < 2)
+ fail |= create_inet_socket(pe);
+ }
+ }
+
+ if (!fail) {
+ logit("Socket re-init done.\n");
+ retry = NULL;
+ }
+}
+
/*
* INIT -- Initialize syslogd from configuration table
*/
@@ -2725,8 +2778,8 @@ static void init(void)
{
struct files newf = SIMPLEQ_HEAD_INITIALIZER(newf);
struct peer *pe, *penext;
+ int bflag = 0, fail = 0;
struct filed *f;
- int bflag = 0;
FILE *fp;
char *p;
@@ -2840,23 +2893,6 @@ static void init(void)
});
}
- /*
- * Open or close sockets for local and remote communication
- */
- TAILQ_FOREACH(pe, &pqueue, pe_link) {
- if (pe->pe_name && pe->pe_name[0] == '/') {
- create_unix_socket(pe);
- } else {
- for (size_t i = 0; i < pe->pe_socknum; i++)
- socket_close(pe->pe_sock[i]);
- pe->pe_socknum = 0;
-
- /* skip any marked for deletion */
- if (SecureMode < 2 && pe->pe_mark <= 0)
- create_inet_socket(pe);
- }
- }
-
/*
* Sweep
*/
@@ -2865,11 +2901,35 @@ static void init(void)
continue;
TAILQ_REMOVE(&pqueue, pe, pe_link);
+ close_socket(pe);
free(pe);
}
Initialized = 1;
+ flog(LOG_SYSLOG | LOG_INFO, "syslogd v" VERSION ": restart.");
+ logit("syslogd: restarted.\n");
+
+ /*
+ * Open or close sockets for local and remote communication
+ * These may be delayed, so start local logging first.
+ */
+ TAILQ_FOREACH(pe, &pqueue, pe_link) {
+ if (pe->pe_name && pe->pe_name[0] == '/') {
+ fail |= create_unix_socket(pe);
+ } else {
+ close_socket(pe);
+
+ if (SecureMode < 2)
+ fail |= create_inet_socket(pe);
+ }
+ }
+
+ if (fail)
+ retry = &init_tv;
+ else
+ retry = NULL;
+
if (Debug) {
if (!TAILQ_EMPTY(&nothead)) {
struct notifier *np;
@@ -2924,9 +2984,6 @@ static void init(void)
printf("\n");
}
}
-
- flog(LOG_SYSLOG | LOG_INFO, "syslogd v" VERSION ": restart.");
- logit("syslogd: restarted.\n");
}
static void cflisten(char *ptr, void *arg)
--
2.43.0
@@ -1,30 +0,0 @@
From 87ccd3eb37087ffb4b5f5b0322a558522a705215 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Thu, 18 Jul 2024 11:42:36 +0200
Subject: [PATCH 11/17] Read *.conf files from include/ directories sorted
Organization: Addiva Elektronik
No point in "saving time" on this operation. It is more important to
users that we read the files in a predefined order, alphabetically.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslogd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/syslogd.c b/src/syslogd.c
index 402a85e..87da475 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -3400,7 +3400,7 @@ static int cfparse(FILE *fp, struct files *newf)
p++;
logit("Searching for %s ...\n", p);
- if (glob(p, GLOB_NOSORT, NULL, &gl))
+ if (glob(p, 0, NULL, &gl))
logit("No files match %s\n", p);
for (size_t i = 0; i < gl.gl_pathc; i++) {
--
2.43.0
@@ -1,44 +0,0 @@
From 035dccad53efcd4237f040dc702ab435212ecf03 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Sun, 21 Jul 2024 19:15:48 +0200
Subject: [PATCH 12/17] Fix #87: segfault on shutdown
Organization: Addiva Elektronik
Regression introduced in in 36295e3, for issue #82.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslogd.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/syslogd.c b/src/syslogd.c
index 87da475..64da821 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -2578,11 +2578,6 @@ void die(int signo)
*/
timer_exit();
- /*
- * Close all open log files.
- */
- close_open_log_files();
-
/*
* Close all UNIX and inet sockets
*/
@@ -2592,6 +2587,11 @@ void die(int signo)
free(pe);
}
+ /*
+ * Close all open log files.
+ */
+ close_open_log_files();
+
kern_console_on();
exit(0);
--
2.43.0
@@ -1,62 +0,0 @@
From c7267011224ebd28d8a9daccd589109288fbde11 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 26 Aug 2024 11:47:10 +0200
Subject: [PATCH 13/17] Fix #85: logging to remote IPv6 address does not work
Organization: Addiva Elektronik
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslogd.c | 13 ++++++++++++-
test/fwd.sh | 4 ++--
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/src/syslogd.c b/src/syslogd.c
index 64da821..a2502c9 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -3216,8 +3216,19 @@ static struct filed *cfline(char *line)
switch (*p) {
case '@':
cfopts(p, f);
+ p++;
+ if (*p == '[') {
+ p++;
- bp = strchr(++p, ':');
+ q = strchr(p, ']');
+ if (!q) {
+ ERR("Invalid IPv6 address in remote target, missing ']'");
+ break;
+ }
+ *q++ = 0;
+ bp = strchr(q, ':');
+ } else
+ bp = strchr(p, ':');
if (bp)
*bp++ = 0;
else
diff --git a/test/fwd.sh b/test/fwd.sh
index 70fba5b..e37dc1f 100755
--- a/test/fwd.sh
+++ b/test/fwd.sh
@@ -13,7 +13,7 @@ MSG="fwd and allow"
cat <<EOF >"${CONFD}/fwd.conf"
kern.* /dev/null
-ntp.* @127.0.0.2:${PORT2} ;RFC5424
+ntp.* @[::1]:${PORT2} ;RFC5424
EOF
reload
@@ -23,7 +23,7 @@ kern.* /dev/null
*.*;kern.none ${LOG2} ;RFC5424
EOF
-setup2 -m0 -a 127.0.0.2:* -b ":${PORT2}"
+setup2 -m0 -a "[::1]:*" -b ":${PORT2}"
print "TEST: Starting"
--
2.43.0
@@ -1,45 +0,0 @@
From 1a2e13cb3f3e4fb9f33a56cc87fb96ebc3bb45c7 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 26 Aug 2024 11:49:27 +0200
Subject: [PATCH 14/17] Fix #86: adapt facilities for RFC5424 compliance
Organization: Addiva Elektronik
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslog.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/syslog.h b/src/syslog.h
index 873e7f8..0a9c31b 100644
--- a/src/syslog.h
+++ b/src/syslog.h
@@ -118,8 +118,10 @@ CODE prioritynames[] = {
#define LOG_FTP (11<<3) /* ftp daemon */
#define LOG_NTP (12<<3) /* NTP subsystem */
#define LOG_SECURITY (13<<3) /* Log audit, for audit trails */
+#define LOG_AUDIT LOG_SECURITY /* Alias for RFC5424 compat. */
#define LOG_CONSOLE (14<<3) /* Log alert */
#define LOG_CRON_SOL (15<<3) /* clock daemon (Solaris) */
+#define LOG_CRON2 LOG_CRON_SOL /* Alias for RFC5424 compat. */
#define LOG_LOCAL0 (16<<3) /* reserved for local use */
#define LOG_LOCAL1 (17<<3) /* reserved for local use */
#define LOG_LOCAL2 (18<<3) /* reserved for local use */
@@ -141,6 +143,7 @@ CODE facilitynames[] = {
{ "console", LOG_CONSOLE },
{ "cron", LOG_CRON },
{ "cron_sol", LOG_CRON_SOL }, /* Solaris cron */
+ { "cron2", LOG_CRON2 },
{ "daemon", LOG_DAEMON },
{ "ftp", LOG_FTP },
{ "kern", LOG_KERN },
@@ -150,6 +153,7 @@ CODE facilitynames[] = {
{ "news", LOG_NEWS },
{ "ntp", LOG_NTP },
{ "security", LOG_SECURITY },
+ { "audit", LOG_AUDIT },
{ "syslog", LOG_SYSLOG },
{ "user", LOG_USER },
{ "uucp", LOG_UUCP },
--
2.43.0
@@ -1,34 +0,0 @@
From d6e7d2c6ee36cfc67eeef643d4a6c69dfbbd36ab Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 26 Aug 2024 11:50:13 +0200
Subject: [PATCH 15/17] Fix #88: initial delay for unresolvable remote target
Organization: Addiva Elektronik
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslogd.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/syslogd.c b/src/syslogd.c
index a2502c9..fecf281 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -871,8 +871,14 @@ static int nslookup(const char *host, const char *service, struct addrinfo **ai)
if (!node || !node[0])
node = NULL;
- /* Reset resolver cache and retry name lookup */
+ /*
+ * Reset resolver cache and retry name lookup. The use of
+ * `_res` here seems to be the most portable way to adjust
+ * the per-process timeout and retry.
+ */
res_init();
+ _res.retrans = 1;
+ _res.retry = 1;
logit("nslookup '%s:%s'\n", node ?: "*", service);
memset(&hints, 0, sizeof(hints));
--
2.43.0
@@ -1,123 +0,0 @@
From fbded7ec91a0747b4d9c9059ef48aebb5d5fc4e8 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 27 Aug 2024 13:32:18 +0200
Subject: [PATCH 16/17] Fix #89: data corruption using .conf file listen
directive
Organization: Addiva Elektronik
The addpeer() function must save a copy of the name:service argument,
otherwise, when called from cfparse(), the contents of the string will
be corrupted.
Also, add a delpeer() function to wrap the logic for when closing and
deleting peers when stopping or reloading syslogd.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslogd.c | 47 +++++++++++++++++++++++++++++++++--------------
src/syslogd.h | 4 ++--
2 files changed, 35 insertions(+), 16 deletions(-)
diff --git a/src/syslogd.c b/src/syslogd.c
index fecf281..9b8dc24 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -298,12 +298,43 @@ static int addpeer(struct peer *pe0)
pe = calloc(1, sizeof(*pe));
if (pe == NULL)
err(1, "malloc failed");
+
*pe = *pe0;
+ if (pe0->pe_name)
+ pe->pe_name = strdup(pe0->pe_name);
+ if (pe0->pe_serv)
+ pe->pe_serv = strdup(pe0->pe_serv);
+
TAILQ_INSERT_TAIL(&pqueue, pe, pe_link);
return 0;
}
+static void close_socket(struct peer *pe)
+{
+ for (size_t i = 0; i < pe->pe_socknum; i++) {
+ if (pe->pe_mode & 01000)
+ NOTE("Closing inet socket %s:%s", pe->pe_name ?: "*", pe->pe_serv);
+ socket_close(pe->pe_sock[i]);
+ }
+ pe->pe_socknum = 0;
+}
+
+static void delpeer(struct peer *pe)
+{
+ if (!pe)
+ return;
+
+ close_socket(pe);
+
+ if (pe->pe_name)
+ free(pe->pe_name);
+ if (pe->pe_serv)
+ free(pe->pe_serv);
+
+ free(pe);
+}
+
static void sys_seqno_load(void)
{
char buf[32], *str;
@@ -938,16 +969,6 @@ static int create_inet_socket(struct peer *pe)
return 0;
}
-static void close_socket(struct peer *pe)
-{
- for (size_t i = 0; i < pe->pe_socknum; i++) {
- if (pe->pe_mode & 01000)
- NOTE("Closing inet socket %s:%s", pe->pe_name ?: "*", pe->pe_serv);
- socket_close(pe->pe_sock[i]);
- }
- pe->pe_socknum = 0;
-}
-
void untty(void)
{
#ifdef HAVE_SETSID
@@ -2589,8 +2610,7 @@ void die(int signo)
*/
TAILQ_FOREACH_SAFE(pe, &pqueue, pe_link, next) {
TAILQ_REMOVE(&pqueue, pe, pe_link);
- close_socket(pe);
- free(pe);
+ delpeer(pe);
}
/*
@@ -2907,8 +2927,7 @@ static void init(void)
continue;
TAILQ_REMOVE(&pqueue, pe, pe_link);
- close_socket(pe);
- free(pe);
+ delpeer(pe);
}
Initialized = 1;
diff --git a/src/syslogd.h b/src/syslogd.h
index d74c0ed..0dce0ed 100644
--- a/src/syslogd.h
+++ b/src/syslogd.h
@@ -226,8 +226,8 @@
*/
struct peer {
TAILQ_ENTRY(peer) pe_link;
- const char *pe_name;
- const char *pe_serv;
+ char *pe_name;
+ char *pe_serv;
int pe_mark;
mode_t pe_mode;
int pe_sock[16];
--
2.43.0
@@ -1,47 +0,0 @@
From 691aea6cbe27134d4d4106bb0bca396aff2802f9 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 27 Aug 2024 13:35:03 +0200
Subject: [PATCH 17/17] Fix #90: add support for IPv6 addresses in listen
directive
Organization: Addiva Elektronik
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslogd.c | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/src/syslogd.c b/src/syslogd.c
index 9b8dc24..033be84 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -3014,8 +3014,26 @@ static void init(void)
static void cflisten(char *ptr, void *arg)
{
char *peer = ptr;
+ char *p;
+
+ while (*peer && isspace(*peer))
+ ++peer;
+
+ logit("cflisten[%s]\n", peer);
+
+ p = peer;
+ if (*p == '[') {
+ p++;
+
+ p = strchr(p, ']');
+ if (!p) {
+ ERR("Invalid IPv6 address in listen '%s', missing ']'", peer);
+ return;
+ }
+ *p++ = 0;
+ }
- ptr = strchr(peer, ':');
+ ptr = strchr(p, ':');
if (ptr)
*ptr++ = 0;
addpeer(&(struct peer) {
--
2.43.0
@@ -0,0 +1,28 @@
From 8e230d3f2e1e33691998862e99ab4e13410527b9 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Wed, 8 Jan 2025 07:49:06 +0100
Subject: [PATCH 01/16] Drop redundant initial call to localtime_r()
Organization: Wires
Fixes #94
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslogd.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/syslogd.c b/src/syslogd.c
index 17115fc..5ad4dbc 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -1508,7 +1508,6 @@ void printsys(char *msg)
*/
if (KeepKernTime || !sys_seqno_init) {
now = boot_time + ustime / 1000000;
- localtime_r(&now, &buffer.timestamp.tm);
} else {
struct timeval tv;
--
2.43.0
@@ -0,0 +1,28 @@
From 13c8071821ad27247061dbf4efe5a34505520bc1 Mon Sep 17 00:00:00 2001
From: Patrick Oppenlander <patrick.oppenlander@gmail.com>
Date: Thu, 23 Jan 2025 15:22:57 +1100
Subject: [PATCH 02/16] fix local hostname '+@', '-@' support
Organization: Wires
Signed-off-by: Patrick Oppenlander <patrick.oppenlander@gmail.com>
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslogd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/syslogd.c b/src/syslogd.c
index 5ad4dbc..c07e143 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -3895,7 +3895,7 @@ static int cfparse(FILE *fp, struct files *newf)
char *local = LocalHostName;
while (i < sizeof(host) - 1 && *local)
- host[i++] = *local;
+ host[i++] = *local++;
p++;
} else if (!isprint(*p) || isblank(*p))
break;
--
2.43.0
@@ -0,0 +1,31 @@
From 979edb2515d24174fe9a3e2d6402d62172028c52 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Sat, 1 Feb 2025 20:33:19 +0100
Subject: [PATCH 03/16] Fix #95: printsys(), minor code simplification
Organization: Wires
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslogd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/syslogd.c b/src/syslogd.c
index c07e143..f812d9e 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -1511,11 +1511,11 @@ void printsys(char *msg)
} else {
struct timeval tv;
- now = time(NULL);
if (gettimeofday(&tv, NULL) == -1) {
tv.tv_sec = time(NULL);
tv.tv_usec = 0;
}
+ now = tv.tv_sec;
ustime = tv.tv_usec;
}
--
2.43.0
@@ -0,0 +1,31 @@
From 360dfe4b6b17378990daef797a7e6a551c799b98 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Sun, 2 Feb 2025 06:34:16 +0100
Subject: [PATCH 04/16] Fix #98: fprintlog_first(), drop superfluous call
Organization: Wires
The call to check_timestamp() is not needed (anymore) already called in
logmsg(), which is the only way of entering this function (today).
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslogd.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/src/syslogd.c b/src/syslogd.c
index f812d9e..6748cc6 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -2424,9 +2424,6 @@ static void fprintlog_first(struct filed *f, struct buf_msg *buffer)
logit("Called fprintlog_first(), ");
- /* Messages generated by syslogd itself may not have a timestamp */
- check_timestamp(buffer);
-
if (f->f_type != F_FORW_SUSP && f->f_type != F_FORW_UNKN) {
f->f_time = timer_now();
f->f_prevcount = 0;
--
2.43.0
@@ -0,0 +1,118 @@
From 472c3d6a24e43f8186ce069da267e9ae52c18699 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Thu, 27 Feb 2025 19:07:11 +0100
Subject: [PATCH 05/16] Fix #100: parsing of userspace messages in /dev/kmsg
Organization: Wires
Some applications that inject log messages to /dev/kmsg do not use a
space separating the APP_NAME (and optional PID), while some do. So we
need to support the following variants for the human readable payload,
as defined in [1]:
1. APP: MESG
2. APP:MESG
3. APP MESG
4. APP[PID]: MESG
5. APP[PID]:MESG
6. APP[PID] MESG
Prior to this change, 4 & 5 were treated the same, causing #100, and the
other alternatives were not supported at all. This patch drops the bad
local implementation in printsys() in favor of the generic parsemsg()
helper function for RFC3164 messages, which properly extracts both the
application name and PID if present.
This helper's ': ' separator check is relaxed since some clients only
send ':' (no space) before the message. The RFC can be interpreted
either way, so we now allow either/or or no separator.
[1]: https://www.kernel.org/doc/Documentation/ABI/testing/dev-kmsg
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslogd.c | 55 +++++++++++++++++++++++++++------------------------
1 file changed, 29 insertions(+), 26 deletions(-)
diff --git a/src/syslogd.c b/src/syslogd.c
index 6748cc6..b52af73 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -1242,16 +1242,38 @@ parsemsg_rfc3164_app_name_procid(char **msg, char **app_name, char **procid)
procid_length = 0;
}
- /* Separator. */
- if (m[0] != ':' || m[1] != ' ')
- goto bad;
+ /*
+ * Relaxed separator check. This function is used both for
+ * incoming remote/local syslog messages, and the /dev/kmsg
+ * printsys() function.
+ *
+ * RFC3164 sec. 4.1.3 states that: "the conclusion of the TAG
+ * field has been seen to be the left square bracket character
+ * ('['), a colon character (':'), or a space character". This
+ * uncertainty continues in sec. 5.3: "a colon and a space
+ * character *usually* follow the TAG" (emphasis added).
+ *
+ * Hence, we should be prepared for any of:
+ * - APP: msg
+ * - APP:msg
+ * - APP msg
+ * - APP[PID]: msg
+ * - APP[PID]:msg
+ * - APP[PID] msg
+ */
+ if (*m == ':') {
+ m++;
+ if (isblank(*m))
+ m++;
+ } else if (isblank(*m))
+ m++;
/* Split strings from input. */
app_name_begin[app_name_length] = '\0';
if (procid_begin != 0)
procid_begin[procid_length] = '\0';
- *msg = m + 2;
+ *msg = m;
*app_name = app_name_begin;
*procid = procid_begin;
return;
@@ -1630,29 +1652,10 @@ void printsys(char *msg)
/*
* Check for user writing to /dev/kmsg before /dev/log
* is up. Syntax to write: <PRI>APP_NAME[PROC_ID]:msg
+ * Kernel facility is 0, anything != 0 is userspace.
*/
- if (buffer.pri & LOG_FACMASK) {
- for (q = p; *q && !isspace(*q) && *q != '['; q++)
- ;
-
- if (*q == '[') {
- char *ptr = &q[1];
-
- while (*ptr && isdigit(*ptr))
- ptr++;
-
- if (ptr[0] == ']' && ptr[1] == ':') {
- *ptr++ = 0;
- *q++ = 0;
-
- buffer.app_name = p;
- buffer.proc_id = q;
-
- /* user log message cont. here */
- p = &ptr[1];
- }
- }
- }
+ if (buffer.pri & LOG_FACMASK)
+ parsemsg_rfc3164_app_name_procid(&p, &buffer.app_name, &buffer.proc_id);
q = lp;
while (*p != '\0' && (c = *p++) != '\n' && q < &line[MAXLINE])
--
2.43.0
@@ -0,0 +1,99 @@
From 8cdf4b0c4b9914b8b7aa1c1c1d76dad0fa429115 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Sat, 1 Mar 2025 09:23:01 +0100
Subject: [PATCH 06/16] Fix #93: update documentation on behavior of -T flag
Organization: Wires
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
man/syslogd.8 | 17 ++++++++++-------
src/syslogd.c | 10 +++++-----
2 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/man/syslogd.8 b/man/syslogd.8
index f3e6ad2..7534529 100644
--- a/man/syslogd.8
+++ b/man/syslogd.8
@@ -411,10 +411,13 @@ the command line option always wins, so it must be removed for
.Nm
to consider the .conf file option instead.
.It Fl T
-Always use the local time and date for messages received from the network,
-instead of the timestamp field supplied in the message by the remote host.
-This is useful if some of the originating hosts cannot keep time properly
-or are unable to generate a correct timestamp.
+Always use the local time and date for messages instead of the timestamp
+field in the log message. This applies to both messages received from a
+remote syslog server and locally originated. Useful if the originating
+hosts cannot keep time properly or are unable to generate a correct
+timestamp. See
+.Fl t
+for details on the timestamp of (local) kernel messages.
.It Fl t
Keep (trust) kernel timestamp.
.Pp
@@ -472,9 +475,9 @@ API included with the
.Nm sysklogd
project.
.Pp
-The date and time are taken from the received message. If the format of
-the timestamp field is incorrect, time obtained from the local host is
-used instead. This can be overridden by the
+The date and time for a log message are by default read from the
+received message. If the format of the timestamp field is incorrect,
+the time of reception is used instead. See also the
.Fl T
flag.
.Sh SECURITY
diff --git a/src/syslogd.c b/src/syslogd.c
index b52af73..5a40732 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -148,7 +148,7 @@ static int no_compress; /* don't compress messages (1=pipes, 2=all) */
static int secure_opt; /* sink for others, log to remote, or only unix domain socks */
static int secure_mode; /* same as above but from syslog.conf, only if cmdline unset */
-static int RemoteAddDate; /* Always set the date on remote messages */
+static int AlwaysAddDate; /* Always use our timestamp for log messages */
static int RemoteHostname; /* Log remote hostname from the message */
static int KernLog = 1; /* Track kernel logs by default */
@@ -458,7 +458,7 @@ int usage(int code)
" If specified twice, no socket at all will be opened, which also\n"
" disables support for logging to remote machines.\n"
" -t Keep kernel timestamp, even after initial ring buffer emptying\n"
- " -T Use local time and date for messages received from remote hosts\n"
+ " -T Use local time and date for log messages (both local and remote)\n"
" -? Show this help text\n"
" -v Show program version and exit\n"
"\n"
@@ -585,7 +585,7 @@ int main(int argc, char *argv[])
break;
case 'T':
- RemoteAddDate = 1;
+ AlwaysAddDate = 1;
break;
case 't': /* keep/trust kernel timestamp always */
@@ -1129,7 +1129,7 @@ parsemsg_rfc5424(const char *from, int pri, char *msg)
}
#undef PARSE_NUMBER
PARSE_CHAR("TIMESTAMP", ' ');
- if (!RemoteAddDate)
+ if (!AlwaysAddDate)
timestamp = &timestamp_remote;
}
@@ -1311,7 +1311,7 @@ parsemsg_rfc3164(const char *from, int pri, char *msg)
msg += RFC3164_DATELEN + 1;
- if (!RemoteAddDate) {
+ if (!AlwaysAddDate) {
struct timeval tv;
time_t t_remote;
struct tm tm_now;
--
2.43.0
@@ -0,0 +1,44 @@
From b5b4a4ecb893dd643fb25763fb9c6f6ca972725e Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Sun, 2 Mar 2025 13:56:46 +0100
Subject: [PATCH 07/16] Update internal timer consistently
Organization: Wires
Timer is already updated by parsemsg() before calling logmsg(). For
consistency, add explicit update also to printsys() (kernel) and
flog() (internally originated) messages.
Issue #70
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslogd.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/syslogd.c b/src/syslogd.c
index 5a40732..1737f7c 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -1467,6 +1467,9 @@ void printsys(char *msg)
char *lp, *p, *q;
int c;
+ /* Update current time before logging */
+ timer_update();
+
lp = line;
for (p = msg; *p != '\0';) {
memset(&buffer, 0, sizeof(buffer));
@@ -2669,6 +2672,9 @@ void flog(int pri, char *fmt, ...)
char proc_id[10];
va_list ap;
+ /* Update current time before logging */
+ timer_update();
+
va_start(ap, fmt);
(void)vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
--
2.43.0
@@ -0,0 +1,61 @@
From d3362a104b414af2b352a15a6d1e92f823bdb9b6 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Sun, 2 Mar 2025 14:06:37 +0100
Subject: [PATCH 08/16] Update ChangeLog and bump version for upcoming v2.7.1
release
Organization: Wires
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
ChangeLog.md | 14 ++++++++++++++
configure.ac | 2 +-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/ChangeLog.md b/ChangeLog.md
index b96857f..aa3e793 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -4,6 +4,19 @@ Change Log
All relevant changes to the project are documented in this file.
+[v2.7.1][UNRELEASED] - 2025-03-xx
+-----------------------
+
+### Changes
+- Update `syslogd -T` documentation, it applies to messages originating
+ both locally and from both remote syslog servers, issue #93
+
+### Fixes
+- Fix #99: hostname filtering support, introduced in v2.7.0, broken
+- Fix #100: parsing of userspace messages in `/dev/kmsg` inserted an
+ extra space before the message payload
+
+
[v2.7.0][] - 2025-01-06
-----------------------
@@ -667,6 +680,7 @@ and a replacement for `syslog.h` to enable new features in RFC5424.
[UNRELEASED]: https://github.com/troglobit/sysklogd/compare/v2.7.0...HEAD
+[v2.7.1]: https://github.com/troglobit/sysklogd/compare/v2.7.0...v2.7.1
[v2.7.0]: https://github.com/troglobit/sysklogd/compare/v2.6.2...v2.7.0
[v2.6.2]: https://github.com/troglobit/sysklogd/compare/v2.6.1...v2.6.2
[v2.6.1]: https://github.com/troglobit/sysklogd/compare/v2.6.0...v2.6.1
diff --git a/configure.ac b/configure.ac
index f387800..64de416 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,7 +25,7 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
-AC_INIT([sysklogd], [2.7.0],
+AC_INIT([sysklogd], [2.7.1-rc1],
[https://github.com/troglobit/sysklogd/issues],,
[https://github.com/troglobit/sysklogd])
AC_CONFIG_AUX_DIR(aux)
--
2.43.0
@@ -0,0 +1,47 @@
From 5552a3ea0d025573a5e212d62ee3e04bd376c7c4 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 3 Mar 2025 03:17:39 +0100
Subject: [PATCH 09/16] Bump version and update ChangeLog for v2.7.1 release
Organization: Wires
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
ChangeLog.md | 4 ++--
configure.ac | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/ChangeLog.md b/ChangeLog.md
index aa3e793..12829c0 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -4,12 +4,12 @@ Change Log
All relevant changes to the project are documented in this file.
-[v2.7.1][UNRELEASED] - 2025-03-xx
+[v2.7.1][] - 2025-03-03
-----------------------
### Changes
- Update `syslogd -T` documentation, it applies to messages originating
- both locally and from both remote syslog servers, issue #93
+ both locally and from remote syslog servers, issue #93
### Fixes
- Fix #99: hostname filtering support, introduced in v2.7.0, broken
diff --git a/configure.ac b/configure.ac
index 64de416..a2cf9be 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,7 +25,7 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
-AC_INIT([sysklogd], [2.7.1-rc1],
+AC_INIT([sysklogd], [2.7.1],
[https://github.com/troglobit/sysklogd/issues],,
[https://github.com/troglobit/sysklogd])
AC_CONFIG_AUX_DIR(aux)
--
2.43.0
@@ -0,0 +1,162 @@
From 64cd26232e598f902cf93b540152df5f7d8991e8 Mon Sep 17 00:00:00 2001
From: Luz Paz <luzpaz@pm.me>
Date: Mon, 3 Mar 2025 07:16:35 -0500
Subject: [PATCH 10/16] Fix various typos Fixes user-facing and non-user-facing
typos Found via `codespell -q 3 -L bootup,clen,nd,servent,siz,tast,unx`
Organization: Wires
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
ChangeLog.md | 2 +-
README.md | 2 +-
man/syslog.conf.5 | 2 +-
src/logger.c | 2 +-
src/syslog.h | 2 +-
src/syslogd.c | 4 ++--
src/syslogd.h | 2 +-
syslog.conf | 4 ++--
test/listen.sh | 4 ++--
9 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/ChangeLog.md b/ChangeLog.md
index 12829c0..da44e01 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -508,7 +508,7 @@ and a replacement for `syslog.h` to enable new features in RFC5424.
- New `syslogp()` API from NetBSD, for applications wanting to use
RFC5424 features like MsgID or structured data
- Many *incompatible changes* to command line options in `syslogd` and
- `klogd` for compatiblity with FreeBSD and NetBSD syslogd. Examples:
+ `klogd` for compatibility with FreeBSD and NetBSD syslogd. Examples:
- In syslogd: `-b` and `-c` have been replaced with `-r` for global
log rotation, `-a` has been replaced with the new `-p` support. The
`-r` flag and `-s HOST` has also been dropped in favor of the BSD
diff --git a/README.md b/README.md
index eff6b03..12ce92c 100644
--- a/README.md
+++ b/README.md
@@ -63,7 +63,7 @@ Main differences from the original sysklogd package are:
- The separate `klogd` daemon is no longer part of the sysklogd project,
syslogd now natively supports logging kernel messages as well
-- *Major* command line changes to `syslogd`, for compatibilty with *BSD
+- *Major* command line changes to `syslogd`, for compatibility with *BSD
- Supports `include /etc/syslog.d/*.conf` directive, see example .conf
- Built-in log-rotation support, with compression by default, useful for
embedded systems. No need for cron and/or a separate log rotate daemon
diff --git a/man/syslog.conf.5 b/man/syslog.conf.5
index f7d9ea1..64a7260 100644
--- a/man/syslog.conf.5
+++ b/man/syslog.conf.5
@@ -704,7 +704,7 @@ This example shows one combination of program and hostname filters.
!-ppp
*.* /var/log/syslog
-# Local pppd messages of severity info, or higer, go to its own log file
+# Local pppd messages of severity info, or higher, go to its own log file
!+ppp
*.info /var/log/ppp.log
diff --git a/src/logger.c b/src/logger.c
index ffdb9e1..8fcb42a 100644
--- a/src/logger.c
+++ b/src/logger.c
@@ -286,7 +286,7 @@ static int usage(int code)
" -h HOST Send (UDP) message to this remote syslog server (IP or DNS name)\n"
" -H NAME Use NAME instead of system hostname in message header\n"
" -i Log process ID of the logger process with each line (LOG_PID)\n"
- " -I PID Log process ID using PID, recommed using PID $$ for shell scripts\n"
+ " -I PID Log process ID using PID, recommend using PID $$ for shell scripts\n"
#ifdef __linux__
" -k Log to kernel /dev/kmsg if /dev/log doesn't exist yet\n"
#endif
diff --git a/src/syslog.h b/src/syslog.h
index 9c33967..4f35ad0 100644
--- a/src/syslog.h
+++ b/src/syslog.h
@@ -191,7 +191,7 @@ CODE facilitynames[] = {
#define LOG_NDELAY 0x008 /* don't delay open */
#define LOG_NOWAIT 0x010 /* don't wait for console forks: DEPRECATED */
#define LOG_PERROR 0x020 /* log to stderr as well */
-#define LOG_PTRIM 0x040 /* trim anything syslog addded when writing to stderr */
+#define LOG_PTRIM 0x040 /* trim anything syslog added when writing to stderr */
#define LOG_NLOG 0x080 /* don't write to the system log */
#define LOG_STDOUT 0x100 /* like nlog, for debugging syslogp() API */
#define LOG_RFC3164 0x200 /* Log to remote/ipc socket in old BSD format */
diff --git a/src/syslogd.c b/src/syslogd.c
index 1737f7c..9128e7f 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -177,7 +177,7 @@ static TAILQ_HEAD(notifiers, notifier) nothead = TAILQ_HEAD_INITIALIZER(nothead)
static TAILQ_HEAD(peers, peer) pqueue = TAILQ_HEAD_INITIALIZER(pqueue);
/*
- * List fo peers allowed to log to us.
+ * List of peers allowed to log to us.
*/
static SIMPLEQ_HEAD(allowed, allowedpeer) aphead = SIMPLEQ_HEAD_INITIALIZER(aphead);
@@ -4456,7 +4456,7 @@ static void notifier_free_all(void)
}
/*
- * The following function is resposible for handling a SIGHUP signal. Since
+ * The following function is responsible for handling a SIGHUP signal. Since
* we are now doing mallocs/free as part of init we had better not being
* doing this during a signal handler. Instead this function simply sets
* a flag variable which will tell the main loop to go through a restart.
diff --git a/src/syslogd.h b/src/syslogd.h
index ff97a0a..511e3e8 100644
--- a/src/syslogd.h
+++ b/src/syslogd.h
@@ -224,7 +224,7 @@
#define F_PIPE 9 /* named pipe */
/*
- * Stuct to hold property-based filters
+ * Struct to hold property-based filters
*/
struct prop_filter {
uint8_t prop_type;
diff --git a/syslog.conf b/syslog.conf
index 581fc32..3426c25 100644
--- a/syslog.conf
+++ b/syslog.conf
@@ -44,7 +44,7 @@ mail.err /var/log/mail.err
#
# Store all critical events, except kernel logs, in critical RFC5424 format.
-# Overide global log rotation settings, rotate every 10MiB, keep 5 old logs,
+# Override global log rotation settings, rotate every 10MiB, keep 5 old logs,
#
#*.=crit;kern.none /var/log/critical ;rotate=10M:5,RFC5424
@@ -68,7 +68,7 @@ mail.err /var/log/mail.err
# Secure mode, same as -s, none(0), on(1), full(2). When enabled
# only logging to remote syslog server possible, with full secure
# mode, not even that is possible. We default to prevent syslogd
-# from opening UDP/514 and receving messages from other systems.
+# from opening UDP/514 and receiving messages from other systems.
#
secure_mode 1
diff --git a/test/listen.sh b/test/listen.sh
index 1b706e8..7665261 100755
--- a/test/listen.sh
+++ b/test/listen.sh
@@ -99,10 +99,10 @@ run_step "Verify listen off - no remote no ports" verify_secure_daem
run_step "Verify listen off - only send to remote, no ports" verify_safe_daemon
run_step "Verify listen on, default" verify_default_daemon
-run_step "Verfiy listen on 127.0.0.1:510" verify_local_daemon
+run_step "Verify listen on 127.0.0.1:510" verify_local_daemon
run_step "Verify port 514 is closed" check_not_open 514
-run_step "Verfiy listen on 10.0.0.1:512" verify_bind
+run_step "Verify listen on 10.0.0.1:512" verify_bind
run_step "Verify port 510 is closed" check_not_open 510
run_step "Verify delayed bind to new address 10.0.0.2:513" verify_delayed_bind
--
2.43.0
@@ -0,0 +1,70 @@
From 2fbac9e54b60e813a5ecfb4ff4177b6351bfbffd Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Tue, 18 Mar 2025 06:32:27 +0100
Subject: [PATCH 11/16] test: update tag.sh, include dots in name and verify
tag in logfile
Organization: Wires
Issue #102
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
test/tag.sh | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/test/tag.sh b/test/tag.sh
index 3e1c598..bfc409a 100755
--- a/test/tag.sh
+++ b/test/tag.sh
@@ -1,16 +1,20 @@
#!/bin/sh
# Verify log filtering based on ident/tag.
+#DEBUG=true
. "${srcdir:-.}/lib.sh"
TG1=pimd
TG2=mrouted
+TG3=in.tftpd
MSG="Multicast, a perfect weapon for an imperfect time."
UNX="In UNIX we trust"
+DOT="We bring 512 byte block gifts"
LOGDIR="$DIR/log"
SYSLOG="${LOGDIR}/syslog"
TG1LOG="${LOGDIR}/$TG1.log"
TG2LOG="${LOGDIR}/$TG2.log"
+TG3LOG="${LOGDIR}/$TG3.log"
setup_syslogd()
{
@@ -22,6 +26,8 @@ setup_syslogd()
*.* $TG1LOG
#!$TG2
*.* $TG2LOG
+ #!$TG3
+ *.* $TG3LOG
EOF
setup -m0
}
@@ -32,8 +38,8 @@ verify_tag()
log="$1"; shift
msg="$*"
- logger -t "$tag" "$msg"
- grep "$msg" "$log"
+ logger -ip user.debug -t "$tag" "$msg"
+ grep "$msg" "$log" |grep "$tag"
}
verify_log()
@@ -52,6 +58,7 @@ verify_not()
run_step "Set up property based filtering syslogd" setup_syslogd
run_step "Verify basic tag based filtering (1)" verify_tag "$TG1" "$TG1LOG" "$MSG"
run_step "Verify basic tag based filtering (2)" verify_tag "$TG2" "$TG2LOG" "$MSG"
+run_step "Verify basic tag based filtering (3)" verify_tag "$TG3" "$TG3LOG" "$DOT"
run_step "Verify not in syslog" verify_not "$SYSLOG" "$MSG"
run_step "Verify unfiltered tag logging" verify_tag "foo" "$SYSLOG" "$UNX"
--
2.43.0
@@ -0,0 +1,72 @@
From ff09758a63f100d5e611d28b1f219ea10f2ca996 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Wed, 19 Mar 2025 06:08:45 +0100
Subject: [PATCH 12/16] test: further extend tag test to check RFC3164 code
path as well
Organization: Wires
Reproduces issue #102
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
test/tag.sh | 33 +++++++++++++++++++++++++++++----
1 file changed, 29 insertions(+), 4 deletions(-)
diff --git a/test/tag.sh b/test/tag.sh
index bfc409a..53aa745 100755
--- a/test/tag.sh
+++ b/test/tag.sh
@@ -1,6 +1,11 @@
#!/bin/sh
-# Verify log filtering based on ident/tag.
-#DEBUG=true
+# Verify log filtering based on ident/tag for both RFC3154 (BSD)
+# and RFC5424 formatted log messages sent to syslogd. A logged
+# message can also contain a [PID], so the combinations of various
+# tags + pid are also covered.
+#
+# Regression test for issue #102.
+#
. "${srcdir:-.}/lib.sh"
TG1=pimd
@@ -32,14 +37,34 @@ setup_syslogd()
setup -m0
}
+# Verify both RFC3164 (BSD) log format and RFC5424, because
+# they have different format parsers in syslogd. Generates
+# three additional variants of the given log message: rev,
+# rot13, and alphabetically sorted.
verify_tag()
{
tag="$1"; shift
log="$1"; shift
msg="$*"
+ rev=$(echo "$msg" | rev)
+ rot=$(echo "$msg" | tr 'a-zA-Z' 'n-za-mN-ZA-M')
+ bin=$(echo "$msg" | sed 's/./&\n/g' | sort | tr -d '\n')
- logger -ip user.debug -t "$tag" "$msg"
- grep "$msg" "$log" |grep "$tag"
+ # BSD log format (with -b)
+ logger -b -ip user.debug -t "$tag" "$msg"
+ verify_log "$log" "$msg" | grep "$tag" || return 1
+
+ # RFC5424 (default)
+ logger -ip user.debug -t "$tag" "$rev"
+ verify_log "$log" "$rev" | grep "$tag" || return 1
+
+ # BSD without -p flag
+ logger -b -i -t "$tag" "$rot"
+ verify_log "$log" "$rot" | grep "$tag" || return 1
+
+ # RFC5424 without -p flag
+ logger -i -t "$tag" "$bin"
+ verify_log "$log" "$bin" | grep "$tag" || return 1
}
verify_log()
--
2.43.0
@@ -0,0 +1,40 @@
From c0622119d6baf45dcaef01897f6c686f2eb92ee4 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Wed, 19 Mar 2025 06:35:39 +0100
Subject: [PATCH 13/16] Fix #102: allow '.' in tag names, regression in v2.7.1
Organization: Wires
RFC3164 specifies; "The TAG is a string of ABNF alphanumeric characters
that MUST NOT exceed 32 characters. Any non-alphanumeric character
will terminate the TAG field and will be assumed to be the starting
character of the CONTENT field."
Strictly speaking, ABNF (Augmented Backus-Naur Form) only includes the
alphanumeric characters, meaning just be letters and digits.
However, in real-life scenarios, and per previous behavior, we should
definitely allow '.' as well. The existing argument to `strspn()` is
from FreeBSD, which for some reason do *not* allow '.', but they do
also allow '_-/' ... '/' seems like the real outlier here.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/syslogd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/syslogd.c b/src/syslogd.c
index 9128e7f..07abdf9 100644
--- a/src/syslogd.c
+++ b/src/syslogd.c
@@ -1223,7 +1223,7 @@ parsemsg_rfc3164_app_name_procid(char **msg, char **app_name, char **procid)
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789"
- "_-/");
+ "._-/");
if (app_name_length == 0)
goto bad;
m += app_name_length;
--
2.43.0
@@ -0,0 +1,60 @@
From 93f9cd74856be4b9a77c72b8e4c55a49c32ce26e Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 24 Mar 2025 06:01:46 +0100
Subject: [PATCH 14/16] Prepare for upcoming v2.7.2
Organization: Wires
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
ChangeLog.md | 14 +++++++++++++-
configure.ac | 2 +-
2 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/ChangeLog.md b/ChangeLog.md
index da44e01..140cfc4 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -4,6 +4,17 @@ Change Log
All relevant changes to the project are documented in this file.
+[v2.7.2][UNRELEASED]
+-----------------------
+
+### Changes
+- Increased code coverage testing of tag parser
+
+### Fixes
+- Fix #102: allow `.` in tag names, regression in v2.7.1
+- Fix various typos in documentation, by Luz Paz
+
+
[v2.7.1][] - 2025-03-03
-----------------------
@@ -679,7 +690,8 @@ and a replacement for `syslog.h` to enable new features in RFC5424.
- Several bugfixes and improvements, please refer to the .c files
-[UNRELEASED]: https://github.com/troglobit/sysklogd/compare/v2.7.0...HEAD
+[UNRELEASED]: https://github.com/troglobit/sysklogd/compare/v2.7.1...HEAD
+[v2.7.2]: https://github.com/troglobit/sysklogd/compare/v2.7.1...v2.7.2
[v2.7.1]: https://github.com/troglobit/sysklogd/compare/v2.7.0...v2.7.1
[v2.7.0]: https://github.com/troglobit/sysklogd/compare/v2.6.2...v2.7.0
[v2.6.2]: https://github.com/troglobit/sysklogd/compare/v2.6.1...v2.6.2
diff --git a/configure.ac b/configure.ac
index a2cf9be..13dadfa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,7 +25,7 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
-AC_INIT([sysklogd], [2.7.1],
+AC_INIT([sysklogd], [2.7.2-beta1],
[https://github.com/troglobit/sysklogd/issues],,
[https://github.com/troglobit/sysklogd])
AC_CONFIG_AUX_DIR(aux)
--
2.43.0
@@ -0,0 +1,57 @@
From debc8c337b3e7d8c76701991a4566714b78c1846 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 31 Mar 2025 13:22:47 +0200
Subject: [PATCH 15/16] logger: show invalid option arguments if -p and -o
parsing fail
Organization: Wires
Instead of just showing the usage instructions, include information
about the option and its argument failing. Useful when debugging
faulty calls to the logger program deep in an operating system.
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
src/logger.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/logger.c b/src/logger.c
index 8fcb42a..5bf263f 100644
--- a/src/logger.c
+++ b/src/logger.c
@@ -393,13 +393,17 @@ int main(int argc, char *argv[])
break;
case 'o':
- if (parse_opts(optarg, &iface, &ttl))
+ if (parse_opts(optarg, &iface, &ttl)) {
+ printf("Invalid option argument '-%c %s'\n", c, optarg);
return usage(1);
+ }
break;
case 'p':
- if (parse_prio(optarg, &facility, &severity))
+ if (parse_prio(optarg, &facility, &severity)) {
+ printf("Invalid option argument '-%c %s'\n", c, optarg);
return usage(1);
+ }
break;
case 'P':
@@ -428,8 +432,12 @@ int main(int argc, char *argv[])
printf("%s\n", version_info);
return 0;
- default:
+ case '?':
return usage(0);
+
+ default:
+ printf("Unsupported option '-%c'\n", c);
+ return usage(1);
}
}
--
2.43.0
@@ -0,0 +1,47 @@
From 5fb314cb9060afa3bd4eed2f0be3200f02f729e9 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Mon, 31 Mar 2025 13:26:13 +0200
Subject: [PATCH 16/16] Update ChangeLog and bump version for v2.7.2 release
Organization: Wires
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
ChangeLog.md | 4 +++-
configure.ac | 2 +-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/ChangeLog.md b/ChangeLog.md
index 140cfc4..8d8bb43 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -4,11 +4,13 @@ Change Log
All relevant changes to the project are documented in this file.
-[v2.7.2][UNRELEASED]
+[v2.7.2][] - 2025-03-31
-----------------------
### Changes
- Increased code coverage testing of tag parser
+- Improved error handling in `logger` when invalid arguments to
+ `-p` and `-o` are encountered
### Fixes
- Fix #102: allow `.` in tag names, regression in v2.7.1
diff --git a/configure.ac b/configure.ac
index 13dadfa..fe79595 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,7 +25,7 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
-AC_INIT([sysklogd], [2.7.2-beta1],
+AC_INIT([sysklogd], [2.7.2],
[https://github.com/troglobit/sysklogd/issues],,
[https://github.com/troglobit/sysklogd])
AC_CONFIG_AUX_DIR(aux)
--
2.43.0
+10 -3
View File
@@ -10,7 +10,7 @@
banner_append()
{
printf "\n$@\n" | tee -a \
printf "\n%s\n" "$*" | tee -a \
/etc/banner \
/etc/issue \
/etc/issue.net \
@@ -28,12 +28,14 @@ perms()
note()
{
logger -I $$ -p user.notice -t load "$*"
msg="$*"
logger -I $$ -p user.notice -t load -- "$msg"
}
err()
{
logger -I $$ -p user.error -t load "$*"
msg="$*"
logger -I $$ -p user.error -t load -- "$msg"
}
@@ -46,6 +48,8 @@ while getopts "t:" opt; do
t)
sysrepocfg="$sysrepocfg -t $OPTARG"
;;
*)
;;
esac
done
shift $((OPTIND - 1))
@@ -123,6 +127,9 @@ if ! $sysrepocfg -v2 -I"$fn" -f json; then
banner_append "CRITICAL ERROR: Logins are disabled, no credentials available"
initctl -nbq runlevel 9
;;
*)
err "Unknown config $config, aborting!"
;;
esac
exit 1
+70 -70
View File
@@ -27,7 +27,7 @@ cleanup()
note()
{
if [ -n "$quiet" ]; then
return
return
fi
logger -I $$ -k -p user.notice -t "$ident" "$1"
}
@@ -46,11 +46,11 @@ atoi()
file_version()
{
jq -r '
if .["infix-meta:meta"] | has("infix-meta:version") then
.["infix-meta:meta"]["infix-meta:version"]
else
"0.0"
end
if .["infix-meta:meta"] | has("version") then
.["infix-meta:meta"]["version"]
else
"0.0"
end
' "$1"
}
@@ -58,16 +58,16 @@ file_version()
confd_version()
{
find "$scripts" -mindepth 1 -maxdepth 1 -type d \
| sort -V | tail -n1 | xargs -n1 basename
}
| sort -V | tail -n1 | xargs -n1 basename
}
# Update meta data with the latest version
meta_version()
{
if jq --arg version "$sys_version" '.["infix-meta:meta"] = {"infix-meta:version": $version}' "$2" \
> "${2}.tmp" && mv "${2}.tmp" "$2"; then
note "$1: configuration updated to version $sys_version."
return 0
if jq --arg version "$sys_version" '.["infix-meta:meta"] = {"version": $version}' "$2" \
> "${2}.tmp" && mv "${2}.tmp" "$2"; then
note "$1: configuration updated to version $sys_version."
return 0
fi
err "$1: failed updating configuration to version $sys_version!"
@@ -80,23 +80,23 @@ migrate()
note "$1: migrating from version $cfg_version"
for version_dir in $(find "$scripts" -mindepth 1 -maxdepth 1 -type d | sort -V); do
dir=$(basename "$version_dir")
version=$(atoi "$dir")
dir=$(basename "$version_dir")
version=$(atoi "$dir")
# Step by step upgrade file to latest version
if [ "$cfg_level" -lt "$version" ]; then
note "Applying migrations for version $dir ..."
# Step by step upgrade file to latest version
if [ "$cfg_level" -lt "$version" ]; then
note "Applying migrations for version $dir ..."
# Apply all scripts in the version directory in order
for script in $(find "$version_dir" -type f -name '*.sh' | sort -V); do
note "$1: calling $script ..."
sh "$script" "$2"
done
# Apply all scripts in the version directory in order
for script in $(find "$version_dir" -type f -name '*.sh' | sort -V); do
note "$1: calling $script ..."
sh "$script" "$2"
done
# File now at $version ...
cfg_level="$version"
fi
done
# File now at $version ...
cfg_level="$version"
fi
done
}
# Try migrating a copy, then diff the files, for factory-config check
@@ -126,31 +126,31 @@ eval set -- "$OPTS"
while [ -n "$1" ]; do
case $1 in
-b)
bak=$2
shift
;;
-c)
check=1
;;
-h)
usage
exit 0
;;
-i)
inplace=1
;;
-q)
quiet=1
;;
--)
shift
break
;;
*)
# Likely file argument
break
;;
-b)
bak=$2
shift
;;
-c)
check=1
;;
-h)
usage
exit 0
;;
-i)
inplace=1
;;
-q)
quiet=1
;;
--)
shift
break
;;
*)
# Likely file argument
break
;;
esac
shift
done
@@ -190,22 +190,22 @@ if [ "$cfg_level" -eq "$sys_level" ]; then
exit 0
else
if [ -n "$check" ]; then
# We may be called to check a file without meta:version (factory)
if [ "$cfg_version" = "0.0" ]; then
if diff "$tmp"; then
# File is OK, despite lacking meta:version
exit 0
fi
msg="$orig: has syntax error, requires migrating."
else
msg="$orig: version $cfg_version, requires migrating."
fi
if [ -t 0 ]; then
echo "$msg"
else
note "$msg"
fi
exit 1
# We may be called to check a file without meta:version (factory)
if [ "$cfg_version" = "0.0" ]; then
if diff "$tmp"; then
# File is OK, despite lacking meta:version
exit 0
fi
msg="$orig: has syntax error, requires migrating."
else
msg="$orig: version $cfg_version, requires migrating."
fi
if [ -t 0 ]; then
echo "$msg"
else
note "$msg"
fi
exit 1
fi
fi
@@ -214,10 +214,10 @@ if [ -n "$bak" ]; then
ext="${bak##*.}"
bak="${fil}-${cfg_version}.${ext}"
if cp -p "$tmp" "$bak" 2>/dev/null; then
note "$orig: backup created: $bak"
note "$orig: backup created: $bak"
else
err "$orig: failed creating backup: $bak"
exit 1
err "$orig: failed creating backup: $bak"
exit 1
fi
fi
+14 -11
View File
@@ -3,14 +3,17 @@
file=$1
temp=${file}.tmp
jq '.["infix-services:ssh"] = {
"enabled": true,
"hostkey": ["genkey"],
"listen": [
{"name": "ipv4", "address": "0.0.0.0", "port": 22},
{"name": "ipv6", "address": "::", "port": 22}
]
}' "$file" > "$temp"
mv "$temp" "$file"
jq '
if has("infix-services:ssh") then
.
else
.["infix-services:ssh"] = {
"enabled": true,
"hostkey": ["genkey"],
"listen": [
{"name": "ipv4", "address": "0.0.0.0", "port": 22},
{"name": "ipv6", "address": "::", "port": 22}
]
}
end' $file > temp.json
mv temp.json $file