Implement and document --syslog
authorEmil Mikulic <emikulic@gmail.com>
Wed, 16 Sep 2009 13:01:52 +0000 (23:01 +1000)
committerEmil Mikulic <emikulic@gmail.com>
Wed, 18 Nov 2009 11:55:01 +0000 (22:55 +1100)
Makefile.in
darkstat.8
darkstat.c
err.c
err.h

index 4993aad..fb16631 100644 (file)
@@ -1,5 +1,5 @@
 # darkstat 3
-# copyright (c) 2001-2007 Emil Mikulic.
+# copyright (c) 2001-2009 Emil Mikulic.
 #
 # You may use, modify and redistribute this file under the terms of the
 # GNU General Public License version 2. (see COPYING.GPL)
@@ -100,7 +100,7 @@ db.o: db.c darkstat.h config.h err.h hosts_db.h str.h graph_db.h db.h
 decode.o: decode.c darkstat.h config.h acct.h decode.h cap.h err.h
 dns.o: dns.c darkstat.h config.h conv.h decode.h dns.h err.h hosts_db.h \
   str.h queue.h tree.h
-err.o: err.c darkstat.h config.h err.h pidfile.h
+err.o: err.c darkstat.h config.h conv.h err.h pidfile.h
 graph_db.o: graph_db.c cap.h conv.h darkstat.h config.h db.h acct.h \
   decode.h err.h str.h html.h graph_db.h now.h
 hosts_db.o: hosts_db.c darkstat.h config.h conv.h decode.h dns.h err.h \
