hr_print.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:9k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  *  Host Resources MIB - printer device group implementation - hr_print.c
  3.  *
  4.  */
  5. #include <net-snmp/net-snmp-config.h>
  6. #if HAVE_STRING_H
  7. #include <string.h>
  8. #else
  9. #include <strings.h>
  10. #endif
  11. #if HAVE_UNISTD_H
  12. #include <unistd.h>
  13. #endif
  14. #include "host_res.h"
  15. #include "hr_print.h"
  16. #include "struct.h"
  17. #include "util_funcs.h"
  18. #define HRPRINT_MONOTONICALLY_INCREASING
  19.         /*********************
  20.  *
  21.  *  Kernel & interface information,
  22.  *   and internal forward declarations
  23.  *
  24.  *********************/
  25. void            Init_HR_Print(void);
  26. int             Get_Next_HR_Print(void);
  27. void            Save_HR_Print(void);
  28. const char     *describe_printer(int);
  29. int             printer_status(int);
  30. int             printer_detail_status(int);
  31. int             printer_errors(int);
  32. int             header_hrprint(struct variable *, oid *, size_t *, int,
  33.                                size_t *, WriteMethod **);
  34. FILE           *run_lpstat(int *);
  35.         /*********************
  36.  *
  37.  *  Initialisation & common implementation functions
  38.  *
  39.  *********************/
  40. #define HRPRINT_STATUS 1
  41. #define HRPRINT_ERROR 2
  42. struct variable4 hrprint_variables[] = {
  43.     {HRPRINT_STATUS, ASN_INTEGER, RONLY, var_hrprint, 2, {1, 1}},
  44.     {HRPRINT_ERROR, ASN_OCTET_STR, RONLY, var_hrprint, 2, {1, 2}}
  45. };
  46. oid             hrprint_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 3, 5 };
  47. void
  48. init_hr_print(void)
  49. {
  50.     init_device[HRDEV_PRINTER] = Init_HR_Print;
  51.     next_device[HRDEV_PRINTER] = Get_Next_HR_Print;
  52.     /*
  53.      * save_device[ HRDEV_PRINTER ] = Save_HR_Print;        
  54.      */
  55. #ifdef HRPRINT_MONOTONICALLY_INCREASING
  56.     dev_idx_inc[HRDEV_PRINTER] = 1;
  57. #endif
  58.     device_descr[HRDEV_PRINTER] = describe_printer;
  59.     device_status[HRDEV_PRINTER] = printer_status;
  60.     device_errors[HRDEV_PRINTER] = printer_errors;
  61.     REGISTER_MIB("host/hr_print", hrprint_variables, variable4,
  62.                  hrprint_variables_oid);
  63. }
  64. /*
  65.  * header_hrprint(...
  66.  * Arguments:
  67.  * vp     IN      - pointer to variable entry that points here
  68.  * name    IN/OUT  - IN/name requested, OUT/name found
  69.  * length  IN/OUT  - length of IN/OUT oid's 
  70.  * exact   IN      - TRUE if an exact match was requested
  71.  * var_len OUT     - length of variable or 0 if function returned
  72.  * write_method
  73.  * 
  74.  */
  75. int
  76. header_hrprint(struct variable *vp,
  77.                oid * name,
  78.                size_t * length,
  79.                int exact, size_t * var_len, WriteMethod ** write_method)
  80. {
  81. #define HRPRINT_ENTRY_NAME_LENGTH 11
  82.     oid             newname[MAX_OID_LEN];
  83.     int             print_idx, LowIndex = -1;
  84.     int             result;
  85.     DEBUGMSGTL(("host/hr_print", "var_hrprint: "));
  86.     DEBUGMSGOID(("host/hr_print", name, *length));
  87.     DEBUGMSG(("host/hr_print", " %dn", exact));
  88.     memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
  89.     /*
  90.      * Find "next" print entry 
  91.      */
  92.     Init_HR_Print();
  93.     for (;;) {
  94.         print_idx = Get_Next_HR_Print();
  95.         if (print_idx == -1)
  96.             break;
  97.         newname[HRPRINT_ENTRY_NAME_LENGTH] = print_idx;
  98.         result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
  99.         if (exact && (result == 0)) {
  100.             LowIndex = print_idx;
  101.             /*
  102.              * Save printer status information 
  103.              */
  104.             break;
  105.         }
  106.         if ((!exact && (result < 0)) &&
  107.             (LowIndex == -1 || print_idx < LowIndex)) {
  108.             LowIndex = print_idx;
  109.             /*
  110.              * Save printer status information 
  111.              */
  112. #ifdef HRPRINT_MONOTONICALLY_INCREASING
  113.             break;
  114. #endif
  115.         }
  116.     }
  117.     if (LowIndex == -1) {
  118.         DEBUGMSGTL(("host/hr_print", "... index out of rangen"));
  119.         return (MATCH_FAILED);
  120.     }
  121.     memcpy((char *) name, (char *) newname,
  122.            (vp->namelen + 1) * sizeof(oid));
  123.     *length = vp->namelen + 1;
  124.     *write_method = 0;
  125.     *var_len = sizeof(long);    /* default to 'long' results */
  126.     DEBUGMSGTL(("host/hr_print", "... get print stats "));
  127.     DEBUGMSGOID(("host/hr_print", name, *length));
  128.     DEBUGMSG(("host/hr_print", "n"));
  129.     return LowIndex;
  130. }
  131.         /*********************
  132.  *
  133.  *  System specific implementation functions
  134.  *
  135.  *********************/
  136. u_char         *
  137. var_hrprint(struct variable * vp,
  138.             oid * name,
  139.             size_t * length,
  140.             int exact, size_t * var_len, WriteMethod ** write_method)
  141. {
  142.     int             print_idx;
  143.     print_idx =
  144.         header_hrprint(vp, name, length, exact, var_len, write_method);
  145.     if (print_idx == MATCH_FAILED)
  146.         return NULL;
  147.     switch (vp->magic) {
  148.     case HRPRINT_STATUS:
  149.         long_return = printer_detail_status(print_idx);
  150.         return (u_char *) & long_return;
  151.     case HRPRINT_ERROR:
  152. #if NO_DUMMY_VALUES
  153.         return NULL;
  154. #endif
  155.         long_return = 0;        /* Null string */
  156.         return (u_char *) & long_return;
  157.     default:
  158.         DEBUGMSGTL(("host/hr_print", "unknown sub-id %d in var_hrprintn",
  159.                     vp->magic));
  160.     }
  161.     return NULL;
  162. }
  163.         /*********************
  164.  *
  165.  *  Internal implementation functions
  166.  *
  167.  *********************/
  168. static int      HRP_index;
  169. static char   **HRP_name;
  170. static int      HRP_nbrnames, HRP_maxnames;
  171. #define HRP_MAX_INCR 10
  172. void
  173. Init_HR_Print(void)
  174. {
  175. #if HAVE_LPSTAT || HAVE_CGETNEXT || HAVE_PRINTCAP
  176.     int             i;
  177. #if HAVE_PRINTCAP
  178.     FILE           *p;
  179. #elif HAVE_CGETNEXT
  180.     const char     *caps[] = { "/etc/printcap", NULL };
  181. #elif HAVE_LPSTAT
  182.     int             fd;
  183.     FILE           *p;
  184. #endif
  185.     HRP_index = 0; /* fail safe at Get_Next_HR_Print */
  186.     if (HRP_name) {
  187.         for (i = 0; i < HRP_nbrnames; i++)
  188.             free(HRP_name[i]);
  189.         HRP_nbrnames = 0;
  190.         HRP_maxnames = 0;
  191.         SNMP_FREE(HRP_name);
  192.     }
  193. #if HAVE_PRINTCAP
  194.     if ((p = fopen("/etc/printcap", "r")) != NULL) {
  195.         char            buf[BUFSIZ], *ptr;
  196.         while (fgets(buf, sizeof buf, p)) {
  197.             buf[strlen(buf) - 1] = 0;
  198.             if (buf[0] == '#' || buf[0] == 0 || buf[0] == ' '
  199.                 || buf[0] == 't')
  200.                 continue;
  201.             if ((ptr = strchr(buf, '\')))
  202.                 *ptr = 0;
  203.             if ((ptr = strchr(buf, ':')))
  204.                 *ptr = 0;
  205.             if ((ptr = strchr(buf, '|')))
  206.                 *ptr = 0;
  207.             ptr = buf;
  208. #elif HAVE_CGETNEXT
  209.     {
  210.         char           *buf = NULL, *ptr;
  211.         while (cgetnext(&buf, caps) > 0) {
  212.             if ((ptr = strchr(buf, ':')))
  213.                 *ptr = 0;
  214.             if ((ptr = strchr(buf, '|')))
  215.                 *ptr = 0;
  216.             ptr = buf;
  217. #elif HAVE_LPSTAT
  218.     if ((p = run_lpstat(&fd)) != NULL) {
  219.         char            buf[BUFSIZ], ptr[BUFSIZ];
  220.         while (fgets(buf, sizeof buf, p)) {
  221.             sscanf(buf, "%*s %*s %[^:]", ptr);
  222. #endif
  223.             if (HRP_nbrnames == HRP_maxnames) {
  224.                 char          **tmp;
  225.                 tmp = (char **) calloc(HRP_maxnames + HRP_MAX_INCR, sizeof(char *));
  226.                 if (!tmp)
  227.                     goto finish;
  228. if (HRP_name) {
  229. memcpy(tmp, HRP_name, HRP_nbrnames * sizeof(char *));
  230. free(HRP_name);
  231. }
  232.                 HRP_maxnames += HRP_MAX_INCR;
  233.                 HRP_name = tmp;
  234.             }
  235.             HRP_name[HRP_nbrnames++] = strdup(ptr);
  236. #if !defined(HAVE_PRINTCAP) && defined(HAVE_CGETNEXT)
  237.             if (buf)
  238.                 free(buf);
  239. #endif
  240.         }
  241. finish:
  242. #if HAVE_PRINTCAP
  243.         fclose(p);
  244. #elif HAVE_CGETNEXT
  245.         cgetclose();
  246. #elif HAVE_LPSTAT
  247.         fclose(p);
  248.         close(fd);
  249. #endif
  250.     }
  251. #endif                          /* HAVE_anything */
  252. }
  253. int
  254. Get_Next_HR_Print(void)
  255. {
  256.     /*
  257.      * The initial implementation system
  258.      *   has no printers attached, and I've
  259.      *   no real idea how to detect them,
  260.      *   so don't bother.
  261.      */
  262.     if (HRP_index < HRP_nbrnames)  /* No printer */
  263.         return (HRDEV_PRINTER << HRDEV_TYPE_SHIFT) + HRP_index++;
  264.     else
  265.         return -1;
  266. }
  267. const char     *
  268. describe_printer(int idx)
  269. {
  270.     if (HRP_index == 0)  /* return empty string if not initialized */
  271. return "";
  272.     DEBUGMSGTL(("host/hr_print", "describe p: %d/%d %sn", HRP_index, idx,
  273.                 HRP_name[HRP_index - 1]));
  274.     return HRP_name[HRP_index - 1];
  275. }
  276. int
  277. printer_status(int idx)
  278. {
  279.     /*
  280.      * hrDeviceStatus OBJECT-TYPE
  281.      * SYNTAX     INTEGER {
  282.      * unknown(1), running(2), warning(3), testing(4), down(5)
  283.      * }
  284.      */
  285.     return 1;                   /* unknown */
  286. }
  287. int
  288. printer_detail_status(int idx)
  289. {
  290.     /*
  291.      * hrPrinterStatus OBJECT-TYPE
  292.      * SYNTAX     INTEGER {
  293.      * other(1), unknown(2), idle(3), printing(4), warmup(5)
  294.      * }
  295.      */
  296.     return 2;                   /* unknown */
  297. }
  298. int
  299. printer_errors(int idx)
  300. {
  301.     return 0;
  302. }
  303. #ifdef        HAVE_LPSTAT
  304. /*
  305.  * Run the lpstat command. If compiled with EXCACHE support, this
  306.  * will actually cache the output for a while which helps a lot
  307.  * with snmpbulkwalk (in fact, it keeps the client from exiting
  308.  * due to timeouts).
  309.  */
  310. FILE           *
  311. run_lpstat(int *fd)
  312. {
  313.     struct extensible ex;
  314.     memset(&ex, 0, sizeof(ex));
  315.     strcpy(ex.command, LPSTAT_PATH " -v");
  316.     if ((*fd = get_exec_output(&ex)) < 0)
  317.         return NULL;
  318.     return fdopen(*fd, "r");
  319. }
  320. #endif