net-snmp 5.7
|
00001 /* Portions of this file are subject to the following copyright(s). See 00002 * the Net-SNMP's COPYING file for more details and other copyrights 00003 * that may apply: 00004 */ 00005 /* 00006 * Portions of this file are copyrighted by: 00007 * Copyright (C) 2007 Apple, Inc. All rights reserved. 00008 * Use is subject to license terms specified in the COPYING file 00009 * distributed with the Net-SNMP package. 00010 */ 00011 #include <net-snmp/net-snmp-config.h> 00012 #include <net-snmp/net-snmp-features.h> 00013 #include <net-snmp/net-snmp-includes.h> 00014 #include <net-snmp/library/container.h> 00015 #include <net-snmp/library/container_binary_array.h> 00016 #include <net-snmp/library/container_list_ssll.h> 00017 #include <net-snmp/library/container_null.h> 00018 00019 netsnmp_feature_child_of(container_all, libnetsnmp) 00020 00021 netsnmp_feature_child_of(container_factories, container_all) 00022 netsnmp_feature_child_of(container_types, container_all) 00023 netsnmp_feature_child_of(container_compare, container_all) 00024 netsnmp_feature_child_of(container_dup, container_all) 00025 netsnmp_feature_child_of(container_free_all, container_all) 00026 netsnmp_feature_child_of(subcontainer_find, container_all) 00027 00028 netsnmp_feature_child_of(container_ncompare_cstring, container_compare) 00029 netsnmp_feature_child_of(container_compare_mem, container_compare) 00030 netsnmp_feature_child_of(container_compare_long, container_compare) 00031 netsnmp_feature_child_of(container_compare_ulong, container_compare) 00032 netsnmp_feature_child_of(container_compare_int32, container_compare) 00033 netsnmp_feature_child_of(container_compare_uint32, container_compare) 00034 00035 netsnmp_feature_child_of(container_find_factory, container_factories) 00036 00040 /*------------------------------------------------------------------ 00041 */ 00042 static netsnmp_container *containers = NULL; 00043 00044 typedef struct container_type_s { 00045 const char *name; 00046 netsnmp_factory *factory; 00047 netsnmp_container_compare *compare; 00048 } container_type; 00049 00050 netsnmp_factory * 00051 netsnmp_container_get_factory(const char *type); 00052 00053 /*------------------------------------------------------------------ 00054 */ 00055 static void 00056 _factory_free(void *dat, void *context) 00057 { 00058 container_type *data = (container_type *)dat; 00059 if (data == NULL) 00060 return; 00061 00062 if (data->name != NULL) { 00063 DEBUGMSGTL(("container", " _factory_free_list() called for %s\n", 00064 data->name)); 00065 free(NETSNMP_REMOVE_CONST(void *, data->name)); /* SNMP_FREE wasted on object about to be freed */ 00066 } 00067 free(data); /* SNMP_FREE wasted on param */ 00068 } 00069 00070 /*------------------------------------------------------------------ 00071 */ 00072 void 00073 netsnmp_container_init_list(void) 00074 { 00075 if (NULL != containers) 00076 return; 00077 00078 /* 00079 * create a binary arry container to hold container 00080 * factories 00081 */ 00082 containers = netsnmp_container_get_binary_array(); 00083 containers->compare = netsnmp_compare_cstring; 00084 containers->container_name = strdup("container list"); 00085 00086 /* 00087 * register containers 00088 */ 00089 netsnmp_container_binary_array_init(); 00090 #ifndef NETSNMP_FEATURE_REMOVE_CONTAINER_LINKED_LIST 00091 netsnmp_container_ssll_init(); 00092 #endif /* NETSNMP_FEATURE_REMOVE_CONTAINER_LINKED_LIST */ 00093 #ifndef NETSNMP_FEATURE_REMOVE_CONTAINER_NULL 00094 netsnmp_container_null_init(); 00095 #endif /* NETSNMP_FEATURE_REMOVE_CONTAINER_NULL */ 00096 00097 /* 00098 * default aliases for some containers 00099 */ 00100 netsnmp_container_register("table_container", 00101 netsnmp_container_get_factory("binary_array")); 00102 00103 #ifndef NETSNMP_FEATURE_REMOVE_CONTAINER_LINKED_LIST 00104 netsnmp_container_register("linked_list", 00105 netsnmp_container_get_factory("sorted_singly_linked_list")); 00106 netsnmp_container_register("ssll_container", 00107 netsnmp_container_get_factory("sorted_singly_linked_list")); 00108 #endif /* NETSNMP_FEATURE_REMOVE_CONTAINER_LINKED_LIST */ 00109 00110 netsnmp_container_register_with_compare 00111 ("cstring", netsnmp_container_get_factory("binary_array"), 00112 netsnmp_compare_direct_cstring); 00113 00114 netsnmp_container_register_with_compare 00115 ("string", netsnmp_container_get_factory("binary_array"), 00116 netsnmp_compare_cstring); 00117 netsnmp_container_register_with_compare 00118 ("string_binary_array", netsnmp_container_get_factory("binary_array"), 00119 netsnmp_compare_cstring); 00120 00121 } 00122 00123 void 00124 netsnmp_container_free_list(void) 00125 { 00126 DEBUGMSGTL(("container", "netsnmp_container_free_list() called\n")); 00127 if (containers == NULL) 00128 return; 00129 00130 /* 00131 * free memory used by each factory entry 00132 */ 00133 CONTAINER_FOR_EACH(containers, ((netsnmp_container_obj_func *)_factory_free), NULL); 00134 00135 /* 00136 * free factory container 00137 */ 00138 CONTAINER_FREE(containers); 00139 containers = NULL; 00140 } 00141 00142 int 00143 netsnmp_container_register_with_compare(const char* name, netsnmp_factory *f, 00144 netsnmp_container_compare *c) 00145 { 00146 container_type *ct, tmp; 00147 00148 if (NULL==containers) 00149 return -1; 00150 00151 tmp.name = NETSNMP_REMOVE_CONST(char *, name); 00152 ct = (container_type *)CONTAINER_FIND(containers, &tmp); 00153 if (NULL!=ct) { 00154 DEBUGMSGT(("container_registry", 00155 "replacing previous container factory\n")); 00156 ct->factory = f; 00157 } 00158 else { 00159 ct = SNMP_MALLOC_TYPEDEF(container_type); 00160 if (NULL == ct) 00161 return -1; 00162 ct->name = strdup(name); 00163 ct->factory = f; 00164 ct->compare = c; 00165 CONTAINER_INSERT(containers, ct); 00166 } 00167 DEBUGMSGT(("container_registry", "registered container factory %s (%s)\n", 00168 ct->name, f->product)); 00169 00170 return 0; 00171 } 00172 00173 int 00174 netsnmp_container_register(const char* name, netsnmp_factory *f) 00175 { 00176 return netsnmp_container_register_with_compare(name, f, NULL); 00177 } 00178 00179 /*------------------------------------------------------------------ 00180 */ 00181 netsnmp_factory * 00182 netsnmp_container_get_factory(const char *type) 00183 { 00184 container_type ct, *found; 00185 00186 if (NULL==containers) 00187 return NULL; 00188 00189 ct.name = type; 00190 found = (container_type *)CONTAINER_FIND(containers, &ct); 00191 00192 return found ? found->factory : NULL; 00193 } 00194 00195 #ifndef NETSNMP_FEATURE_REMOVE_CONTAINER_FIND_FACTORY 00196 netsnmp_factory * 00197 netsnmp_container_find_factory(const char *type_list) 00198 { 00199 netsnmp_factory *f = NULL; 00200 char *list, *entry; 00201 char *st = NULL; 00202 00203 if (NULL==type_list) 00204 return NULL; 00205 00206 list = strdup(type_list); 00207 entry = strtok_r(list, ":", &st); 00208 while(entry) { 00209 f = netsnmp_container_get_factory(entry); 00210 if (NULL != f) 00211 break; 00212 entry = strtok_r(NULL, ":", &st); 00213 } 00214 00215 free(list); 00216 return f; 00217 } 00218 #endif /* NETSNMP_FEATURE_REMOVE_CONTAINER_FIND_FACTORY */ 00219 00220 /*------------------------------------------------------------------ 00221 */ 00222 static container_type * 00223 netsnmp_container_get_ct(const char *type) 00224 { 00225 container_type ct; 00226 00227 if (NULL == containers) 00228 return NULL; 00229 00230 ct.name = type; 00231 return (container_type *)CONTAINER_FIND(containers, &ct); 00232 } 00233 00234 static container_type * 00235 netsnmp_container_find_ct(const char *type_list) 00236 { 00237 container_type *ct = NULL; 00238 char *list, *entry; 00239 char *st = NULL; 00240 00241 if (NULL==type_list) 00242 return NULL; 00243 00244 list = strdup(type_list); 00245 entry = strtok_r(list, ":", &st); 00246 while(entry) { 00247 ct = netsnmp_container_get_ct(entry); 00248 if (NULL != ct) 00249 break; 00250 entry = strtok_r(NULL, ":", &st); 00251 } 00252 00253 free(list); 00254 return ct; 00255 } 00256 00257 00258 00259 /*------------------------------------------------------------------ 00260 */ 00261 netsnmp_container * 00262 netsnmp_container_get(const char *type) 00263 { 00264 netsnmp_container *c; 00265 container_type *ct = netsnmp_container_get_ct(type); 00266 if (ct) { 00267 c = (netsnmp_container *)(ct->factory->produce()); 00268 if (c && ct->compare) 00269 c->compare = ct->compare; 00270 return c; 00271 } 00272 00273 return NULL; 00274 } 00275 00276 /*------------------------------------------------------------------ 00277 */ 00278 netsnmp_container * 00279 netsnmp_container_find(const char *type) 00280 { 00281 container_type *ct = netsnmp_container_find_ct(type); 00282 netsnmp_container *c = ct ? (netsnmp_container *)(ct->factory->produce()) : NULL; 00283 00284 /* 00285 * provide default compare 00286 */ 00287 if (c) { 00288 if (ct->compare) 00289 c->compare = ct->compare; 00290 else if (NULL == c->compare) 00291 c->compare = netsnmp_compare_netsnmp_index; 00292 } 00293 00294 return c; 00295 } 00296 00297 /*------------------------------------------------------------------ 00298 */ 00299 void 00300 netsnmp_container_add_index(netsnmp_container *primary, 00301 netsnmp_container *new_index) 00302 { 00303 netsnmp_container *curr = primary; 00304 00305 if((NULL == new_index) || (NULL == primary)) { 00306 snmp_log(LOG_ERR, "add index called with null pointer\n"); 00307 return; 00308 } 00309 00310 while(curr->next) 00311 curr = curr->next; 00312 00313 curr->next = new_index; 00314 new_index->prev = curr; 00315 } 00316 00317 /*------------------------------------------------------------------ 00318 * These functions should EXACTLY match the inline version in 00319 * container.h. If you change one, change them both. 00320 */ 00321 int CONTAINER_INSERT_HELPER(netsnmp_container* x, const void* k) 00322 { 00323 while(x && x->insert_filter && x->insert_filter(x,k) == 1) 00324 x = x->next; 00325 if(x) { 00326 int rc = x->insert(x,k); 00327 if(rc) 00328 snmp_log(LOG_DEBUG,"error on subcontainer '%s' insert (%d)\n", 00329 x->container_name ? x->container_name : "", rc); 00330 else { 00331 rc = CONTAINER_INSERT_HELPER(x->next, k); 00332 if(rc) 00333 x->remove(x,k); 00334 } 00335 return rc; 00336 } 00337 return 0; 00338 } 00339 00340 /*------------------------------------------------------------------ 00341 * These functions should EXACTLY match the inline version in 00342 * container.h. If you change one, change them both. 00343 */ 00344 int CONTAINER_INSERT(netsnmp_container* x, const void* k) 00345 { 00347 while(x->prev) 00348 x = x->prev; 00349 return CONTAINER_INSERT_HELPER(x, k); 00350 } 00351 00352 /*------------------------------------------------------------------ 00353 * These functions should EXACTLY match the inline version in 00354 * container.h. If you change one, change them both. 00355 */ 00356 int CONTAINER_REMOVE(netsnmp_container *x, const void *k) 00357 { 00358 int rc2, rc = 0; 00359 00361 while(x->next) 00362 x = x->next; 00363 while(x) { 00364 rc2 = x->remove(x,k); 00366 if ((rc2) && (NULL == x->insert_filter)) { 00367 snmp_log(LOG_ERR,"error on subcontainer '%s' remove (%d)\n", 00368 x->container_name ? x->container_name : "", rc2); 00369 rc = rc2; 00370 } 00371 x = x->prev; 00372 00373 } 00374 return rc; 00375 } 00376 00377 /*------------------------------------------------------------------ 00378 * These functions should EXACTLY match the function version in 00379 * container.c. If you change one, change them both. 00380 */ 00381 #ifndef NETSNMP_FEATURE_REMOVE_CONTAINER_DUP 00382 netsnmp_container *CONTAINER_DUP(netsnmp_container *x, void *ctx, u_int flags) 00383 { 00384 if (NULL == x->duplicate) { 00385 snmp_log(LOG_ERR, "container '%s' does not support duplicate\n", 00386 x->container_name ? x->container_name : ""); 00387 return NULL; 00388 } 00389 return x->duplicate(x, ctx, flags); 00390 } 00391 #endif /* NETSNMP_FEATURE_REMOVE_CONTAINER_DUP */ 00392 00393 /*------------------------------------------------------------------ 00394 * These functions should EXACTLY match the inline version in 00395 * container.h. If you change one, change them both. 00396 */ 00397 int CONTAINER_FREE(netsnmp_container *x) 00398 { 00399 int rc2, rc = 0; 00400 00402 while(x->next) 00403 x = x->next; 00404 while(x) { 00405 netsnmp_container *tmp; 00406 char *name; 00407 tmp = x->prev; 00408 name = x->container_name; 00409 x->container_name = NULL; 00410 rc2 = x->cfree(x); 00411 if (rc2) { 00412 snmp_log(LOG_ERR,"error on subcontainer '%s' cfree (%d)\n", 00413 name ? name : "", rc2); 00414 rc = rc2; 00415 } 00416 SNMP_FREE(name); 00417 x = tmp; 00418 } 00419 return rc; 00420 } 00421 00422 /*------------------------------------------------------------------ 00423 * These functions should EXACTLY match the function version in 00424 * container.c. If you change one, change them both. 00425 */ 00426 /* 00427 * clear all containers. When clearing the *first* container, and 00428 * *only* the first container, call the function f for each item. 00429 * After calling this function, all containers should be empty. 00430 */ 00431 void CONTAINER_CLEAR(netsnmp_container *x, netsnmp_container_obj_func *f, 00432 void *c) 00433 { 00435 while(x->next) 00436 x = x->next; 00437 while(x->prev) { 00438 x->clear(x, NULL, c); 00439 x = x->prev; 00440 } 00441 x->clear(x, f, c); 00442 } 00443 00444 #ifndef NETSNMP_FEATURE_REMOVE_CONTAINER_FREE_ALL 00445 /* 00446 * clear all containers. When clearing the *first* container, and 00447 * *only* the first container, call the free_item function for each item. 00448 * After calling this function, all containers should be empty. 00449 */ 00450 void CONTAINER_FREE_ALL(netsnmp_container *x, void *c) 00451 { 00452 CONTAINER_CLEAR(x, x->free_item, c); 00453 } 00454 #endif /* NETSNMP_FEATURE_REMOVE_CONTAINER_FREE_ALL */ 00455 00456 #ifndef NETSNMP_FEATURE_REMOVE_SUBCONTAINER_FIND 00457 /*------------------------------------------------------------------ 00458 * These functions should EXACTLY match the function version in 00459 * container.c. If you change one, change them both. 00460 */ 00461 /* 00462 * Find a sub-container with the given name 00463 */ 00464 netsnmp_container *SUBCONTAINER_FIND(netsnmp_container *x, 00465 const char* name) 00466 { 00467 if ((NULL == x) || (NULL == name)) 00468 return NULL; 00469 00471 while(x->prev) 00472 x = x->prev; 00473 while(x) { 00474 if ((NULL != x->container_name) && (0 == strcmp(name,x->container_name))) 00475 break; 00476 x = x->next; 00477 } 00478 return x; 00479 } 00480 #endif /* NETSNMP_FEATURE_REMOVE_SUBCONTAINER_FIND */ 00481 00482 00483 /*------------------------------------------------------------------ 00484 */ 00485 void 00486 netsnmp_init_container(netsnmp_container *c, 00487 netsnmp_container_rc *init, 00488 netsnmp_container_rc *cfree, 00489 netsnmp_container_size *size, 00490 netsnmp_container_compare *cmp, 00491 netsnmp_container_op *ins, 00492 netsnmp_container_op *rem, 00493 netsnmp_container_rtn *fnd) 00494 { 00495 if (c == NULL) 00496 return; 00497 00498 c->init = init; 00499 c->cfree = cfree; 00500 c->get_size = size; 00501 c->compare = cmp; 00502 c->insert = ins; 00503 c->remove = rem; 00504 c->find = fnd; 00505 c->free_item = netsnmp_container_simple_free; 00506 } 00507 00508 int 00509 netsnmp_container_data_dup(netsnmp_container *dup, netsnmp_container *c) 00510 { 00511 if (!dup || !c) 00512 return -1; 00513 00514 if (c->container_name) 00515 dup->container_name = strdup(c->container_name); 00516 dup->compare = c->compare; 00517 dup->ncompare = c->ncompare; 00518 dup->release = c->release; 00519 dup->insert_filter = c->insert_filter; 00520 dup->free_item = c->free_item; 00521 dup->sync = c->sync; 00522 dup->flags = c->flags; 00523 00524 return 0; 00525 } 00526 00527 /*------------------------------------------------------------------ 00528 * 00529 * simple comparison routines 00530 * 00531 */ 00532 int 00533 netsnmp_compare_netsnmp_index(const void *lhs, const void *rhs) 00534 { 00535 int rc; 00536 netsnmp_assert((NULL != lhs) && (NULL != rhs)); 00537 DEBUGIF("compare:index") { 00538 DEBUGMSGT(("compare:index", "compare ")); 00539 DEBUGMSGSUBOID(("compare:index", ((const netsnmp_index *) lhs)->oids, 00540 ((const netsnmp_index *) lhs)->len)); 00541 DEBUGMSG(("compare:index", " to ")); 00542 DEBUGMSGSUBOID(("compare:index", ((const netsnmp_index *) rhs)->oids, 00543 ((const netsnmp_index *) rhs)->len)); 00544 DEBUGMSG(("compare:index", "\n")); 00545 } 00546 rc = snmp_oid_compare(((const netsnmp_index *) lhs)->oids, 00547 ((const netsnmp_index *) lhs)->len, 00548 ((const netsnmp_index *) rhs)->oids, 00549 ((const netsnmp_index *) rhs)->len); 00550 DEBUGMSGT(("compare:index", "result was %d\n", rc)); 00551 return rc; 00552 } 00553 00554 int 00555 netsnmp_ncompare_netsnmp_index(const void *lhs, const void *rhs) 00556 { 00557 int rc; 00558 netsnmp_assert((NULL != lhs) && (NULL != rhs)); 00559 DEBUGIF("compare:index") { 00560 DEBUGMSGT(("compare:index", "compare ")); 00561 DEBUGMSGSUBOID(("compare:index", ((const netsnmp_index *) lhs)->oids, 00562 ((const netsnmp_index *) lhs)->len)); 00563 DEBUGMSG(("compare:index", " to ")); 00564 DEBUGMSGSUBOID(("compare:index", ((const netsnmp_index *) rhs)->oids, 00565 ((const netsnmp_index *) rhs)->len)); 00566 DEBUGMSG(("compare:index", "\n")); 00567 } 00568 rc = snmp_oid_ncompare(((const netsnmp_index *) lhs)->oids, 00569 ((const netsnmp_index *) lhs)->len, 00570 ((const netsnmp_index *) rhs)->oids, 00571 ((const netsnmp_index *) rhs)->len, 00572 ((const netsnmp_index *) rhs)->len); 00573 DEBUGMSGT(("compare:index", "result was %d\n", rc)); 00574 return rc; 00575 } 00576 00577 int 00578 netsnmp_compare_cstring(const void * lhs, const void * rhs) 00579 { 00580 return strcmp(((const container_type*)lhs)->name, 00581 ((const container_type*)rhs)->name); 00582 } 00583 00584 #ifndef NETSNMP_FEATURE_REMOVE_CONTAINER_NCOMPARE_CSTRING 00585 int 00586 netsnmp_ncompare_cstring(const void * lhs, const void * rhs) 00587 { 00588 return strncmp(((const container_type*)lhs)->name, 00589 ((const container_type*)rhs)->name, 00590 strlen(((const container_type*)rhs)->name)); 00591 } 00592 #endif /* NETSNMP_FEATURE_REMOVE_CONTAINER_NCOMPARE_CSTRING */ 00593 00594 int 00595 netsnmp_compare_direct_cstring(const void * lhs, const void * rhs) 00596 { 00597 return strcmp((const char*)lhs, (const char*)rhs); 00598 } 00599 00600 /* 00601 * compare two memory buffers 00602 * 00603 * since snmp strings aren't NULL terminated, we can't use strcmp. So 00604 * compare up to the length of the smaller, and then use length to 00605 * break any ties. 00606 */ 00607 #ifndef NETSNMP_FEATURE_REMOVE_CONTAINER_COMPARE_MEM 00608 int 00609 netsnmp_compare_mem(const char * lhs, size_t lhs_len, 00610 const char * rhs, size_t rhs_len) 00611 { 00612 int rc, min = SNMP_MIN(lhs_len, rhs_len); 00613 00614 rc = memcmp(lhs, rhs, min); 00615 if((rc==0) && (lhs_len != rhs_len)) { 00616 if(lhs_len < rhs_len) 00617 rc = -1; 00618 else 00619 rc = 1; 00620 } 00621 00622 return rc; 00623 } 00624 #endif /* NETSNMP_FEATURE_REMOVE_CONTAINER_COMPARE_MEM */ 00625 00626 #ifndef NETSNMP_FEATURE_REMOVE_CONTAINER_COMPARE_LONG 00627 int 00628 netsnmp_compare_long(const void * lhs, const void * rhs) 00629 { 00630 typedef struct { long index; } dummy; 00631 00632 const dummy *lhd = (const dummy*)lhs; 00633 const dummy *rhd = (const dummy*)rhs; 00634 00635 if (lhd->index < rhd->index) 00636 return -1; 00637 else if (lhd->index > rhd->index) 00638 return 1; 00639 00640 return 0; 00641 } 00642 #endif /* NETSNMP_FEATURE_REMOVE_CONTAINER_COMPARE_LONG */ 00643 00644 #ifndef NETSNMP_FEATURE_REMOVE_CONTAINER_COMPARE_ULONG 00645 int 00646 netsnmp_compare_ulong(const void * lhs, const void * rhs) 00647 { 00648 typedef struct { u_long index; } dummy; 00649 00650 const dummy *lhd = (const dummy*)lhs; 00651 const dummy *rhd = (const dummy*)rhs; 00652 00653 if (lhd->index < rhd->index) 00654 return -1; 00655 else if (lhd->index > rhd->index) 00656 return 1; 00657 00658 return 0; 00659 } 00660 #endif /* NETSNMP_FEATURE_REMOVE_CONTAINER_COMPARE_ULONG */ 00661 00662 #ifndef NETSNMP_FEATURE_REMOVE_CONTAINER_COMPARE_INT32 00663 int 00664 netsnmp_compare_int32(const void * lhs, const void * rhs) 00665 { 00666 typedef struct { int32_t index; } dummy; 00667 00668 const dummy *lhd = (const dummy*)lhs; 00669 const dummy *rhd = (const dummy*)rhs; 00670 00671 if (lhd->index < rhd->index) 00672 return -1; 00673 else if (lhd->index > rhd->index) 00674 return 1; 00675 00676 return 0; 00677 } 00678 #endif /* NETSNMP_FEATURE_REMOVE_CONTAINER_COMPARE_INT32 */ 00679 00680 #ifndef NETSNMP_FEATURE_REMOVE_CONTAINER_COMPARE_UINT32 00681 int 00682 netsnmp_compare_uint32(const void * lhs, const void * rhs) 00683 { 00684 typedef struct { uint32_t index; } dummy; 00685 00686 const dummy *lhd = (const dummy*)lhs; 00687 const dummy *rhd = (const dummy*)rhs; 00688 00689 if (lhd->index < rhd->index) 00690 return -1; 00691 else if (lhd->index > rhd->index) 00692 return 1; 00693 00694 return 0; 00695 } 00696 #endif /* NETSNMP_FEATURE_REMOVE_CONTAINER_COMPARE_UINT32 */ 00697 00698 /*------------------------------------------------------------------ 00699 * netsnmp_container_simple_free 00700 * 00701 * useful function to pass to CONTAINER_FOR_EACH, when a simple 00702 * free is needed for every item. 00703 */ 00704 void 00705 netsnmp_container_simple_free(void *data, void *context) 00706 { 00707 if (data == NULL) 00708 return; 00709 00710 DEBUGMSGTL(("verbose:container", 00711 "netsnmp_container_simple_free) called for %p/%p\n", 00712 data, context)); 00713 free((void*)data); /* SNMP_FREE wasted on param */ 00714 }