summaryrefslogtreecommitdiff
path: root/agent/mibgroup/host/hr_print.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/mibgroup/host/hr_print.c')
-rw-r--r--agent/mibgroup/host/hr_print.c368
1 files changed, 368 insertions, 0 deletions
diff --git a/agent/mibgroup/host/hr_print.c b/agent/mibgroup/host/hr_print.c
new file mode 100644
index 0000000..e7660ff
--- /dev/null
+++ b/agent/mibgroup/host/hr_print.c
@@ -0,0 +1,368 @@
+/*
+ * 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, NETSNMP_OLDAPI_RONLY,
+ var_hrprint, 2, {1, 1}},
+ {HRPRINT_ERROR, ASN_OCTET_STR, NETSNMP_OLDAPI_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", " %d\n", 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 range\n"));
+ return (MATCH_FAILED);
+ }
+
+ memcpy((char *) name, (char *) newname,
+ (vp->namelen + 1) * sizeof(oid));
+ *length = vp->namelen + 1;
+ *write_method = (WriteMethod*)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 NETSNMP_NO_DUMMY_VALUES
+ return NULL;
+#else
+ long_return = 0; /* Null string */
+ return (u_char *) & long_return;
+#endif
+ default:
+ DEBUGMSGTL(("host/hr_print", "unknown sub-id %d in var_hrprint\n",
+ 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 %s\n", 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