From: Dennis H Jensen Date: Wed, 22 May 2013 11:12:08 +0000 (+0200) Subject: logger: add support for --prio-prefix when logging stdin X-Git-Tag: v2.24-rc1~532 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=98920f80591b61ffdf7bfd99e2dd824406276e78;p=thirdparty%2Futil-linux.git logger: add support for --prio-prefix when logging stdin This patch adds a new option to logger that will make it look for a priority prefix at the beginning of every line. The priority is a single decimal number formed as explained in syslog(3). If a prefix is found logger will log the message using the found facility and level in that prefix, if the prefix doesn't contain a facility the default facility specified by the -p option will be used. If no prefix is found, logger will use the priority specified by -p. [kzak@redhat.com: - add --prio-prefix to usage() output] Signed-off-by: Dennis H Jensen Signed-off-by: Karel Zak --- diff --git a/misc-utils/logger.1 b/misc-utils/logger.1 index 09ecdc4f88..f4cadc6970 100644 --- a/misc-utils/logger.1 +++ b/misc-utils/logger.1 @@ -109,6 +109,19 @@ Write to the specified .I socket instead of to the builtin syslog routines. .TP +\fB\-\-prio\-prefix\fR +Look for a syslog prefix on every line read from standard input, a +number contained within angle brackets that contain both the facility +and level. The decimal prefix is constructed by multiplying the +facility by 8 and then adding the level, thus \fIlocal0.info\fR, +facility=16 and level=6, becomes \fI<134>\fR. + +If the prefix contains no facility, the facility defaults to what is +specified by \fB\-p\fR option, similarly if no prefix is provided the +line is logged using the \fB\-p\fR \fIpriority\fR. + +This option doesn't affect a command-line message. +.TP \fB\-V\fR, \fB\-\-version\fR Display version information and exit. .TP diff --git a/misc-utils/logger.c b/misc-utils/logger.c index c83c0b817f..5b4d055f47 100644 --- a/misc-utils/logger.c +++ b/misc-utils/logger.c @@ -64,6 +64,30 @@ enum { ALL_TYPES = TYPE_UDP | TYPE_TCP }; +enum { + OPT_PRIO_PREFIX = CHAR_MAX + 1 +}; + + +static char* get_prio_prefix(char *msg, int *prio) +{ + int p; + char *end = NULL; + int facility = *prio & LOG_FACMASK; + + errno = 0; + p = strtoul(msg + 1, &end, 10); + + if (errno || !end || end == msg + 1 || end[0] != '>') + return msg; + + if (p & LOG_FACMASK) + facility = p & LOG_FACMASK; + + *prio = facility | (p & LOG_PRIMASK); + return end + 1; +} + static int decode(char *name, CODE *codetab) { register CODE *c; @@ -225,6 +249,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE *out) " -P, --port use this UDP port\n" " -p, --priority mark given message with this priority\n" " -s, --stderr output message to standard error as well\n"), out); + fputs(_(" --prio-prefix look for a prefix on every line read from stdin\n"), out); fputs(_(" -t, --tag mark every line with this tag\n" " -u, --socket write to this Unix socket\n" " -V, --version output version information and exit\n\n"), out); @@ -240,7 +265,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE *out) */ int main(int argc, char **argv) { - int ch, logflags, pri; + int ch, logflags, pri, prio_prefix; char *tag, buf[1024]; char *usock = NULL; char *server = NULL; @@ -260,6 +285,7 @@ main(int argc, char **argv) { { "port", required_argument, 0, 'P' }, { "version", no_argument, 0, 'V' }, { "help", no_argument, 0, 'h' }, + { "prio-prefix", no_argument, 0, OPT_PRIO_PREFIX }, { NULL, 0, 0, 0 } }; @@ -271,9 +297,10 @@ main(int argc, char **argv) { tag = NULL; pri = LOG_NOTICE; logflags = 0; + prio_prefix = 0; while ((ch = getopt_long(argc, argv, "f:ip:st:u:dTn:P:Vh", longopts, NULL)) != -1) { - switch((char)ch) { + switch (ch) { case 'f': /* file to log */ if (freopen(optarg, "r", stdin) == NULL) err(EXIT_FAILURE, _("file %s"), @@ -311,6 +338,9 @@ main(int argc, char **argv) { exit(EXIT_SUCCESS); case 'h': usage(stdout); + case OPT_PRIO_PREFIX: + prio_prefix = 1; + break; case '?': default: usage(stderr); @@ -360,6 +390,8 @@ main(int argc, char **argv) { mysyslog(LogSock, logflags, pri, tag, buf); } } else { + char *msg; + int default_priority = pri; while (fgets(buf, sizeof(buf), stdin) != NULL) { /* glibc is buggy and adds an additional newline, so we have to remove it here until glibc is fixed */ @@ -368,10 +400,15 @@ main(int argc, char **argv) { if (len > 0 && buf[len - 1] == '\n') buf[len - 1] = '\0'; + msg = buf; + pri = default_priority; + if (prio_prefix && msg[0] == '<') + msg = get_prio_prefix(msg, &pri); + if (!usock && !server) - syslog(pri, "%s", buf); + syslog(pri, "%s", msg); else - mysyslog(LogSock, logflags, pri, tag, buf); + mysyslog(LogSock, logflags, pri, tag, msg); } } if (!usock && !server)