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

« back to all changes in this revision

Viewing changes to snmplib/container.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
#include <net-snmp/net-snmp-config.h>
 
2
#include <net-snmp/net-snmp-includes.h>
 
3
#include <net-snmp/library/container.h>
 
4
#include <net-snmp/library/container_binary_array.h>
 
5
#include <net-snmp/library/container_list_ssll.h>
 
6
#include <net-snmp/library/container_null.h>
 
7
 
 
8
/*------------------------------------------------------------------
 
9
 */
 
10
static netsnmp_container *containers = NULL;
 
11
 
 
12
typedef struct container_type_s {
 
13
   const char                 *name;
 
14
   netsnmp_factory            *factory;
 
15
} container_type;
 
16
 
 
17
netsnmp_factory *
 
18
netsnmp_container_get_factory(const char *type);
 
19
 
 
20
/*------------------------------------------------------------------
 
21
 */
 
22
static void 
 
23
_factory_free(container_type *data, void *context)
 
24
{
 
25
    if (data == NULL)
 
26
        return;
 
27
    
 
28
    if (data->name != NULL) {
 
29
        DEBUGMSGTL(("container", "  _factory_free_list() called for %s\n",
 
30
                    data->name));
 
31
        free((const void*)data->name); /* SNMP_FREE wasted on object about to be freed */
 
32
    }
 
33
    free(data); /* SNMP_FREE wasted on param */
 
34
}
 
35
 
 
36
/*------------------------------------------------------------------
 
37
 */
 
38
void
 
39
netsnmp_container_init_list(void)
 
40
{
 
41
    if (NULL != containers)
 
42
        return;
 
43
 
 
44
    /*
 
45
     * create a binary arry container to hold container
 
46
     * factories
 
47
     */
 
48
    containers = netsnmp_container_get_binary_array();
 
49
    containers->compare = netsnmp_compare_cstring;
 
50
 
 
51
    /*
 
52
     * register containers
 
53
     */
 
54
    netsnmp_container_binary_array_init();
 
55
    netsnmp_container_ssll_init();
 
56
    netsnmp_container_null_init();
 
57
 
 
58
    /*
 
59
     * default aliases for some containers
 
60
     */
 
61
    netsnmp_container_register("table_container",
 
62
                               netsnmp_container_get_factory("binary_array"));
 
63
    netsnmp_container_register("linked_list",
 
64
                               netsnmp_container_get_factory("sorted_singly_linked_list"));
 
65
    netsnmp_container_register("ssll_container",
 
66
                               netsnmp_container_get_factory("sorted_singly_linked_list"));
 
67
}
 
68
 
 
69
void
 
70
netsnmp_container_free_list(void)
 
71
{
 
72
    DEBUGMSGTL(("container", "netsnmp_container_free_list() called\n"));
 
73
    if (containers == NULL)
 
74
        return;
 
75
 
 
76
    /*
 
77
     * free memory used by each factory entry
 
78
     */
 
79
    CONTAINER_FOR_EACH(containers, _factory_free, NULL);
 
80
 
 
81
    /*
 
82
     * free factory container
 
83
     */
 
84
    CONTAINER_FREE(containers);
 
85
    containers = NULL;
 
86
}
 
87
 
 
88
int
 
89
netsnmp_container_register(const char* name, netsnmp_factory *f)
 
90
{
 
91
    container_type *ct, tmp;
 
92
 
 
93
    tmp.name = name;
 
94
    ct = CONTAINER_FIND(containers, &tmp);
 
95
    if (NULL!=ct) {
 
96
        DEBUGMSGT(("container_registry",
 
97
                   "replacing previous container factory\n"));
 
98
        ct->factory = f;
 
99
    }
 
100
    else {
 
101
        ct = SNMP_MALLOC_TYPEDEF(container_type);
 
102
        if (NULL == ct)
 
103
            return -1;
 
104
        ct->name = strdup(name);
 
105
        ct->factory = f;
 
106
        CONTAINER_INSERT(containers, ct);
 
107
    }
 
108
    DEBUGMSGT(("container_registry", "registered container factory %s (%s)\n",
 
109
               ct->name, f->product));
 
110
 
 
111
    return 0;
 
112
}
 
113
 
 
114
/*------------------------------------------------------------------
 
115
 */
 
116
netsnmp_factory *
 
117
netsnmp_container_get_factory(const char *type)
 
118
{
 
119
    container_type ct, *found;
 
120
    
 
121
    ct.name = type;
 
122
    found = CONTAINER_FIND(containers, &ct);
 
123
 
 
124
    return found ? found->factory : NULL;
 
125
}
 
126
 
 
127
netsnmp_factory *
 
128
netsnmp_container_find_factory(const char *type_list)
 
