and added files
[bcm963xx.git] / userapps / opensource / net-snmp / snmplib / callback.c
1 /*
2  * callback.c: A generic callback mechanism 
3  */
4
5 #include <net-snmp/net-snmp-config.h>
6 #include <sys/types.h>
7 #include <stdio.h>
8 #if HAVE_STDLIB_H
9 #include <stdlib.h>
10 #endif
11 #if HAVE_WINSOCK_H
12 #include <winsock.h>
13 #endif
14 #if HAVE_NETINET_IN_H
15 #include <netinet/in.h>
16 #endif
17 #if HAVE_STRING_H
18 #include <string.h>
19 #else
20 #include <strings.h>
21 #endif
22
23 #if HAVE_DMALLOC_H
24 #include <dmalloc.h>
25 #endif
26
27 #include <net-snmp/types.h>
28 #include <net-snmp/output_api.h>
29 #include <net-snmp/utilities.h>
30
31 #include <net-snmp/library/callback.h>
32 #include <net-snmp/library/snmp_api.h>
33
34 static struct snmp_gen_callback
35                *thecallbacks[MAX_CALLBACK_IDS][MAX_CALLBACK_SUBIDS];
36
37 /*
38  * the chicken. or the egg.  You pick. 
39  */
40 void
41 init_callbacks(void)
42 {
43     /*
44      * probably not needed? Should be full of 0's anyway? 
45      */
46     /*
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 
50      */
51     /*
52      * memset(thecallbacks, 0, sizeof(thecallbacks)); 
53      */
54     DEBUGMSGTL(("callback", "initialized\n"));
55 }
56
57 int
58 snmp_register_callback(int major, int minor, SNMPCallback * new_callback,
59                        void *arg)
60 {
61     struct snmp_gen_callback *newscp = NULL, *scp = NULL;
62     struct snmp_gen_callback **prevNext = &(thecallbacks[major][minor]);
63
64     if (major >= MAX_CALLBACK_IDS || minor >= MAX_CALLBACK_SUBIDS) {
65         return SNMPERR_GENERR;
66     }
67
68     if ((newscp = SNMP_MALLOC_STRUCT(snmp_gen_callback)) == NULL) {
69         return SNMPERR_GENERR;
70     } else {
71         newscp->sc_client_arg = arg;
72         newscp->sc_callback = new_callback;
73         newscp->next = NULL;
74
75         for (scp = thecallbacks[major][minor]; scp != NULL;
76              scp = scp->next) {
77             prevNext = &(scp->next);
78         }
79
80         *prevNext = newscp;
81
82         DEBUGMSGTL(("callback", "registered (%d,%d) at %p\n", major, minor,
83                     newscp));
84         return SNMPERR_SUCCESS;
85     }
86 }
87
88 int
89 snmp_call_callbacks(int major, int minor, void *caller_arg)
90 {
91     struct snmp_gen_callback *scp;
92     unsigned int    count = 0;
93
94     if (major >= MAX_CALLBACK_IDS || minor >= MAX_CALLBACK_SUBIDS) {
95         return SNMPERR_GENERR;
96     }
97
98     DEBUGMSGTL(("callback", "START calling callbacks for maj=%d min=%d\n",
99                 major, minor));
100
101     /*
102      * for each registered callback of type major and minor 
103      */
104     for (scp = thecallbacks[major][minor]; scp != NULL; scp = scp->next) {
105
106         DEBUGMSGTL(("callback", "calling a callback for maj=%d min=%d\n",
107                     major, minor));
108
109         /*
110          * call them 
111          */
112         (*(scp->sc_callback)) (major, minor, caller_arg,
113                                scp->sc_client_arg);
114         count++;
115     }
116
117     DEBUGMSGTL(("callback",
118                 "END calling callbacks for maj=%d min=%d (%d called)\n",
119                 major, minor, count));
120
121     return SNMPERR_SUCCESS;
122 }
123
124 int
125 snmp_count_callbacks(int major, int minor)
126 {
127     int             count = 0;
128     struct snmp_gen_callback *scp;
129
130     if (major >= MAX_CALLBACK_IDS || minor >= MAX_CALLBACK_SUBIDS) {
131         return SNMPERR_GENERR;
132     }
133
134     for (scp = thecallbacks[major][minor]; scp != NULL; scp = scp->next) {
135         count++;
136     }
137
138     return count;
139 }
140
141 int
142 snmp_callback_available(int major, int minor)
143 {
144     if (major >= MAX_CALLBACK_IDS || minor >= MAX_CALLBACK_SUBIDS) {
145         return SNMPERR_GENERR;
146     }
147
148     if (thecallbacks[major][minor] != NULL) {
149         return SNMPERR_SUCCESS;
150     }
151
152     return SNMPERR_GENERR;
153 }
154
155 int
156 snmp_unregister_callback(int major, int minor, SNMPCallback * target,
157                          void *arg, int matchargs)
158 {
159     struct snmp_gen_callback *scp = thecallbacks[major][minor];
160     struct snmp_gen_callback **prevNext = &(thecallbacks[major][minor]);
161     int             count = 0;
162
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,
167                         minor, scp));
168             *prevNext = scp->next;
169             SNMP_FREE(scp);
170             scp = *prevNext;
171             count++;
172         } else {
173             prevNext = &(scp->next);
174             scp = scp->next;
175         }
176     }
177
178     return count;
179 }
180
181 struct snmp_gen_callback *
182 snmp_callback_list(int major, int minor)
183 {
184     return (thecallbacks[major][minor]);
185 }