From b29a3c4d11ec1cf778b253e3c3fbbf04b0794f86 Mon Sep 17 00:00:00 2001 From: Duncaen Date: Wed, 1 Mar 2017 19:15:03 +0100 Subject: Add vlogger(8) vlogger(8) is a alternative to logger(1), by default it sends messages from stdin to syslog. The main reason to replace logger(1) is, that logger only connects once to the syslog socket in default mode and puts all messages into the void if syslog is not running at the time. logger(1) has a new `--socket-errors=on` mode which would work, but some void uses don't use syslog at all and in this case the log service would constantly restart. As a bonus vlogger(8) looks for /etc/vlogger and if its executable it just executes it and is replaced by it. This can be used to avoid syslog and just write all logs to files with svlogd(8) as example, without having to edit all log services. --- vlogger.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 vlogger.c (limited to 'vlogger.c') 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 +#include +#include +#include +#include + +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; +} -- cgit 1.4.1