hr_print.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:9k
- /*
- * Host Resources MIB - printer device group implementation - hr_print.c
- *
- */
- #include <net-snmp/net-snmp-config.h>
- #if HAVE_STRING_H
- #include <string.h>
- #else
- #include <strings.h>
- #endif
- #if HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #include "host_res.h"
- #include "hr_print.h"
- #include "struct.h"
- #include "util_funcs.h"
- #define HRPRINT_MONOTONICALLY_INCREASING
- /*********************
- *
- * Kernel & interface information,
- * and internal forward declarations
- *
- *********************/
- void Init_HR_Print(void);
- int Get_Next_HR_Print(void);
- void Save_HR_Print(void);
- const char *describe_printer(int);
- int printer_status(int);
- int printer_detail_status(int);
- int printer_errors(int);
- int header_hrprint(struct variable *, oid *, size_t *, int,
- size_t *, WriteMethod **);
- FILE *run_lpstat(int *);
- /*********************
- *
- * Initialisation & common implementation functions
- *
- *********************/
- #define HRPRINT_STATUS 1
- #define HRPRINT_ERROR 2
- struct variable4 hrprint_variables[] = {
- {HRPRINT_STATUS, ASN_INTEGER, RONLY, var_hrprint, 2, {1, 1}},
- {HRPRINT_ERROR, ASN_OCTET_STR, RONLY, var_hrprint, 2, {1, 2}}
- };
- oid hrprint_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 3, 5 };
- void
- init_hr_print(void)
- {
- init_device[HRDEV_PRINTER] = Init_HR_Print;
- next_device[HRDEV_PRINTER] = Get_Next_HR_Print;
- /*
- * save_device[ HRDEV_PRINTER ] = Save_HR_Print;
- */
- #ifdef HRPRINT_MONOTONICALLY_INCREASING
- dev_idx_inc[HRDEV_PRINTER] = 1;
- #endif
- device_descr[HRDEV_PRINTER] = describe_printer;
- device_status[HRDEV_PRINTER] = printer_status;
- device_errors[HRDEV_PRINTER] = printer_errors;
- REGISTER_MIB("host/hr_print", hrprint_variables, variable4,
- hrprint_variables_oid);
- }
- /*
- * header_hrprint(...
- * Arguments:
- * vp IN - pointer to variable entry that points here
- * name IN/OUT - IN/name requested, OUT/name found
- * length IN/OUT - length of IN/OUT oid's
- * exact IN - TRUE if an exact match was requested
- * var_len OUT - length of variable or 0 if function returned
- * write_method
- *
- */
- int
- header_hrprint(struct variable *vp,
- oid * name,
- size_t * length,
- int exact, size_t * var_len, WriteMethod ** write_method)
- {
- #define HRPRINT_ENTRY_NAME_LENGTH 11
- oid newname[MAX_OID_LEN];
- int print_idx, LowIndex = -1;
- int result;
- DEBUGMSGTL(("host/hr_print", "var_hrprint: "));
- DEBUGMSGOID(("host/hr_print", name, *length));
- DEBUGMSG(("host/hr_print", " %dn", exact));
- memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
- /*
- * Find "next" print entry
- */
- Init_HR_Print();
- for (;;) {
- print_idx = Get_Next_HR_Print();
- if (print_idx == -1)
- break;
- newname[HRPRINT_ENTRY_NAME_LENGTH] = print_idx;
- result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
- if (exact && (result == 0)) {
- LowIndex = print_idx;
- /*
- * Save printer status information
- */
- break;
- }
- if ((!exact && (result < 0)) &&
- (LowIndex == -1 || print_idx < LowIndex)) {
- LowIndex = print_idx;
- /*
- * Save printer status information
- */
- #ifdef HRPRINT_MONOTONICALLY_INCREASING
- break;
- #endif
- }
- }
- if (LowIndex == -1) {
- DEBUGMSGTL(("host/hr_print", "... index out of rangen"));
- return (MATCH_FAILED);
- }
- memcpy((char *) name, (char *) newname,
- (vp->namelen + 1) * sizeof(oid));
- *length = vp->namelen + 1;
- *write_method = 0;
- *var_len = sizeof(long); /* default to 'long' results */
- DEBUGMSGTL(("host/hr_print", "... get print stats "));
- DEBUGMSGOID(("host/hr_print", name, *length));
- DEBUGMSG(("host/hr_print", "n"));
- return LowIndex;
- }
- /*********************
- *
- * System specific implementation functions
- *
- *********************/
- u_char *
- var_hrprint(struct variable * vp,
- oid * name,
- size_t * length,
- int exact, size_t * var_len, WriteMethod ** write_method)
- {
- int print_idx;
- print_idx =
- header_hrprint(vp, name, length, exact, var_len, write_method);
- if (print_idx == MATCH_FAILED)
- return NULL;
- switch (vp->magic) {
- case HRPRINT_STATUS:
- long_return = printer_detail_status(print_idx);
- return (u_char *) & long_return;
- case HRPRINT_ERROR:
- #if NO_DUMMY_VALUES
- return NULL;
- #endif
- long_return = 0; /* Null string */
- return (u_char *) & long_return;
- default:
- DEBUGMSGTL(("host/hr_print", "unknown sub-id %d in var_hrprintn",
- vp->magic));
- }
- return NULL;
- }
- /*********************
- *
- * Internal implementation functions
- *
- *********************/
- static int HRP_index;
- static char **HRP_name;
- static int HRP_nbrnames, HRP_maxnames;
- #define HRP_MAX_INCR 10
- void
- Init_HR_Print(void)
- {
- #if HAVE_LPSTAT || HAVE_CGETNEXT || HAVE_PRINTCAP
- int i;
- #if HAVE_PRINTCAP
- FILE *p;
- #elif HAVE_CGETNEXT
- const char *caps[] = { "/etc/printcap", NULL };
- #elif HAVE_LPSTAT
- int fd;
- FILE *p;
- #endif
- HRP_index = 0; /* fail safe at Get_Next_HR_Print */
- if (HRP_name) {
- for (i = 0; i < HRP_nbrnames; i++)
- free(HRP_name[i]);
- HRP_nbrnames = 0;
- HRP_maxnames = 0;
- SNMP_FREE(HRP_name);
- }
- #if HAVE_PRINTCAP
- if ((p = fopen("/etc/printcap", "r")) != NULL) {
- char buf[BUFSIZ], *ptr;
- while (fgets(buf, sizeof buf, p)) {
- buf[strlen(buf) - 1] = 0;
- if (buf[0] == '#' || buf[0] == 0 || buf[0] == ' '
- || buf[0] == 't')
- continue;
- if ((ptr = strchr(buf, '\')))
- *ptr = 0;
- if ((ptr = strchr(buf, ':')))
- *ptr = 0;
- if ((ptr = strchr(buf, '|')))
- *ptr = 0;
- ptr = buf;
- #elif HAVE_CGETNEXT
- {
- char *buf = NULL, *ptr;
- while (cgetnext(&buf, caps) > 0) {
- if ((ptr = strchr(buf, ':')))
- *ptr = 0;
- if ((ptr = strchr(buf, '|')))
- *ptr = 0;
- ptr = buf;
- #elif HAVE_LPSTAT
- if ((p = run_lpstat(&fd)) != NULL) {
- char buf[BUFSIZ], ptr[BUFSIZ];
- while (fgets(buf, sizeof buf, p)) {
- sscanf(buf, "%*s %*s %[^:]", ptr);
- #endif
- if (HRP_nbrnames == HRP_maxnames) {
- char **tmp;
- tmp = (char **) calloc(HRP_maxnames + HRP_MAX_INCR, sizeof(char *));
- if (!tmp)
- goto finish;
- if (HRP_name) {
- memcpy(tmp, HRP_name, HRP_nbrnames * sizeof(char *));
- free(HRP_name);
- }
- HRP_maxnames += HRP_MAX_INCR;
- HRP_name = tmp;
- }
- HRP_name[HRP_nbrnames++] = strdup(ptr);
- #if !defined(HAVE_PRINTCAP) && defined(HAVE_CGETNEXT)
- if (buf)
- free(buf);
- #endif
- }
- finish:
- #if HAVE_PRINTCAP
- fclose(p);
- #elif HAVE_CGETNEXT
- cgetclose();
- #elif HAVE_LPSTAT
- fclose(p);
- close(fd);
- #endif
- }
- #endif /* HAVE_anything */
- }
- int
- Get_Next_HR_Print(void)
- {
- /*
- * The initial implementation system
- * has no printers attached, and I've
- * no real idea how to detect them,
- * so don't bother.
- */
- if (HRP_index < HRP_nbrnames) /* No printer */
- return (HRDEV_PRINTER << HRDEV_TYPE_SHIFT) + HRP_index++;
- else
- return -1;
- }
- const char *
- describe_printer(int idx)
- {
- if (HRP_index == 0) /* return empty string if not initialized */
- return "";
- DEBUGMSGTL(("host/hr_print", "describe p: %d/%d %sn", HRP_index, idx,
- HRP_name[HRP_index - 1]));
- return HRP_name[HRP_index - 1];
- }
- int
- printer_status(int idx)
- {
- /*
- * hrDeviceStatus OBJECT-TYPE
- * SYNTAX INTEGER {
- * unknown(1), running(2), warning(3), testing(4), down(5)
- * }
- */
- return 1; /* unknown */
- }
- int
- printer_detail_status(int idx)
- {
- /*
- * hrPrinterStatus OBJECT-TYPE
- * SYNTAX INTEGER {
- * other(1), unknown(2), idle(3), printing(4), warmup(5)
- * }
- */
- return 2; /* unknown */
- }
- int
- printer_errors(int idx)
- {
- return 0;
- }
- #ifdef HAVE_LPSTAT
- /*
- * Run the lpstat command. If compiled with EXCACHE support, this
- * will actually cache the output for a while which helps a lot
- * with snmpbulkwalk (in fact, it keeps the client from exiting
- * due to timeouts).
- */
- FILE *
- run_lpstat(int *fd)
- {
- struct extensible ex;
- memset(&ex, 0, sizeof(ex));
- strcpy(ex.command, LPSTAT_PATH " -v");
- if ((*fd = get_exec_output(&ex)) < 0)
- return NULL;
- return fdopen(*fd, "r");
- }
- #endif