129
{
 
130
    netsnmp_factory   *f = NULL;
 
131
    char              *list, *entry;
 
132
 
 
133
    if (NULL==type_list)
 
134
        return NULL;
 
135
 
 
136
    list = strdup(type_list);
 
137
    entry = strtok(list, ":");
 
138
    while(entry) {
 
139
        f = netsnmp_container_get_factory(entry);
 
140
        if (NULL != f)
 
141
            break;
 
142
        entry = strtok(NULL, ":");
 
143
    }
 
144
 
 
145
    free(list);
 
146
    return f;
 
147
}
 
148
 
 
149
/*------------------------------------------------------------------
 
150
 */
 
151
netsnmp_container *
 
152
netsnmp_container_get(const char *type)
 
153
{
 
154
    netsnmp_factory *f = netsnmp_container_get_factory(type);
 
155
    if (f)
 
156
        return f->produce();
 
157
 
 
158
    return NULL;
 
159
}
 
160
 
 
161
/*------------------------------------------------------------------
 
162
 */
 
163
netsnmp_container *
 
164
netsnmp_container_find(const char *type)
 
165
{
 
166
    netsnmp_factory *f = netsnmp_container_find_factory(type);
 
167
    if (f)
 
168
        return f->produce();
 
169
 
 
170
    return NULL;
 
171
}
 
172
 
 
173
/*------------------------------------------------------------------
 
174
 */
 
175
void
 
176
netsnmp_container_add_index(netsnmp_container *primary,
 
177
                            netsnmp_container *new_index)
 
178
{
 
179
    netsnmp_container *curr = primary;
 
180
 
 
181
    if((NULL == new_index) || (NULL == primary)) {
 
182
        snmp_log(LOG_ERR, "add index called with null pointer\n");
 
183
        return;
 
184
    }
 
185
 
 
186
    while(curr->next)
 
187
        curr = curr->next;
 
188
 
 
189
    curr->next = new_index;
 
190
    new_index->prev = curr;
 
191
}
 
192
 
 
193
#ifndef NETSNMP_USE_INLINE /* default is to inline */
 
194
 
 
195
/*------------------------------------------------------------------
 
196
 * These functions should EXACTLY match the inline version in
 
197
 * container.h. If you chance one, change them both.
 
198
 */
 
199
int CONTAINER_INSERT(netsnmp_container *x, const void *k)
 
200
 
201
    int rc2, rc = 0;
 
202
    
 
203
    /** start at first container */
 
204
    while(x->prev)
 
205
        x = x->prev;
 
206
    while(x) {
 
207
        rc2 = x->insert(x,k);
 
208
        if (rc2) {
 
209
            snmp_log(LOG_ERR,"error on subcontainer insert (%d)\n", rc2);
 
210
            rc = rc2;
 
211
        }
 
212
        x = x->next;
 
213
    }
 
214
    return rc;
 
215
}
 
216
 
 
217
/*------------------------------------------------------------------
 
218
 * These functions should EXACTLY match the inline version in
 
219
 * container.h. If you chance one, change them both.
 
220
 */
 
221
int CONTAINER_REMOVE(netsnmp_container *x, const void *k)
 
222
{
 
223
    int rc2, rc = 0;
 
224
    
 
225
    /** start at last container */
 
226
    while(x->next)
 
227
        x = x->next;
 
228
    while(x) {
 
229
        rc2 = x->remove(x,k);
 
230
        if (rc2) {
 
231
            snmp_log(LOG_ERR,"error on subcontainer remove (%d)\n", rc2);
 
232
            rc = rc2;
 
233
        }
 
234
        x = x->prev;
 
235
        
 
236
    }
 
237
    return rc;
 
238
}
 
239
 
 
240
/*------------------------------------------------------------------
 
241
 * These functions should EXACTLY match the inline version in
 
242
 * container.h. If you chance one, change them both.
 
243
 */
 
244
int CONTAINER_FREE(netsnmp_container *x)
 
245
{
 
246
    int  rc2, rc = 0;
 
247
        
 
248
    /** start at last container */
 
249
    while(x->next)
 
250
        x = x->next;
 
251
    while(x) {
 
252
        netsnmp_container *tmp;
 
253
        tmp = x->prev;
 
254
        rc2 = x->cfree(x);
 
255
        if (rc2) {
 
256
            snmp_log(LOG_ERR,"error on subcontainer cfree (%d)\n", rc2);
 
257
            rc = rc2;
 
258
        }
 
259
        x = tmp;
 
260
    }
 
261
    return rc;
 
262
}
 
263
#endif
 
264
 
 
265
 
 
266
/*------------------------------------------------------------------
 
267
 */
 
268
void
 
269
netsnmp_init_container(netsnmp_container         *c,
 
270
                       netsnmp_container_rc      *init,
 
271
                       netsnmp_container_rc      *cfree,
 
272
                       netsnmp_container_size    *size,
 
273
                       netsnmp_container_compare *cmp,
 
274
                       netsnmp_container_op      *ins,
 
275
                       netsnmp_container_op      *rem,
 
276
                       netsnmp_container_rtn     *fnd)
 
