summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/maxfd.c26
-rw-r--r--lib/maxfd.h9
-rw-r--r--lib/utils_base.c33
-rw-r--r--lib/utils_base.h4
-rw-r--r--lib/utils_cmd.c29
-rw-r--r--lib/utils_cmd.h13
-rw-r--r--lib/utils_disk.c61
-rw-r--r--lib/utils_disk.h8
9 files changed, 153 insertions, 32 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 01d73a6..1a47395 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -7,7 +7,7 @@ noinst_LIBRARIES = libmonitoringplug.a
7AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \ 7AM_CPPFLAGS = -DNP_STATE_DIR_PREFIX=\"$(localstatedir)\" \
8 -I$(srcdir) -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins 8 -I$(srcdir) -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/plugins
9 9
10libmonitoringplug_a_SOURCES = utils_base.c utils_disk.c utils_tcp.c utils_cmd.c 10libmonitoringplug_a_SOURCES = utils_base.c utils_disk.c utils_tcp.c utils_cmd.c maxfd.c
11EXTRA_DIST = utils_base.h utils_disk.h utils_tcp.h utils_cmd.h parse_ini.h extra_opts.h 11EXTRA_DIST = utils_base.h utils_disk.h utils_tcp.h utils_cmd.h parse_ini.h extra_opts.h
12 12
13if USE_PARSE_INI 13if USE_PARSE_INI
diff --git a/lib/maxfd.c b/lib/maxfd.c
new file mode 100644
index 0000000..529b356
--- /dev/null
+++ b/lib/maxfd.c
@@ -0,0 +1,26 @@
1#include "./maxfd.h"
2#include <errno.h>
3
4long mp_open_max (void) {
5 long maxfd = 0L;
6 /* Try sysconf(_SC_OPEN_MAX) first, as it can be higher than OPEN_MAX.
7 * If that fails and the macro isn't defined, we fall back to an educated
8 * guess. There's no guarantee that our guess is adequate and the program
9 * will die with SIGSEGV if it isn't and the upper boundary is breached. */
10
11#ifdef _SC_OPEN_MAX
12 errno = 0;
13 if ((maxfd = sysconf (_SC_OPEN_MAX)) < 0) {
14 if (errno == 0)
15 maxfd = DEFAULT_MAXFD; /* it's indeterminate */
16 else
17 die (STATE_UNKNOWN, _("sysconf error for _SC_OPEN_MAX\n"));
18 }
19#elif defined(OPEN_MAX)
20 return OPEN_MAX
21#else /* sysconf macro unavailable, so guess (may be wildly inaccurate) */
22 return DEFAULT_MAXFD;
23#endif
24
25 return(maxfd);
26}
diff --git a/lib/maxfd.h b/lib/maxfd.h
new file mode 100644
index 0000000..45218d0
--- /dev/null
+++ b/lib/maxfd.h
@@ -0,0 +1,9 @@
1#ifndef _MAXFD_
2#define _MAXFD_
3
4#define DEFAULT_MAXFD 256 /* fallback value if no max open files value is set */
5#define MAXFD_LIMIT 8192 /* upper limit of open files */
6
7long mp_open_max (void);
8
9#endif // _MAXFD_
diff --git a/lib/utils_base.c b/lib/utils_base.c
index c458cf6..0f52126 100644
--- a/lib/utils_base.c
+++ b/lib/utils_base.c
@@ -402,26 +402,45 @@ int mp_translate_state (char *state_text) {
402 * parse of argv, so that uniqueness in parameters are reflected there. 402 * parse of argv, so that uniqueness in parameters are reflected there.
403 */ 403 */
404char *_np_state_generate_key() { 404char *_np_state_generate_key() {
405 struct sha256_ctx ctx;
406 int i; 405 int i;
407 char **argv = this_monitoring_plugin->argv; 406 char **argv = this_monitoring_plugin->argv;
408 unsigned char result[20];
409 char keyname[41]; 407 char keyname[41];
410 char *p=NULL; 408 char *p=NULL;
411 409
412 sha256_init_ctx(&ctx); 410 unsigned char result[256];
413 411
412#ifdef USE_OPENSSL
413 /*
414 * This code path is chosen if openssl is available (which should be the most common
415 * scenario). Alternatively, the gnulib implementation/
416 *
417 */
418 EVP_MD_CTX *ctx = EVP_MD_CTX_new();
419
420 EVP_DigestInit(ctx, EVP_sha256());
421
422 for(i=0; i<this_monitoring_plugin->argc; i++) {
423 EVP_DigestUpdate(ctx, argv[i], strlen(argv[i]));
424 }
425
426 EVP_DigestFinal(ctx, result, NULL);
427#else
428
429 struct sha256_ctx ctx;
430
414 for(i=0; i<this_monitoring_plugin->argc; i++) { 431 for(i=0; i<this_monitoring_plugin->argc; i++) {
415 sha256_process_bytes(argv[i], strlen(argv[i]), &ctx); 432 sha256_process_bytes(argv[i], strlen(argv[i]), &ctx);
416 } 433 }
417 434
418 sha256_finish_ctx(&ctx, &result); 435 sha256_finish_ctx(&ctx, result);
419 436#endif // FOUNDOPENSSL
437
420 for (i=0; i<20; ++i) { 438 for (i=0; i<20; ++i) {
421 sprintf(&keyname[2*i], "%02x", result[i]); 439 sprintf(&keyname[2*i], "%02x", result[i]);
422 } 440 }
441
423 keyname[40]='\0'; 442 keyname[40]='\0';
424 443
425 p = strdup(keyname); 444 p = strdup(keyname);
426 if(p==NULL) { 445 if(p==NULL) {
427 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno)); 446 die(STATE_UNKNOWN, _("Cannot execute strdup: %s"), strerror(errno));
diff --git a/lib/utils_base.h b/lib/utils_base.h
index 5906550..9cb4276 100644
--- a/lib/utils_base.h
+++ b/lib/utils_base.h
@@ -2,7 +2,9 @@
2#define _UTILS_BASE_ 2#define _UTILS_BASE_
3/* Header file for Monitoring Plugins utils_base.c */ 3/* Header file for Monitoring Plugins utils_base.c */
4 4
5#include "sha256.h" 5#ifndef USE_OPENSSL
6# include "sha256.h"
7#endif
6 8
7/* This file holds header information for thresholds - use this in preference to 9/* This file holds header information for thresholds - use this in preference to
8 individual plugin logic */ 10 individual plugin logic */
diff --git a/lib/utils_cmd.c b/lib/utils_cmd.c
index 8b8e570..f66fd57 100644
--- a/lib/utils_cmd.c
+++ b/lib/utils_cmd.c
@@ -42,7 +42,20 @@
42#include "common.h" 42#include "common.h"
43#include "utils.h" 43#include "utils.h"
44#include "utils_cmd.h" 44#include "utils_cmd.h"
45/* This variable must be global, since there's no way the caller
46 * can forcibly slay a dead or ungainly running program otherwise.
47 * Multithreading apps and plugins can initialize it (via CMD_INIT)
48 * in an async safe manner PRIOR to calling cmd_run() or cmd_run_array()
49 * for the first time.
50 *
51 * The check for initialized values is atomic and can
52 * occur in any number of threads simultaneously. */
53static pid_t *_cmd_pids = NULL;
54
45#include "utils_base.h" 55#include "utils_base.h"
56
57#include "./maxfd.h"
58
46#include <fcntl.h> 59#include <fcntl.h>
47 60
48#ifdef HAVE_SYS_WAIT_H 61#ifdef HAVE_SYS_WAIT_H
@@ -86,13 +99,7 @@ extern void die (int, const char *, ...)
86void 99void
87cmd_init (void) 100cmd_init (void)
88{ 101{
89#ifndef maxfd 102 long maxfd = mp_open_max();
90 if (!maxfd && (maxfd = sysconf (_SC_OPEN_MAX)) < 0) {
91 /* possibly log or emit a warning here, since there's no
92 * guarantee that our guess at maxfd will be adequate */
93 maxfd = DEFAULT_MAXFD;
94 }
95#endif
96 103
97 /* if maxfd is unnaturally high, we force it to a lower value 104 /* if maxfd is unnaturally high, we force it to a lower value
98 * ( e.g. on SunOS, when ulimit is set to unlimited: 2147483647 this would cause 105 * ( e.g. on SunOS, when ulimit is set to unlimited: 2147483647 this would cause
@@ -118,10 +125,6 @@ _cmd_open (char *const *argv, int *pfd, int *pfderr)
118 125
119 int i = 0; 126 int i = 0;
120 127
121 /* if no command was passed, return with no error */
122 if (argv == NULL)
123 return -1;
124
125 if (!_cmd_pids) 128 if (!_cmd_pids)
126 CMD_INIT; 129 CMD_INIT;
127 130
@@ -152,6 +155,7 @@ _cmd_open (char *const *argv, int *pfd, int *pfderr)
152 /* close all descriptors in _cmd_pids[] 155 /* close all descriptors in _cmd_pids[]
153 * This is executed in a separate address space (pure child), 156 * This is executed in a separate address space (pure child),
154 * so we don't have to worry about async safety */ 157 * so we don't have to worry about async safety */
158 long maxfd = mp_open_max();
155 for (i = 0; i < maxfd; i++) 159 for (i = 0; i < maxfd; i++)
156 if (_cmd_pids[i] > 0) 160 if (_cmd_pids[i] > 0)
157 close (i); 161 close (i);
@@ -178,6 +182,7 @@ _cmd_close (int fd)
178 pid_t pid; 182 pid_t pid;
179 183
180 /* make sure the provided fd was opened */ 184 /* make sure the provided fd was opened */
185 long maxfd = mp_open_max();
181 if (fd < 0 || fd > maxfd || !_cmd_pids || (pid = _cmd_pids[fd]) == 0) 186 if (fd < 0 || fd > maxfd || !_cmd_pids || (pid = _cmd_pids[fd]) == 0)
182 return -1; 187 return -1;
183 188
@@ -269,7 +274,6 @@ _cmd_fetch_output (int fd, output * op, int flags)
269int 274int
270cmd_run (const char *cmdstring, output * out, output * err, int flags) 275cmd_run (const char *cmdstring, output * out, output * err, int flags)
271{ 276{
272 int fd, pfd_out[2], pfd_err[2];
273 int i = 0, argc; 277 int i = 0, argc;
274 size_t cmdlen; 278 size_t cmdlen;
275 char **argv = NULL; 279 char **argv = NULL;
@@ -391,6 +395,7 @@ timeout_alarm_handler (int signo)
391 printf (_("%s - Plugin timed out after %d seconds\n"), 395 printf (_("%s - Plugin timed out after %d seconds\n"),
392 state_text(timeout_state), timeout_interval); 396 state_text(timeout_state), timeout_interval);
393 397
398 long maxfd = mp_open_max();
394 if(_cmd_pids) for(i = 0; i < maxfd; i++) { 399 if(_cmd_pids) for(i = 0; i < maxfd; i++) {
395 if(_cmd_pids[i] != 0) kill(_cmd_pids[i], SIGKILL); 400 if(_cmd_pids[i] != 0) kill(_cmd_pids[i], SIGKILL);
396 } 401 }
diff --git a/lib/utils_cmd.h b/lib/utils_cmd.h
index 6f3aeb8..f1b06c8 100644
--- a/lib/utils_cmd.h
+++ b/lib/utils_cmd.h
@@ -32,17 +32,8 @@ void cmd_init (void);
32#define CMD_NO_ARRAYS 0x01 /* don't populate arrays at all */ 32#define CMD_NO_ARRAYS 0x01 /* don't populate arrays at all */
33#define CMD_NO_ASSOC 0x02 /* output.line won't point to buf */ 33#define CMD_NO_ASSOC 0x02 /* output.line won't point to buf */
34 34
35/* This variable must be global, since there's no way the caller 35
36 * can forcibly slay a dead or ungainly running program otherwise. 36void timeout_alarm_handler (int);
37 * Multithreading apps and plugins can initialize it (via CMD_INIT)
38 * in an async safe manner PRIOR to calling cmd_run() or cmd_run_array()
39 * for the first time.
40 *
41 * The check for initialized values is atomic and can
42 * occur in any number of threads simultaneously. */
43static pid_t *_cmd_pids = NULL;
44
45RETSIGTYPE timeout_alarm_handler (int);
46 37
47 38
48#endif /* _UTILS_CMD_ */ 39#endif /* _UTILS_CMD_ */
diff --git a/lib/utils_disk.c b/lib/utils_disk.c
index 582d3ea..f5ac0b3 100644
--- a/lib/utils_disk.c
+++ b/lib/utils_disk.c
@@ -29,6 +29,7 @@
29#include "common.h" 29#include "common.h"
30#include "utils_disk.h" 30#include "utils_disk.h"
31#include "gl/fsusage.h" 31#include "gl/fsusage.h"
32#include <string.h>
32 33
33void 34void
34np_add_name (struct name_list **list, const char *name) 35np_add_name (struct name_list **list, const char *name)
@@ -40,6 +41,42 @@ np_add_name (struct name_list **list, const char *name)
40 *list = new_entry; 41 *list = new_entry;
41} 42}
42 43
44/* @brief Initialises a new regex at the begin of list via regcomp(3)
45 *
46 * @details if the regex fails to compile the error code of regcomp(3) is returned
47 * and list is not modified, otherwise list is modified to point to the new
48 * element
49 * @param list Pointer to a linked list of regex_list elements
50 * @param regex the string containing the regex which should be inserted into the list
51 * @param clags the cflags parameter for regcomp(3)
52 */
53int
54np_add_regex (struct regex_list **list, const char *regex, int cflags)
55{
56 struct regex_list *new_entry = (struct regex_list *) malloc (sizeof *new_entry);
57
58 if (new_entry == NULL) {
59 die(STATE_UNKNOWN, _("Cannot allocate memory: %s"),
60 strerror(errno));
61 }
62
63 int regcomp_result = regcomp(&new_entry->regex, regex, cflags);
64
65 if (!regcomp_result) {
66 // regcomp succeeded
67 new_entry->next = *list;
68 *list = new_entry;
69
70 return 0;
71 } else {
72 // regcomp failed
73 free(new_entry);
74
75 return regcomp_result;
76 }
77
78}
79
43/* Initialises a new parameter at the end of list */ 80/* Initialises a new parameter at the end of list */
44struct parameter_list * 81struct parameter_list *
45np_add_parameter(struct parameter_list **list, const char *name) 82np_add_parameter(struct parameter_list **list, const char *name)
@@ -196,6 +233,30 @@ np_find_name (struct name_list *list, const char *name)
196 return FALSE; 233 return FALSE;
197} 234}
198 235
236/* Returns TRUE if name is in list */
237bool
238np_find_regmatch (struct regex_list *list, const char *name)
239{
240 int len;
241 regmatch_t m;
242
243 if (name == NULL) {
244 return false;
245 }
246
247 len = strlen(name);
248
249 for (; list; list = list->next) {
250 /* Emulate a full match as if surrounded with ^( )$
251 by checking whether the match spans the whole name */
252 if (!regexec(&list->regex, name, 1, &m, 0) && m.rm_so == 0 && m.rm_eo == len) {
253 return true;
254 }
255 }
256
257 return false;
258}
259
199int 260int
200np_seen_name(struct name_list *list, const char *name) 261np_seen_name(struct name_list *list, const char *name)
201{ 262{
diff --git a/lib/utils_disk.h b/lib/utils_disk.h
index 3b5a45f..6b83ac7 100644
--- a/lib/utils_disk.h
+++ b/lib/utils_disk.h
@@ -10,6 +10,12 @@ struct name_list
10 struct name_list *next; 10 struct name_list *next;
11}; 11};
12 12
13struct regex_list
14{
15 regex_t regex;
16 struct regex_list *next;
17};
18
13struct parameter_list 19struct parameter_list
14{ 20{
15 char *name; 21 char *name;
@@ -35,6 +41,8 @@ struct parameter_list
35void np_add_name (struct name_list **list, const char *name); 41void np_add_name (struct name_list **list, const char *name);
36int np_find_name (struct name_list *list, const char *name); 42int np_find_name (struct name_list *list, const char *name);
37int np_seen_name (struct name_list *list, const char *name); 43int np_seen_name (struct name_list *list, const char *name);
44int np_add_regex (struct regex_list **list, const char *regex, int cflags);
45bool np_find_regmatch (struct regex_list *list, const char *name);
38struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name); 46struct parameter_list *np_add_parameter(struct parameter_list **list, const char *name);
39struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name); 47struct parameter_list *np_find_parameter(struct parameter_list *list, const char *name);
40struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev); 48struct parameter_list *np_del_parameter(struct parameter_list *item, struct parameter_list *prev);