~ubuntu-branches/ubuntu/trusty/net-snmp/trusty

« back to all changes in this revision

Viewing changes to snmplib/callback.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2004-09-13 12:06:21 UTC
  • Revision ID: james.westby@ubuntu.com-20040913120621-g952ntonlleihcvm
Tags: upstream-5.1.1
ImportĀ upstreamĀ versionĀ 5.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * callback.c: A generic callback mechanism 
 
3
 */
 
4
/* Portions of this file are subject to the following copyright(s).  See
 
5
 * the Net-SNMP's COPYING file for more details and other copyrights
 
6
 * that may apply:
 
7
 */
 
8
/*
 
9
 * Portions of this file are copyrighted by:
 
10
 * Copyright ļæ½ 2003 Sun Microsystems, Inc. All rights reserved.
 
11
 * Use is subject to license terms specified in the COPYING file
 
12
 * distributed with the Net-SNMP package.
 
13
 */
 
14
/** @defgroup callback A generic callback mechanism 
 
15
 *  @ingroup library
 
16
 * 
 
17
 *  @{
 
18
 */
 
19
#include <net-snmp/net-snmp-config.h>
 
20
#include <sys/types.h>
 
21
#include <stdio.h>
 
22
#if HAVE_STDLIB_H
 
23
#include <stdlib.h>
 
24
#endif
 
25
#if HAVE_WINSOCK_H
 
26
#include <winsock.h>
 
27
#endif
 
28
#if HAVE_NETINET_IN_H
 
29
#include <netinet/in.h>
 
30
#endif
 
31
#if HAVE_STRING_H
 
32
#include <string.h>
 
33
#else
 
34
#include <strings.h>
 
35
#endif
 
36
 
 
37
#if HAVE_DMALLOC_H
 
38
#include <dmalloc.h>
 
39
#endif
 
40
 
 
41
#include <net-snmp/types.h>
 
42
#include <net-snmp/output_api.h>
 
43
#include <net-snmp/utilities.h>
 
44
 
 
45
#include <net-snmp/library/callback.h>
 
46
#include <net-snmp/library/snmp_api.h>
 
47
 
 
48
static struct snmp_gen_callback
 
49
               *thecallbacks[MAX_CALLBACK_IDS][MAX_CALLBACK_SUBIDS];
 
50
 
 
51
/*
 
52
 * the chicken. or the egg.  You pick. 
 
53
 */
 
54
void
 
55
init_callbacks(void)
 
56
{
 
57
    /*
 
58
     * probably not needed? Should be full of 0's anyway? 
 
59
     */
 
60
    /*
 
61
     * (poses a problem if you put init_callbacks() inside of
 
62
     * init_snmp() and then want the app to register a callback before
 
63
     * init_snmp() is called in the first place.  -- Wes 
 
64
     */
 
65
    /*
 
66
     * memset(thecallbacks, 0, sizeof(thecallbacks)); 
 
67
     */
 
68
    DEBUGMSGTL(("callback", "initialized\n"));
 
69
}
 
70
 
 
71
/**
 
72
 * This function registers a generic callback function.  The major and
 
73
 * minor values are used to set the new_callback function into a global 
 
74
 * static multi-dimensional array of type struct snmp_gen_callback.  
 
75
 * The function makes sure to append this callback function at the end
 
76
 * of the link list, snmp_gen_callback->next.
 
77
 *
 
78
 * @param major is the SNMP callback major type used
 
79
 *              - SNMP_CALLBACK_LIBRARY
 
80
 *              - SNMP_CALLBACK_APPLICATION
 
81
 *
 
82
 * @param minor is the SNMP callback minor type used
 
83
 *              - SNMP_CALLBACK_POST_READ_CONFIG
 
84
 *              - SNMP_CALLBACK_STORE_DATA              
 
85
 *              - SNMP_CALLBACK_SHUTDOWN                        
 
86
 *              - SNMP_CALLBACK_POST_PREMIB_READ_CONFIG 
 
87
 *              - SNMP_CALLBACK_LOGGING                 
 
88
 *              - SNMP_CALLBACK_SESSION_INIT           
 
89
 *
 
90
 * @param new_callback is the callback function that is registered.
 
91
 *
 
92
 * @param arg when not NULL is a void pointer used whenever new_callback 
 
93
 *      function is exercised.
 
94
 *
 
95
 * @return 
 
96
 *      Returns SNMPERR_GENERR if major is >= MAX_CALLBACK_IDS or minor is >=
 
97
 *      MAX_CALLBACK_SUBIDS or a snmp_gen_callback pointer could not be 
 
98
 *      allocated, otherwise SNMPERR_SUCCESS is returned.
 
99
 *      - #define MAX_CALLBACK_IDS    2
 
100
 *      - #define MAX_CALLBACK_SUBIDS 16
 
101
 *
 
102
 * @see snmp_call_callbacks
 
103
 * @see snmp_unregister_callback
 
104
 */
 