277
{
 
278
    if (c == NULL)
 
279
        return;
 
280
 
 
281
    c->init = init;
 
282
    c->cfree = cfree;
 
283
    c->get_size = size;
 
284
    c->compare = cmp;
 
285
    c->insert = ins;
 
286
    c->remove = rem;
 
287
    c->find = fnd;
 
288
}
 
289
 
 
290
/*------------------------------------------------------------------
 
291
 *
 
292
 * simple comparison routines
 
293
 *
 
294
 */
 
295
int
 
296
netsnmp_compare_netsnmp_index(const void *lhs, const void *rhs)
 
297
{
 
298
    int rc;
 
299
    netsnmp_assert((NULL != lhs) && (NULL != rhs));
 
300
    DEBUGIF("compare:index") {
 
301
        DEBUGMSGT(("compare:index", "compare "));
 
302
        DEBUGMSGSUBOID(("compare:index", ((const netsnmp_index *) lhs)->oids,
 
303
                     ((const netsnmp_index *) lhs)->len));
 
304
        DEBUGMSG(("compare:index", " to "));
 
305
        DEBUGMSGSUBOID(("compare:index", ((const netsnmp_index *) rhs)->oids,
 
306
                     ((const netsnmp_index *) rhs)->len));
 
307
        DEBUGMSG(("compare:index", "\n"));
 
308
    }
 
309
    rc = snmp_oid_compare(((const netsnmp_index *) lhs)->oids,
 
310
                          ((const netsnmp_index *) lhs)->len,
 
311
                          ((const netsnmp_index *) rhs)->oids,
 
312
                          ((const netsnmp_index *) rhs)->len);
 
313
    DEBUGMSGT(("compare:index", "result was %d\n", rc));
 
314
    return rc;
 
315
}
 
316
 
 
317
int
 
318
netsnmp_ncompare_netsnmp_index(const void *lhs, const void *rhs)
 
319
{
 
320
    int rc;
 
321
    netsnmp_assert((NULL != lhs) && (NULL != rhs));
 
322
    DEBUGIF("compare:index") {
 
323
        DEBUGMSGT(("compare:index", "compare "));
 
324
        DEBUGMSGSUBOID(("compare:index", ((const netsnmp_index *) lhs)->oids,
 
325
                     ((const netsnmp_index *) lhs)->len));
 
326
        DEBUGMSG(("compare:index", " to "));
 
327
        DEBUGMSGSUBOID(("compare:index", ((const netsnmp_index *) rhs)->oids,
 
328
                     ((const netsnmp_index *) rhs)->len));
 
329
        DEBUGMSG(("compare:index", "\n"));
 
330
    }
 
331
    rc = snmp_oid_ncompare(((const netsnmp_index *) lhs)->oids,
 
332
                           ((const netsnmp_index *) lhs)->len,
 
333
                           ((const netsnmp_index *) rhs)->oids,
 
334
                           ((const netsnmp_index *) rhs)->len,
 
335
                           ((const netsnmp_index *) rhs)->len);
 
336
    DEBUGMSGT(("compare:index", "result was %d\n", rc));
 
337
    return rc;
 
338
}
 
339
 
 
340
int
 
341
netsnmp_compare_cstring(const void * lhs, const void * rhs)
 
342
{
 
343
    return strcmp(((const container_type*)lhs)->name,
 
344
                  ((const container_type*)rhs)->name);
 
345
}
 
346
 
 
347
int
 
348
netsnmp_ncompare_cstring(const void * lhs, const void * rhs)
 
349
{
 
350
    return strncmp(((const container_type*)lhs)->name,
 
351
                   ((const container_type*)rhs)->name,
 
352
                   strlen(((const container_type*)rhs)->name));
 
353
}
 
354
 
 
355
/*
 
356
 * compare two memory buffers
 
357
 *
 
358
 * since snmp strings aren't NULL terminated, we can't use strcmp. So
 
359
 * compare up to the length of the smaller, and then use length to
 
360
 * break any ties.
 
361
 */
 
362
int
 
363
netsnmp_compare_mem(const char * lhs, size_t lhs_len,
 
364
                    const char * rhs, size_t rhs_len)
 
365
{
 
366
    int rc, min = SNMP_MIN(lhs_len, rhs_len);
 
367
 
 
368
    rc = memcmp(lhs, rhs, min);
 
369
    if((rc==0) && (lhs_len != rhs_len)) {
 
370
        if(lhs_len < rhs_len)
 
371
            rc = -1;
 
372
        else
 
373
            rc = 1;
 
374
    }
 
375
 
 
376
    return rc;
 
377
}