summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.in38
-rw-r--r--lib/utils_base.c202
-rw-r--r--lib/utils_base.h19
-rw-r--r--plugins/utils.c17
-rw-r--r--plugins/utils.h2
5 files changed, 259 insertions, 19 deletions
diff --git a/configure.in b/configure.in
index 9067978..474522d 100644
--- a/configure.in
+++ b/configure.in
@@ -40,6 +40,39 @@ INSTALL="$INSTALL $extra_install_args"
40INSTALL_STRIP_PROGRAM="$INSTALL_STRIP_PROGRAM $extra_install_args" 40INSTALL_STRIP_PROGRAM="$INSTALL_STRIP_PROGRAM $extra_install_args"
41AC_SUBST(INSTALL) 41AC_SUBST(INSTALL)
42 42
43dnl Configure the plugin output format
44default_output_format="%s %x: %i\n"
45AC_ARG_WITH([standard_output_format],
46 [AS_HELP_STRING([--with-standard-output-format=FORMAT],
47 [specify the standard plugin output FORMAT; %p, %s, %x, and %m
48 will be replaced by the plugin name, the service name, the
49 status string, and the information message, respectively; tabs
50 or newlines can be inserted using \t or \n
51 @<:@default="%s %x: %m\n"@:>@])],
52 [standard_output_format=$withval],
53 [standard_output_format="yes"])
54AC_ARG_WITH([verbose_output_format],
55 [AS_HELP_STRING([--with-verbose-output-format=FORMAT],
56 [specify the verbose plugin output FORMAT; %p, %s, %x, and %m
57 will be replaced by the plugin name, the service name, the
58 status string, and the information message, respectively; tabs
59 or newlines can be inserted using \t or \n
60 @<:@default="%s %x: %m\n"@:>@])],
61 [verbose_output_format=$withval],
62 [verbose_output_format="yes"])
63AS_IF([test "$standard_output_format" = yes],
64 [standard_output_format=$default_output_format],
65 [test "$standard_output_format" = no],
66 [standard_output_format=""],
67 [test "$verbose_output_format" = yes],
68 [verbose_output_format=$default_output_format],
69 [test "$verbose_output_format" = no],
70 [verbose_output_format=""])
71AC_DEFINE_UNQUOTED([STANDARD_OUTPUT_FORMAT], ["$standard_output_format"],
72 [Define the standard plugin output format.])
73AC_DEFINE_UNQUOTED([VERBOSE_OUTPUT_FORMAT], ["$verbose_output_format"],
74 [Define the verbose plugin output format.])
75
43AC_PROG_CC 76AC_PROG_CC
44gl_EARLY 77gl_EARLY
45AC_PROG_GCC_TRADITIONAL 78AC_PROG_GCC_TRADITIONAL
@@ -147,6 +180,11 @@ AC_CHECK_LIB(socket,socket,SOCKETLIBS="$SOCKETLIBS -lsocket")
147AC_CHECK_LIB(resolv,main,SOCKETLIBS="$SOCKETLIBS -lresolv") 180AC_CHECK_LIB(resolv,main,SOCKETLIBS="$SOCKETLIBS -lresolv")
148AC_SUBST(SOCKETLIBS) 181AC_SUBST(SOCKETLIBS)
149 182
183dnl check for basename(3) which needs -lgen on some systems (e.g. IRIX)
184AC_CHECK_HEADERS([libgen.h])
185AC_SEARCH_LIBS([basename], [gen])
186AC_CHECK_FUNCS([basename])
187
150dnl 188dnl
151dnl check for math-related functions needing -lm 189dnl check for math-related functions needing -lm
152AC_CHECK_HEADERS(math.h) 190AC_CHECK_HEADERS(math.h)
diff --git a/lib/utils_base.c b/lib/utils_base.c
index fbed360..7eada0c 100644
--- a/lib/utils_base.c
+++ b/lib/utils_base.c
@@ -12,10 +12,150 @@
12 * $Date$ 12 * $Date$
13 ****************************************************************************/ 13 ****************************************************************************/
14 14
15#if HAVE_LIBGEN_H
16#include <libgen.h> /* basename(3) */
17#endif
15#include <stdarg.h> 18#include <stdarg.h>
16#include "common.h" 19#include "common.h"
17#include "utils_base.h" 20#include "utils_base.h"
18 21
22#define PRINT_OUTPUT(fmt, ap) \
23 do { \
24 fmt = insert_syserr(fmt); \
25 va_start(ap, fmt); \
26 vprintf(fmt, ap); \
27 va_end(ap); \
28 } while (/* CONSTCOND */ 0)
29
30static char *insert_syserr(const char *);
31
32extern int errno;
33static int verbosity_level = -2;
34static const char *program_name = NULL;
35static const char *service_name = NULL;
36
37/*
38 * Set static variables for use in output functions. Usually, argv[0] may be
39 * used as progname, since we call basename(3) ourselves. If a verbosity value
40 * of -2 is specified, the verbosity_level won't be set. Currently, no flags
41 * are implemented.
42 */
43void
44np_set_output(const char *progname, const char *servname, int verbosity,
45 int flags __attribute__((unused)))
46{
47 static char pathbuf[128], progbuf[128], servbuf[32];
48
49 if (progname != NULL) {
50#if HAVE_BASENAME
51 /*
52 * Copy the progname into a temporary buffer in order to cope
53 * with basename(3) implementations which modify their argument.
54 * TODO: Maybe we should implement an np_basename()? Gnulib's
55 * base_name() dies on error, writing a message to stderr, which
56 * is probably not what we want. Once we have some replacement,
57 * the libgen-/basename(3)-related checks can be removed from
58 * configure.in.
59 */
60 strncpy(pathbuf, progname, sizeof(pathbuf) - 1);
61 pathbuf[sizeof(pathbuf) - 1] = '\0';
62 progname = basename(pathbuf);
63#endif
64 strncpy(progbuf, progname, sizeof(progbuf) - 1);
65 progbuf[sizeof(progbuf) - 1] = '\0';
66 program_name = progbuf;
67 }
68 if (servname != NULL) {
69 strncpy(servbuf, servname, sizeof(servbuf) - 1);
70 servbuf[sizeof(servbuf) - 1] = '\0';
71 service_name = servbuf;
72 }
73 if (verbosity != -2)
74 verbosity_level = verbosity;
75}
76
77int
78np_adjust_verbosity(int by)
79{
80 if (verbosity_level == -2)
81 verbosity_level = by;
82 else
83 verbosity_level += by;
84
85 /* We don't support verbosity levels < -1. */
86 if (verbosity_level < -1)
87 verbosity_level = -1;
88
89 return verbosity_level;
90}
91
92void
93np_debug(int verbosity, const char *fmt, ...)
94{
95 va_list ap;
96
97 if (verbosity_level != -1 && verbosity >= verbosity_level)
98 PRINT_OUTPUT(fmt, ap);
99}
100
101void
102np_verbose(const char *fmt, ...)
103{
104 va_list ap;
105
106 if (verbosity_level >= 1) {
107 PRINT_OUTPUT(fmt, ap);
108 putchar('\n');
109 }
110}
111
112void
113np_die(int status, const char *fmt, ...)
114{
115 va_list ap;
116 const char *p;
117
118 if (program_name == NULL || service_name == NULL)
119 PRINT_OUTPUT(fmt, ap);
120
121 for (p = (verbosity_level > 0) ?
122 VERBOSE_OUTPUT_FORMAT : STANDARD_OUTPUT_FORMAT;
123 *p != '\0'; p++) {
124 if (*p == '%') {
125 if (*++p == '\0')
126 break;
127 switch (*p) {
128 case 'm':
129 PRINT_OUTPUT(fmt, ap);
130 continue;
131 case 'p':
132 fputs(program_name, stdout);
133 continue;
134 case 's':
135 fputs(service_name, stdout);
136 continue;
137 case 'x':
138 fputs(state_text(status), stdout);
139 continue;
140 }
141 } else if (*p == '\\') {
142 if (*++p == '\0')
143 break;
144 switch (*p) {
145 case 'n':
146 putchar('\n');
147 continue;
148 case 't':
149 putchar('\t');
150 continue;
151 }
152 }
153 putchar(*p);
154 }
155 exit(status);
156}
157
158/* TODO: die() can be removed as soon as all plugins use np_die() instead. */
19void 159void
20die (int result, const char *fmt, ...) 160die (int result, const char *fmt, ...)
21{ 161{
@@ -243,3 +383,65 @@ int np_warn_if_not_root(void) {
243 } 383 }
244 return status; 384 return status;
245} 385}
386
387const char *
388state_text(int result)
389{
390 switch (result) {
391 case STATE_OK:
392 return "OK";
393 case STATE_WARNING:
394 return "WARNING";
395 case STATE_CRITICAL:
396 return "CRITICAL";
397 case STATE_DEPENDENT:
398 return "DEPENDENT";
399 default:
400 return "UNKNOWN";
401 }
402}
403
404/*
405 * Replace occurrences of "%m" by strerror(errno). Other printf(3)-style
406 * conversion specifications will be copied verbatim, including "%%", even if
407 * followed by an "m". Returns a static buffer in order to not fail on memory
408 * allocation error.
409 */
410static char *
411insert_syserr(const char *buf)
412{
413 static char newbuf[8192];
414 char *errstr = strerror(errno);
415 size_t errlen = strlen(errstr);
416 size_t copylen;
417 unsigned i, j;
418
419 for (i = 0, j = 0; buf[i] != '\0' && j < sizeof(newbuf) - 2; i++, j++) {
420 if (buf[i] == '%') {
421 if (buf[++i] == 'm') {
422 copylen = (errlen > sizeof(newbuf) - j - 1) ?
423 sizeof(newbuf) - j - 1 : errlen;
424 memcpy(newbuf + j, errstr, copylen);
425 /*
426 * As we'll increment j by 1 after the iteration
427 * anyway, we only increment j by the number of
428 * copied bytes - 1.
429 */
430 j += copylen - 1;
431 continue;
432 } else {
433 /*
434 * The possibility to run into this block is the
435 * reason we checked for j < sizeof(newbuf) - 2
436 * instead of j < sizeof(newbuf) - 1.
437 */
438 newbuf[j++] = '%';
439 if (buf[i] == '\0')
440 break;
441 }
442 }
443 newbuf[j] = buf[i];
444 }
445 newbuf[j] = '\0';
446 return newbuf;
447}
diff --git a/lib/utils_base.h b/lib/utils_base.h
index bda7659..b6e8128 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 */
@@ -50,4 +67,6 @@ int np_check_if_root(void);
50 * code from the above function, in case it's helpful for testing */ 67 * code from the above function, in case it's helpful for testing */
51int np_warn_if_not_root(void); 68int np_warn_if_not_root(void);
52 69
70const char *state_text(int);
71
53#endif /* _UTILS_BASE_ */ 72#endif /* _UTILS_BASE_ */
diff --git a/plugins/utils.c b/plugins/utils.c
index 0e79fbd..5967647 100644
--- a/plugins/utils.c
+++ b/plugins/utils.c
@@ -121,23 +121,6 @@ print_revision (const char *command_name, const char *revision_string)
121 command_name, clean_revstring(revision_string), PACKAGE, VERSION); 121 command_name, clean_revstring(revision_string), PACKAGE, VERSION);
122} 122}
123 123
124const char *
125state_text (int result)
126{
127 switch (result) {
128 case STATE_OK:
129 return "OK";
130 case STATE_WARNING:
131 return "WARNING";
132 case STATE_CRITICAL:
133 return "CRITICAL";
134 case STATE_DEPENDENT:
135 return "DEPENDENT";
136 default:
137 return "UNKNOWN";
138 }
139}
140
141void 124void
142timeout_alarm_handler (int signo) 125timeout_alarm_handler (int signo)
143{ 126{
diff --git a/plugins/utils.h b/plugins/utils.h
index f15a7b1..98d19d2 100644
--- a/plugins/utils.h
+++ b/plugins/utils.h
@@ -84,8 +84,6 @@ void usage4(const char *) __attribute__((noreturn));
84void usage5(void) __attribute__((noreturn)); 84void usage5(void) __attribute__((noreturn));
85void usage_va(const char *fmt, ...) __attribute__((noreturn)); 85void usage_va(const char *fmt, ...) __attribute__((noreturn));
86 86
87const char *state_text (int);
88
89#define max(a,b) (((a)>(b))?(a):(b)) 87#define max(a,b) (((a)>(b))?(a):(b))
90#define min(a,b) (((a)<(b))?(a):(b)) 88#define min(a,b) (((a)<(b))?(a):(b))
91 89