/* 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 #include #include #include #include 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 */ /** @} */