diff -urN ./plugins/check_nt.c ../plugins/plugins/check_nt.c --- ./plugins/check_nt.c 2005-01-24 08:29:53.000000000 +0100 +++ ../plugins/plugins/check_nt.c 2005-02-17 12:26:57.000000000 +0100 @@ -35,6 +35,9 @@ const char *copyright = "2003-2004"; const char *email = "nagiosplug-devel@lists.sourceforge.net"; +extern const char *status_strings; +extern int timeout_status; + #include "common.h" #include "netutils.h" #include "utils.h" @@ -454,6 +457,7 @@ {"hostname", required_argument,0,'H'}, {"version", no_argument, 0,'V'}, {"help", no_argument, 0,'h'}, + {"timeout-status", required_argument, 0, 'T'}, {0,0,0,0} }; @@ -478,7 +482,7 @@ } while (1){ - c = getopt_long(argc,argv,"+hVH:t:c:w:p:v:l:s:d:",longopts,&option); + c = getopt_long(argc,argv,"+hVH:t:c:w:p:v:l:s:d:T:",longopts,&option); if (c==-1||c==EOF||c==1) break; @@ -549,8 +553,11 @@ socket_timeout=atoi(optarg); if(socket_timeout<=0) return ERROR; + break; + case 'T': + if(set_timeout_status(optarg) == ERROR) return ERROR; + break; } - } if (vars_to_check==CHECK_NONE) diff -urN ./plugins/common.h ../plugins/plugins/common.h --- ./plugins/common.h 2004-12-10 11:42:00.000000000 +0100 +++ ../plugins/plugins/common.h 2005-02-17 12:26:57.000000000 +0100 @@ -157,8 +157,13 @@ ERROR = -1 }; -/* AIX seems to have this defined somewhere else */ -#ifndef FALSE +/* AIX seems to have FALSE defined somewhere else, so make sure + * TRUE means something else (we assume it does if it's already defined) */ +#ifdef FALSE +# ifndef TRUE +# define TRUE (FALSE ^ 1) +# endif +#else enum { FALSE, TRUE @@ -170,7 +175,8 @@ STATE_WARNING, STATE_CRITICAL, STATE_UNKNOWN, - STATE_DEPENDENT + STATE_DEPENDENT, + STATE_OOB /* result out of bounds (keep last in list!) */ }; enum { diff -urN ./plugins/netutils.c ../plugins/plugins/netutils.c --- ./plugins/netutils.c 2005-01-05 21:53:22.000000000 +0100 +++ ../plugins/plugins/netutils.c 2005-02-17 12:34:23.000000000 +0100 @@ -38,18 +38,23 @@ int econn_refuse_state = STATE_CRITICAL; int was_refused = FALSE; int address_family = AF_UNSPEC; +extern char *status_strings; +extern int timeout_status; static int my_connect(const char *address, int port, int *sd, int proto); /* handles socket timeouts */ void socket_timeout_alarm_handler (int sig) { - if (sig == SIGALRM) - printf (_("CRITICAL - Socket timeout after %d seconds\n"), socket_timeout); - else - printf (_("CRITICAL - Abnormal timeout after %d seconds\n"), socket_timeout); + /* this can only happen with poorly written plugins, so chalk + * it up as input validation error and return STATE_UNKNOWN */ + if(timeout_status < 0 || timeout_status >= STATE_OOB) + timeout_status = STATE_UNKNOWN; - exit (STATE_CRITICAL); + printf (_("%s - Socket timeout after %d seconds\n"), + status_strings[timeout_status], socket_timeout); + + exit (timeout_status); } diff -urN ./plugins/utils.c ../plugins/plugins/utils.c --- ./plugins/utils.c 2005-01-05 21:53:23.000000000 +0100 +++ ../plugins/plugins/utils.c 2005-02-17 12:26:57.000000000 +0100 @@ -23,6 +23,20 @@ extern void print_usage (void); extern const char *progname; +/* NULL-terminate these arrays just to be prudent + * It's a bit faster and a lot more portable to use two separate + * arrays for this, as we don't need to rely on strcasecmp being available + */ +const char *status_strings[] = { + "OK", "WARNING", "CRITICAL", "UNKNOWN", "DEPENDENT", NULL +}; +const char *lowercase_status_strings[] = { + "ok", "warning", "critical", "unknown", "dependent", NULL +}; +/* plugins may set this themselves, so export it from here + * and have the plugins import it explicitly as extern */ +int timeout_status = STATE_CRITICAL; + #define STRLEN 64 #define TXTBLK 128 @@ -105,18 +119,10 @@ const char * state_text (int result) { - switch (result) { - case STATE_OK: - return "OK"; - case STATE_WARNING: - return "WARNING"; - case STATE_CRITICAL: - return "CRITICAL"; - case STATE_DEPENDENT: - return "DEPENDENT"; - default: + if(result < 0 || result >= STATE_OOB) return "UNKNOWN"; - } + + return status_strings[result]; } void @@ -129,14 +135,54 @@ exit (result); } +int +set_timeout_status(const char *arg) +{ + int i; + + timeou_status = -1; + for(i = 0; status_strings[i],lowercase_status_strings[i]; i++) { + if(status_strings[i][0] = arg[0] || + lowercase_status_strings[i][0] = arg[0]) + { + timeout_status = i; + break; + } + + if(timeout_status != -1) return OK; + + errno = 0; + timeout_status = (int)strtol(arg, NULL, 0); + if(timeout_status < STATE_OK || timeout_status >= STATE_OOB || + (!timeout_status && errno)) + { + timeout_status = STATE_UNKNOWN; + return ERROR; + } + } + + return OK; +} + + void timeout_alarm_handler (int signo) { + /* don't segfault if someone stupid has set this arbitrarily */ + if(timeout_status < 0 || timeout_status >= STATE_OOB) + timeout_status = STATE_UNKNOWN; + if (signo == SIGALRM) { - printf (_("CRITICAL - Plugin timed out after %d seconds\n"), - timeout_interval); - exit (STATE_CRITICAL); + printf (_("%s - Plugin timed out after %d seconds\n"), + status_strings[timeout_status], timeout_interval); + exit (timeout_status); } + + /* fallthrough so we print something in case some stupid plugin + * contributor has set this function to the catch-all sighandler */ + printf(_("Caught signal %d in timeout_alarm_handler (bad coding).\n"), + signo); + exit(STATE_UNKNOWN); } int