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

SNMP编程

开发平台:

Unix_Linux

  1. #include <net-snmp/net-snmp-config.h>
  2. #if HAVE_STRING_H
  3. #include <string.h>
  4. #else
  5. #include <strings.h>
  6. #endif
  7. #include <net-snmp/net-snmp-includes.h>
  8. #include <net-snmp/agent/net-snmp-agent-includes.h>
  9. #include <net-snmp/agent/stash_cache.h>
  10. #if HAVE_DMALLOC_H
  11. #include <dmalloc.h>
  12. #endif
  13. /** @defgroup stash_cache stash_cache: automatically caches data for certain handlers.
  14.  *  This handler caches data in an optimized way which may aleviate
  15.  *  the need for the lower level handlers to perform as much
  16.  *  optimization.  Specifically, somewhere in the lower level handlers
  17.  *  must be a handler that supports the MODE_GET_STASH operation.
  18.  *  Note that the table_iterator helper supports this.
  19.  *  @ingroup handler
  20.  *  @{
  21.  */
  22. netsnmp_stash_cache_info *
  23. netsnmp_get_new_stash_cache(void)
  24. {
  25.     netsnmp_stash_cache_info *cinfo;
  26.     cinfo = SNMP_MALLOC_TYPEDEF(netsnmp_stash_cache_info);
  27.     cinfo->cache_length = 30;
  28.     return cinfo;
  29. }
  30. /** returns a stash_cache handler that can be injected into a given
  31.  *  handler chain.
  32.  */
  33. netsnmp_mib_handler *
  34. netsnmp_get_stash_cache_handler(void)
  35. {
  36.     netsnmp_mib_handler *handler;
  37.     netsnmp_stash_cache_info *cinfo;
  38.     cinfo = netsnmp_get_new_stash_cache();
  39.     if (!cinfo)
  40.         return NULL;
  41.     handler = netsnmp_create_handler("stash_cache", netsnmp_stash_cache_helper);
  42.     if (!handler) {
  43.         free(cinfo);
  44.         return NULL;
  45.     }
  46.     handler->myvoid = cinfo;
  47.     return handler;
  48. }
  49. /** extracts a pointer to the stash_cache info from the reqinfo structure. */
  50. netsnmp_oid_stash_node  **
  51. netsnmp_extract_stash_cache(netsnmp_agent_request_info *reqinfo)
  52. {
  53.     return netsnmp_agent_get_list_data(reqinfo, STASH_CACHE_NAME);
  54. }
  55. /** @internal Implements the stash_cache handler */
  56. int
  57. netsnmp_stash_cache_helper(netsnmp_mib_handler *handler,
  58.                            netsnmp_handler_registration *reginfo,
  59.                            netsnmp_agent_request_info *reqinfo,
  60.                            netsnmp_request_info *requests)
  61. {
  62.     netsnmp_stash_cache_info *cinfo;
  63.     netsnmp_oid_stash_node *cnode;
  64.     netsnmp_variable_list *cdata;
  65.     netsnmp_request_info *request;
  66.     int ret;
  67.     DEBUGMSGTL(("helper:stash_cache", "Got requestn"));
  68.     cinfo = (netsnmp_stash_cache_info *) handler->myvoid;
  69.     if (!cinfo) {
  70.         cinfo = netsnmp_get_new_stash_cache();
  71.         handler->myvoid = cinfo;
  72.     }
  73.     switch (reqinfo->mode) {
  74.     case MODE_GET:
  75.         if ((ret = netsnmp_stash_cache_update(handler, reginfo,
  76.                                               reqinfo, requests, cinfo)))
  77.             return ret;
  78.         for(request = requests; request; request = request->next) {
  79.             cdata =
  80.                 netsnmp_oid_stash_get_data(cinfo->cache,
  81.                                            requests->requestvb->name,
  82.                                            requests->requestvb->name_length);
  83.             if (cdata && cdata->val.string && cdata->val_len) {
  84.                 snmp_set_var_typed_value(request->requestvb, cdata->type,
  85.                                          cdata->val.string, cdata->val_len);
  86.             }
  87.         }
  88.         return SNMP_ERR_NOERROR;
  89.         break;
  90.     case MODE_GETNEXT:
  91.         if ((ret = netsnmp_stash_cache_update(handler, reginfo,
  92.                                               reqinfo, requests, cinfo)))
  93.             return ret;
  94.         for(request = requests; request; request = request->next) {
  95.             cnode =
  96.                 netsnmp_oid_stash_getnext_node(cinfo->cache,
  97.                                                requests->requestvb->name,
  98.                                                requests->requestvb->name_length);
  99.             if (cnode && cnode->thedata) {
  100.                 cdata = cnode->thedata;
  101.                 if (cdata->val.string && cdata->name && cdata->name_length) {
  102.                     snmp_set_var_typed_value(request->requestvb, cdata->type,
  103.                                              cdata->val.string, cdata->val_len);
  104.                     snmp_set_var_objid(request->requestvb, cdata->name,
  105.                                        cdata->name_length);
  106.                 }
  107.             }
  108.         }
  109.         return SNMP_ERR_NOERROR;
  110.         break;
  111.     default:
  112.         cinfo->cache_valid = 0;
  113.         return netsnmp_call_next_handler(handler, reginfo, reqinfo,
  114.                                          requests);
  115.     }
  116.     return SNMP_ERR_GENERR;     /* should never get here */
  117. }
  118. /** updates a given cache depending on whether it needs to or not.
  119.  */
  120. int
  121. netsnmp_stash_cache_update(netsnmp_mib_handler *handler,
  122.                            netsnmp_handler_registration *reginfo,
  123.                            netsnmp_agent_request_info *reqinfo,
  124.                            netsnmp_request_info *requests,
  125.                            netsnmp_stash_cache_info *cinfo)
  126. {
  127.     int old_mode;
  128.     int ret;
  129.     if (!cinfo->cache_time ||
  130.         atime_ready(cinfo->cache_time, 1000*cinfo->cache_length)) {
  131.         DEBUGMSGTL(("stash_cache",
  132.                     "(re)filling cache (done every %d seconds)n",
  133.                     cinfo->cache_length));
  134.         /* free the old */
  135.         netsnmp_oid_stash_free(&cinfo->cache,
  136.                                (NetSNMPStashFreeNode *) snmp_free_var);
  137.         /* change modes to the GET_STASH mode */
  138.         old_mode = reqinfo->mode;
  139.         reqinfo->mode = MODE_GET_STASH;
  140.         netsnmp_agent_add_list_data(reqinfo,
  141.                                     netsnmp_create_data_list(STASH_CACHE_NAME,
  142.                                                              &cinfo->cache,
  143.                                                              NULL));
  144.         /* have the next handler fill stuff in and switch modes back */
  145.         ret = netsnmp_call_next_handler(handler, reginfo, reqinfo, requests);
  146.         reqinfo->mode = old_mode;
  147.         /* update the cache time */
  148.         if (cinfo->cache_time) {
  149.             atime_setMarker(cinfo->cache_time);
  150.         } else {
  151.             cinfo->cache_time = atime_newMarker();
  152.         }
  153.         return ret;
  154.     }
  155.     return SNMP_ERR_NOERROR;
  156. }
  157. /** initializes the stash_cache helper which then registers a stash_cache
  158.  *  handler as a run-time injectable handler for configuration file
  159.  *  use.
  160.  */
  161. void
  162. netsnmp_init_stash_cache_helper(void)
  163. {
  164.     netsnmp_register_handler_by_name("stash_cache",
  165.                                      netsnmp_get_stash_cache_handler());
  166. }