From 6b7d70a8a57d0a68f473ab6b245cd4ae2dd672e8 Mon Sep 17 00:00:00 2001 From: Steve Dickson Date: Wed, 4 Feb 2015 10:05:27 -0500 Subject: rpcbind: Introduce the xlog logging code To improve rpcbind's debugging the xlog code from the nfs-utils package has been ported. Signed-off-by: Steve Dickson --- Makefile.am | 3 +- src/xlog.c | 234 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/xlog.h | 52 ++++++++++++++ 3 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 src/xlog.c create mode 100644 src/xlog.h diff --git a/Makefile.am b/Makefile.am index ea5725f..3add1e3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -38,7 +38,8 @@ rpcbind_SOURCES = \ src/rpcbind.h \ src/security.c \ src/util.c \ - src/warmstart.c + src/warmstart.c \ + src/xlog.c rpcbind_LDADD = $(TIRPC_LIBS) if SYSTEMD diff --git a/src/xlog.c b/src/xlog.c new file mode 100644 index 0000000..ab6c717 --- /dev/null +++ b/src/xlog.c @@ -0,0 +1,234 @@ +/* + * support/nfs/xlog.c + * + * This module handles the logging of requests. + * + * TODO: Merge the two "XXX_log() calls. + * + * Authors: Donald J. Becker, + * Rick Sladkey, + * Fred N. van Kempen, + * Olaf Kirch, + * + * This software maybe be used for any purpose provided + * the above copyright notice is retained. It is supplied + * as is, with no warranty expressed or implied. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xlog.h" + +#undef VERBOSE_PRINTF + +static int log_stderr = 1; +static int log_syslog = 1; +static int logging = 0; /* enable/disable DEBUG logs */ +static int logmask = 0; /* What will be logged */ +static char log_name[256]; /* name of this program */ +static int log_pid = -1; /* PID of this program */ + +int export_errno = 0; + +static void xlog_toggle(int sig); +static struct xlog_debugfac debugnames[] = { + { "general", D_GENERAL, }, + { "call", D_CALL, }, + { "auth", D_AUTH, }, + { "parse", D_PARSE, }, + { "all", D_ALL, }, + { NULL, 0, }, +}; + +void +xlog_open(char *progname) +{ + openlog(progname, LOG_PID, LOG_DAEMON); + + strncpy(log_name, progname, sizeof (log_name) - 1); + log_name [sizeof (log_name) - 1] = '\0'; + log_pid = getpid(); + + signal(SIGUSR1, xlog_toggle); + signal(SIGUSR2, xlog_toggle); +} + +void +xlog_stderr(int on) +{ + log_stderr = on; +} + +void +xlog_syslog(int on) +{ + log_syslog = on; +} + +static void +xlog_toggle(int sig) +{ + unsigned int tmp, i; + + if (sig == SIGUSR1) { + if ((logmask & D_ALL) && !logging) { + xlog(D_GENERAL, "turned on logging"); + logging = 1; + return; + } + tmp = ~logmask; + logmask |= ((logmask & D_ALL) << 1) | D_GENERAL; + for (i = -1, tmp &= logmask; tmp; tmp >>= 1, i++) + if (tmp & 1) + xlog(D_GENERAL, + "turned on logging level %d", i); + } else { + xlog(D_GENERAL, "turned off logging"); + logging = 0; + } + signal(sig, xlog_toggle); +} + +void +xlog_config(int fac, int on) +{ + if (on) + logmask |= fac; + else + logmask &= ~fac; + if (on) + logging = 1; +} + +void +xlog_sconfig(char *kind, int on) +{ + struct xlog_debugfac *tbl = debugnames; + + while (tbl->df_name != NULL && strcasecmp(tbl->df_name, kind)) + tbl++; + if (!tbl->df_name) { + xlog (L_WARNING, "Invalid debug facility: %s\n", kind); + return; + } + xlog_config(tbl->df_fac, on); +} + +int +xlog_enabled(int fac) +{ + return (logging && (fac & logmask)); +} + + +/* Write something to the system logfile and/or stderr */ +void +xlog_backend(int kind, const char *fmt, va_list args) +{ + va_list args2; + + if (!(kind & (L_ALL)) && !(logging && (kind & logmask))) + return; + + if (log_stderr) + va_copy(args2, args); + + if (log_syslog) { + switch (kind) { + case L_FATAL: + vsyslog(LOG_ERR, fmt, args); + break; + case L_ERROR: + vsyslog(LOG_ERR, fmt, args); + break; + case L_WARNING: + vsyslog(LOG_WARNING, fmt, args); + break; + case L_NOTICE: + vsyslog(LOG_NOTICE, fmt, args); + break; + default: + if (!log_stderr) + vsyslog(LOG_INFO, fmt, args); + break; + } + } + + if (log_stderr) { +#ifdef VERBOSE_PRINTF + time_t now; + struct tm *tm; + + time(&now); + tm = localtime(&now); + fprintf(stderr, "%s[%d] %04d-%02d-%02d %02d:%02d:%02d ", + log_name, log_pid, + tm->tm_year+1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); +#else + fprintf(stderr, "%s: ", log_name); +#endif + vfprintf(stderr, fmt, args2); + fprintf(stderr, "\n"); + va_end(args2); + } + + if (kind == L_FATAL) + exit(1); +} + +void +xlog(int kind, const char* fmt, ...) +{ + va_list args; + + if (kind & (L_ERROR|D_GENERAL)) + export_errno = 1; + + va_start(args, fmt); + xlog_backend(kind, fmt, args); + va_end(args); +} + +void +xlog_warn(const char* fmt, ...) +{ + va_list args; + + va_start(args, fmt); + xlog_backend(L_WARNING, fmt, args); + va_end(args); +} + + +void +xlog_err(const char* fmt, ...) +{ + va_list args; + + va_start(args, fmt); + xlog_backend(L_FATAL, fmt, args); + va_end(args); +} + +void +xlog_errno(int err, const char *fmt, ...) +{ + va_list args; + + errno = err; + va_start(args, fmt); + xlog_backend(L_FATAL, fmt, args); + va_end(args); +} diff --git a/src/xlog.h b/src/xlog.h new file mode 100644 index 0000000..a57b96c --- /dev/null +++ b/src/xlog.h @@ -0,0 +1,52 @@ +/* + * xlog Logging functionality + * + * Copyright (C) 1995 Olaf Kirch + */ + +#ifndef XLOG_H +#define XLOG_H + +#include + +/* These are logged always. L_FATAL also does exit(1) */ +#define L_FATAL 0x0100 +#define L_ERROR 0x0200 +#define L_WARNING 0x0400 +#define L_NOTICE 0x0800 +#define L_ALL 0xFF00 + +/* These are logged if enabled with xlog_[s]config */ +/* NB: code does not expect ORing together D_ and L_ */ +#define D_GENERAL 0x0001 /* general debug info */ +#define D_CALL 0x0002 +#define D_AUTH 0x0004 +#define D_FAC3 0x0008 +#define D_FAC4 0x0010 +#define D_FAC5 0x0020 +#define D_PARSE 0x0040 +#define D_FAC7 0x0080 +#define D_ALL 0x00FF + +/* This can be used to define symbolic log names that can be passed to + * xlog_config. + */ +struct xlog_debugfac { + char *df_name; + int df_fac; +}; + +extern int export_errno; +void xlog_open(char *progname); +void xlog_stderr(int on); +void xlog_syslog(int on); +void xlog_config(int fac, int on); +void xlog_sconfig(char *, int on); +int xlog_enabled(int fac); +void xlog(int fac, const char *fmt, ...); +void xlog_warn(const char *fmt, ...); +void xlog_err(const char *fmt, ...); +void xlog_errno(int err, const char *fmt, ...); +void xlog_backend(int fac, const char *fmt, va_list args); + +#endif /* XLOG_H */ -- cgit v1.2.1