Back to index

nagios-plugins  1.4.16
check_hpjd.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002 * 
00003 * Nagios check_hpjd plugin
00004 * 
00005 * License: GPL
00006 * Copyright (c) 2000-2007 Nagios Plugins Development Team
00007 * 
00008 * Description:
00009 * 
00010 * This file contains the check_hpjd plugin
00011 * 
00012 * This plugin tests the STATUS of an HP printer with a JetDirect card.
00013 * Net-SNMP must be installed on the computer running the plugin.
00014 * 
00015 * 
00016 * This program is free software: you can redistribute it and/or modify
00017 * it under the terms of the GNU General Public License as published by
00018 * the Free Software Foundation, either version 3 of the License, or
00019 * (at your option) any later version.
00020 * 
00021 * This program is distributed in the hope that it will be useful,
00022 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024 * GNU General Public License for more details.
00025 * 
00026 * You should have received a copy of the GNU General Public License
00027 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00028 * 
00029 * 
00030 *****************************************************************************/
00031 
00032 const char *progname = "check_hpjd";
00033 const char *copyright = "2000-2007";
00034 const char *email = "nagiosplug-devel@lists.sourceforge.net";
00035 
00036 #include "common.h"
00037 #include "popen.h"
00038 #include "utils.h"
00039 #include "netutils.h"
00040 
00041 #define DEFAULT_COMMUNITY "public"
00042 
00043 
00044 const char *option_summary = "-H host [-C community]\n";
00045 
00046 #define HPJD_LINE_STATUS           ".1.3.6.1.4.1.11.2.3.9.1.1.2.1"
00047 #define HPJD_PAPER_STATUS          ".1.3.6.1.4.1.11.2.3.9.1.1.2.2"
00048 #define HPJD_INTERVENTION_REQUIRED ".1.3.6.1.4.1.11.2.3.9.1.1.2.3"
00049 #define HPJD_GD_PERIPHERAL_ERROR   ".1.3.6.1.4.1.11.2.3.9.1.1.2.6"
00050 #define HPJD_GD_PAPER_OUT          ".1.3.6.1.4.1.11.2.3.9.1.1.2.8"
00051 #define HPJD_GD_PAPER_JAM          ".1.3.6.1.4.1.11.2.3.9.1.1.2.9"
00052 #define HPJD_GD_TONER_LOW          ".1.3.6.1.4.1.11.2.3.9.1.1.2.10"
00053 #define HPJD_GD_PAGE_PUNT          ".1.3.6.1.4.1.11.2.3.9.1.1.2.11"
00054 #define HPJD_GD_MEMORY_OUT         ".1.3.6.1.4.1.11.2.3.9.1.1.2.12"
00055 #define HPJD_GD_DOOR_OPEN          ".1.3.6.1.4.1.11.2.3.9.1.1.2.17"
00056 #define HPJD_GD_PAPER_OUTPUT       ".1.3.6.1.4.1.11.2.3.9.1.1.2.19"
00057 #define HPJD_GD_STATUS_DISPLAY     ".1.3.6.1.4.1.11.2.3.9.1.1.3"
00058 
00059 #define ONLINE              0
00060 #define OFFLINE             1
00061 
00062 int process_arguments (int, char **);
00063 int validate_arguments (void);
00064 void print_help (void);
00065 void print_usage (void);
00066 
00067 char *community = NULL;
00068 char *address = NULL;
00069 
00070 int
00071 main (int argc, char **argv)
00072 {
00073        char command_line[1024];
00074        int result = STATE_UNKNOWN;
00075        int line;
00076        char input_buffer[MAX_INPUT_BUFFER];
00077        char query_string[512];
00078        char *errmsg;
00079        char *temp_buffer;
00080        int line_status = ONLINE;
00081        int paper_status = 0;
00082        int intervention_required = 0;
00083        int peripheral_error = 0;
00084        int paper_jam = 0;
00085        int paper_out = 0;
00086        int toner_low = 0;
00087        int page_punt = 0;
00088        int memory_out = 0;
00089        int door_open = 0;
00090        int paper_output = 0;
00091        char display_message[MAX_INPUT_BUFFER];
00092 
00093        errmsg = malloc(MAX_INPUT_BUFFER);
00094 
00095        setlocale (LC_ALL, "");
00096        bindtextdomain (PACKAGE, LOCALEDIR);
00097        textdomain (PACKAGE);
00098 
00099        /* Parse extra opts if any */
00100        argv=np_extra_opts (&argc, argv, progname);
00101 
00102        if (process_arguments (argc, argv) == ERROR)
00103               usage4 (_("Could not parse arguments"));
00104 
00105        /* removed ' 2>1' at end of command 10/27/1999 - EG */
00106        /* create the query string */
00107        sprintf
00108               (query_string,
00109                "%s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0",
00110                HPJD_LINE_STATUS,
00111                HPJD_PAPER_STATUS,
00112                HPJD_INTERVENTION_REQUIRED,
00113                HPJD_GD_PERIPHERAL_ERROR,
00114                HPJD_GD_PAPER_JAM,
00115                HPJD_GD_PAPER_OUT,
00116                HPJD_GD_TONER_LOW,
00117                HPJD_GD_PAGE_PUNT,
00118                HPJD_GD_MEMORY_OUT,
00119                HPJD_GD_DOOR_OPEN, HPJD_GD_PAPER_OUTPUT, HPJD_GD_STATUS_DISPLAY);
00120 
00121        /* get the command to run */
00122        sprintf (command_line, "%s -OQa -m : -v 1 -c %s %s %s", PATH_TO_SNMPGET, community,
00123                                                                address, query_string);
00124 
00125        /* run the command */
00126        child_process = spopen (command_line);
00127        if (child_process == NULL) {
00128               printf (_("Could not open pipe: %s\n"), command_line);
00129               return STATE_UNKNOWN;
00130        }
00131 
00132        child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
00133        if (child_stderr == NULL) {
00134               printf (_("Could not open stderr for %s\n"), command_line);
00135        }
00136 
00137        result = STATE_OK;
00138 
00139        line = 0;
00140        while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
00141 
00142               /* strip the newline character from the end of the input */
00143               if (input_buffer[strlen (input_buffer) - 1] == '\n')
00144                      input_buffer[strlen (input_buffer) - 1] = 0;
00145 
00146               line++;
00147 
00148               temp_buffer = strtok (input_buffer, "=");
00149               temp_buffer = strtok (NULL, "=");
00150 
00151               if (temp_buffer == NULL && line < 13) {
00152 
00153                             result = STATE_UNKNOWN;
00154                             strcpy (errmsg, input_buffer);
00155 
00156               } else {
00157 
00158                      switch (line) {
00159 
00160                      case 1:                                                                      /* 1st line should contain the line status */
00161                             line_status = atoi (temp_buffer);
00162                             break;
00163                      case 2:                                                                      /* 2nd line should contain the paper status */
00164                             paper_status = atoi (temp_buffer);
00165                             break;
00166                      case 3:                                                                      /* 3rd line should be intervention required */
00167                             intervention_required = atoi (temp_buffer);
00168                             break;
00169                      case 4:                                                                      /* 4th line should be peripheral error */
00170                             peripheral_error = atoi (temp_buffer);
00171                             break;
00172                      case 5:                                                                      /* 5th line should contain the paper jam status */
00173                             paper_jam = atoi (temp_buffer);
00174                             break;
00175                      case 6:                                                                      /* 6th line should contain the paper out status */
00176                             paper_out = atoi (temp_buffer);
00177                             break;
00178                      case 7:                                                                      /* 7th line should contain the toner low status */
00179                             toner_low = atoi (temp_buffer);
00180                             break;
00181                      case 8:                                                                      /* did data come too slow for engine */
00182                             page_punt = atoi (temp_buffer);
00183                             break;
00184                      case 9:                                                                      /* did we run out of memory */
00185                             memory_out = atoi (temp_buffer);
00186                             break;
00187                      case 10:                                                                     /* is there a door open */
00188                             door_open = atoi (temp_buffer);
00189                             break;
00190                      case 11:                                                                     /* is output tray full */
00191                             paper_output = atoi (temp_buffer);
00192                             break;
00193                      case 12:                                                                     /* display panel message */
00194                             strcpy (display_message, temp_buffer + 1);
00195                             break;
00196                      default:                                                                     /* fold multiline message */
00197                             strncat (display_message, input_buffer,
00198                                           sizeof (display_message) - strlen (display_message) - 1);
00199                      }
00200 
00201               }
00202 
00203               /* break out of the read loop if we encounter an error */
00204               if (result != STATE_OK)
00205                      break;
00206        }
00207 
00208        /* WARNING if output found on stderr */
00209        if (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) {
00210               result = max_state (result, STATE_WARNING);
00211               /* remove CRLF */
00212               if (input_buffer[strlen (input_buffer) - 1] == '\n')
00213                      input_buffer[strlen (input_buffer) - 1] = 0;
00214               sprintf (errmsg, "%s", input_buffer );
00215 
00216        }
00217 
00218        /* close stderr */
00219        (void) fclose (child_stderr);
00220 
00221        /* close the pipe */
00222        if (spclose (child_process))
00223               result = max_state (result, STATE_WARNING);
00224 
00225        /* if there wasn't any output, display an error */
00226        if (line == 0) {
00227 
00228               /* might not be the problem, but most likely is. */
00229               result = STATE_UNKNOWN ;
00230               asprintf (&errmsg, "%s : Timeout from host %s\n", errmsg, address );
00231 
00232        }
00233 
00234        /* if we had no read errors, check the printer status results... */
00235        if (result == STATE_OK) {
00236 
00237               if (paper_jam) {
00238                      result = STATE_WARNING;
00239                      strcpy (errmsg, _("Paper Jam"));
00240               }
00241               else if (paper_out) {
00242                      result = STATE_WARNING;
00243                      strcpy (errmsg, _("Out of Paper"));
00244               }
00245               else if (line_status == OFFLINE) {
00246                      if (strcmp (errmsg, "POWERSAVE ON") != 0) {
00247                             result = STATE_WARNING;
00248                             strcpy (errmsg, _("Printer Offline"));
00249                      }
00250               }
00251               else if (peripheral_error) {
00252                      result = STATE_WARNING;
00253                      strcpy (errmsg, _("Peripheral Error"));
00254               }
00255               else if (intervention_required) {
00256                      result = STATE_WARNING;
00257                      strcpy (errmsg, _("Intervention Required"));
00258               }
00259               else if (toner_low) {
00260                      result = STATE_WARNING;
00261                      strcpy (errmsg, _("Toner Low"));
00262               }
00263               else if (memory_out) {
00264                      result = STATE_WARNING;
00265                      strcpy (errmsg, _("Insufficient Memory"));
00266               }
00267               else if (door_open) {
00268                      result = STATE_WARNING;
00269                      strcpy (errmsg, _("A Door is Open"));
00270               }
00271               else if (paper_output) {
00272                      result = STATE_WARNING;
00273                      strcpy (errmsg, _("Output Tray is Full"));
00274               }
00275               else if (page_punt) {
00276                      result = STATE_WARNING;
00277                      strcpy (errmsg, _("Data too Slow for Engine"));
00278               }
00279               else if (paper_status) {
00280                      result = STATE_WARNING;
00281                      strcpy (errmsg, _("Unknown Paper Error"));
00282               }
00283        }
00284 
00285        if (result == STATE_OK)
00286               printf (_("Printer ok - (%s)\n"), display_message);
00287 
00288        else if (result == STATE_UNKNOWN) {
00289 
00290               printf ("%s\n", errmsg);
00291 
00292               /* if printer could not be reached, escalate to critical */
00293               if (strstr (errmsg, "Timeout"))
00294                      result = STATE_CRITICAL;
00295        }
00296 
00297        else if (result == STATE_WARNING)
00298               printf ("%s (%s)\n", errmsg, display_message);
00299 
00300        return result;
00301 }
00302 
00303 
00304 /* process command-line arguments */
00305 int
00306 process_arguments (int argc, char **argv)
00307 {
00308        int c;
00309 
00310        int option = 0;
00311        static struct option longopts[] = {
00312               {"hostname", required_argument, 0, 'H'},
00313               {"community", required_argument, 0, 'C'},
00314 /*            {"critical",       required_argument,0,'c'}, */
00315 /*            {"warning",        required_argument,0,'w'}, */
00316 /*            {"port",           required_argument,0,'P'}, */
00317               {"version", no_argument, 0, 'V'},
00318               {"help", no_argument, 0, 'h'},
00319               {0, 0, 0, 0}
00320        };
00321 
00322        if (argc < 2)
00323               return ERROR;
00324 
00325 
00326        while (1) {
00327               c = getopt_long (argc, argv, "+hVH:C:", longopts, &option);
00328 
00329               if (c == -1 || c == EOF || c == 1)
00330                      break;
00331 
00332               switch (c) {
00333               case 'H':                                                             /* hostname */
00334                      if (is_host (optarg)) {
00335                             address = strscpy(address, optarg) ;
00336                      }
00337                      else {
00338                             usage2 (_("Invalid hostname/address"), optarg);
00339                      }
00340                      break;
00341               case 'C':                                                             /* community */
00342                      community = strscpy (community, optarg);
00343                      break;
00344               case 'V':                                                             /* version */
00345                      print_revision (progname, NP_VERSION);
00346                      exit (STATE_OK);
00347               case 'h':                                                             /* help */
00348                      print_help ();
00349                      exit (STATE_OK);
00350               case '?':                                                             /* help */
00351                      usage5 ();
00352               }
00353        }
00354 
00355        c = optind;
00356        if (address == NULL) {
00357               if (is_host (argv[c])) {
00358                      address = argv[c++];
00359               }
00360               else {
00361                      usage2 (_("Invalid hostname/address"), argv[c]);
00362               }
00363        }
00364 
00365        if (community == NULL) {
00366               if (argv[c] != NULL )
00367                      community = argv[c];
00368               else
00369                      community = strdup (DEFAULT_COMMUNITY);
00370        }
00371 
00372        return validate_arguments ();
00373 }
00374 
00375 
00376 int
00377 validate_arguments (void)
00378 {
00379        return OK;
00380 }
00381 
00382 
00383 void
00384 print_help (void)
00385 {
00386        print_revision (progname, NP_VERSION);
00387 
00388        printf ("Copyright (c) 1999 Ethan Galstad <nagios@nagios.org>\n");
00389        printf (COPYRIGHT, copyright, email);
00390 
00391        printf ("%s\n", _("This plugin tests the STATUS of an HP printer with a JetDirect card."));
00392        printf ("%s\n", _("Net-snmp must be installed on the computer running the plugin."));
00393 
00394        printf ("\n\n");
00395 
00396        print_usage ();
00397 
00398        printf (UT_HELP_VRSN);
00399        printf (UT_EXTRA_OPTS);
00400 
00401        printf (" %s\n", "-C, --community=STRING");
00402        printf ("    %s", _("The SNMP community name "));
00403        printf (_("(default=%s)"), DEFAULT_COMMUNITY);
00404        printf ("\n");
00405 
00406        printf (UT_SUPPORT);
00407 }
00408 
00409 
00410 
00411 void
00412 print_usage (void)
00413 {
00414   printf ("%s\n", _("Usage:"));
00415        printf ("%s -H host [-C community]\n", progname);
00416 }