summaryrefslogtreecommitdiffstats
path: root/plugins/check_hpjd.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_hpjd.c')
-rw-r--r--plugins/check_hpjd.c571
1 files changed, 571 insertions, 0 deletions
diff --git a/plugins/check_hpjd.c b/plugins/check_hpjd.c
new file mode 100644
index 00000000..8234abdf
--- /dev/null
+++ b/plugins/check_hpjd.c
@@ -0,0 +1,571 @@
1/******************************************************************************
2*
3* CHECK_HPJD.C
4*
5* Program: HP printer plugin for Nagios
6* License: GPL
7* Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)
8*
9* Last Modified: $Date$
10*
11* Command line: CHECK_HPJD <ip_address> [community]
12*
13* Description:
14*
15* This plugin will attempt to check the status of an HP printer. The
16* printer must have a JetDirect card installed and TCP/IP protocol
17* stack enabled. This plugin has only been tested on a few printers
18* and may not work well on all models of JetDirect cards. Multiple
19* port JetDirect devices must have an IP address assigned to each
20* port in order to be monitored.
21*
22* Dependencies:
23*
24* This plugin used the 'snmpget' command included with the UCD-SNMP
25* package. If you don't have the package installed you will need to
26* download it from http://ucd-snmp.ucdavis.edu before you can use
27* this plugin.
28*
29* Return Values:
30*
31* UNKNOWN = The plugin could not read/process the output from the printer
32* OK = Printer looks normal
33* WARNING = Low toner, paper jam, intervention required, paper out, etc.
34* CRITICAL = The printer could not be reached (it's probably turned off)
35*
36* Acknowledgements:
37*
38* The idea for the plugin (as well as some code) were taken from Jim
39* Trocki's pinter alert script in his "mon" utility, found at
40* http://www.kernel.org/software/mon
41*
42* Notes:
43* 'JetDirect' is copyrighted by Hewlett-Packard.
44* HP, please don't sue me... :-)
45*
46* License Information:
47*
48* This program is free software; you can redistribute it and/or modify
49* it under the terms of the GNU General Public License as published by
50* the Free Software Foundation; either version 2 of the License, or
51* (at your option) any later version.
52*
53* This program is distributed in the hope that it will be useful,
54* but WITHOUT ANY WARRANTY; without even the implied warranty of
55* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
56* GNU General Public License for more details.
57*
58* You should have received a copy of the GNU General Public License
59* along with this program; if not, write to the Free Software
60* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
61*
62*****************************************************************************/
63
64#include "common.h"
65#include "popen.h"
66#include "utils.h"
67
68#define PROGNAME "check_hpjd"
69
70#define HPJD_LINE_STATUS ".1.3.6.1.4.1.11.2.3.9.1.1.2.1"
71#define HPJD_PAPER_STATUS ".1.3.6.1.4.1.11.2.3.9.1.1.2.2"
72#define HPJD_INTERVENTION_REQUIRED ".1.3.6.1.4.1.11.2.3.9.1.1.2.3"
73#define HPJD_GD_PERIPHERAL_ERROR ".1.3.6.1.4.1.11.2.3.9.1.1.2.6"
74#define HPJD_GD_PAPER_JAM ".1.3.6.1.4.1.11.2.3.9.1.1.2.8"
75#define HPJD_GD_PAPER_OUT ".1.3.6.1.4.1.11.2.3.9.1.1.2.9"
76#define HPJD_GD_TONER_LOW ".1.3.6.1.4.1.11.2.3.9.1.1.2.10"
77#define HPJD_GD_PAGE_PUNT ".1.3.6.1.4.1.11.2.3.9.1.1.2.11"
78#define HPJD_GD_MEMORY_OUT ".1.3.6.1.4.1.11.2.3.9.1.1.2.12"
79#define HPJD_GD_DOOR_OPEN ".1.3.6.1.4.1.11.2.3.9.1.1.2.17"
80#define HPJD_GD_PAPER_OUTPUT ".1.3.6.1.4.1.11.2.3.9.1.1.2.19"
81#define HPJD_GD_STATUS_DISPLAY ".1.3.6.1.4.1.11.2.3.9.1.1.3"
82
83#define ONLINE 0
84#define OFFLINE 1
85
86int process_arguments (int, char **);
87int call_getopt (int, char **);
88int validate_arguments (void);
89void print_help (void);
90void print_usage (void);
91
92char *community = NULL;
93char *address = NULL;
94
95int
96main (int argc, char **argv)
97{
98 char command_line[1024];
99 int result;
100 int line;
101 char input_buffer[MAX_INPUT_BUFFER];
102 char query_string[512];
103 char error_message[MAX_INPUT_BUFFER];
104 char *temp_buffer;
105 int line_status = ONLINE;
106 int paper_status = 0;
107 int intervention_required = 0;
108 int peripheral_error = 0;
109 int paper_jam = 0;
110 int paper_out = 0;
111 int toner_low = 0;
112 int page_punt = 0;
113 int memory_out = 0;
114 int door_open = 0;
115 int paper_output = 0;
116 char display_message[MAX_INPUT_BUFFER];
117
118 if (process_arguments (argc, argv) != OK)
119 usage ("Invalid command arguments supplied\n");
120
121 /* removed ' 2>1' at end of command 10/27/1999 - EG */
122 /* create the query string */
123 sprintf
124 (query_string,
125 "%s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0",
126 HPJD_LINE_STATUS,
127 HPJD_PAPER_STATUS,
128 HPJD_INTERVENTION_REQUIRED,
129 HPJD_GD_PERIPHERAL_ERROR,
130 HPJD_GD_PAPER_JAM,
131 HPJD_GD_PAPER_OUT,
132 HPJD_GD_TONER_LOW,
133 HPJD_GD_PAGE_PUNT,
134 HPJD_GD_MEMORY_OUT,
135 HPJD_GD_DOOR_OPEN, HPJD_GD_PAPER_OUTPUT, HPJD_GD_STATUS_DISPLAY);
136
137 /* get the command to run */
138 sprintf (command_line, "%s -v 1 %s %s %s", PATH_TO_SNMPGET, address,
139 community, query_string);
140
141 /* run the command */
142 child_process = spopen (command_line);
143 if (child_process == NULL) {
144 printf ("Could not open pipe: %s\n", command_line);
145 return STATE_UNKNOWN;
146 }
147
148 child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
149 if (child_stderr == NULL) {
150 printf ("Could not open stderr for %s\n", command_line);
151 }
152
153 result = STATE_OK;
154
155 line = 0;
156 while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
157
158 /* strip the newline character from the end of the input */
159 if (input_buffer[strlen (input_buffer) - 1] == '\n')
160 input_buffer[strlen (input_buffer) - 1] = 0;
161
162 line++;
163
164 temp_buffer = strtok (input_buffer, "=");
165 temp_buffer = strtok (NULL, "=");
166
167 switch (line) {
168
169 case 1: /* 1st line should contain the line status */
170 if (temp_buffer != NULL)
171 line_status = atoi (temp_buffer);
172 else {
173 result = STATE_UNKNOWN;
174 strcpy (error_message, input_buffer);
175 }
176 break;
177
178 case 2: /* 2nd line should contain the paper status */
179 if (temp_buffer != NULL)
180 paper_status = atoi (temp_buffer);
181 else {
182 result = STATE_UNKNOWN;
183 strcpy (error_message, input_buffer);
184 }
185 break;
186
187 case 3: /* 3rd line should be intervention required */
188 if (temp_buffer != NULL)
189 intervention_required = atoi (temp_buffer);
190 else {
191 result = STATE_UNKNOWN;
192 strcpy (error_message, input_buffer);
193 }
194 break;
195
196 case 4: /* 4th line should be peripheral error */
197 if (temp_buffer != NULL)
198 peripheral_error = atoi (temp_buffer);
199 else {
200 result = STATE_UNKNOWN;
201 strcpy (error_message, input_buffer);
202 }
203 break;
204
205 case 5: /* 5th line should contain the paper jam status */
206 if (temp_buffer != NULL)
207 paper_jam = atoi (temp_buffer);
208 else {
209 result = STATE_UNKNOWN;
210 strcpy (error_message, input_buffer);
211 }
212 break;
213
214 case 6: /* 6th line should contain the paper out status */
215 if (temp_buffer != NULL)
216 paper_out = atoi (temp_buffer);
217 else {
218 result = STATE_UNKNOWN;
219 strcpy (error_message, input_buffer);
220 }
221 break;
222
223 case 7: /* 7th line should contain the toner low status */
224 if (temp_buffer != NULL)
225 toner_low = atoi (temp_buffer);
226 else {
227 result = STATE_UNKNOWN;
228 strcpy (error_message, input_buffer);
229 }
230 break;
231
232 case 8: /* did data come too slow for engine */
233 if (temp_buffer != NULL)
234 page_punt = atoi (temp_buffer);
235 else {
236 result = STATE_UNKNOWN;
237 strcpy (error_message, input_buffer);
238 }
239 break;
240
241 case 9: /* did we run out of memory */
242 if (temp_buffer != NULL)
243 memory_out = atoi (temp_buffer);
244 else {
245 result = STATE_UNKNOWN;
246 strcpy (error_message, input_buffer);
247 }
248 break;
249
250 case 10: /* is there a door open */
251 if (temp_buffer != NULL)
252 door_open = atoi (temp_buffer);
253 else {
254 result = STATE_UNKNOWN;
255 strcpy (error_message, input_buffer);
256 }
257 break;
258
259 case 11: /* is output tray full */
260 if (temp_buffer != NULL)
261 paper_output = atoi (temp_buffer);
262 else {
263 result = STATE_UNKNOWN;
264 strcpy (error_message, input_buffer);
265 }
266 break;
267
268 case 12: /* display panel message */
269 if (temp_buffer != NULL)
270 strcpy (display_message, temp_buffer + 1);
271 else {
272 result = STATE_UNKNOWN;
273 strcpy (error_message, input_buffer);
274 }
275 break;
276
277 default:
278 break;
279 }
280
281 /* break out of the read loop if we encounter an error */
282 if (result != STATE_OK)
283 break;
284 }
285
286 /* WARNING if output found on stderr */
287 if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr))
288 result = max (result, STATE_WARNING);
289
290 /* close stderr */
291 (void) fclose (child_stderr);
292
293 /* close the pipe */
294 if (spclose (child_process))
295 result = max (result, STATE_WARNING);
296
297 /* if there wasn't any output, display an error */
298 if (line == 0) {
299
300 /*
301 result=STATE_UNKNOWN;
302 strcpy(error_message,"Error: Could not read plugin output\n");
303 */
304
305 /* might not be the problem, but most likely is.. */
306 result = STATE_UNKNOWN;
307 sprintf (error_message, "Timeout: No response from %s\n", address);
308 }
309
310 /* if we had no read errors, check the printer status results... */
311 if (result == STATE_OK) {
312
313 if (paper_jam) {
314 result = STATE_WARNING;
315 strcpy (error_message, "Paper Jam");
316 }
317 else if (paper_out) {
318 result = STATE_WARNING;
319 strcpy (error_message, "Out of Paper");
320 }
321 else if (line_status == OFFLINE) {
322 if (strcmp (error_message, "POWERSAVE ON") != 0) {
323 result = STATE_WARNING;
324 strcpy (error_message, "Printer Offline");
325 }
326 }
327 else if (peripheral_error) {
328 result = STATE_WARNING;
329 strcpy (error_message, "Peripheral Error");
330 }
331 else if (intervention_required) {
332 result = STATE_WARNING;
333 strcpy (error_message, "Intervention Required");
334 }
335 else if (toner_low) {
336 result = STATE_WARNING;
337 strcpy (error_message, "Toner Low");
338 }
339 else if (memory_out) {
340 result = STATE_WARNING;
341 strcpy (error_message, "Insufficient Memory");
342 }
343 else if (door_open) {
344 result = STATE_WARNING;
345 strcpy (error_message, "A Door is Open");
346 }
347 else if (paper_output) {
348 result = STATE_WARNING;
349 strcpy (error_message, "Output Tray is Full");
350 }
351 else if (page_punt) {
352 result = STATE_WARNING;
353 strcpy (error_message, "Data too Slow for Engine");
354 }
355 else if (paper_status) {
356 result = STATE_WARNING;
357 strcpy (error_message, "Unknown Paper Error");
358 }
359 }
360
361 if (result == STATE_OK)
362 printf ("Printer ok - (%s)\n", display_message);
363
364 else if (result == STATE_UNKNOWN) {
365
366 printf ("%s\n", error_message);
367
368 /* if printer could not be reached, escalate to critical */
369 if (strstr (error_message, "Timeout"))
370 result = STATE_CRITICAL;
371 }
372
373 else if (result == STATE_WARNING)
374 printf ("%s (%s)\n", error_message, display_message);
375
376 return result;
377}
378
379
380
381
382
383/* process command-line arguments */
384int
385process_arguments (int argc, char **argv)
386{
387 int c;
388
389 if (argc < 2)
390 return ERROR;
391
392 for (c = 1; c < argc; c++) {
393 if (strcmp ("-to", argv[c]) == 0)
394 strcpy (argv[c], "-t");
395 else if (strcmp ("-wt", argv[c]) == 0)
396 strcpy (argv[c], "-w");
397 else if (strcmp ("-ct", argv[c]) == 0)
398 strcpy (argv[c], "-c");
399 }
400
401
402
403 c = 0;
404 while ((c += (call_getopt (argc - c, &argv[c]))) < argc) {
405
406 if (is_option (argv[c]))
407 continue;
408
409 if (address == NULL) {
410 if (is_host (argv[c])) {
411 address = argv[c];
412 }
413 else {
414 usage ("Invalid host name");
415 }
416 }
417 else if (community == NULL) {
418 community = argv[c];
419 }
420 }
421
422 if (address == NULL)
423 address = strscpy (NULL, "127.0.0.1");
424
425 return validate_arguments ();
426}
427
428
429
430
431
432
433int
434call_getopt (int argc, char **argv)
435{
436 int c, i = 0;
437
438#ifdef HAVE_GETOPT_H
439 int option_index = 0;
440 static struct option long_options[] = {
441 {"hostname", required_argument, 0, 'H'},
442 {"expect", required_argument, 0, 'e'},
443/* {"critical", required_argument,0,'c'}, */
444/* {"warning", required_argument,0,'w'}, */
445/* {"port", required_argument,0,'P'}, */
446 {"verbose", no_argument, 0, 'v'},
447 {"version", no_argument, 0, 'V'},
448 {"help", no_argument, 0, 'h'},
449 {0, 0, 0, 0}
450 };
451#endif
452
453 while (1) {
454#ifdef HAVE_GETOPT_H
455 c = getopt_long (argc, argv, "+hVH:C:", long_options, &option_index);
456#else
457 c = getopt (argc, argv, "+?hVH:C:");
458#endif
459
460 i++;
461
462 if (c == -1 || c == EOF || c == 1)
463 break;
464
465 switch (c) {
466 case 'H':
467 case 'C':
468 i++;
469 }
470
471 switch (c) {
472 case 'H': /* hostname */
473 if (is_host (optarg)) {
474 address = optarg;
475 }
476 else {
477 usage ("Invalid host name\n");
478 }
479 break;
480 case 'C': /* community */
481 community = optarg;
482 break;
483 case 'V': /* version */
484 print_revision (PROGNAME, "$Revision$");
485 exit (STATE_OK);
486 case 'h': /* help */
487 print_help ();
488 exit (STATE_OK);
489 case '?': /* help */
490 usage ("Invalid argument\n");
491 }
492 }
493 return i;
494}
495
496
497
498
499
500int
501validate_arguments (void)
502{
503 return OK;
504}
505
506
507
508
509
510void
511print_help (void)
512{
513 print_revision (PROGNAME, "$Revision$");
514 printf
515 ("Copyright (c) 2000 Ethan Galstad/Karl DeBisschop\n\n"
516 "This plugin tests the STATUS of an HP printer with a JetDirect card.\n"
517 "Ucd-snmp must be installed on the computer running the plugin.\n\n");
518 print_usage ();
519 printf
520 ("\nOptions:\n"
521 " -H, --hostname=STRING or IPADDRESS\n"
522 " Check server on the indicated host\n"
523 " -C, --community=STRING\n"
524 " The SNMP community name\n"
525 " -h, --help\n"
526 " Print detailed help screen\n"
527 " -V, --version\n" " Print version information\n\n");
528 support ();
529}
530
531
532
533
534
535void
536print_usage (void)
537{
538 printf
539 ("Usage: %s -H host [-C community]\n"
540 " %s --help\n"
541 " %s --version\n", PROGNAME, PROGNAME, PROGNAME);
542}
543
544
545/*
546 if(argc<2||argc>3){
547 printf("Incorrect number of arguments supplied\n");
548 printf("\n");
549 print_revision(argv[0],"$Revision$");
550 printf("Copyright (c) 1999 Ethan Galstad (nagios@nagios.org)\n");
551 printf("License: GPL\n");
552 printf("\n");
553 printf("Usage: %s <ip_address> [community]\n",argv[0]);
554 printf("\n");
555 printf("Note:\n");
556 printf(" <ip_address> = The IP address of the JetDirect card\n");
557 printf(" [community] = An optional community string used for SNMP communication\n");
558 printf(" with the JetDirect card. The default is 'public'.\n");
559 printf("\n");
560 return STATE_UNKNOWN;
561 }
562
563 // get the IP address of the JetDirect device
564 strcpy(address,argv[1]);
565
566 // get the community name to use for SNMP communication
567 if(argc>=3)
568 strcpy(community,argv[2]);
569 else
570 strcpy(community,"public");
571*/