index 7391531..081b723 100644 (file)
@@ -20,6 +20,8 @@ darkstat \- network statistics gatherer
 ] [
 .BI \-\-pppoe
 ] [
+.BI \-\-syslog
+] [
 .BI \-\-verbose
 ] [
 .BI \-\-no\-daemon
@@ -115,8 +117,16 @@ argument.
 .RE
 .\"
 .TP
+.BI \-\-syslog
+Errors, warnings, and verbose messages will go to \fBsyslog\fR (facility
+daemon, priority debug) instead of \fBstderr\fR.
+
+On some systems, these messages end up in \fB/var/log/debug\fR or
+\fBdebug.log\fR by default.
+.\"
+.TP
 .BI \-\-verbose
-Print debugging messages to the terminal.
+Output verbose debugging messages.
 .\"
 .TP
 .BI \-\-no\-daemon
index ab3a68c..f079203 100644 (file)
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <syslog.h>
 #include <unistd.h>
 #include <pcap.h>
 
@@ -75,6 +76,8 @@ static void cb_snaplen(const char *arg) { want_snaplen = parsenum(arg, 0); }
 int want_pppoe = 0;
 static void cb_pppoe(const char *arg _unused_) { want_pppoe = 1; }
 
+static void cb_syslog(const char *arg _unused_) { want_syslog = 1; }
+
 static void cb_verbose(const char *arg _unused_) { want_verbose = 1; }
 
 int want_daemonize = 1;
@@ -190,6 +193,7 @@ static struct cmdline_arg cmdline_args[] = {
    {"-r",             "file",            cb_capfile,      0},
    {"--snaplen",      "bytes",           cb_snaplen,      0},
    {"--pppoe",        NULL,              cb_pppoe,        0},
+   {"--syslog",       NULL,              cb_syslog,       0},
    {"--verbose",      NULL,              cb_verbose,      0},
    {"--no-daemon",    NULL,              cb_no_daemon,    0},
    {"--no-promisc",   NULL,              cb_no_promisc,   0},
@@ -257,13 +261,15 @@ parse_sub_cmdline(const int argc, char * const *argv)
    for (arg = cmdline_args; arg->name != NULL; arg++)
       if (strcmp(argv[0], arg->name) == 0) {
          if ((arg->arg_name != NULL) && (argc == 1)) {
-            printf("\nerror: argument \"%s\" requires parameter \"%s\"\n",
+            fprintf(stderr,
+               "error: argument \"%s\" requires parameter \"%s\"\n",
                arg->name, arg->arg_name);
             usage();
             exit(EXIT_FAILURE);
          }
          if (arg->num_seen > 0) {
-            printf("\nerror: already specified argument \"%s\"\n",
+            fprintf(stderr,
+               "error: already specified argument \"%s\"\n",
                arg->name);
             usage();
             exit(EXIT_FAILURE);
@@ -280,7 +286,7 @@ parse_sub_cmdline(const int argc, char * const *argv)
          return;
       }
 
-   printf("\nerror: illegal argument: \"%s\"\n", argv[0]);
+   fprintf(stderr, "error: illegal argument: \"%s\"\n", argv[0]);
    usage();
    exit(EXIT_FAILURE);
 }
@@ -296,6 +302,9 @@ parse_cmdline(const int argc, char * const *argv)
 
    parse_sub_cmdline(argc, argv);
 
+   /* start syslogging as early as possible */
+   if (want_syslog) openlog("darkstat", LOG_NDELAY | LOG_PID, LOG_DAEMON);
+
    /* some default values */
    if (chroot_dir == NULL) chroot_dir = CHROOT_DIR;
    if (privdrop_user == NULL) privdrop_user = PRIVDROP_USER;
diff --git a/err.c b/err.c
index 0628cd7..eb2a24a 100644 (file)
--- a/err.c
+++ b/err.c
@@ -1,5 +1,5 @@
 /* darkstat 3
- * copyright (c) 2001-2008 Emil Mikulic.
+ * copyright (c) 2001-2009 Emil Mikulic.
  *
  * err.c: BSD-like err() and warn() functions
  *
@@ -17,6 +17,7 @@
  */
 
 #include "darkstat.h"
+#include "conv.h"
 #include "err.h"
 #include "pidfile.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <syslog.h>
 #include <unistd.h>
 #include <unistd.h>
 
+static void
+to_syslog(const char *type, const int want_err,
+          const char *format, va_list va)
+{
+   char buf[512];
+   size_t pos = 0;
+   int saved_errno = errno;
+
+   if (type != NULL) {
+      strlcpy(buf, type, sizeof(buf));
+      pos = strlen(buf);
+   }
+   vsnprintf(buf+pos, sizeof(buf)-pos, format, va);
+   if (want_err) {
+      strlcat(buf, ": ", sizeof(buf));
+      strlcat(buf, strerror(saved_errno), sizeof(buf));
+   }
+   syslog(LOG_DEBUG, "%s", buf);
+}
+
 void
 err(const int code, const char *format, ...)
 {
    va_list va;
 
-   fprintf(stderr, "%5d: error: ", (int)getpid());
    va_start(va, format);
-   vfprintf(stderr, format, va);
+   if (want_syslog)
+      to_syslog("ERROR: ", 1, format, va);
+   else {
+      fprintf(stderr, "%5d: error: ", (int)getpid());
+      vfprintf(stderr, format, va);
+      fprintf(stderr, ": %s\n", strerror(errno));
+   }
    va_end(va);
-   fprintf(stderr, ": %s\n", strerror(errno));
    pidfile_unlink();
    exit(code);
 }
@@ -47,11 +73,15 @@ errx(const int code, const char *format, ...)
 {
    va_list va;
 
-   fprintf(stderr, "%5d: error: ", (int)getpid());
    va_start(va, format);
-   vfprintf(stderr, format, va);
+   if (want_syslog)
+      to_syslog("ERROR: ", 0, format, va);
+   else {
+      fprintf(stderr, "%5d: error: ", (int)getpid());
+      vfprintf(stderr, format, va);
+      fprintf(stderr, "\n");
+   }
    va_end(va);
-   fprintf(stderr, "\n");
    pidfile_unlink();
    exit(code);
 }
@@ -61,11 +91,15 @@ warn(const char *format, ...)
 {
    va_list va;
 
-   fprintf(stderr, "%5d: warning: ", (int)getpid());
    va_start(va, format);
-   vfprintf(stderr, format, va);
+   if (want_syslog)
+      to_syslog("WARNING: ", 1, format, va);
+   else {
+      fprintf(stderr, "%5d: warning: ", (int)getpid());
+      vfprintf(stderr, format, va);
+      fprintf(stderr, ": %s\n", strerror(errno));
+   }
    va_end(va);
-   fprintf(stderr, ": %s\n", strerror(errno));
 }
 
 void
@@ -73,11 +107,15 @@ warnx(const char *format, ...)
 {
    va_list va;
 
-   fprintf(stderr, "%5d: warning: ", (int)getpid());
    va_start(va, format);
-   vfprintf(stderr, format, va);
+   if (want_syslog)
+      to_syslog("WARNING: ", 0, format, va);
+   else {
+      fprintf(stderr, "%5d: warning: ", (int)getpid());
+      vfprintf(stderr, format, va);
+      fprintf(stderr, "\n");
+   }
    va_end(va);
-   fprintf(stderr, "\n");
 }
 
 /* We interlock verbosef() between processes by using a pipe with a single
@@ -127,7 +165,7 @@ unlock(void)
    }
 }
 
-int want_verbose = 0;
+int want_verbose = 0, want_syslog = 0;
 
 void
 verbosef(const char *format, ...)
@@ -135,13 +173,17 @@ verbosef(const char *format, ...)
    va_list va;
 
    if (!want_verbose) return;
-   lock();
-   fprintf(stderr, "darkstat (%05d): ", (int)getpid());
    va_start(va, format);
-   vfprintf(stderr, format, va);
+   if (want_syslog)
+      to_syslog(NULL, 0, format, va);
+   else {
+      lock();
+      fprintf(stderr, "darkstat (%05d): ", (int)getpid());
+      vfprintf(stderr, format, va);
+      fprintf(stderr, "\n");
+      unlock();
+   }
    va_end(va);
-   fprintf(stderr, "\n");
-   unlock();
 }
 
 void
diff --git a/err.h b/err.h
index 26ee7d8..14276ff 100644 (file)
--- a/err.h
+++ b/err.h
@@ -1,5 +1,5 @@
 /* darkstat 3
- * copyright (c) 2001-2008 Emil Mikulic.
+ * copyright (c) 2001-2009 Emil Mikulic.
  *
  * err.h: BSD-like err() and warn() functions
  *
@@ -22,7 +22,7 @@ void errx(const int code, const char *format, ...) _noreturn_;
 void warn(const char *format, ...);
 void warnx(const char *format, ...);
 
-extern int want_verbose;
+extern int want_verbose, want_syslog;
 void verbosef(const char *format, ...);
 void dverbosef(const char *format _unused_, ...);