2 * callback.c: A generic callback mechanism
5 #include <net-snmp/net-snmp-config.h>
15 #include <netinet/in.h>
27 #include <net-snmp/types.h>
28 #include <net-snmp/output_api.h>
29 #include <net-snmp/utilities.h>
31 #include <net-snmp/library/callback.h>
32 #include <net-snmp/library/snmp_api.h>
34 static struct snmp_gen_callback
35 *thecallbacks[MAX_CALLBACK_IDS][MAX_CALLBACK_SUBIDS];
38 * the chicken. or the egg. You pick.
44 * probably not needed? Should be full of 0's anyway?
47 * (poses a problem if you put init_callbacks() inside of
48 * init_snmp() and then want the app to register a callback before
49 * init_snmp() is called in the first place. -- Wes
52 * memset(thecallbacks, 0, sizeof(thecallbacks));
54 DEBUGMSGTL(("callback", "initialized\n"));
58 snmp_register_callback(int major, int minor, SNMPCallback * new_callback,
61 struct snmp_gen_callback *newscp = NULL, *scp = NULL;
62 struct snmp_gen_callback **prevNext = &(thecallbacks[major][minor]);
64 if (major >= MAX_CALLBACK_IDS || minor >= MAX_CALLBACK_SUBIDS) {
65 return SNMPERR_GENERR;
68 if ((newscp = SNMP_MALLOC_STRUCT(snmp_gen_callback)) == NULL) {
69 return SNMPERR_GENERR;
71 newscp->sc_client_arg = arg;
72 newscp->sc_callback = new_callback;
75 for (scp = thecallbacks[major][minor]; scp != NULL;
77 prevNext = &(scp->next);
82 DEBUGMSGTL(("callback", "registered (%d,%d) at %p\n", major, minor,
84 return SNMPERR_SUCCESS;
89 snmp_call_callbacks(int major, int minor, void *caller_arg)
91 struct snmp_gen_callback *scp;
92 unsigned int count = 0;
94 if (major >= MAX_CALLBACK_IDS || minor >= MAX_CALLBACK_SUBIDS) {
95 return SNMPERR_GENERR;
98 DEBUGMSGTL(("callback", "START calling callbacks for maj=%d min=%d\n",
102 * for each registered callback of type major and minor
104 for (scp = thecallbacks[major][minor]; scp != NULL; scp = scp->next) {
106 DEBUGMSGTL(("callback", "calling a callback for maj=%d min=%d\n",
112 (*(scp->sc_callback)) (major, minor, caller_arg,
117 DEBUGMSGTL(("callback",
118 "END calling callbacks for maj=%d min=%d (%d called)\n",
119 major, minor, count));
121 return SNMPERR_SUCCESS;
125 snmp_count_callbacks(int major, int minor)
128 struct snmp_gen_callback *scp;
130 if (major >= MAX_CALLBACK_IDS || minor >= MAX_CALLBACK_SUBIDS) {
131 return SNMPERR_GENERR;
134 for (scp = thecallbacks[major][minor]; scp != NULL; scp = scp->next) {
142 snmp_callback_available(int major, int minor)
144 if (major >= MAX_CALLBACK_IDS || minor >= MAX_CALLBACK_SUBIDS) {
145 return SNMPERR_GENERR;
148 if (thecallbacks[major][minor] != NULL) {
149 return SNMPERR_SUCCESS;
152 return SNMPERR_GENERR;
156 snmp_unregister_callback(int major, int minor, SNMPCallback * target,
157 void *arg, int matchargs)
159 struct snmp_gen_callback *scp = thecallbacks[major][minor];
160 struct snmp_gen_callback **prevNext = &(thecallbacks[major][minor]);
163 while (scp != NULL) {
164 if ((scp->sc_callback == target) &&
165 (!matchargs || (scp->sc_client_arg == arg))) {
166 DEBUGMSGTL(("callback", "unregistering (%d,%d) at %p\n", major,
168 *prevNext = scp->next;
173 prevNext = &(scp->next);
181 struct snmp_gen_callback *
182 snmp_callback_list(int major, int minor)
184 return (thecallbacks[major][minor]);