diff options
-rw-r--r-- | configure.in | 38 | ||||
-rw-r--r-- | lib/utils_base.c | 202 | ||||
-rw-r--r-- | lib/utils_base.h | 19 | ||||
-rw-r--r-- | plugins/utils.c | 17 | ||||
-rw-r--r-- | plugins/utils.h | 2 |
5 files changed, 259 insertions, 19 deletions
diff --git a/configure.in b/configure.in index 9067978a..474522d4 100644 --- a/configure.in +++ b/configure.in | |||
@@ -40,6 +40,39 @@ INSTALL="$INSTALL $extra_install_args" | |||
40 | INSTALL_STRIP_PROGRAM="$INSTALL_STRIP_PROGRAM $extra_install_args" | 40 | INSTALL_STRIP_PROGRAM="$INSTALL_STRIP_PROGRAM $extra_install_args" |
41 | AC_SUBST(INSTALL) | 41 | AC_SUBST(INSTALL) |
42 | 42 | ||
43 | dnl Configure the plugin output format | ||
44 | default_output_format="%s %x: %i\n" | ||
45 | AC_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"]) | ||
54 | AC_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"]) | ||
63 | AS_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=""]) | ||
71 | AC_DEFINE_UNQUOTED([STANDARD_OUTPUT_FORMAT], ["$standard_output_format"], | ||
72 | [Define the standard plugin output format.]) | ||
73 | AC_DEFINE_UNQUOTED([VERBOSE_OUTPUT_FORMAT], ["$verbose_output_format"], | ||
74 | [Define the verbose plugin output format.]) | ||
75 | |||
43 | AC_PROG_CC | 76 | AC_PROG_CC |
44 | gl_EARLY | 77 | gl_EARLY |
45 | AC_PROG_GCC_TRADITIONAL | 78 | AC_PROG_GCC_TRADITIONAL |
@@ -147,6 +180,11 @@ AC_CHECK_LIB(socket,socket,SOCKETLIBS="$SOCKETLIBS -lsocket") | |||
147 | AC_CHECK_LIB(resolv,main,SOCKETLIBS="$SOCKETLIBS -lresolv") | 180 | AC_CHECK_LIB(resolv,main,SOCKETLIBS="$SOCKETLIBS -lresolv") |
148 | AC_SUBST(SOCKETLIBS) | 181 | AC_SUBST(SOCKETLIBS) |
149 | 182 | ||
183 | dnl check for basename(3) which needs -lgen on some systems (e.g. IRIX) | ||
184 | AC_CHECK_HEADERS([libgen.h]) | ||
185 | AC_SEARCH_LIBS([basename], [gen]) | ||
186 | AC_CHECK_FUNCS([basename]) | ||
187 | |||
150 | dnl | 188 | dnl |
151 | dnl check for math-related functions needing -lm | 189 | dnl check for math-related functions needing -lm |
152 | AC_CHECK_HEADERS(math.h) | 190 | AC_CHECK_HEADERS(math.h) |
diff --git a/lib/utils_base.c b/lib/utils_base.c index fbed3607..7eada0cc 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 | |||
30 | static char *insert_syserr(const char *); | ||
31 | |||
32 | extern int errno; | ||
33 | static int verbosity_level = -2; | ||
34 | static const char *program_name = NULL; | ||
35 | static 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 | */ | ||
43 | void | ||
44 | np_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 | |||
77 | int | ||
78 | np_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 | |||
92 | void | ||
93 | np_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 | |||
101 | void | ||
102 | np_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 | |||
112 | void | ||
113 | np_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. */ | ||
19 | void | 159 | void |
20 | die (int result, const char *fmt, ...) | 160 | die (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 | |||
387 | const char * | ||
388 | state_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 | */ | ||
410 | static char * | ||
411 | insert_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 bda76595..b6e8128b 100644 --- a/lib/utils_base.h +++ b/lib/utils_base.h | |||
@@ -37,6 +37,23 @@ int get_status(double, thresholds *); | |||
37 | 37 | ||
38 | char *np_escaped_string (const char *); | 38 | char *np_escaped_string (const char *); |
39 | 39 | ||
40 | void np_set_output(const char *, const char *, int, int); | ||
41 | int np_adjust_verbosity(int); | ||
42 | void np_debug(int, const char *, ...) | ||
43 | __attribute__((format(printf, 2, 3))); | ||
44 | void np_verbose(const char *, ...) | ||
45 | __attribute__((format(printf, 1, 2))); | ||
46 | void 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. */ | ||
40 | void die (int, const char *, ...) __attribute__((noreturn,format(printf, 2, 3))); | 57 | void 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 */ |
51 | int np_warn_if_not_root(void); | 68 | int np_warn_if_not_root(void); |
52 | 69 | ||
70 | const char *state_text(int); | ||
71 | |||
53 | #endif /* _UTILS_BASE_ */ | 72 | #endif /* _UTILS_BASE_ */ |
diff --git a/plugins/utils.c b/plugins/utils.c index 0e79fbdb..5967647a 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 | ||
124 | const char * | ||
125 | state_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 | |||
141 | void | 124 | void |
142 | timeout_alarm_handler (int signo) | 125 | timeout_alarm_handler (int signo) |
143 | { | 126 | { |
diff --git a/plugins/utils.h b/plugins/utils.h index f15a7b16..98d19d20 100644 --- a/plugins/utils.h +++ b/plugins/utils.h | |||
@@ -84,8 +84,6 @@ void usage4(const char *) __attribute__((noreturn)); | |||
84 | void usage5(void) __attribute__((noreturn)); | 84 | void usage5(void) __attribute__((noreturn)); |
85 | void usage_va(const char *fmt, ...) __attribute__((noreturn)); | 85 | void usage_va(const char *fmt, ...) __attribute__((noreturn)); |
86 | 86 | ||
87 | const 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 | ||