about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile2
-rw-r--r--vlogger.8138
-rw-r--r--vlogger.c111
4 files changed, 252 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index ed231ec..2440471 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
 halt
 pause
+vlogger
diff --git a/Makefile b/Makefile
index a21e5c9..001c17b 100644
--- a/Makefile
+++ b/Makefile
@@ -4,6 +4,7 @@ SCRIPTS=	1 2 3 ctrlaltdel
 all:
 	$(CC) $(CFLAGS) halt.c -o halt $(LDFLAGS)
 	$(CC) $(CFLAGS) pause.c -o pause $(LDFLAGS)
+	$(CC) $(CFLAGS) vlogger.c -o vlogger $(LDFLAGS)
 
 install:
 	install -d ${DESTDIR}/${PREFIX}/sbin
@@ -22,6 +23,7 @@ install:
 	install -m644 shutdown.8 ${DESTDIR}/${PREFIX}/share/man/man8
 	install -m644 halt.8 ${DESTDIR}/${PREFIX}/share/man/man8
 	install -m644 modules-load.8 ${DESTDIR}/${PREFIX}/share/man/man8
+	install -m644 vlogger.8 ${DESTDIR}/${PREFIX}/share/man/man8
 	ln -sf halt.8 ${DESTDIR}/${PREFIX}/share/man/man8/poweroff.8
 	ln -sf halt.8 ${DESTDIR}/${PREFIX}/share/man/man8/reboot.8
 	install -d ${DESTDIR}/etc/sv