105
int
 
106
snmp_register_callback(int major, int minor, SNMPCallback * new_callback,
 
107
                       void *arg)
 
108
{
 
109
    return netsnmp_register_callback( major, minor, new_callback, arg, 0);
 
110
}
 
111
 
 
112
int
 
113
netsnmp_register_callback(int major, int minor, SNMPCallback * new_callback,
 
114
                          void *arg, int priority)
 
115
{
 
116
    struct snmp_gen_callback *newscp = NULL, *scp = NULL;
 
117
    struct snmp_gen_callback **prevNext = &(thecallbacks[major][minor]);
 
118
 
 
119
    if (major >= MAX_CALLBACK_IDS || minor >= MAX_CALLBACK_SUBIDS) {
 
120
        return SNMPERR_GENERR;
 
121
    }
 
122
 
 
123
    if ((newscp = SNMP_MALLOC_STRUCT(snmp_gen_callback)) == NULL) {
 
124
        return SNMPERR_GENERR;
 
125
    } else {
 
126
        newscp->priority = priority;
 
127
        newscp->sc_client_arg = arg;
 
128
        newscp->sc_callback = new_callback;
 
129
        newscp->next = NULL;
 
130
 
 
131
        for (scp = thecallbacks[major][minor]; scp != NULL;
 
132
             scp = scp->next) {
 
133
            if (newscp->priority < scp->priority) {
 
134
                newscp->next = scp;
 
135
                break;
 
136
            }
 
137
            prevNext = &(scp->next);
 
138
        }
 
139
 
 
140
        *prevNext = newscp;
 
141
 
 
142
        DEBUGMSGTL(("callback", "registered (%d,%d) at %p with priority %d\n",
 
143
                    major, minor, newscp, priority));
 
144
        return SNMPERR_SUCCESS;
 
145
    }
 
146
}
 
147
 
 
148
/**
 
149
 * This function calls the callback function for each registered callback of
 
150
 * type major and minor.
 
151
 *
 
152
 * @param major is the SNMP callback major type used
 
153
 *
 
154
 * @param minor is the SNMP callback minor type used
 
155
 *
 
156
 * @param caller_arg is a void pointer which is sent in as the callback's 
 
157
 *      serverarg parameter, if needed.
 
158
 *
 
159
 * @return Returns SNMPERR_GENERR if major is >= MAX_CALLBACK_IDS or
 
160
 * minor is >= MAX_CALLBACK_SUBIDS, otherwise SNMPERR_SUCCESS is returned.
 
161
 *
 
162
 * @see snmp_register_callback
 
163
 * @see snmp_unregister_callback
 
164
 */
 
165
int
 
166
snmp_call_callbacks(int major, int minor, void *caller_arg)
 
167
{
 
168
    struct snmp_gen_callback *scp;
 
169
    unsigned int    count = 0;
 
170
 
 
171
    if (major >= MAX_CALLBACK_IDS || minor >= MAX_CALLBACK_SUBIDS) {
 
172
        return SNMPERR_GENERR;
 
173
    }
 
174
 
 
175
    DEBUGMSGTL(("callback", "START calling callbacks for maj=%d min=%d\n",
 
176
                major, minor));
 
177
 
 
178
    /*
 
179
     * for each registered callback of type major and minor 
 
180
     */
 
181
    for (scp = thecallbacks[major][minor]; scp != NULL; scp = scp->next) {
 
182
 
 
183
        DEBUGMSGTL(("callback", "calling a callback for maj=%d min=%d\n",
 
184
                    major, minor));
 
185
 
 
186
        /*
 
187
         * call them 
 
188
         */
 
189
        (*(scp->sc_callback)) (major, minor, caller_arg,
 
190
                               scp->sc_client_arg);
 
191
        count++;
 
192
    }
 
193
 
 
194
    DEBUGMSGTL(("callback",
 
195
                "END calling callbacks for maj=%d min=%d (%d called)\n",
 
196
                major, minor, count));
 
197
 
 
198
    return SNMPERR_SUCCESS;
 
199
}
 
