check_hpjd hack. Any testers?

Andreas Ericsson ae at op5.se
Fri Feb 18 12:44:24 CET 2005


(this isn't a good day for me).

I just found a small issue with it. This new one is the one to try.

Andreas Ericsson wrote:
> Andreas Ericsson wrote:
> 
>> I accidentally deleted the mail from the guy having problems with his 
>> check_hpjd from nagiosplug cvs.
>>
>> I've reworked it a bit and added some cool features, although I don't 
>> have any hp printer to test it on.
>>
>> It's attached. I'll send a patch to the tracker item when I've gotten 
>> it tested a bit more.
>>
> 
> Perhaps I should be so kind as to really attach it as well. ;)
> Sorry about that.
> 
> Howto; Copy this check_hpjd.c to your plugin distribution, run 
> ./configure if you haven't previously done so, and then make.
> 
> If you're using a wonky sort of MS mailer that adds funky line endings 
> to the file, you can wash it by the following command;
> sed 's/.$//' check_hpjd.c > foo && mv foo check_hpjd.c
> 
> Cheers.
> 
> 
> ------------------------------------------------------------------------
> 
> /******************************************************************************
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published by
> * the Free Software Foundation; either version 2 of the License, or
> * (at your option) any later version.
> *
> * This program is distributed in the hope that it will be useful,
> * but WITHOUT ANY WARRANTY; without even the implied warranty of
> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> * GNU General Public License for more details.
> *
> * You should have received a copy of the GNU General Public License
> * along with this program; if not, write to the Free Software
> * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> *
> * $Id: check_hpjd.c,v 1.31 2004/12/25 23:17:44 opensides Exp $
> *****************************************************************************/
> 
> const char *progname = "check_hpjd";
> const char *revision = "$Revision: 1.31 $";
> const char *copyright = "2000-2004";
> const char *email = "nagiosplug-devel at lists.sourceforge.net";
> 
> #include "common.h"
> #include "popen.h"
> #include "utils.h"
> #include "netutils.h"
> 
> #define DEFAULT_COMMUNITY "public"
> 
> 
> const char *option_summary = "-H host [-C community]\n";
> 
> #define HPJD_LINE_STATUS           ".1.3.6.1.4.1.11.2.3.9.1.1.2.1"
> #define HPJD_PAPER_STATUS          ".1.3.6.1.4.1.11.2.3.9.1.1.2.2"
> #define HPJD_INTERVENTION_REQUIRED ".1.3.6.1.4.1.11.2.3.9.1.1.2.3"
> #define HPJD_GD_PERIPHERAL_ERROR   ".1.3.6.1.4.1.11.2.3.9.1.1.2.6"
> #define HPJD_GD_PAPER_JAM          ".1.3.6.1.4.1.11.2.3.9.1.1.2.8"
> #define HPJD_GD_PAPER_OUT          ".1.3.6.1.4.1.11.2.3.9.1.1.2.9"
> #define HPJD_GD_TONER_LOW          ".1.3.6.1.4.1.11.2.3.9.1.1.2.10"
> #define HPJD_GD_PAGE_PUNT          ".1.3.6.1.4.1.11.2.3.9.1.1.2.11"
> #define HPJD_GD_MEMORY_OUT         ".1.3.6.1.4.1.11.2.3.9.1.1.2.12"
> #define HPJD_GD_DOOR_OPEN          ".1.3.6.1.4.1.11.2.3.9.1.1.2.17"
> #define HPJD_GD_PAPER_OUTPUT       ".1.3.6.1.4.1.11.2.3.9.1.1.2.19"
> #define HPJD_GD_STATUS_DISPLAY     ".1.3.6.1.4.1.11.2.3.9.1.1.3"
> #define SNMP_VARS 12
> 
> #define ONLINE		0
> #define OFFLINE		1
> 
> int process_arguments (int, char **);
> int validate_arguments (void);
> void print_help (void);
> void print_usage (void);
> 
> char *community = NULL;
> char *address = NULL;
> 
> int
> main (int argc, char **argv)
> {
> 	char command_line[1024];
> 	int result = STATE_UNKNOWN;
> 	int line, val = 0;
> 	char input_buffer[MAX_INPUT_BUFFER];
> 	char query_string[512];
> 	char *errmsg;
> 	char *temp_buffer;
> 	int line_status = ONLINE;
> 	int errorflag = 0;	/* bitflag error tracker */
> 	char *display_message;
> 	char *errmsg_strings[11];
> 	int i;
> 
> 	/* get the error messages. Will complain about discarded qualifiers
> 	 * with --disable-nls, but that doesn't matter since they're immutable */
> 	errmsg_strings[0] = _("Paper Jam");
> 	errmsg_strings[1] = _("Out of Paper");
> 	errmsg_strings[2] = _("Printer Offline");
> 	errmsg_strings[3] = _("Peripheral Error");
> 	errmsg_strings[4] = _("Intervention Required");
> 	errmsg_strings[5] = _("Toner Low");
> 	errmsg_strings[6] = _("Insufficient Memory");
> 	errmsg_strings[7] = _("A Door is Open");
> 	errmsg_strings[8] = _("Output Tray is Full");
> 	errmsg_strings[9] = _("Data too Slow for Engine");
> 	errmsg_strings[10] = _("Unknown Paper Error");
> 
> 	errmsg = malloc(MAX_INPUT_BUFFER);
> 
> 	setlocale (LC_ALL, "");
> 	bindtextdomain (PACKAGE, LOCALEDIR);
> 	textdomain (PACKAGE);
> 
> 	if (process_arguments (argc, argv) == ERROR)
> 		usage4 (_("Could not parse arguments"));
> 
> 	/* removed ' 2>1' at end of command 10/27/1999 - EG */
> 	/* create the query string */
> 	/* get status display line first, so we can match line status against
> 	 * powersave as we parse it */
> 	sprintf
> 		(query_string,
> 		 "%s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0 %s.0",
> 		 HPJD_GD_STATUS_DISPLAY,
> 		 HPJD_LINE_STATUS,
> 		 HPJD_PAPER_STATUS,
> 		 HPJD_INTERVENTION_REQUIRED,
> 		 HPJD_GD_PERIPHERAL_ERROR,
> 		 HPJD_GD_PAPER_JAM,
> 		 HPJD_GD_PAPER_OUT,
> 		 HPJD_GD_TONER_LOW,
> 		 HPJD_GD_PAGE_PUNT,
> 		 HPJD_GD_MEMORY_OUT,
> 		 HPJD_GD_DOOR_OPEN, HPJD_GD_PAPER_OUTPUT);
> 
> 	/* get the command to run */
> 	sprintf (command_line, "%s -Oqa -m : -v 1 -c %s %s %s", PATH_TO_SNMPGET, community,
> 	         address, query_string);
> 
> 	/* run the command */
> 	child_process = spopen (command_line);
> 	if (child_process == NULL) {
> 		printf (_("Could not open pipe: %s\n"), command_line);
> 		return STATE_UNKNOWN;
> 	}
> 
> 	child_stderr = fdopen (child_stderr_array[fileno (child_process)], "r");
> 	if (child_stderr == NULL) {
> 		/* don't print newline here, or we might return OK while
> 		 * only printing an error message (highly confusing) */
> 		printf (_("Could not open stderr for %s :: "), command_line);
> 	}
> 
> 	result = STATE_OK;
> 
> 	line = 0;
> 	/* end parsing when we have display_message, since we won't know
> 	 * what to do with line 13 or more anyway */
> 	while (fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_process)) {
> 		/* strip the newline character from the end of the input, if any */
> 		temp_buffer = strrchr(input_buffer, '\n');
> 		if(temp_buffer) *temp_buffer = '\0';
> 
> 		if(line == 0) {
> 			display_message = strdup(input_buffer);
> 			continue;
> 		}
> 		val = (int)strtol(input_buffer, NULL, 0);
> 		if(!val) continue; /* no errors here, so don't handle it */
> 		errorflag |= 1 << line; /* set the error flag */
> 
> 		/* this switch statement is largely for adding additional
> 		 * exception handling (POWERSAVE and such) */
> 		switch (line) {
> 		case 1:		/* line status */
> 			/* clear the flag if it's powersaving */
> 			if(!strstr("POWERSAVE ON", display_message) != 0)
> 				errorflag ^= 1 << line;
> 		case 2:		/* paper status */
> 		case 3:		/* intervention required */
> 		case 4:		/* peripheral error */
> 		case 5:		/* paper jam */
> 		case 6:		/* paper out */
> 		case 7:		/* toner low */
> 		case 8:		/* data came too slow for engine */
> 		case 9:		/* out of memory */
> 		case 10:	/* is there a door open */
> 		case 11:	/* is output tray full */
> 		default:	/* notreached */
> 			break;
> 		}
> 
> 		if(++line >= SNMP_VARS)
> 			break;
> 	}
> 
> 	/* WARNING if output found on stderr, but only if we
> 	 * haven't already found an error condition */
> 	if (!errorflag && fgets (input_buffer, MAX_INPUT_BUFFER - 1, child_stderr)) {
> 		result = max_state (result, STATE_WARNING);
> 		/* remove CRLF */
> 		if (input_buffer[strlen (input_buffer) - 1] == '\n')
> 			input_buffer[strlen (input_buffer) - 1] = 0;
> 		strncpy(errmsg, input_buffer, sizeof(errmsg));
> 	}
> 
> 	/* close stderr */
> 	(void) fclose (child_stderr);
> 
> 	/* close the pipe. set warning at least if snmpget didn't return 0 */
> 	if (spclose (child_process))
> 		result = STATE_WARNING;
> 
> 	/* if there wasn't any output, display an error */
> 	if (line == 0) {
> 		/* timeout is not necessarily the problem, and produces wildly
> 		 * inaccurate error messages when it isn't, so just say
> 		 * the host didn't return anything and return immediately
> 		 * (old plugin unconditionally escalated STATE_UNKNOWN to
> 		 * STATE_CRITICAL at the end, so this just saves a bit of
> 		 * output really. */
> 		/* it will unconditionally be escalated to STATE_CRITICAL later,
> 		 * so we might as well return that now. */
> 		printf (_("%s : No data returned from %s\n"), errmsg, address );
> 		return STATE_CRITICAL;
> 	}
> 
> 	/* obviously no read errors, so check the printer status results... */
> 	if (!errors) {
> 		result = STATE_OK;
> 		printf (_("Printer ok - (%s)\n"), display_message);
> 	}
> 	else {
> 		/* some error occured, so print them all */
> 		while(i < SNMP_VARS) {
> 			printf ("%s (%s)\n", errmsg ? errmsg : "", display_message);
> 			if((errorflag >> i) & 1) /* only print if flag is set */
> 				printf(":: %s", errmsg_strings[i++]);
> 		}
> 	}
> 
> 	return result;
> }
> 
> 
> /* process command-line arguments */
> int
> process_arguments (int argc, char **argv)
> {
> 	int c;
> 
> 	int option = 0;
> 	static struct option longopts[] = {
> 		{"hostname", required_argument, 0, 'H'},
> 		{"community", required_argument, 0, 'C'},
> /*  		{"critical",       required_argument,0,'c'}, */
> /*  		{"warning",        required_argument,0,'w'}, */
> /*  		{"port",           required_argument,0,'P'}, */
> 		{"version", no_argument, 0, 'V'},
> 		{"help", no_argument, 0, 'h'},
> 		{0, 0, 0, 0}
> 	};
> 
> 	if (argc < 2)
> 		return ERROR;
> 
> 	
> 	while (1) {
> 		c = getopt_long (argc, argv, "+hVH:C:", longopts, &option);
> 
> 		if (c == -1 || c == EOF || c == 1)
> 			break;
> 
> 		switch (c) {
> 		case 'H':									/* hostname */
> 			if (is_host (optarg)) {
> 				address = strscpy(address, optarg) ;
> 			}
> 			else {
> 				usage2 (_("Invalid hostname/address"), optarg);
> 			}
> 			break;
> 		case 'C':									/* community */
> 			community = strscpy (community, optarg);
> 			break;
> 		case 'V':									/* version */
> 			print_revision (progname, revision);
> 			exit (STATE_OK);
> 		case 'h':									/* help */
> 			print_help ();
> 			exit (STATE_OK);
> 		case '?':									/* help */
> 			usage2 (_("Unknown argument"), optarg);
> 		}
> 	}
> 
> 	c = optind;
> 	if (address == NULL) {
> 		if (is_host (argv[c])) {
> 			address = argv[c++];
> 		}
> 		else {
> 			usage2 (_("Invalid hostname/address"), argv[c]);
> 		}
> 	}
> 
> 	if (community == NULL) {
> 		if (argv[c] != NULL )
> 			community = argv[c];
> 		else
> 			community = DEFAULT_COMMUNITY;
> 	}
> 
> 	return validate_arguments ();
> }
> 
> 
> int
> validate_arguments (void)
> {
> 	return OK;
> }
> 
> 
> void
> print_help (void)
> {
> 	print_revision (progname, revision);
> 
> 	printf ("Copyright (c) 1999 Ethan Galstad <nagios at nagios.org>\n");
> 	printf (COPYRIGHT, copyright, email);
> 
> 	printf (_("\
> This plugin tests the STATUS of an HP printer with a JetDirect card.\n\
> Net-snmp must be installed on the computer running the plugin.\n\n"));
> 
> 	print_usage ();
> 
> 	printf (_(UT_HELP_VRSN));
> 
> 	printf (_("\
>  -C, --community=STRING\n\
>     The SNMP community name (default=%s)\n"), DEFAULT_COMMUNITY);
> 
> 	printf (_(UT_SUPPORT));
> }
> 
> 
> 
> void
> print_usage (void)
> {
> 	printf ("Usage: %s -H host [-C community]\n", progname);
> }

-- 
Andreas Ericsson                   andreas.ericsson at op5.se
OP5 AB                             www.op5.se
Lead Developer
-------------- next part --------------
A non-text attachment was scrubbed...
Name: check_hpjd.c
Type: text/x-csrc
Size: 9758 bytes
Desc: not available
URL: <https://www.monitoring-lists.org/archive/users/attachments/20050218/4fa4cd21/attachment.c>


More information about the Users mailing list