summaryrefslogtreecommitdiffstats
path: root/web/attachments/102274-check_upsv2.c
diff options
context:
space:
mode:
Diffstat (limited to 'web/attachments/102274-check_upsv2.c')
-rw-r--r--web/attachments/102274-check_upsv2.c593
1 files changed, 593 insertions, 0 deletions
diff --git a/web/attachments/102274-check_upsv2.c b/web/attachments/102274-check_upsv2.c
new file mode 100644
index 0000000..f238c7d
--- /dev/null
+++ b/web/attachments/102274-check_upsv2.c
@@ -0,0 +1,593 @@
1/******************************************************************************
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or (at
6 your option) any later version.
7
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
17 ******************************************************************************/
18
19const char *progname = "check_ups";
20const char *revision = "$Revision: 1.13 $";
21const char *copyright = "2000-2002";
22const char *email = "nagiosplug-devel@lists.sourceforge.net";
23
24#include <locale.h>
25#include "common.h"
26#include "netutils.h"
27#include "utils.h"
28
29enum {
30 PORT = 3493
31};
32
33#define CHECK_NONE 0
34
35#define UPS_NONE 0 /* no supported options */
36#define UPS_UTILITY 1 /* supports utility line voltage */
37#define UPS_BATTPCT 2 /* supports percent battery remaining */
38#define UPS_STATUS 4 /* supports UPS status */
39#define UPS_TEMP 8 /* supports UPS temperature */
40#define UPS_LOADPCT 16 /* supports load percent */
41
42#define UPSSTATUS_NONE 0
43#define UPSSTATUS_OFF 1
44#define UPSSTATUS_OL 2
45#define UPSSTATUS_OB 4
46#define UPSSTATUS_LB 8
47#define UPSSTATUS_CAL 16
48#define UPSSTATUS_RB 32 /*Replace Battery */
49#define UPSSTATUS_UNKOWN 64
50
51enum { NOSUCHVAR = ERROR-1 };
52
53int server_port = PORT;
54char *server_address;
55char *ups_name = NULL;
56double warning_value = 0.0;
57double critical_value = 0.0;
58int check_warn = FALSE;
59int check_crit = FALSE;
60int check_variable = UPS_NONE;
61int supported_options = UPS_NONE;
62int status = UPSSTATUS_NONE;
63
64double ups_utility_voltage = 0.0;
65double ups_battery_percent = 0.0;
66double ups_load_percent = 0.0;
67double ups_temperature = 0.0;
68char *ups_status;
69
70int determine_status (void);
71int get_ups_variable (const char *, char *, size_t);
72
73int process_arguments (int, char **);
74int validate_arguments (void);
75void print_help (void);
76void print_usage (void);
77
78 int
79main (int argc, char **argv)
80{
81 int result = STATE_OK;
82 char *message;
83 char *data;
84 char temp_buffer[MAX_INPUT_BUFFER];
85 double ups_utility_deviation = 0.0;
86 int res;
87
88 setlocale (LC_ALL, "");
89 bindtextdomain (PACKAGE, LOCALEDIR);
90 textdomain (PACKAGE);
91
92 ups_status = strdup ("N/A");
93 data = strdup ("");
94 message = strdup ("");
95
96 if (process_arguments (argc, argv) != OK)
97 usage ("Invalid command arguments supplied\n");
98
99 /* initialize alarm signal handling */
100 signal (SIGALRM, socket_timeout_alarm_handler);
101
102 /* set socket timeout */
103 alarm (socket_timeout);
104
105 /* get the ups status if possible */
106 if (determine_status () != OK)
107 return STATE_CRITICAL;
108 if (supported_options & UPS_STATUS) {
109
110 ups_status = strdup ("");
111 result = STATE_OK;
112
113 if (status & UPSSTATUS_OFF) {
114 asprintf (&ups_status, "Off");
115 result = STATE_CRITICAL;
116 }
117 else if ((status & (UPSSTATUS_OB | UPSSTATUS_LB)) ==
118 (UPSSTATUS_OB | UPSSTATUS_LB)) {
119 asprintf (&ups_status, "On Battery, Low Battery");
120 result = STATE_CRITICAL;
121 }
122 else {
123 if (status & UPSSTATUS_OL) {
124 asprintf (&ups_status, "%s%s", ups_status, "Online");
125 }
126 if (status & UPSSTATUS_OB) {
127 asprintf (&ups_status, "%s%s", ups_status, "On Battery");
128 result = STATE_WARNING;
129 }
130 if (status & UPSSTATUS_LB) {
131 asprintf (&ups_status, "%s%s", ups_status, ", Low Battery");
132 result = STATE_WARNING;
133 }
134 if (status & UPSSTATUS_CAL) {
135 asprintf (&ups_status, "%s%s", ups_status, ", Calibrating");
136 }
137 if (status & UPSSTATUS_RB) {
138 asprintf (&ups_status, "%s%s", ups_status, ", Replace Battery");
139 result = STATE_WARNING;
140 }
141 if (status & UPSSTATUS_UNKOWN) {
142 asprintf (&ups_status, "%s%s", ups_status, ", Unknown");
143 }
144 }
145 asprintf (&message, "%sStatus=%s ", message, ups_status);
146 }
147
148 /* get the ups utility voltage if possible */
149 res=get_ups_variable ("input.voltage", temp_buffer, sizeof (temp_buffer));
150 if (res == NOSUCHVAR) supported_options &= ~UPS_UTILITY;
151 else if (res != OK)
152 return STATE_CRITICAL;
153 else {
154 supported_options |= UPS_UTILITY;
155
156 ups_utility_voltage = atof (temp_buffer);
157 asprintf (&message, "%sUtility=%3.1fV ", message, ups_utility_voltage);
158
159 if (ups_utility_voltage > 120.0)
160 ups_utility_deviation = 120.0 - ups_utility_voltage;
161 else
162 ups_utility_deviation = ups_utility_voltage - 120.0;
163
164 if (check_variable == UPS_UTILITY) {
165 if (check_crit==TRUE && ups_utility_deviation>=critical_value) {
166 result = STATE_CRITICAL;
167 }
168 else if (check_warn==TRUE && ups_utility_deviation>=warning_value) {
169 result = max_state (result, STATE_WARNING);
170 }
171 asprintf (&data, "%s",
172 perfdata ("voltage", (long)(1000*ups_utility_voltage), "mV",
173 check_warn, (long)(1000*warning_value),
174 check_crit, (long)(1000*critical_value),
175 TRUE, 0, FALSE, 0));
176 } else {
177 asprintf (&data, "%s",
178 perfdata ("voltage", (long)(1000*ups_utility_voltage), "mV",
179 FALSE, 0, FALSE, 0, TRUE, 0, FALSE, 0));
180 }
181 }
182
183 /* get the ups battery percent if possible */
184 res=get_ups_variable ("battery.charge", temp_buffer, sizeof (temp_buffer));
185 if (res == NOSUCHVAR) supported_options &= ~UPS_BATTPCT;
186 else if ( res != OK)
187 return STATE_CRITICAL;
188 else {
189 supported_options |= UPS_BATTPCT;
190 ups_battery_percent = atof (temp_buffer);
191 asprintf (&message, "%sBatt=%3.1f%% ", message, ups_battery_percent);
192
193 if (check_variable == UPS_BATTPCT) {
194 if (check_crit==TRUE && ups_battery_percent <= critical_value) {
195 result = STATE_CRITICAL;
196 }
197 else if (check_warn==TRUE && ups_battery_percent<=warning_value) {
198 result = max_state (result, STATE_WARNING);
199 }
200 asprintf (&data, "%s %s", data,
201 perfdata ("battery", (long)ups_battery_percent, "%",
202 check_warn, (long)(1000*warning_value),
203 check_crit, (long)(1000*critical_value),
204 TRUE, 0, TRUE, 100));
205 } else {
206 asprintf (&data, "%s %s", data,
207 perfdata ("battery", (long)ups_battery_percent, "%",
208 FALSE, 0, FALSE, 0, TRUE, 0, TRUE, 100));
209 }
210 }
211
212 /* get the ups load percent if possible */
213 res=get_ups_variable ("ups.load", temp_buffer, sizeof (temp_buffer));
214 if ( res == NOSUCHVAR ) supported_options &= ~UPS_LOADPCT;
215 else if ( res != OK)
216 return STATE_CRITICAL;
217 else {
218 supported_options |= UPS_LOADPCT;
219 ups_load_percent = atof (temp_buffer);
220 asprintf (&message, "%sLoad=%3.1f%% ", message, ups_load_percent);
221
222 if (check_variable == UPS_LOADPCT) {
223 if (check_crit==TRUE && ups_load_percent>=critical_value) {
224 result = STATE_CRITICAL;
225 }
226 else if (check_warn==TRUE && ups_load_percent>=warning_value) {
227 result = max_state (result, STATE_WARNING);
228 }
229 asprintf (&data, "%s %s", data,
230 perfdata ("load", (long)ups_load_percent, "%",
231 check_warn, (long)(1000*warning_value),
232 check_crit, (long)(1000*critical_value),
233 TRUE, 0, TRUE, 100));
234 } else {
235 asprintf (&data, "%s %s", data,
236 perfdata ("load", (long)ups_load_percent, "%",
237 FALSE, 0, FALSE, 0, TRUE, 0, TRUE, 100));
238 }
239 }
240
241 /* get the ups temperature if possible */
242 res=get_ups_variable ("ups.temperature", temp_buffer, sizeof (temp_buffer));
243 if ( res == NOSUCHVAR ) supported_options &= ~UPS_TEMP;
244 else if ( res != OK)
245 return STATE_CRITICAL;
246 else {
247 supported_options |= UPS_TEMP;
248 ups_temperature = (atof (temp_buffer) * 1.8) + 32;
249 asprintf (&message, "%sTemp=%3.1fF", message, ups_temperature);
250
251 if (check_variable == UPS_TEMP) {
252 if (check_crit==TRUE && ups_temperature>=critical_value) {
253 result = STATE_CRITICAL;
254 }
255 else if (check_warn == TRUE && ups_temperature>=warning_value) {
256 result = max_state (result, STATE_WARNING);
257 }
258 asprintf (&data, "%s %s", data,
259 perfdata ("temp", (long)ups_temperature, "degF",
260 check_warn, (long)(1000*warning_value),
261 check_crit, (long)(1000*critical_value),
262 TRUE, 0, FALSE, 0));
263 } else {
264 asprintf (&data, "%s %s", data,
265 perfdata ("temp", (long)ups_temperature, "degF",
266 FALSE, 0, FALSE, 0, TRUE, 0, FALSE, 0));
267 }
268 }
269
270 /* if the UPS does not support any options we are looking for, report an error */
271 if (supported_options == UPS_NONE) {
272 result = STATE_CRITICAL;
273 asprintf (&message, "UPS does not support any available options\n");
274 }
275
276 /* reset timeout */
277 alarm (0);
278
279 printf ("UPS %s - %s|%s\n", state_text(result), message, data);
280 return result;
281}
282
283
284
285/* determines what options are supported by the UPS */
286int
287determine_status (void)
288{
289 char recv_buffer[MAX_INPUT_BUFFER];
290 char temp_buffer[MAX_INPUT_BUFFER];
291 char *ptr;
292 int res;
293
294 res=get_ups_variable ("ups.status", recv_buffer, sizeof (recv_buffer));
295 if (res == NOSUCHVAR) return OK;
296 if (res != STATE_OK) {
297 printf ("Invalid response received from hostn");
298 return ERROR;
299 }
300
301 supported_options |= UPS_STATUS;
302
303 strcpy (temp_buffer, recv_buffer);
304 for (ptr = (char *) strtok (temp_buffer, " "); ptr != NULL;
305 ptr = (char *) strtok (NULL, " ")) {
306 if (!strcmp (ptr, "OFF"))
307 status |= UPSSTATUS_OFF;
308 else if (!strcmp (ptr, "OL"))
309 status |= UPSSTATUS_OL;
310 else if (!strcmp (ptr, "OB"))
311 status |= UPSSTATUS_OB;
312 else if (!strcmp (ptr, "LB"))
313 status |= UPSSTATUS_LB;
314 else if (!strcmp (ptr, "CAL"))
315 status |= UPSSTATUS_CAL;
316 else if (!strcmp (ptr, "RB"))
317 status |= UPSSTATUS_RB;
318 else
319 status |= UPSSTATUS_UNKOWN;
320 }
321
322 return OK;
323}
324
325
326/* gets a variable value for a specific UPS */
327int
328get_ups_variable (const char *varname, char *buf, size_t buflen)
329{
330 /* char command[MAX_INPUT_BUFFER]; */
331 char temp_buffer[MAX_INPUT_BUFFER];
332 char send_buffer[MAX_INPUT_BUFFER];
333 char *ptr;
334 int len;
335
336 *buf=0;
337
338 /* create the command string to send to the UPS daemon */
339 sprintf (send_buffer, "GET VAR %s %s\n", ups_name, varname);
340
341 /* send the command to the daemon and get a response back */
342 if (process_tcp_request
343 (server_address, server_port, send_buffer, temp_buffer,
344 sizeof (temp_buffer)) != STATE_OK) {
345 printf ("Invalid response received from host\n");
346 return ERROR;
347 }
348
349 ptr = temp_buffer;
350 len = strlen(ptr);
351 if (len > 0 && ptr[len-1] == '\n') ptr[len-1]=0;
352 if (strcmp (ptr, "ERR UNKNOWN-UPS") == 0) {
353 printf ("Error: no such ups '%s' on that host\n", ups_name);
354 return ERROR;
355 }
356
357 if (strcmp (ptr, "ERR VAR-NOT-SUPPORTED") == 0) {
358 //printf ("Error: Variable '%s' is not supported\n", varname);
359 return NOSUCHVAR;
360 }
361
362 if (strcmp (ptr, "ERR DATA-STALE") == 0) {
363 printf ("Error: UPS data is stale\n");
364 return ERROR;
365 }
366
367 if (strncmp (ptr, "ERR", 3) == 0) {
368 printf ("Unkown error: %s\n", ptr);
369 return ERROR;
370 }
371
372 ptr = temp_buffer + strlen (varname) + strlen (ups_name) + 6;
373 len = strlen(ptr);
374 if (len < 2 || ptr[0] != '"' || ptr[len-1] != '"') {
375 printf ("Error: unable to parse variable\n");
376 return ERROR;
377 }
378 strncpy (buf, ptr+1, len - 2);
379 buf[len - 2] = 0;
380
381 return OK;
382}
383
384
385/* Command line: CHECK_UPS -H <host_address> -u ups [-p port] [-v variable]
386 [-wv warn_value] [-cv crit_value] [-to to_sec] */
387
388
389/* process command-line arguments */
390int
391process_arguments (int argc, char **argv)
392{
393 int c;
394
395 int option = 0;
396 static struct option longopts[] = {
397 {"hostname", required_argument, 0, 'H'},
398 {"ups", required_argument, 0, 'u'},
399 {"port", required_argument, 0, 'p'},
400 {"critical", required_argument, 0, 'c'},
401 {"warning", required_argument, 0, 'w'},
402 {"timeout", required_argument, 0, 't'},
403 {"variable", required_argument, 0, 'v'},
404 {"version", no_argument, 0, 'V'},
405 {"help", no_argument, 0, 'h'},
406 {0, 0, 0, 0}
407 };
408
409 if (argc < 2)
410 return ERROR;
411
412 for (c = 1; c < argc; c++) {
413 if (strcmp ("-to", argv[c]) == 0)
414 strcpy (argv[c], "-t");
415 else if (strcmp ("-wt", argv[c]) == 0)
416 strcpy (argv[c], "-w");
417 else if (strcmp ("-ct", argv[c]) == 0)
418 strcpy (argv[c], "-c");
419 }
420
421 while (1) {
422 c = getopt_long (argc, argv, "hVH:u:p:v:c:w:t:", longopts,
423 &option);
424
425 if (c == -1 || c == EOF)
426 break;
427
428 switch (c) {
429 case '?': /* help */
430 usage3 ("Unknown option", optopt);
431 case 'H': /* hostname */
432 if (is_host (optarg)) {
433 server_address = optarg;
434 }
435 else {
436 usage2 ("Invalid host name", optarg);
437 }
438 break;
439 case 'u': /* ups name */
440 ups_name = optarg;
441 break;
442 case 'p': /* port */
443 if (is_intpos (optarg)) {
444 server_port = atoi (optarg);
445 }
446 else {
447 usage2 ("Server port must be a positive integer", optarg);
448 }
449 break;
450 case 'c': /* critical time threshold */
451 if (is_intnonneg (optarg)) {
452 critical_value = atoi (optarg);
453 check_crit = TRUE;
454 }
455 else {
456 usage2 ("Critical time must be a nonnegative integer", optarg);
457 }
458 break;
459 case 'w': /* warning time threshold */
460 if (is_intnonneg (optarg)) {
461 warning_value = atoi (optarg);
462 check_warn = TRUE;
463 }
464 else {
465 usage2 ("Warning time must be a nonnegative integer", optarg);
466 }
467 break;
468 case 'v': /* variable */
469 if (!strcmp (optarg, "LINE"))
470 check_variable = UPS_UTILITY;
471 else if (!strcmp (optarg, "TEMP"))
472 check_variable = UPS_TEMP;
473 else if (!strcmp (optarg, "BATTPCT"))
474 check_variable = UPS_BATTPCT;
475 else if (!strcmp (optarg, "LOADPCT"))
476 check_variable = UPS_LOADPCT;
477 else
478 usage2 ("Unrecognized UPS variable", optarg);
479 break;
480 case 't': /* timeout */
481 if (is_intnonneg (optarg)) {
482 socket_timeout = atoi (optarg);
483 }
484 else {
485 usage ("Time interval must be a nonnegative integer\n");
486 }
487 break;
488 case 'V': /* version */
489 print_revision (progname, "$Revision: 1.13 $");
490 exit (STATE_OK);
491 case 'h': /* help */
492 print_help ();
493 exit (STATE_OK);
494 }
495 }
496
497
498 if (server_address == NULL && argc > optind) {
499 if (is_host (argv[optind]))
500 server_address = argv[optind++];
501 else
502 usage ("Invalid host name");
503 }
504
505 if (server_address == NULL)
506 server_address = strdup("127.0.0.1");
507
508 return validate_arguments();
509}
510
511
512
513
514
515int
516validate_arguments (void)
517{
518 if (! ups_name) {
519 printf ("Error : no ups indicated\n");
520 return ERROR;
521 }
522 return OK;
523}
524
525
526
527
528
529
530void
531print_help (void)
532{
533 char *myport;
534 asprintf (&myport, "%d", PORT);
535
536 print_revision (progname, revision);
537
538 printf (_("Copyright (c) 2000 Tom Shields"));
539 printf (_(COPYRIGHT), copyright, email);
540
541 printf (_("This plugin tests the UPS service on the specified host.\n\
542Network UPS Tools from www.exploits.org must be running for this plugin to\n\
543work.\n\n"));
544
545 print_usage ();
546
547 printf (_(UT_HELP_VRSN));
548
549 printf (_(UT_HOST_PORT), 'p', myport);
550
551 printf (_("\
552 -u, --ups=STRING\n\
553 Name of UPS\n"));
554
555 printf (_(UT_WARN_CRIT));
556
557 printf (_(UT_TIMEOUT), DEFAULT_SOCKET_TIMEOUT);
558
559 printf (_(UT_VERBOSE));
560
561 printf (_("\
562This plugin attempts to determine the status of a UPS (Uninterruptible Power\n\
563Supply) on a local or remote host. If the UPS is online or calibrating, the\n\
564plugin will return an OK state. If the battery is on it will return a WARNING\n\
565state. If the UPS is off or has a low battery the plugin will return a CRITICAL\n\
566state.\n\n"));
567
568 printf (_("\
569You may also specify a variable to check [such as temperature, utility voltage,\n\
570battery load, etc.] as well as warning and critical thresholds for the value of\n\
571that variable. If the remote host has multiple UPS that are being monitored you\n\
572will have to use the [ups] option to specify which UPS to check.\n\n"));
573
574 printf (_("Notes:\n\n\
575This plugin requires that the UPSD daemon distributed with Russel Kroll's\n\
576Smart UPS Tools be installed on the remote host. If you do not have the\n\
577package installed on your system, you can download it from\n\
578http://www.exploits.org/nut\n\n"));
579
580 printf (_(UT_SUPPORT));
581}
582
583
584
585
586void
587print_usage (void)
588{
589 printf (_("\
590Usage: %s -H host -u ups [-p port] [-v variable] [-wv warn_value] [-cv crit_value] [-to to_sec]\n"), progname);
591 printf (_(UT_HLP_VRS), progname, progname);
592}
593