summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.in38
-rw-r--r--lib/utils_base.c205
-rw-r--r--lib/utils_base.h20
-rw-r--r--plugins/utils.c17
-rw-r--r--plugins/utils.h2
5 files changed, 263 insertions, 19 deletions
diff --git a/configure.in b/configure.in
index 68ac0a0..a4b5e96 100644
--- a/configure.in
+++ b/configure.in
@@ -39,6 +39,39 @@ INSTALL="$INSTALL $extra_install_args"
39INSTALL_STRIP_PROGRAM="$INSTALL_STRIP_PROGRAM $extra_install_args" 39INSTALL_STRIP_PROGRAM="$INSTALL_STRIP_PROGRAM $extra_install_args"
40AC_SUBST(INSTALL) 40AC_SUBST(INSTALL)
41 41
42dnl Configure the plugin output format
43default_output_format="%s %x: %i\n"
44AC_ARG_WITH([standard_output_format],
45 [AS_HELP_STRING([--with-standard-output-format=FORMAT],
46 [specify the standard plugin output FORMAT; %p, %s, %x, and %m
47 will be replaced by the plugin name, the service name, the
48 status string, and the information message, respectively; tabs
49 or newlines can be inserted using \t or \n
50 @<:@default="%s %x: %m\n"@:>@])],
51 [standard_output_format=$withval],
52 [standard_output_format="yes"])
53AC_ARG_WITH([verbose_output_format],
54 [AS_HELP_STRING([--with-verbose-output-format=FORMAT],
55 [specify the verbose plugin output FORMAT; %p, %s, %x, and %m
56 will be replaced by the plugin name, the service name, the
57 status string, and the information message, respectively; tabs
58 or newlines can be inserted using \t or \n
59 @<:@default="%s %x: %m\n"@:>@])],
60 [verbose_output_format=$withval],
61 [verbose_output_format="yes"])
62AS_IF([test "$standard_output_format" = yes],
63 [standard_output_format=$default_output_format],
64 [test "$standard_output_format" = no],
65 [standard_output_format=""],
66 [test "$verbose_output_format" = yes],
67 [verbose_output_format=$default_output_format],
68 [test "$verbose_output_format" = no],
69 [verbose_output_format=""])
70AC_DEFINE_UNQUOTED([STANDARD_OUTPUT_FORMAT], ["$standard_output_format"],
71 [Define the standard plugin output format.])
72AC_DEFINE_UNQUOTED([VERBOSE_OUTPUT_FORMAT], ["$verbose_output_format"],
73 [Define the verbose plugin output format.])
74
42AC_PROG_CC 75AC_PROG_CC
43gl_EARLY 76gl_EARLY
44AC_PROG_GCC_TRADITIONAL 77AC_PROG_GCC_TRADITIONAL
@@ -150,6 +183,11 @@ AC_CHECK_LIB(socket,socket,SOCKETLIBS="$SOCKETLIBS -lsocket")
150AC_CHECK_LIB(resolv,main,SOCKETLIBS="$SOCKETLIBS -lresolv") 183AC_CHECK_LIB(resolv,main,SOCKETLIBS="$SOCKETLIBS -lresolv")
151AC_SUBST(SOCKETLIBS) 184AC_SUBST(SOCKETLIBS)
152 185
186dnl check for basename(3) which needs -lgen on some systems (e.g. IRIX)
187AC_CHECK_HEADERS([libgen.h])
188AC_SEARCH_LIBS([basename], [gen])
189AC_CHECK_FUNCS([basename])
190
153dnl 191dnl
154dnl check for math-related functions needing -lm 192dnl check for math-related functions needing -lm
155AC_CHECK_HEADERS(math.h) 193AC_CHECK_HEADERS(math.h)
diff --git a/lib/utils_base.c b/lib/utils_base.c
index 77700f5..ba4f83b 100644
--- a/lib/utils_base.c
+++ b/lib/utils_base.c
@@ -24,10 +24,151 @@
24* 24*
25*****************************************************************************/ 25*****************************************************************************/
26 26
27#if HAVE_LIBGEN_H
28#include <libgen.h> /* basename(3) */
29#endif
30#include <stdarg.h>
27#include "common.h" 31#include "common.h"
28#include <stdarg.h> 32#include <stdarg.h>
29#include "utils_base.h" 33#include "utils_base.h"
30 34
35#define PRINT_OUTPUT(fmt, ap) \
36 do { \
37 fmt = insert_syserr(fmt); \
38 va_start(ap, fmt); \
39 vprintf(fmt, ap); \
40 va_end(ap); \
41 } while (/* CONSTCOND */ 0)
42
43static char *insert_syserr(const char *);
44
45extern int errno;
46static int verbosity_level = -2;
47static const char *program_name = NULL;
48static const char *service_name = NULL;
49
50/*
51 * Set static variables for use in output functions. Usually, argv[0] may be
52 * used as progname, since we call basename(3) ourselves. If a verbosity value
53 * of -2 is specified, the verbosity_level won't be set. Currently, no flags
54 * are implemented.
55 */
56void
57np_set_output(const char *progname, const char *servname, int verbosity,
58 int flags __attribute__((unused)))
59{
60 static char pathbuf[128], progbuf[128], servbuf[32];
61
62 if (progname != NULL) {
63#if HAVE_BASENAME
64 /*
65 * Copy the progname into a temporary buffer in order to cope
66 * with basename(3) implementations which modify their argument.
67 * TODO: Maybe we should implement an np_basename()? Gnulib's
68 * base_name() dies on error, writing a message to stderr, which
69 * is probably not what we want. Once we have some replacement,
70 * the libgen-/basename(3)-related checks can be removed from
71 * configure.in.
72 */
73 strncpy(pathbuf, progname, sizeof(pathbuf) - 1);
74 pathbuf[sizeof(pathbuf) - 1] = '\0';
75 progname = basename(pathbuf);
76#endif
77 strncpy(progbuf, progname, sizeof(progbuf) - 1);
78 progbuf[sizeof(progbuf) - 1] = '\0';
79 program_name = progbuf;
80 }
81 if (servname != NULL) {
82 strncpy(servbuf, servname, sizeof(servbuf) - 1);
83 servbuf[sizeof(servbuf) - 1] = '\0';
84 service_name = servbuf;
85 }
86 if (verbosity != -2)
87 verbosity_level = verbosity;
88}
89
90int
91np_adjust_verbosity(int by)
92{
93 if (verbosity_level == -2)
94 verbosity_level = by;
95 else
96 verbosity_level += by;
97
98 /* We don't support verbosity levels < -1. */
99 if (verbosity_level < -1)
100 verbosity_level = -1;
101
102 return verbosity_level;
103}
104
105void
106np_debug(int verbosity, const char *fmt, ...)
107{
108 va_list ap;
109
110 if (verbosity_level != -1 && verbosity >= verbosity_level)
111 PRINT_OUTPUT(fmt, ap);
112}
113
114void
115np_verbose(const char *fmt, ...)
116{
117 va_list ap;
118
119 if (verbosity_level >= 1) {
120 PRINT_OUTPUT(fmt, ap);
121 putchar('\n');
122 }
123}
124
125void
126np_die(int status, const char *fmt, ...)
127{
128 va_list ap;
129 const char *p;
130
131 if (program_name == NULL || service_name == NULL)
132 PRINT_OUTPUT(fmt, ap);
133
134 for (p = (verbosity_level > 0) ?
135 VERBOSE_OUTPUT_FORMAT : STANDARD_OUTPUT_FORMAT;
136 *p != '\0'; p++) {
137 if (*p == '%') {
138 if (*++p == '\0')
139 break;
140 switch (*p) {
141 case 'm':
142 PRINT_OUTPUT(fmt, ap);
143 continue;
144 case 'p':
145 fputs(program_name, stdout);
146 continue;
147 case 's':
148 fputs(service_name, stdout);
149 continue;
150 case 'x':
151 fputs(state_text(status), stdout);
152 continue;
153 }
154 } else if (*p == '\\') {
155 if (*++p == '\0')
156 break;
157 switch (*p) {
158 case 'n':
159 putchar('\n');
160 continue;
161 case 't':
162 putchar('\t');
163 continue;
164 }
165 }
166 putchar(*p);
167 }
168 exit(status);
169}
170
171/* TODO: die() can be removed as soon as all plugins use np_die() instead. */
31void 172void
32die (int result, const char *fmt, ...) 173die (int result, const char *fmt, ...)
33{ 174{
@@ -308,3 +449,67 @@ char *np_extract_value(const char *varlist, const char *name, char sep) {
308 return value; 449 return value;
309} 450}
310 451
452/*
453 * Replace occurrences of "%m" by strerror(errno). Other printf(3)-style
454 * conversion specifications will be copied verbatim, including "%%", even if
455 * followed by an "m". Returns a pointer to a static buffer in order to not
456 * fail on memory allocation error.
457 */
458static char *
459insert_syserr(const char *buf)
460{
461 static char newbuf[8192];
462 char *errstr = strerror(errno);
463 size_t errlen = strlen(errstr);
464 size_t copylen;
465 unsigned i, j;
466
467 for (i = 0, j = 0; buf[i] != '\0' && j < sizeof(newbuf) - 2; i++, j++) {
468 if (buf[i] == '%') {
469 if (buf[++i] == 'm') {
470 copylen = (errlen > sizeof(newbuf) - j - 1) ?
471 sizeof(newbuf) - j - 1 : errlen;
472 memcpy(newbuf + j, errstr, copylen);
473 /*
474 * As we'll increment j by 1 after the iteration
475 * anyway, we only increment j by the number of
476 * copied bytes - 1.
477 */
478 j += copylen - 1;
479 continue;
480 } else {
481 /*
482 * The possibility to run into this block is the
483 * reason we checked for j < sizeof(newbuf) - 2
484 * instead of j < sizeof(newbuf) - 1.
485 */
486 newbuf[j++] = '%';
487 if (buf[i] == '\0')
488 break;
489 }
490 }
491 newbuf[j] = buf[i];
492 }
493 newbuf[j] = '\0';
494 return newbuf;
495}
496
497/*
498 * Given a numerical status, return a pointer to the according string.
499 */
500const char *
501state_text(int result)
502{
503 switch (result) {
504 case STATE_OK:
505 return "OK";
506 case STATE_WARNING:
507 return "WARNING";
508 case STATE_CRITICAL:
509 return "CRITICAL";
510 case STATE_DEPENDENT:
511 return "DEPENDENT";
512 default:
513 return "UNKNOWN";
514 }
515}
diff --git a/lib/utils_base.h b/lib/utils_base.h
index f40fdb0..8d0b212 100644
--- a/lib/utils_base.h
+++ b/lib/utils_base.h
@@ -37,6 +37,23 @@ int get_status(double, thresholds *);
37 37
38char *np_escaped_string (const char *); 38char *np_escaped_string (const char *);
39 39
40void np_set_output(const char *, const char *, int, int);
41int np_adjust_verbosity(int);
42void np_debug(int, const char *, ...)
43 __attribute__((format(printf, 2, 3)));
44void np_verbose(const char *, ...)
45 __attribute__((format(printf, 1, 2)));
46void np_die(int, const char *, ...)
47 __attribute__((noreturn, format(printf, 2, 3)));
48
49#define np_verbatim(s) np_verbose("%s", s)
50#define np_increase_verbosity(i) np_adjust_verbosity(i)
51#define np_decrease_verbosity(i) np_adjust_verbosity(-i)
52#define np_get_verbosity() np_adjust_verbosity(0)
53#define np_set_verbosity(v) np_set_output(NULL, NULL, v, 0)
54#define np_set_mynames(p, s) np_set_output(p, s, -2, 0)
55
56/* TODO: die() can be removed as soon as all plugins use np_die() instead. */
40void die (int, const char *, ...) __attribute__((noreturn,format(printf, 2, 3))); 57void die (int, const char *, ...) __attribute__((noreturn,format(printf, 2, 3)));
41 58
42/* Return codes for _set_thresholds */ 59/* Return codes for _set_thresholds */
@@ -64,4 +81,7 @@ char *np_extract_value(const char*, const char*, char);
64 */ 81 */
65#define np_extract_ntpvar(l, n) np_extract_value(l, n, ',') 82#define np_extract_ntpvar(l, n) np_extract_value(l, n, ',')
66 83
84/* Given a numerical status, return a pointer to the according string. */
85const char *state_text(int);
86
67#endif /* _UTILS_BASE_ */ 87#endif /* _UTILS_BASE_ */
diff --git a/plugins/utils.c b/plugins/utils.c
index 4537390..91fa671 100644
--- a/plugins/utils.c
+++ b/plugins/utils.c
@@ -147,23 +147,6 @@ print_revision (const char *command_name, const char *revision)
147 command_name, revision, PACKAGE, VERSION); 147 command_name, revision, PACKAGE, VERSION);
148} 148}
149 149
150const char *
151state_text (int result)
152{
153 switch (result) {
154 case STATE_OK:
155 return "OK";
156 case STATE_WARNING:
157 return "WARNING";
158 case STATE_CRITICAL:
159 return "CRITICAL";
160 case STATE_DEPENDENT:
161 return "DEPENDENT";
162 default:
163 return "UNKNOWN";
164 }
165}
166
167void 150void
168timeout_alarm_handler (int signo) 151timeout_alarm_handler (int signo)
169{ 152{
diff --git a/plugins/utils.h b/plugins/utils.h
index d6e9c8f..9912fbf 100644
--- a/plugins/utils.h
+++ b/plugins/utils.h
@@ -92,8 +92,6 @@ void usage4(const char *) __attribute__((noreturn));
92void usage5(void) __attribute__((noreturn)); 92void usage5(void) __attribute__((noreturn));
93void usage_va(const char *fmt, ...) __attribute__((noreturn)); 93void usage_va(const char *fmt, ...) __attribute__((noreturn));
94 94
95const char *state_text (int);
96
97#define max(a,b) (((a)>(b))?(a):(b)) 95#define max(a,b) (((a)>(b))?(a):(b))
98#define min(a,b) (((a)<(b))?(a):(b)) 96#define min(a,b) (((a)<(b))?(a):(b))
99 97