200
 
 
201
int
 
202
snmp_count_callbacks(int major, int minor)
 
203
{
 
204
    int             count = 0;
 
205
    struct snmp_gen_callback *scp;
 
206
 
 
207
    if (major >= MAX_CALLBACK_IDS || minor >= MAX_CALLBACK_SUBIDS) {
 
208
        return SNMPERR_GENERR;
 
209
    }
 
210
 
 
211
    for (scp = thecallbacks[major][minor]; scp != NULL; scp = scp->next) {
 
212
        count++;
 
213
    }
 
214
 
 
215
    return count;
 
216
}
 
217
 
 
218
int
 
219
snmp_callback_available(int major, int minor)
 
220
{
 
221
    if (major >= MAX_CALLBACK_IDS || minor >= MAX_CALLBACK_SUBIDS) {
 
222
        return SNMPERR_GENERR;
 
223
    }
 
224
 
 
225
    if (thecallbacks[major][minor] != NULL) {
 
226
        return SNMPERR_SUCCESS;
 
227
    }
 
228
 
 
229
    return SNMPERR_GENERR;
 
230
}
 
231
 
 
232
/**
 
233
 * This function unregisters a specified callback function given a major
 
234
 * and minor type.
 
235
 *
 
236
 * Note: no bound checking on major and minor.
 
237
 *
 
238
 * @param major is the SNMP callback major type used
 
239
 *
 
240
 * @param minor is the SNMP callback minor type used
 
241
 *
 
242
 * @param target is the callback function that will be unregistered.
 
243
 *
 
244
 * @param arg is a void pointer used for comparison against the registered 
 
245
 *      callback's sc_client_arg variable.
 
246
 *
 
247
 * @param matchargs is an integer used to bypass the comparison of arg and the
 
248
 *      callback's sc_client_arg variable only when matchargs is set to 0.
 
249
 *
 
250
 *
 
251
 * @return
 
252
 *        Returns the number of callbacks that were unregistered.
 
253
 *
 
254
 * @see snmp_register_callback
 
255
 * @see snmp_call_callbacks
 
256
 */
 
257
 
 
258
int
 
259
snmp_unregister_callback(int major, int minor, SNMPCallback * target,
 
260
                         void *arg, int matchargs)
 
261
{
 
262
    struct snmp_gen_callback *scp = thecallbacks[major][minor];
 
263
    struct snmp_gen_callback **prevNext = &(thecallbacks[major][minor]);
 
264
    int             count = 0;
 
265
 
 
266
    while (scp != NULL) {
 
267
        if ((scp->sc_callback == target) &&
 
268
            (!matchargs || (scp->sc_client_arg == arg))) {
 
269
            DEBUGMSGTL(("callback", "unregistering (%d,%d) at %p\n", major,
 
270
                        minor, scp));
 
271
            *prevNext = scp->next;
 
272
            SNMP_FREE(scp);
 
273
            scp = *prevNext;
 
274
            count++;
 
275
        } else {
 
276
            prevNext = &(scp->next);
 
277
            scp = scp->next;
 
278
        }
 
279
    }
 
280
 
 
281
    return count;
 
282
}
 
283
 
 
284
void
 
285
clear_callback(void)
 
286
{
 
287
    unsigned int i = 0, j = 0; 
 
288
    struct snmp_gen_callback *scp = NULL, *next = NULL;
 
289
 
 
290
    DEBUGMSGTL(("callback", "clear callback\n"));
 
291
    for (i = 0; i < MAX_CALLBACK_IDS; i++) {
 
292
        for (j = 0; j < MAX_CALLBACK_SUBIDS; j++) {
 
293
            scp = thecallbacks[i][j]; 
 
294
            while (scp != NULL) {
 
295
                next = scp->next;
 
296
                if (scp->sc_client_arg != NULL)
 
297
                    SNMP_FREE(scp->sc_client_arg);
 
298
                SNMP_FREE(scp);
 
299
                scp = next;
 
300
            }
 
301
            thecallbacks[i][j] = NULL;
 
302
        }
 
303
    }
 
304
}
 
305
 
 
306
struct snmp_gen_callback *
 
307
snmp_callback_list(int major, int minor)
 
308
{
 
309
    return (thecallbacks[major][minor]);
 
310
}
 
311
/**  @} */