net-snmp 5.7
|
00001 /* 00002 * container_binary_array.c 00003 * $Id$ 00004 * 00005 * see comments in header file. 00006 * 00007 */ 00008 00009 #include <net-snmp/net-snmp-config.h> 00010 00011 #if HAVE_IO_H 00012 #include <io.h> 00013 #endif 00014 #include <stdio.h> 00015 #if HAVE_STDLIB_H 00016 #include <stdlib.h> 00017 #endif 00018 #if HAVE_MALLOC_H 00019 #include <malloc.h> 00020 #endif 00021 #include <sys/types.h> 00022 #if HAVE_STRING_H 00023 #include <string.h> 00024 #else 00025 #include <strings.h> 00026 #endif 00027 00028 #include <net-snmp/net-snmp-includes.h> 00029 #include <net-snmp/types.h> 00030 #include <net-snmp/library/snmp_api.h> 00031 #include <net-snmp/library/container.h> 00032 #include <net-snmp/library/container_binary_array.h> 00033 #include <net-snmp/library/tools.h> 00034 #include <net-snmp/library/snmp_assert.h> 00035 00036 typedef struct binary_array_table_s { 00037 size_t max_size; /* Size of the current data table */ 00038 size_t count; /* Index of the next free entry */ 00039 int dirty; 00040 void **data; /* The table itself */ 00041 } binary_array_table; 00042 00043 typedef struct binary_array_iterator_s { 00044 netsnmp_iterator base; 00045 00046 size_t pos; 00047 } binary_array_iterator; 00048 00049 static netsnmp_iterator *_ba_iterator_get(netsnmp_container *c); 00050 00051 /********************************************************************** 00052 * 00053 * 00054 * 00055 */ 00056 static void 00057 array_qsort(void **data, int first, int last, netsnmp_container_compare *f) 00058 { 00059 int i, j; 00060 void *mid, *tmp; 00061 00062 i = first; 00063 j = last; 00064 mid = data[(first+last)/2]; 00065 00066 do { 00067 while (i < last && (*f)(data[i], mid) < 0) 00068 ++i; 00069 while (j > first && (*f)(mid, data[j]) < 0) 00070 --j; 00071 00072 if(i < j) { 00073 tmp = data[i]; 00074 data[i] = data[j]; 00075 data[j] = tmp; 00076 ++i; 00077 --j; 00078 } 00079 else if (i == j) { 00080 ++i; 00081 --j; 00082 break; 00083 } 00084 } while(i <= j); 00085 00086 if (j > first) 00087 array_qsort(data, first, j, f); 00088 00089 if (i < last) 00090 array_qsort(data, i, last, f); 00091 } 00092 00093 static int 00094 Sort_Array(netsnmp_container *c) 00095 { 00096 binary_array_table *t = (binary_array_table*)c->container_data; 00097 netsnmp_assert(t!=NULL); 00098 netsnmp_assert(c->compare!=NULL); 00099 00100 if (c->flags & CONTAINER_KEY_UNSORTED) 00101 return 0; 00102 00103 if (t->dirty) { 00104 /* 00105 * Sort the table 00106 */ 00107 if (t->count > 1) 00108 array_qsort(t->data, 0, t->count - 1, c->compare); 00109 t->dirty = 0; 00110 00111 /* 00112 * no way to know if it actually changed... just assume so. 00113 */ 00114 ++c->sync; 00115 } 00116 00117 return 1; 00118 } 00119 00120 static int 00121 linear_search(const void *val, netsnmp_container *c) 00122 { 00123 binary_array_table *t = (binary_array_table*)c->container_data; 00124 size_t pos = 0; 00125 00126 if (!t->count) 00127 return -1; 00128 00129 if (! (c->flags & CONTAINER_KEY_UNSORTED)) { 00130 snmp_log(LOG_ERR, "linear search on sorted container %s?!?\n", 00131 c->container_name); 00132 return -1; 00133 } 00134 00135 for (; pos < t->count; ++pos) { 00136 if (c->compare(t->data[pos], val) == 0) 00137 break; 00138 } 00139 00140 if (pos >= t->count) 00141 return -1; 00142 00143 return pos; 00144 } 00145 00146 static int 00147 binary_search(const void *val, netsnmp_container *c, int exact) 00148 { 00149 binary_array_table *t = (binary_array_table*)c->container_data; 00150 size_t len = t->count; 00151 size_t half; 00152 size_t middle = 0; 00153 size_t first = 0; 00154 int result = 0; 00155 00156 if (!len) 00157 return -1; 00158 00159 if (c->flags & CONTAINER_KEY_UNSORTED) { 00160 if (!exact) { 00161 snmp_log(LOG_ERR, "non-exact search on unsorted container %s?!?\n", 00162 c->container_name); 00163 return -1; 00164 } 00165 return linear_search(val, c); 00166 } 00167 00168 if (t->dirty) 00169 Sort_Array(c); 00170 00171 while (len > 0) { 00172 half = len >> 1; 00173 middle = first; 00174 middle += half; 00175 if ((result = 00176 c->compare(t->data[middle], val)) < 0) { 00177 first = middle; 00178 ++first; 00179 len = len - half - 1; 00180 } else { 00181 if(result == 0) { 00182 first = middle; 00183 break; 00184 } 00185 len = half; 00186 } 00187 } 00188 00189 if (first >= t->count) 00190 return -1; 00191 00192 if(first != middle) { 00193 /* last compare wasn't against first, so get actual result */ 00194 result = c->compare(t->data[first], val); 00195 } 00196 00197 if(result == 0) { 00198 if (!exact) { 00199 if (++first == t->count) 00200 first = -1; 00201 } 00202 } 00203 else { 00204 if(exact) 00205 first = -1; 00206 } 00207 00208 return first; 00209 } 00210 00211 NETSNMP_STATIC_INLINE binary_array_table * 00212 netsnmp_binary_array_initialize(void) 00213 { 00214 binary_array_table *t; 00215 00216 t = SNMP_MALLOC_TYPEDEF(binary_array_table); 00217 if (t == NULL) 00218 return NULL; 00219 00220 t->max_size = 0; 00221 t->count = 0; 00222 t->dirty = 0; 00223 t->data = NULL; 00224 00225 return t; 00226 } 00227 00228 void 00229 netsnmp_binary_array_release(netsnmp_container *c) 00230 { 00231 binary_array_table *t = (binary_array_table*)c->container_data; 00232 SNMP_FREE(t->data); 00233 SNMP_FREE(t); 00234 SNMP_FREE(c); 00235 } 00236 00237 int 00238 netsnmp_binary_array_options_set(netsnmp_container *c, int set, u_int flags) 00239 { 00240 #define BA_FLAGS (CONTAINER_KEY_ALLOW_DUPLICATES|CONTAINER_KEY_UNSORTED) 00241 00242 if (set) { 00243 if ((flags & BA_FLAGS) == flags) 00244 c->flags = flags; 00245 else 00246 flags = (u_int)-1; /* unsupported flag */ 00247 } 00248 else 00249 return ((c->flags & flags) == flags); 00250 return flags; 00251 } 00252 00253 NETSNMP_STATIC_INLINE size_t 00254 netsnmp_binary_array_count(netsnmp_container *c) 00255 { 00256 binary_array_table *t = (binary_array_table*)c->container_data; 00257 /* 00258 * return count 00259 */ 00260 return t ? t->count : 0; 00261 } 00262 00263 NETSNMP_STATIC_INLINE void * 00264 netsnmp_binary_array_get(netsnmp_container *c, const void *key, int exact) 00265 { 00266 binary_array_table *t = (binary_array_table*)c->container_data; 00267 int index = 0; 00268 00269 /* 00270 * if there is no data, return NULL; 00271 */ 00272 if (!t->count) 00273 return NULL; 00274 00275 /* 00276 * if the table is dirty, sort it. 00277 */ 00278 if (t->dirty) 00279 Sort_Array(c); 00280 00281 /* 00282 * if there is a key, search. Otherwise default is 0; 00283 */ 00284 if (key) { 00285 if ((index = binary_search(key, c, exact)) == -1) 00286 return NULL; 00287 } 00288 00289 return t->data[index]; 00290 } 00291 00292 int 00293 netsnmp_binary_array_remove_at(netsnmp_container *c, size_t index, void **save) 00294 { 00295 binary_array_table *t = (binary_array_table*)c->container_data; 00296 00297 if (save) 00298 *save = NULL; 00299 00300 /* 00301 * if there is no data, return NULL; 00302 */ 00303 if (!t->count) 00304 return 0; 00305 00306 /* 00307 * find old data and save it, if ptr provided 00308 */ 00309 if (save) 00310 *save = t->data[index]; 00311 00312 /* 00313 * if entry was last item, just decrement count 00314 */ 00315 --t->count; 00316 if (index != t->count) { 00317 /* 00318 * otherwise, shift array down 00319 */ 00320 memmove(&t->data[index], &t->data[index+1], 00321 sizeof(void*) * (t->count - index)); 00322 00323 ++c->sync; 00324 } 00325 00326 return 0; 00327 } 00328 int 00329 netsnmp_binary_array_remove(netsnmp_container *c, const void *key, void **save) 00330 { 00331 binary_array_table *t = (binary_array_table*)c->container_data; 00332 int index = 0; 00333 00334 if (save) 00335 *save = NULL; 00336 00337 /* 00338 * if there is no data, return NULL; 00339 */ 00340 if (!t->count) 00341 return 0; 00342 00343 /* 00344 * if the table is dirty, sort it. 00345 */ 00346 if (t->dirty) 00347 Sort_Array(c); 00348 00349 /* 00350 * search 00351 */ 00352 if ((index = binary_search(key, c, 1)) == -1) 00353 return -1; 00354 00355 return netsnmp_binary_array_remove_at(c, (size_t)index, save); 00356 } 00357 00358 NETSNMP_STATIC_INLINE void 00359 netsnmp_binary_array_for_each(netsnmp_container *c, 00360 netsnmp_container_obj_func *fe, 00361 void *context, int sort) 00362 { 00363 binary_array_table *t = (binary_array_table*)c->container_data; 00364 size_t i; 00365 00366 if (sort && t->dirty) 00367 Sort_Array(c); 00368 00369 for (i = 0; i < t->count; ++i) 00370 (*fe) (t->data[i], context); 00371 } 00372 00373 NETSNMP_STATIC_INLINE void 00374 netsnmp_binary_array_clear(netsnmp_container *c, 00375 netsnmp_container_obj_func *fe, 00376 void *context) 00377 { 00378 binary_array_table *t = (binary_array_table*)c->container_data; 00379 00380 if( NULL != fe ) { 00381 size_t i; 00382 00383 for (i = 0; i < t->count; ++i) 00384 (*fe) (t->data[i], context); 00385 } 00386 00387 t->count = 0; 00388 t->dirty = 0; 00389 ++c->sync; 00390 } 00391 00392 NETSNMP_STATIC_INLINE int 00393 netsnmp_binary_array_insert(netsnmp_container *c, const void *entry) 00394 { 00395 binary_array_table *t = (binary_array_table*)c->container_data; 00396 int was_dirty = 0; 00397 /* 00398 * check for duplicates 00399 */ 00400 if (! (c->flags & CONTAINER_KEY_ALLOW_DUPLICATES)) { 00401 was_dirty = t->dirty; 00402 if (NULL != netsnmp_binary_array_get(c, entry, 1)) { 00403 DEBUGMSGTL(("container","not inserting duplicate key\n")); 00404 return -1; 00405 } 00406 } 00407 00408 /* 00409 * check if we need to resize the array 00410 */ 00411 if (t->max_size <= t->count) { 00412 /* 00413 * Table is full, so extend it to double the size, or use 10 elements 00414 * if it is empty. 00415 */ 00416 size_t const new_max = t->max_size > 0 ? 2 * t->max_size : 10; 00417 void ** const new_data = 00418 (void**) realloc(t->data, new_max * sizeof(void*)); 00419 00420 if (new_data == NULL) 00421 return -1; 00422 00423 memset(new_data + t->max_size, 0x0, 00424 (new_max - t->max_size) * sizeof(void*)); 00425 00426 t->data = new_data; 00427 t->max_size = new_max; 00428 } 00429 00430 /* 00431 * Insert the new entry into the data array 00432 */ 00433 t->data[t->count++] = NETSNMP_REMOVE_CONST(void *, entry); 00434 t->dirty = 1; 00435 00436 /* 00437 * if array was dirty before we called get, sync was incremented when 00438 * get called SortArray. If we didn't call get or the array wasn't dirty, 00439 * bump sync now. 00440 */ 00441 if (!was_dirty) 00442 ++c->sync; 00443 00444 return 0; 00445 } 00446 00447 /********************************************************************** 00448 * 00449 * Special case support for subsets 00450 * 00451 */ 00452 static int 00453 binary_search_for_start(netsnmp_index *val, netsnmp_container *c) 00454 { 00455 binary_array_table *t = (binary_array_table*)c->container_data; 00456 size_t len = t->count; 00457 size_t half; 00458 size_t middle; 00459 size_t first = 0; 00460 int result = 0; 00461 00462 if (!len) 00463 return -1; 00464 00465 if (t->dirty) 00466 Sort_Array(c); 00467 00468 while (len > 0) { 00469 half = len >> 1; 00470 middle = first; 00471 middle += half; 00472 if ((result = c->ncompare(t->data[middle], val)) < 0) { 00473 first = middle; 00474 ++first; 00475 len = len - half - 1; 00476 } else 00477 len = half; 00478 } 00479 00480 if ((first >= t->count) || 00481 c->ncompare(t->data[first], val) != 0) 00482 return -1; 00483 00484 return first; 00485 } 00486 00487 void ** 00488 netsnmp_binary_array_get_subset(netsnmp_container *c, void *key, int *len) 00489 { 00490 binary_array_table *t = (binary_array_table*)c->container_data; 00491 void **subset; 00492 int start, end; 00493 size_t i; 00494 00495 /* 00496 * if there is no data, return NULL; 00497 */ 00498 if (!c || !key) 00499 return NULL; 00500 00501 t = (binary_array_table*)c->container_data; 00502 netsnmp_assert(c->ncompare); 00503 if (!t->count | !c->ncompare) 00504 return NULL; 00505 00506 /* 00507 * if the table is dirty, sort it. 00508 */ 00509 if (t->dirty) 00510 Sort_Array(c); 00511 00512 /* 00513 * find matching items 00514 */ 00515 start = end = binary_search_for_start((netsnmp_index *)key, c); 00516 if (start == -1) 00517 return NULL; 00518 00519 for (i = start + 1; i < t->count; ++i) { 00520 if (0 != c->ncompare(t->data[i], key)) 00521 break; 00522 ++end; 00523 } 00524 00525 *len = end - start + 1; 00526 subset = (void **)malloc((*len) * sizeof(void*)); 00527 if (subset) 00528 memcpy(subset, &t->data[start], sizeof(void*) * (*len)); 00529 00530 return subset; 00531 } 00532 00533 /********************************************************************** 00534 * 00535 * container 00536 * 00537 */ 00538 static void * 00539 _ba_find(netsnmp_container *container, const void *data) 00540 { 00541 return netsnmp_binary_array_get(container, data, 1); 00542 } 00543 00544 static void * 00545 _ba_find_next(netsnmp_container *container, const void *data) 00546 { 00547 return netsnmp_binary_array_get(container, data, 0); 00548 } 00549 00550 static int 00551 _ba_insert(netsnmp_container *container, const void *data) 00552 { 00553 return netsnmp_binary_array_insert(container, data); 00554 } 00555 00556 static int 00557 _ba_remove(netsnmp_container *container, const void *data) 00558 { 00559 return netsnmp_binary_array_remove(container,data, NULL); 00560 } 00561 00562 static int 00563 _ba_free(netsnmp_container *container) 00564 { 00565 netsnmp_binary_array_release(container); 00566 return 0; 00567 } 00568 00569 static size_t 00570 _ba_size(netsnmp_container *container) 00571 { 00572 return netsnmp_binary_array_count(container); 00573 } 00574 00575 static void 00576 _ba_for_each(netsnmp_container *container, netsnmp_container_obj_func *f, 00577 void *context) 00578 { 00579 netsnmp_binary_array_for_each(container, f, context, 1); 00580 } 00581 00582 static void 00583 _ba_clear(netsnmp_container *container, netsnmp_container_obj_func *f, 00584 void *context) 00585 { 00586 netsnmp_binary_array_clear(container, f, context); 00587 } 00588 00589 static netsnmp_void_array * 00590 _ba_get_subset(netsnmp_container *container, void *data) 00591 { 00592 netsnmp_void_array * va; 00593 void ** rtn; 00594 int len; 00595 00596 rtn = netsnmp_binary_array_get_subset(container, data, &len); 00597 if ((NULL==rtn) || (len <=0)) 00598 return NULL; 00599 00600 va = SNMP_MALLOC_TYPEDEF(netsnmp_void_array); 00601 if (NULL==va) 00602 { 00603 free (rtn); 00604 return NULL; 00605 } 00606 00607 va->size = len; 00608 va->array = rtn; 00609 00610 return va; 00611 } 00612 00613 static int _ba_options(netsnmp_container *c, int set, u_int flags) 00614 { 00615 return netsnmp_binary_array_options_set(c, set, flags); 00616 } 00617 00618 static netsnmp_container * 00619 _ba_duplicate(netsnmp_container *c, void *ctx, u_int flags) 00620 { 00621 netsnmp_container *dup; 00622 binary_array_table *dupt, *t; 00623 00624 if (flags) { 00625 snmp_log(LOG_ERR, "binary arry duplicate does not supprt flags yet\n"); 00626 return NULL; 00627 } 00628 00629 dup = netsnmp_container_get_binary_array(); 00630 if (NULL == dup) { 00631 snmp_log(LOG_ERR," no memory for binary array duplicate\n"); 00632 return NULL; 00633 } 00634 /* 00635 * deal with container stuff 00636 */ 00637 if (netsnmp_container_data_dup(dup, c) != 0) { 00638 netsnmp_binary_array_release(dup); 00639 return NULL; 00640 } 00641 00642 /* 00643 * deal with data 00644 */ 00645 dupt = (binary_array_table*)dup->container_data; 00646 t = (binary_array_table*)c->container_data; 00647 00648 dupt->max_size = t->max_size; 00649 dupt->count = t->count; 00650 dupt->dirty = t->dirty; 00651 00652 /* 00653 * shallow copy 00654 */ 00655 dupt->data = (void**) malloc(dupt->max_size * sizeof(void*)); 00656 if (NULL == dupt->data) { 00657 snmp_log(LOG_ERR, "no memory for binary array duplicate\n"); 00658 netsnmp_binary_array_release(dup); 00659 return NULL; 00660 } 00661 00662 memcpy(dupt->data, t->data, dupt->max_size * sizeof(void*)); 00663 00664 return dup; 00665 } 00666 00667 netsnmp_container * 00668 netsnmp_container_get_binary_array(void) 00669 { 00670 /* 00671 * allocate memory 00672 */ 00673 netsnmp_container *c = SNMP_MALLOC_TYPEDEF(netsnmp_container); 00674 if (NULL==c) { 00675 snmp_log(LOG_ERR, "couldn't allocate memory\n"); 00676 return NULL; 00677 } 00678 00679 c->container_data = netsnmp_binary_array_initialize(); 00680 00681 /* 00682 * NOTE: CHANGES HERE MUST BE DUPLICATED IN duplicate AS WELL!! 00683 */ 00684 netsnmp_init_container(c, NULL, _ba_free, _ba_size, NULL, _ba_insert, 00685 _ba_remove, _ba_find); 00686 c->find_next = _ba_find_next; 00687 c->get_subset = _ba_get_subset; 00688 c->get_iterator = _ba_iterator_get; 00689 c->for_each = _ba_for_each; 00690 c->clear = _ba_clear; 00691 c->options = _ba_options; 00692 c->duplicate = _ba_duplicate; 00693 00694 return c; 00695 } 00696 00697 netsnmp_factory * 00698 netsnmp_container_get_binary_array_factory(void) 00699 { 00700 static netsnmp_factory f = { "binary_array", 00701 (netsnmp_factory_produce_f*) 00702 netsnmp_container_get_binary_array }; 00703 00704 return &f; 00705 } 00706 00707 void 00708 netsnmp_container_binary_array_init(void) 00709 { 00710 netsnmp_container_register("binary_array", 00711 netsnmp_container_get_binary_array_factory()); 00712 } 00713 00714 /********************************************************************** 00715 * 00716 * iterator 00717 * 00718 */ 00719 NETSNMP_STATIC_INLINE binary_array_table * 00720 _ba_it2cont(binary_array_iterator *it) 00721 { 00722 if(NULL == it) { 00723 netsnmp_assert(NULL != it); 00724 return NULL; 00725 } 00726 if(NULL == it->base.container) { 00727 netsnmp_assert(NULL != it->base.container); 00728 return NULL; 00729 } 00730 if(NULL == it->base.container->container_data) { 00731 netsnmp_assert(NULL != it->base.container->container_data); 00732 return NULL; 00733 } 00734 00735 return (binary_array_table*)(it->base.container->container_data); 00736 } 00737 00738 NETSNMP_STATIC_INLINE void * 00739 _ba_iterator_position(binary_array_iterator *it, size_t pos) 00740 { 00741 binary_array_table *t = _ba_it2cont(it); 00742 if (NULL == t) 00743 return t; /* msg already logged */ 00744 00745 if(it->base.container->sync != it->base.sync) { 00746 DEBUGMSGTL(("container:iterator", "out of sync\n")); 00747 return NULL; 00748 } 00749 00750 if(0 == t->count) { 00751 DEBUGMSGTL(("container:iterator", "empty\n")); 00752 return NULL; 00753 } 00754 else if(pos >= t->count) { 00755 DEBUGMSGTL(("container:iterator", "end of container\n")); 00756 return NULL; 00757 } 00758 00759 return t->data[ pos ]; 00760 } 00761 00762 static void * 00763 _ba_iterator_curr(binary_array_iterator *it) 00764 { 00765 if(NULL == it) { 00766 netsnmp_assert(NULL != it); 00767 return NULL; 00768 } 00769 00770 return _ba_iterator_position(it, it->pos); 00771 } 00772 00773 static void * 00774 _ba_iterator_first(binary_array_iterator *it) 00775 { 00776 return _ba_iterator_position(it, 0); 00777 } 00778 00779 static void * 00780 _ba_iterator_next(binary_array_iterator *it) 00781 { 00782 if(NULL == it) { 00783 netsnmp_assert(NULL != it); 00784 return NULL; 00785 } 00786 00787 ++it->pos; 00788 00789 return _ba_iterator_position(it, it->pos); 00790 } 00791 00792 static void * 00793 _ba_iterator_last(binary_array_iterator *it) 00794 { 00795 binary_array_table* t = _ba_it2cont(it); 00796 if(NULL == t) { 00797 netsnmp_assert(NULL != t); 00798 return NULL; 00799 } 00800 00801 return _ba_iterator_position(it, t->count - 1 ); 00802 } 00803 00804 static int 00805 _ba_iterator_remove(binary_array_iterator *it) 00806 { 00807 binary_array_table* t = _ba_it2cont(it); 00808 if(NULL == t) { 00809 netsnmp_assert(NULL != t); 00810 return -1; 00811 } 00812 00813 /* 00814 * since this iterator was used for the remove, keep it in sync with 00815 * the container. Also, back up one so that next will be the position 00816 * that was just removed. 00817 */ 00818 ++it->base.sync; 00819 return netsnmp_binary_array_remove_at(it->base.container, it->pos--, NULL); 00820 00821 } 00822 00823 static int 00824 _ba_iterator_reset(binary_array_iterator *it) 00825 { 00826 binary_array_table* t = _ba_it2cont(it); 00827 if(NULL == t) { 00828 netsnmp_assert(NULL != t); 00829 return -1; 00830 } 00831 00832 if (t->dirty) 00833 Sort_Array(it->base.container); 00834 00835 /* 00836 * save sync count, to make sure container doesn't change while 00837 * iterator is in use. 00838 */ 00839 it->base.sync = it->base.container->sync; 00840 00841 it->pos = 0; 00842 00843 return 0; 00844 } 00845 00846 static int 00847 _ba_iterator_release(netsnmp_iterator *it) 00848 { 00849 free(it); 00850 00851 return 0; 00852 } 00853 00854 static netsnmp_iterator * 00855 _ba_iterator_get(netsnmp_container *c) 00856 { 00857 binary_array_iterator* it; 00858 00859 if(NULL == c) 00860 return NULL; 00861 00862 it = SNMP_MALLOC_TYPEDEF(binary_array_iterator); 00863 if(NULL == it) 00864 return NULL; 00865 00866 it->base.container = c; 00867 00868 it->base.first = (netsnmp_iterator_rtn*)_ba_iterator_first; 00869 it->base.next = (netsnmp_iterator_rtn*)_ba_iterator_next; 00870 it->base.curr = (netsnmp_iterator_rtn*)_ba_iterator_curr; 00871 it->base.last = (netsnmp_iterator_rtn*)_ba_iterator_last; 00872 it->base.remove = (netsnmp_iterator_rc*)_ba_iterator_remove; 00873 it->base.reset = (netsnmp_iterator_rc*)_ba_iterator_reset; 00874 it->base.release = (netsnmp_iterator_rc*)_ba_iterator_release; 00875 00876 (void)_ba_iterator_reset(it); 00877 00878 return (netsnmp_iterator *)it; 00879 }