diff options
Diffstat (limited to 'agent/helpers/mode_end_call.c')
-rw-r--r-- | agent/helpers/mode_end_call.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/agent/helpers/mode_end_call.c b/agent/helpers/mode_end_call.c new file mode 100644 index 0000000..0bfcc69 --- /dev/null +++ b/agent/helpers/mode_end_call.c @@ -0,0 +1,127 @@ +/* Portions of this file are subject to the following copyright(s). See + * the Net-SNMP's COPYING file for more details and other copyrights + * that may apply: + */ +/* + * Portions of this file are copyrighted by: + * Copyright © 2003 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms specified in the COPYING file + * distributed with the Net-SNMP package. + */ +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-features.h> + +#include <net-snmp/net-snmp-includes.h> +#include <net-snmp/agent/net-snmp-agent-includes.h> + +#include <net-snmp/agent/mode_end_call.h> + +netsnmp_feature_provide(mode_end_call) +netsnmp_feature_child_of(mode_end_call, mib_helpers) + +#ifndef NETSNMP_FEATURE_REMOVE_MODE_END_CALL +/** @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 utilities + * @{ + */ + +/** 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 endlist 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 = NULL; + + 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 = (netsnmp_mode_handler_list*)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; +} +#else +netsnmp_feature_unused(mode_end_call); +#endif /* NETSNMP_FEATURE_REMOVE_MODE_END_CALL */ + + +/** @} */ + |