diff --git a/vlogger.8 b/vlogger.8
new file mode 100644
index 0000000..2f46fcd
--- /dev/null
+++ b/vlogger.8
@@ -0,0 +1,138 @@
+.Dd March 1, 2017
+.Dt VLOGGER 8
+.Os Linux
+.Sh NAME
+.Nm vlogger
+.Nd log messages to syslog or an arbitrary executable
+.Sh SYNOPSIS
+.Nm vlogger
+.Op Fl p Ar priority
+.Op Fl t Ar tag
+.Sh DESCRIPTION
+By default,
+.Nm
+reads lines from
+.Dv stdin
+and sends them to syslog.
+If the file
+.Pa /etc/vlogger
+exists and is executable it is executed with
+.Ar tag
+as only argument and replaces
+.Nm .
+.Pp
+If
+.Nm
+is executed as a log service for runit or another daemontools like
+supervision suite it uses the service name as default
+.Ar tag .
+As example if
+.Nm
+is linked to
+.Dv /var/service/foo/log/run
+it uses
+.Dv foo
+as default
+.Ar tag .
+.Bl -tag -width indent
+.It Fl p Ar priority
+The.
+.Ar priority
+can be
+.Pa facility.level
+or just
+.Pa facility .
+See
+.Sx FACILITIES ,
+.Sx LEVELS
+or
+.Xr syslog 3 .
+The default is
+.Pa daemon.info .
+.It Fl t Ar tag
+Defines the
+.Xr openlog 3
+.Pa ident
+which is used as prefix for each log message or passed as first argument to
+.Pa /etc/vlogger .
+.El
+.Sh FACILITIES
+.Bl -tag -width 11n -compact
+.It auth
+.It authpriv
+.It cron
+.It daemon
+.It ftp
+.It kern
+can not be used from userspace replaced with
+.Pa daemon .
+.It lpr
+.It mail
+.It news
+.It syslog
+.It user
+.It uucp
+.It local[0-7]
+.It security
+deprecated synonym for
+.Pa auth.
+.El
+.Sh LEVELS
+.Bl -tag -width 11n -compact
+.It emerg
+.It alert
+.It crit
+.It err
+.It warning
+.It notice
+.It info
+.It debug
+.It panic
+deprecated synonym for
+.Pa emerg .
+.It error
+deprecated synonym for
+.Ar err .
+.It warn
+deprecated synonym for
+.Pa warning .
+.El
+.Sh FILES
+.Bl -tag -width indent
+.It /etc/vlogger
+An optional executable file that is used to to handle the messages.
+It is executed with
+.Ar tag
+as first argument and replaces the
+.Nm
+process.
+.El
+.Sh EXIT STATUS
+.Ex -std
+.Sh EXAMPLES
+.Pa /etc/vlogger :
+.Bd -literal -offset indent
+#!/bin/sh
+exec svlogd /var/log/$1
+.Ed
+.Sh SEE ALSO
+.Xr logger 1 ,
+.Xr syslog 3 ,
+.Xr svlogd 8
+.Sh HISTORY
+This program is a replacement for the
+.Nm logger
+utility provided by
+.Nm util-linux .
+.Sh AUTHOR
+.An Duncan Overbruck Aq Mt mail@duncano.de
+.Sh LICENSE
+.Nm
+is in the public domain.
+.Pp
+To the extent possible under law,
+the creator of this work
+has waived all copyright and related or
+neighboring rights to this work.
+.Pp
+.Lk http://creativecommons.org/publicdomain/zero/1.0/
diff --git a/vlogger.c b/vlogger.c
new file mode 100644
index 0000000..981b692
--- /dev/null
+++ b/vlogger.c
@@ -0,0 +1,111 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+typedef struct _code {
+  const char *const c_name;
+  int c_val;
+} CODE;
+
+CODE prioritynames[] = {
+	{ "alert", LOG_ALERT },
+	{ "crit", LOG_CRIT },
+	{ "debug", LOG_DEBUG },
+	{ "emerg", LOG_EMERG },
+	{ "err", LOG_ERR },
+	{ "error", LOG_ERR },
+	{ "info", LOG_INFO },
+	{ "notice", LOG_NOTICE },
+	{ "panic", LOG_EMERG },
+	{ "warn", LOG_WARNING },
+	{ "warning", LOG_WARNING },
+	{ 0, -1 }
+};
+
+CODE facilitynames[] = {
+	{ "auth", LOG_AUTH },
+	{ "authpriv", LOG_AUTHPRIV },
+	{ "cron", LOG_CRON },
+	{ "daemon", LOG_DAEMON },
+	{ "ftp", LOG_FTP },
+	{ "kern", LOG_KERN },
+	{ "lpr", LOG_LPR },
+	{ "mail", LOG_MAIL },
+	{ "news", LOG_NEWS },
+	{ "security", LOG_AUTH },
+	{ "syslog", LOG_SYSLOG },
+	{ "user", LOG_USER },
+	{ "uucp", LOG_UUCP },
+	{ "local0", LOG_LOCAL0 },
+	{ "local1", LOG_LOCAL1 },
+	{ "local2", LOG_LOCAL2 },
+	{ "local3", LOG_LOCAL3 },
+	{ "local4", LOG_LOCAL4 },
+	{ "local5", LOG_LOCAL5 },
+	{ "local6", LOG_LOCAL6 },
+	{ "local7", LOG_LOCAL7 },
+	{ 0, -1 }
+};
+
+static char *tag;
+
+static void
+strpriority(char *s, int *facility, int *level)
+{
+	char *p;
+	CODE *cp;
+
+	if ((p = strchr(s, '.'))) {
+		*p++ = 0;
+		for (cp = prioritynames; cp->c_name; cp++) {
+			if (strcmp(cp->c_name, p) == 0)
+				*level = cp->c_val;
+		}
+	}
+	if (*s)
+		for (cp = facilitynames; cp->c_name; cp++) {
+			if (strcmp(cp->c_name, s) == 0)
+				*facility = cp->c_val;
+		}
+}
+
+int
+main(int argc, char *argv[])
+{
+	char c, *p;
+	int facility = LOG_DAEMON;
+	int level = LOG_INFO;
+
+	if (((p = strrchr(*argv, '/')) && !strncmp(p+1, "run", 3)) &&
+	    (*p = 0, (p = strrchr(*argv, '/')) && !strncmp(p+1, "log", 3)) &&
+	    (*p = 0, (p = strrchr(*argv, '/'))) != 0) {
+		tag = strdup(p+1);
+	}
+
+	while ((c = getopt(argc, argv, "p:t:")) != -1)
+		switch (c) {
+		case 'p': strpriority(optarg, &facility, &level); break;
+		case 't': tag = optarg; break;
+		default:
+			fprintf(stderr, "usage: vlogger [-p priority] [-t tag]\n");
+			exit(1);
+		}
+
+	if (access("/etc/vlogger", X_OK) != -1)
+		execl("/etc/vlogger", "/etc/vlogger", tag, (char *)0);
+
+	openlog(tag, 0, facility);
+
+	char *line;
+	size_t linelen = 0;
+	ssize_t rd;
+	while ((rd = getline(&line, &linelen, stdin)) != -1) {
+		if (line[rd-1] == '\n')
+			line[rd-1] = 0;
+		syslog(level|facility, "%s", line);
+	}
+
+	return 1;
+}