X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=userapps%2Fopensource%2Fnet-snmp%2Fagent%2Fhelpers%2Fmode_end_call.c;fp=userapps%2Fopensource%2Fnet-snmp%2Fagent%2Fhelpers%2Fmode_end_call.c;h=a7da8aaec375a3004ab014e5f411ce26dbdbc3e1;hb=9dffd9f7659a1b28265e0dc9497343eb3d108d02;hp=0000000000000000000000000000000000000000;hpb=e48c2529a5a7e7dbf1797bb6d1bf964bc03e78a7;p=bcm963xx.git diff --git a/userapps/opensource/net-snmp/agent/helpers/mode_end_call.c b/userapps/opensource/net-snmp/agent/helpers/mode_end_call.c new file mode 100644 index 00000000..a7da8aae --- /dev/null +++ b/userapps/opensource/net-snmp/agent/helpers/mode_end_call.c @@ -0,0 +1,108 @@ +#include + +#include +#include + +#include + +#if HAVE_DMALLOC_H +#include +#endif + +/** @defgroup mode_end_call mode_end_call: at the end of a series of requests, call another handler hook. + * Handlers that want to loop through a series of requests and then + * receive a callback at the end of a particular MODE can use this + * helper to make this possible. For most modules, this is not + * needed as the handler itself could perform a for() loop around the + * request list and then perform its actions afterwards. However, if + * something like the serialize helper is in use this isn't possible + * because not all the requests for a given handler are being passed + * downward in a single group. Thus, this helper *must* be added + * above other helpers like the serialize helper to be useful. + * + * Multiple mode specific handlers can be registered and will be + * called in the order they were regestered in. Callbacks regesterd + * with a mode of NETSNMP_MODE_END_ALL_MODES will be called for all + * modes. + * + * @ingroup handler + * @{ + */ + +/** returns a mode_end_call handler that can be injected into a given + * handler chain. + * @param endlist The callback list for the handler to make use of. + * @return An injectable Net-SNMP handler. + */ +netsnmp_mib_handler * +netsnmp_get_mode_end_call_handler(netsnmp_mode_handler_list *endlist) +{ + netsnmp_mib_handler *me = + netsnmp_create_handler("mode_end_call", + netsnmp_mode_end_call_helper); + + if (!me) + return NULL; + + me->myvoid = endlist; + return me; +} + +/** adds a mode specific callback to the callback list. + * @param endinfo the information structure for the mode_end_call helper. Can be NULL to create a new list. + * @param mode the mode to be called upon. A mode of NETSNMP_MODE_END_ALL_MODES = all modes. + * @param callbackh the netsnmp_mib_handler callback to call. + * @return the new registration information list upon success. + */ +netsnmp_mode_handler_list * +netsnmp_mode_end_call_add_mode_callback(netsnmp_mode_handler_list *endlist, + int mode, + netsnmp_mib_handler *callbackh) { + netsnmp_mode_handler_list *ptr, *ptr2; + ptr = SNMP_MALLOC_TYPEDEF(netsnmp_mode_handler_list); + if (!ptr) + return NULL; + + ptr->mode = mode; + ptr->callback_handler = callbackh; + ptr->next = endlist; + + if (!endlist) + return ptr; + + /* get to end */ + for(ptr2 = endlist; ptr2->next != NULL; ptr2 = ptr2->next); + + ptr2->next = ptr; + return endlist; +} + +/** @internal Implements the mode_end_call handler */ +int +netsnmp_mode_end_call_helper(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + + int ret; + int ret2 = SNMP_ERR_NOERROR; + netsnmp_mode_handler_list *ptr; + + /* always call the real handlers first */ + ret = netsnmp_call_next_handler(handler, reginfo, reqinfo, + requests); + + /* then call the callback handlers */ + for(ptr = handler->myvoid; ptr; ptr = ptr->next) { + if (ptr->mode == NETSNMP_MODE_END_ALL_MODES || + reqinfo->mode == ptr->mode) { + ret2 = netsnmp_call_handler(ptr->callback_handler, reginfo, + reqinfo, requests); + if (ret != SNMP_ERR_NOERROR) + ret = ret2; + } + } + + return ret2; +}