commit 5d1e46fefa12eae9fd7e6321b0ab1c8f4a304fa3
Author: sin <[email protected]>
Date:   Thu Dec 4 11:34:39 2014 +0000

    Implement POSIX 2008 compliant logger(1)

diff --git a/Makefile b/Makefile
index 6c526db..d27583b 100644
--- a/Makefile
+++ b/Makefile
@@ -85,6 +85,7 @@ BIN =\
        kill\
        link\
        ln\
+       logger\
        logname\
        ls\
        md5sum\
diff --git a/README b/README
index 0057949..d2728c1 100644
--- a/README
+++ b/README
@@ -36,6 +36,7 @@ hostname
 kill            yes                             none
 link
 ln
+logger         yes
 logname
 ls
 md5sum
diff --git a/TODO b/TODO
index 0b9dcc2..af5cfec 100644
--- a/TODO
+++ b/TODO
@@ -13,7 +13,6 @@ find
 getconf
 install
 join
-logger
 make
 od
 patch
diff --git a/logger.1 b/logger.1
new file mode 100644
index 0000000..99d76a7
--- /dev/null
+++ b/logger.1
@@ -0,0 +1,50 @@
+.Dd December 4, 2014
+.Dt LOGGER 1 sbase\-VERSION
+.Os
+.Sh NAME
+.Nm logger
+.Nd make entries in the system log
+.Sh SYNOPSIS
+.Nm logger
+.Op Fl is
+.Op Fl p Ar priority
+.Op Fl t Ar tag
+.Op Ar message ...
+.Sh DESCRIPTION
+.Nm
+provides a shell command interface to the
+.Xr syslog 3
+system log module.
+.Pp
+.Sh OPTIONS
+.Bl -tag -width xxxxxxxxxxxx
+.It Fl i
+Log the process ID of the logger process with each line.
+.It Fl p Ar priority
+Enter the message with the specified priority.  They priority
+has to be specified symbolically as
+.Dq facility.level
+pair.  The default is
+.Dq user.notice .
+.It Fl s
+Log the message to standard error, as well as the system log.
+.It Fl t Ar tag
+Mark every line in the log with the specified
+.Ar tag .
+.It Ar message
+Write the message to the log; if not specified, standard input
+is logged.
+.El
+.Sh SEE ALSO
+.Xr syslog 3 ,
+.Xr syslogd 1
+.Sh STANDARDS
+The
+.Nm
+utility is compliant with the
+.St -p1003.1-2008
+specification.
+.Pp
+The flags
+.Op Fl ipst
+are extensions to that specification.
diff --git a/logger.c b/logger.c
new file mode 100644
index 0000000..b276837
--- /dev/null
+++ b/logger.c
@@ -0,0 +1,106 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#define SYSLOG_NAMES
+#include <syslog.h>
+#include <unistd.h>
+
+#include "util.h"
+
+int
+decodefac(char *fac)
+{
+       CODE *c;
+       int facility = -1;
+
+       for (c = facilitynames; c->c_name; c++)
+               if (!strcasecmp(fac, c->c_name))
+                       facility = c->c_val;
+       if (facility == -1)
+               eprintf("invalid facility name: %s\n", fac);
+       return facility & LOG_FACMASK;
+}
+
+int
+decodelev(char *lev)
+{
+       CODE *c;
+       int level = -1;
+
+       for (c = prioritynames; c->c_name; c++)
+               if (!strcasecmp(lev, c->c_name))
+                       level = c->c_val;
+       if (level == -1)
+               eprintf("invalid level name: %s\n", lev);
+       return level & LOG_PRIMASK;
+}
+
+int
+decodepri(char *pri)
+{
+       char *p;
+
+       if (!(p = strchr(pri, '.')))
+               eprintf("invalid priority name: %s\n", pri);
+       *p++ = '\0';
+       if (!*p)
+               eprintf("invalid priority name: %s\n", pri);
+       return decodefac(pri) | decodelev(p);
+}
+
+static void
+usage(void)
+{
+       eprintf("usage: %s [-is] [-p priority] [-t tag] [message ...]\n", 
argv0);
+}
+
+int
+main(int argc, char *argv[])
+{
+       char *buf = NULL, *tag = NULL;
+       size_t sz = 0;
+       int logflags = 0, priority = LOG_NOTICE;
+       int i;
+
+       ARGBEGIN {
+       case 'i':
+               logflags |= LOG_PID;
+               break;
+       case 'p':
+               priority = decodepri(EARGF(usage()));
+               break;
+       case 's':
+               logflags |= LOG_PERROR;
+               break;
+       case 't':
+               tag = EARGF(usage());
+               break;
+       default:
+               usage();
+       } ARGEND;
+
+       openlog(tag ? tag : getlogin(), logflags, 0);
+
+       if (argc == 0) {
+               while(getline(&buf, &sz, stdin) != -1)
+                       syslog(priority, "%s", buf);
+               if (ferror(stdin))
+                       eprintf("%s: read error:", "<stdin>");
+       } else {
+               for (i = 0; i < argc; i++)
+                       sz += strlen(argv[i]);
+               sz += argc;
+               buf = ecalloc(1, sz);
+               for (i = 0; i < argc; i++) {
+                       strlcat(buf, argv[i], sz);
+                       if (i + 1 < argc)
+                               strlcat(buf, " ", sz);
+               }
+               syslog(priority, "%s", buf);
+       }
+       free(buf);
+       closelog();
+       return 0;
+}


Reply via email to