and added files
[bcm963xx.git] / userapps / opensource / net-snmp / agent / helpers / mode_end_call.c
1 #include <net-snmp/net-snmp-config.h>
2
3 #include <net-snmp/net-snmp-includes.h>
4 #include <net-snmp/agent/net-snmp-agent-includes.h>
5
6 #include <net-snmp/agent/mode_end_call.h>
7
8 #if HAVE_DMALLOC_H
9 #include <dmalloc.h>
10 #endif
11
12 /** @defgroup mode_end_call mode_end_call: at the end of a series of requests, call another handler hook.
13  *  Handlers that want to loop through a series of requests and then
14  *  receive a callback at the end of a particular MODE can use this
15  *  helper to make this possible.  For most modules, this is not
16  *  needed as the handler itself could perform a for() loop around the
17  *  request list and then perform its actions afterwards.  However, if
18  *  something like the serialize helper is in use this isn't possible
19  *  because not all the requests for a given handler are being passed
20  *  downward in a single group.  Thus, this helper *must* be added
21  *  above other helpers like the serialize helper to be useful.
22  *
23  *  Multiple mode specific handlers can be registered and will be
24  *  called in the order they were regestered in.  Callbacks regesterd
25  *  with a mode of NETSNMP_MODE_END_ALL_MODES will be called for all
26  *  modes.
27  * 
28  *  @ingroup handler
29  *  @{
30  */
31
32 /** returns a mode_end_call handler that can be injected into a given
33  *  handler chain.
34  * @param endlist The callback list for the handler to make use of.
35  * @return An injectable Net-SNMP handler.
36  */
37 netsnmp_mib_handler *
38 netsnmp_get_mode_end_call_handler(netsnmp_mode_handler_list *endlist)
39 {
40     netsnmp_mib_handler *me =
41         netsnmp_create_handler("mode_end_call",
42                                netsnmp_mode_end_call_helper);
43
44     if (!me)
45         return NULL;
46
47     me->myvoid = endlist;
48     return me;
49 }
50
51 /** adds a mode specific callback to the callback list.
52  * @param endinfo the information structure for the mode_end_call helper.  Can be NULL to create a new list.
53  * @param mode the mode to be called upon.  A mode of NETSNMP_MODE_END_ALL_MODES = all modes.
54  * @param callbackh the netsnmp_mib_handler callback to call.
55  * @return the new registration information list upon success.
56  */
57 netsnmp_mode_handler_list *
58 netsnmp_mode_end_call_add_mode_callback(netsnmp_mode_handler_list *endlist,
59                                         int mode,
60                                         netsnmp_mib_handler *callbackh) {
61     netsnmp_mode_handler_list *ptr, *ptr2;
62     ptr = SNMP_MALLOC_TYPEDEF(netsnmp_mode_handler_list);
63     if (!ptr)
64         return NULL;
65     
66     ptr->mode = mode;
67     ptr->callback_handler = callbackh;
68     ptr->next = endlist;
69
70     if (!endlist)
71         return ptr;
72
73     /* get to end */
74     for(ptr2 = endlist; ptr2->next != NULL; ptr2 = ptr2->next);
75
76     ptr2->next = ptr;
77     return endlist;
78 }
79     
80 /** @internal Implements the mode_end_call handler */
81 int
82 netsnmp_mode_end_call_helper(netsnmp_mib_handler *handler,
83                             netsnmp_handler_registration *reginfo,
84                             netsnmp_agent_request_info *reqinfo,
85                             netsnmp_request_info *requests)
86 {
87
88     int             ret;
89     int             ret2 = SNMP_ERR_NOERROR;
90     netsnmp_mode_handler_list *ptr;
91
92     /* always call the real handlers first */
93     ret = netsnmp_call_next_handler(handler, reginfo, reqinfo,
94                                     requests);
95
96     /* then call the callback handlers */
97     for(ptr = handler->myvoid; ptr; ptr = ptr->next) {
98         if (ptr->mode == NETSNMP_MODE_END_ALL_MODES ||
99             reqinfo->mode == ptr->mode) {
100             ret2 = netsnmp_call_handler(ptr->callback_handler, reginfo,
101                                              reqinfo, requests);
102             if (ret != SNMP_ERR_NOERROR)
103                 ret = ret2;
104         }
105     }
106     
107     return ret2;
108 }