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>
8
/*------------------------------------------------------------------
10
static netsnmp_container *containers = NULL;
12
typedef struct container_type_s {
14
netsnmp_factory *factory;
18
netsnmp_container_get_factory(const char *type);
20
/*------------------------------------------------------------------
23
_factory_free(container_type *data, void *context)
28
if (data->name != NULL) {
29
DEBUGMSGTL(("container", " _factory_free_list() called for %s\n",
31
free((const void*)data->name); /* SNMP_FREE wasted on object about to be freed */
33
free(data); /* SNMP_FREE wasted on param */
36
/*------------------------------------------------------------------
39
netsnmp_container_init_list(void)
41
if (NULL != containers)
45
* create a binary arry container to hold container
48
containers = netsnmp_container_get_binary_array();
49
containers->compare = netsnmp_compare_cstring;
54
netsnmp_container_binary_array_init();
55
netsnmp_container_ssll_init();
56
netsnmp_container_null_init();
59
* default aliases for some containers
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"));
70
netsnmp_container_free_list(void)
72
DEBUGMSGTL(("container", "netsnmp_container_free_list() called\n"));
73
if (containers == NULL)
77
* free memory used by each factory entry
79
CONTAINER_FOR_EACH(containers, _factory_free, NULL);
82
* free factory container
84
CONTAINER_FREE(containers);
89
netsnmp_container_register(const char* name, netsnmp_factory *f)
91
container_type *ct, tmp;
94
ct = CONTAINER_FIND(containers, &tmp);
96
DEBUGMSGT(("container_registry",
97
"replacing previous container factory\n"));
101
ct = SNMP_MALLOC_TYPEDEF(container_type);
104
ct->name = strdup(name);
106
CONTAINER_INSERT(containers, ct);
108
DEBUGMSGT(("container_registry", "registered container factory %s (%s)\n",
109
ct->name, f->product));
114
/*------------------------------------------------------------------
117
netsnmp_container_get_factory(const char *type)
119
container_type ct, *found;
122
found = CONTAINER_FIND(containers, &ct);
124
return found ? found->factory : NULL;
128
netsnmp_container_find_factory(const char *type_list)
130
netsnmp_factory *f = NULL;
136
list = strdup(type_list);
137
entry = strtok(list, ":");
139
f = netsnmp_container_get_factory(entry);
142
entry = strtok(NULL, ":");
149
/*------------------------------------------------------------------
152
netsnmp_container_get(const char *type)
154
netsnmp_factory *f = netsnmp_container_get_factory(type);
161
/*------------------------------------------------------------------
164
netsnmp_container_find(const char *type)
166
netsnmp_factory *f = netsnmp_container_find_factory(type);
173
/*------------------------------------------------------------------
176
netsnmp_container_add_index(netsnmp_container *primary,
177
netsnmp_container *new_index)
179
netsnmp_container *curr = primary;
181
if((NULL == new_index) || (NULL == primary)) {
182
snmp_log(LOG_ERR, "add index called with null pointer\n");
189
curr->next = new_index;
190
new_index->prev = curr;
193
#ifndef NETSNMP_USE_INLINE /* default is to inline */
195
/*------------------------------------------------------------------
196
* These functions should EXACTLY match the inline version in
197
* container.h. If you chance one, change them both.
199
int CONTAINER_INSERT(netsnmp_container *x, const void *k)
203
/** start at first container */
207
rc2 = x->insert(x,k);
209
snmp_log(LOG_ERR,"error on subcontainer insert (%d)\n", rc2);
217
/*------------------------------------------------------------------
218
* These functions should EXACTLY match the inline version in
219
* container.h. If you chance one, change them both.
221
int CONTAINER_REMOVE(netsnmp_container *x, const void *k)
225
/** start at last container */
229
rc2 = x->remove(x,k);
231
snmp_log(LOG_ERR,"error on subcontainer remove (%d)\n", rc2);
240
/*------------------------------------------------------------------
241
* These functions should EXACTLY match the inline version in
242
* container.h. If you chance one, change them both.
244
int CONTAINER_FREE(netsnmp_container *x)
248
/** start at last container */
252
netsnmp_container *tmp;
256
snmp_log(LOG_ERR,"error on subcontainer cfree (%d)\n", rc2);
266
/*------------------------------------------------------------------
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)
290
/*------------------------------------------------------------------
292
* simple comparison routines
296
netsnmp_compare_netsnmp_index(const void *lhs, const void *rhs)
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"));
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));
318
netsnmp_ncompare_netsnmp_index(const void *lhs, const void *rhs)
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"));
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));
341
netsnmp_compare_cstring(const void * lhs, const void * rhs)
343
return strcmp(((const container_type*)lhs)->name,
344
((const container_type*)rhs)->name);
348
netsnmp_ncompare_cstring(const void * lhs, const void * rhs)
350
return strncmp(((const container_type*)lhs)->name,
351
((const container_type*)rhs)->name,
352
strlen(((const container_type*)rhs)->name));
356
* compare two memory buffers
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
363
netsnmp_compare_mem(const char * lhs, size_t lhs_len,
364
const char * rhs, size_t rhs_len)
366
int rc, min = SNMP_MIN(lhs_len, rhs_len);
368
rc = memcmp(lhs, rhs, min);
369
if((rc==0) && (lhs_len != rhs_len)) {
370
if(lhs_len < rhs_len)