00001 /* 00002 * table_array.c 00003 * $Id: table__array_8c-source.html 14005 2005-12-30 19:14:23Z alex_b $ 00004 */ 00005 00006 #include <net-snmp/net-snmp-config.h> 00007 00008 #if HAVE_STRING_H 00009 #include <string.h> 00010 #else 00011 #include <strings.h> 00012 #endif 00013 00014 #include <net-snmp/net-snmp-includes.h> 00015 #include <net-snmp/agent/net-snmp-agent-includes.h> 00016 00017 #include <net-snmp/agent/table.h> 00018 #include <net-snmp/agent/table_array.h> 00019 #include <net-snmp/library/container.h> 00020 #include <net-snmp/library/snmp_assert.h> 00021 00022 /* 00023 * snmp.h:#define SNMP_MSG_INTERNAL_SET_BEGIN -1 00024 * snmp.h:#define SNMP_MSG_INTERNAL_SET_RESERVE1 0 00025 * snmp.h:#define SNMP_MSG_INTERNAL_SET_RESERVE2 1 00026 * snmp.h:#define SNMP_MSG_INTERNAL_SET_ACTION 2 00027 * snmp.h:#define SNMP_MSG_INTERNAL_SET_COMMIT 3 00028 * snmp.h:#define SNMP_MSG_INTERNAL_SET_FREE 4 00029 * snmp.h:#define SNMP_MSG_INTERNAL_SET_UNDO 5 00030 */ 00031 00032 static const char *mode_name[] = { 00033 "Reserve 1", 00034 "Reserve 2", 00035 "Action", 00036 "Commit", 00037 "Free", 00038 "Undo" 00039 }; 00040 00041 /* 00042 * PRIVATE structure for holding important info for each table. 00043 */ 00044 typedef struct table_container_data_s { 00045 00047 netsnmp_table_registration_info *tblreg_info; 00048 00050 netsnmp_container *table; 00051 00052 /* 00053 * mutex_type lock; 00054 */ 00055 00058 int group_rows; 00059 00061 netsnmp_table_array_callbacks *cb; 00062 00063 } table_container_data; 00064 00133 /********************************************************************** 00134 ********************************************************************** 00135 * * 00136 * * 00137 * PUBLIC Registration functions * 00138 * * 00139 * * 00140 ********************************************************************** 00141 **********************************************************************/ 00147 int 00148 netsnmp_table_container_register(netsnmp_handler_registration *reginfo, 00149 netsnmp_table_registration_info *tabreg, 00150 netsnmp_table_array_callbacks *cb, 00151 netsnmp_container *container, 00152 int group_rows) 00153 { 00154 table_container_data *tad = SNMP_MALLOC_TYPEDEF(table_container_data); 00155 if (!tad) 00156 return SNMPERR_GENERR; 00157 tad->tblreg_info = tabreg; /* we need it too, but it really is not ours */ 00158 00159 if (!cb) { 00160 snmp_log(LOG_ERR, "table_array registration with no callbacks\n" ); 00161 return SNMPERR_GENERR; 00162 } 00163 /* 00164 * check for required callbacks 00165 */ 00166 if ((cb->can_set && 00167 ((NULL==cb->duplicate_row) || (NULL==cb->delete_row) || 00168 (NULL==cb->row_copy)) )) { 00169 snmp_log(LOG_ERR, "table_array registration with incomplete " 00170 "callback structure.\n"); 00171 return SNMPERR_GENERR; 00172 } 00173 00174 if (NULL==container) 00175 tad->table = netsnmp_container_find("table_array"); 00176 else 00177 tad->table = container; 00178 if (NULL==container->compare) 00179 container->compare = netsnmp_compare_netsnmp_index; 00180 if (NULL==container->ncompare) 00181 container->ncompare = netsnmp_ncompare_netsnmp_index; 00182 00183 tad->cb = cb; 00184 00185 reginfo->handler->myvoid = tad; 00186 00187 return netsnmp_register_table(reginfo, tabreg); 00188 } 00189 00190 int 00191 netsnmp_table_array_register(netsnmp_handler_registration *reginfo, 00192 netsnmp_table_registration_info *tabreg, 00193 netsnmp_table_array_callbacks *cb, 00194 netsnmp_container *container, 00195 int group_rows) 00196 { 00197 netsnmp_inject_handler(reginfo, 00198 netsnmp_create_handler(reginfo->handlerName, 00199 netsnmp_table_array_helper_handler)); 00200 return netsnmp_table_container_register(reginfo, tabreg, cb, 00201 container, group_rows); 00202 } 00203 00205 netsnmp_mib_handler * 00206 netsnmp_find_table_array_handler(netsnmp_handler_registration *reginfo) 00207 { 00208 netsnmp_mib_handler *mh; 00209 if (!reginfo) 00210 return NULL; 00211 mh = reginfo->handler; 00212 while (mh) { 00213 if (mh->access_method == netsnmp_table_array_helper_handler) 00214 break; 00215 mh = mh->next; 00216 } 00217 00218 return mh; 00219 } 00220 00222 netsnmp_container * 00223 netsnmp_extract_array_context(netsnmp_request_info *request) 00224 { 00225 return netsnmp_request_get_list_data(request, TABLE_ARRAY_NAME); 00226 } 00227 00229 int 00230 netsnmp_table_array_check_row_status(netsnmp_table_array_callbacks *cb, 00231 netsnmp_request_group *ag, 00232 long *rs_new, long *rs_old) 00233 { 00234 netsnmp_index *row_ctx; 00235 netsnmp_index *undo_ctx; 00236 if (!ag || !cb) 00237 return SNMPERR_GENERR; 00238 row_ctx = ag->existing_row; 00239 undo_ctx = ag->undo_info; 00240 00241 /* 00242 * xxx-rks: revisit row delete scenario 00243 */ 00244 if (row_ctx) { 00245 /* 00246 * either a new row, or change to old row 00247 */ 00248 /* 00249 * is it set to active? 00250 */ 00251 if (RS_IS_GOING_ACTIVE(*rs_new)) { 00252 /* 00253 * is it ready to be active? 00254 */ 00255 if ((NULL==cb->can_activate) || 00256 cb->can_activate(undo_ctx, row_ctx, ag)) 00257 *rs_new = RS_ACTIVE; 00258 else 00259 return SNMP_ERR_INCONSISTENTVALUE; 00260 } else { 00261 /* 00262 * not going active 00263 */ 00264 if (undo_ctx) { 00265 /* 00266 * change 00267 */ 00268 if (RS_IS_ACTIVE(*rs_old)) { 00269 /* 00270 * check pre-reqs for deactivation 00271 */ 00272 if (cb->can_deactivate && 00273 !cb->can_deactivate(undo_ctx, row_ctx, ag)) { 00274 return SNMP_ERR_INCONSISTENTVALUE; 00275 } 00276 } 00277 } else { 00278 /* 00279 * new row 00280 */ 00281 } 00282 00283 if (*rs_new != RS_DESTROY) { 00284 if ((NULL==cb->can_activate) || 00285 cb->can_activate(undo_ctx, row_ctx, ag)) 00286 *rs_new = RS_NOTINSERVICE; 00287 else 00288 *rs_new = RS_NOTREADY; 00289 } else { 00290 if (cb->can_delete && !cb->can_delete(undo_ctx, row_ctx, ag)) { 00291 return SNMP_ERR_INCONSISTENTVALUE; 00292 } 00293 ag->row_deleted = 1; 00294 } 00295 } 00296 } else { 00297 /* 00298 * check pre-reqs for delete row 00299 */ 00300 if (cb->can_delete && !cb->can_delete(undo_ctx, row_ctx, ag)) { 00301 return SNMP_ERR_INCONSISTENTVALUE; 00302 } 00303 } 00304 00305 return SNMP_ERR_NOERROR; 00306 } 00307 00310 #ifndef DOXYGEN_SHOULD_SKIP_THIS 00311 /********************************************************************** 00312 ********************************************************************** 00313 ********************************************************************** 00314 ********************************************************************** 00315 * * 00316 * * 00317 * * 00318 * * 00319 * EVERYTHING BELOW THIS IS PRIVATE IMPLEMENTATION DETAILS. * 00320 * * 00321 * * 00322 * * 00323 * * 00324 ********************************************************************** 00325 ********************************************************************** 00326 ********************************************************************** 00327 **********************************************************************/ 00328 00329 /********************************************************************** 00330 ********************************************************************** 00331 * * 00332 * * 00333 * Structures, Utility/convenience functions * 00334 * * 00335 * * 00336 ********************************************************************** 00337 **********************************************************************/ 00338 /* 00339 * context info for SET requests 00340 */ 00341 typedef struct set_context_s { 00342 netsnmp_agent_request_info *agtreq_info; 00343 table_container_data *tad; 00344 int status; 00345 } set_context; 00346 00347 static void 00348 release_netsnmp_request_group(netsnmp_index *g, void *v) 00349 { 00350 netsnmp_request_group_item *tmp; 00351 netsnmp_request_group *group = (netsnmp_request_group *) g; 00352 00353 if (!g) 00354 return; 00355 while (group->list) { 00356 tmp = group->list; 00357 group->list = tmp->next; 00358 free(tmp); 00359 } 00360 00361 free(group); 00362 } 00363 00364 static void 00365 release_netsnmp_request_groups(void *vp) 00366 { 00367 netsnmp_container *c = (netsnmp_container*)vp; 00368 CONTAINER_FOR_EACH(c, (netsnmp_container_obj_func*) 00369 release_netsnmp_request_group, NULL); 00370 CONTAINER_FREE(c); 00371 } 00372 00373 void 00374 build_new_oid(netsnmp_handler_registration *reginfo, 00375 netsnmp_table_request_info *tblreq_info, 00376 netsnmp_index *row, netsnmp_request_info *current) 00377 { 00378 oid coloid[MAX_OID_LEN]; 00379 int coloid_len; 00380 00381 if (!tblreq_info || !reginfo || !row || !current) 00382 return; 00383 00384 coloid_len = reginfo->rootoid_len + 2; 00385 memcpy(coloid, reginfo->rootoid, reginfo->rootoid_len * sizeof(oid)); 00386 00388 coloid[reginfo->rootoid_len] = 1; 00389 00391 coloid[reginfo->rootoid_len + 1] = tblreq_info->colnum; 00392 00394 memcpy(&coloid[reginfo->rootoid_len + 2], row->oids, 00395 row->len * sizeof(oid)); 00396 00397 snmp_set_var_objid(current->requestvb, coloid, 00398 reginfo->rootoid_len + 2 + row->len); 00399 } 00400 00401 /********************************************************************** 00402 ********************************************************************** 00403 * * 00404 * * 00405 * GET procession functions * 00406 * * 00407 * * 00408 ********************************************************************** 00409 **********************************************************************/ 00410 int 00411 process_get_requests(netsnmp_handler_registration *reginfo, 00412 netsnmp_agent_request_info *agtreq_info, 00413 netsnmp_request_info *requests, 00414 table_container_data * tad) 00415 { 00416 int rc = SNMP_ERR_NOERROR; 00417 netsnmp_request_info *current; 00418 netsnmp_index *row = NULL; 00419 netsnmp_table_request_info *tblreq_info; 00420 netsnmp_variable_list *var; 00421 00422 /* 00423 * Loop through each of the requests, and 00424 * try to find the appropriate row from the container. 00425 */ 00426 for (current = requests; current; current = current->next) { 00427 00428 var = current->requestvb; 00429 DEBUGMSGTL(("table_array:get", 00430 " process_get_request oid:")); 00431 DEBUGMSGOID(("table_array:get", var->name, 00432 var->name_length)); 00433 DEBUGMSG(("table_array:get", "\n")); 00434 00435 /* 00436 * skip anything that doesn't need processing. 00437 */ 00438 if (current->processed != 0) { 00439 DEBUGMSGTL(("table_array:get", "already processed\n")); 00440 continue; 00441 } 00442 00443 /* 00444 * Get pointer to the table information for this request. This 00445 * information was saved by table_helper_handler. When 00446 * debugging, we double check a few assumptions. For example, 00447 * the table_helper_handler should enforce column boundaries. 00448 */ 00449 tblreq_info = netsnmp_extract_table_info(current); 00450 netsnmp_assert(tblreq_info->colnum <= tad->tblreg_info->max_column); 00451 00452 if ((agtreq_info->mode == MODE_GETNEXT) || 00453 (agtreq_info->mode == MODE_GETBULK)) { 00454 /* 00455 * find the row 00456 */ 00457 row = netsnmp_table_index_find_next_row(tad->table, tblreq_info); 00458 if (!row) { 00459 /* 00460 * no results found. 00461 * 00462 * xxx-rks: how do we skip this entry for the next handler, 00463 * but still allow it a chance to hit another handler? 00464 */ 00465 DEBUGMSGTL(("table_array:get", "no row found\n")); 00466 netsnmp_set_request_error(agtreq_info, current, 00467 SNMP_ENDOFMIBVIEW); 00468 continue; 00469 } 00470 00471 /* 00472 * * if data was found, make sure it has the column we want 00473 */ 00474 /* xxx-rks: add suport for sparse tables */ 00475 00476 /* 00477 * build new oid 00478 */ 00479 build_new_oid(reginfo, tblreq_info, row, current); 00480 00481 } 00482 else { 00483 netsnmp_index index; 00484 index.oids = tblreq_info->index_oid; 00485 index.len = tblreq_info->index_oid_len; 00486 00487 row = CONTAINER_FIND(tad->table, &index); 00488 if (!row) { 00489 DEBUGMSGTL(("table_array:get", "no row found\n")); 00490 netsnmp_set_request_error(agtreq_info, current, 00491 SNMP_NOSUCHINSTANCE); 00492 continue; 00493 } 00494 } 00496 /* 00497 * get the data 00498 */ 00499 rc = tad->cb->get_value(current, row, tblreq_info); 00500 00501 } 00503 return rc; 00504 } 00505 00506 /********************************************************************** 00507 ********************************************************************** 00508 * * 00509 * * 00510 * SET procession functions * 00511 * * 00512 * * 00513 ********************************************************************** 00514 **********************************************************************/ 00515 00516 void 00517 group_requests(netsnmp_agent_request_info *agtreq_info, 00518 netsnmp_request_info *requests, 00519 netsnmp_container *request_group, table_container_data * tad) 00520 { 00521 netsnmp_table_request_info *tblreq_info; 00522 netsnmp_variable_list *var; 00523 netsnmp_index *row, *tmp, index; 00524 netsnmp_request_info *current; 00525 netsnmp_request_group *g; 00526 netsnmp_request_group_item *i; 00527 00528 for (current = requests; current; current = current->next) { 00529 00530 var = current->requestvb; 00531 00532 /* 00533 * skip anything that doesn't need processing. 00534 */ 00535 if (current->processed != 0) { 00536 DEBUGMSGTL(("table_array:group", 00537 "already processed\n")); 00538 continue; 00539 } 00540 00541 /* 00542 * 3.2.1 Setup and paranoia 00543 * * 00544 * * Get pointer to the table information for this request. This 00545 * * information was saved by table_helper_handler. When 00546 * * debugging, we double check a few assumptions. For example, 00547 * * the table_helper_handler should enforce column boundaries. 00548 */ 00549 row = NULL; 00550 tblreq_info = netsnmp_extract_table_info(current); 00551 netsnmp_assert(tblreq_info->colnum <= tad->tblreg_info->max_column); 00552 00553 /* 00554 * search for index 00555 */ 00556 index.oids = tblreq_info->index_oid; 00557 index.len = tblreq_info->index_oid_len; 00558 tmp = CONTAINER_FIND(request_group, &index); 00559 if (tmp) { 00560 DEBUGMSGTL(("table_array:group", 00561 " existing group:")); 00562 DEBUGMSGOID(("table_array:group", index.oids, 00563 index.len)); 00564 DEBUGMSG(("table_array:group", "\n")); 00565 g = (netsnmp_request_group *) tmp; 00566 i = SNMP_MALLOC_TYPEDEF(netsnmp_request_group_item); 00567 i->ri = current; 00568 i->tri = tblreq_info; 00569 i->next = g->list; 00570 g->list = i; 00571 00573 continue; 00574 } 00575 00576 DEBUGMSGTL(("table_array:group", " new group")); 00577 DEBUGMSGOID(("table_array:group", index.oids, 00578 index.len)); 00579 DEBUGMSG(("table_array:group", "\n")); 00580 g = SNMP_MALLOC_TYPEDEF(netsnmp_request_group); 00581 i = SNMP_MALLOC_TYPEDEF(netsnmp_request_group_item); 00582 g->list = i; 00583 g->table = tad->table; 00584 i->ri = current; 00585 i->tri = tblreq_info; 00588 /* 00589 * search for row. all changes are made to the original row, 00590 * later, we'll make a copy in undo_info before we start processing. 00591 */ 00592 row = g->existing_row = CONTAINER_FIND(tad->table, &index); 00593 if (!g->existing_row) { 00594 if (!tad->cb->create_row) { 00595 if(MODE_IS_SET(agtreq_info->mode)) 00596 netsnmp_set_request_error(agtreq_info, current, 00597 SNMP_ERR_NOTWRITABLE); 00598 else 00599 netsnmp_set_request_error(agtreq_info, current, 00600 SNMP_NOSUCHINSTANCE); 00601 free(g); 00602 free(i); 00603 continue; 00604 } 00606 row = g->existing_row = tad->cb->create_row(&index); 00607 if (!row) { 00608 /* xxx-rks : parameter to create_row to allow 00609 * for better error reporting. */ 00610 netsnmp_set_request_error(agtreq_info, current, 00611 SNMP_ERR_GENERR); 00612 free(g); 00613 free(i); 00614 continue; 00615 } 00616 g->row_created = 1; 00617 } 00618 00619 g->index.oids = row->oids; 00620 g->index.len = row->len; 00621 00622 CONTAINER_INSERT(request_group, g); 00623 00624 } 00625 } 00626 00627 static void 00628 process_set_group(netsnmp_index *o, void *c) 00629 { 00630 /* xxx-rks: should we continue processing after an error?? */ 00631 set_context *context = (set_context *) c; 00632 netsnmp_request_group *ag = (netsnmp_request_group *) o; 00633 int rc = SNMP_ERR_NOERROR; 00634 00635 switch (context->agtreq_info->mode) { 00636 00637 case MODE_SET_RESERVE1: 00639 /* 00640 * if not a new row, save undo info 00641 */ 00642 if (ag->row_created == 0) { 00643 if (context->tad->cb->duplicate_row) 00644 ag->undo_info = context->tad->cb->duplicate_row(ag->existing_row); 00645 else 00646 ag->undo_info = NULL; 00647 if (NULL == ag->undo_info) { 00648 rc = SNMP_ERR_RESOURCEUNAVAILABLE; 00649 break; 00650 } 00651 } 00652 00653 if (context->tad->cb->set_reserve1) 00654 context->tad->cb->set_reserve1(ag); 00655 break; 00656 00657 case MODE_SET_RESERVE2: 00658 if (context->tad->cb->set_reserve2) 00659 context->tad->cb->set_reserve2(ag); 00660 break; 00661 00662 case MODE_SET_ACTION: 00663 if (context->tad->cb->set_action) 00664 context->tad->cb->set_action(ag); 00665 break; 00666 00667 case MODE_SET_COMMIT: 00668 if (ag->row_created == 0) { 00669 /* 00670 * this is an existing row, has it been deleted? 00671 */ 00672 if (ag->row_deleted == 1) { 00673 DEBUGMSGT((TABLE_ARRAY_NAME, "action: deleting row\n")); 00674 if (CONTAINER_REMOVE(ag->table, ag->existing_row) != 0) { 00675 rc = SNMP_ERR_COMMITFAILED; 00676 break; 00677 } 00678 } 00679 } else if (ag->row_deleted == 0) { 00680 /* 00681 * new row (that hasn't been deleted) should be inserted 00682 */ 00683 DEBUGMSGT((TABLE_ARRAY_NAME, "action: inserting row\n")); 00684 if (CONTAINER_INSERT(ag->table, ag->existing_row) != 0) { 00685 rc = SNMP_ERR_COMMITFAILED; 00686 break; 00687 } 00688 } 00689 00690 if (context->tad->cb->set_commit) 00691 context->tad->cb->set_commit(ag); 00692 00694 if (ag->undo_info) { 00695 context->tad->cb->delete_row(ag->undo_info); 00696 ag->undo_info = NULL; 00697 } 00698 00699 #if 0 00700 /* XXX-rks: finish row cooperative notifications 00701 * if the table has requested it, send cooperative notifications 00702 * for row operations. 00703 */ 00704 if (context->tad->notifications) { 00705 if (ag->undo_info) { 00706 if (!ag->existing_row) 00707 netsnmp_monitor_notify(EVENT_ROW_DEL); 00708 else 00709 netsnmp_monitor_notify(EVENT_ROW_MOD); 00710 } 00711 else 00712 netsnmp_monitor_notify(EVENT_ROW_ADD); 00713 } 00714 #endif 00715 00716 if ((ag->row_created == 0) && (ag->row_deleted == 1)) { 00717 context->tad->cb->delete_row(ag->existing_row); 00718 ag->existing_row = NULL; 00719 } 00720 break; 00721 00722 case MODE_SET_FREE: 00723 if (context->tad->cb->set_free) 00724 context->tad->cb->set_free(ag); 00725 00727 if (ag->row_created == 1) { 00728 if (context->tad->cb->delete_row) 00729 context->tad->cb->delete_row(ag->existing_row); 00730 ag->existing_row = NULL; 00731 } 00732 else { 00733 if (context->tad->cb->delete_row) 00734 context->tad->cb->delete_row(ag->undo_info); 00735 ag->undo_info = NULL; 00736 } 00737 break; 00738 00739 case MODE_SET_UNDO: 00740 /* 00741 * status already set - don't change it now 00742 */ 00743 if (context->tad->cb->set_undo) 00744 context->tad->cb->set_undo(ag); 00745 00746 /* 00747 * no more use for undo_info, so free it 00748 */ 00749 if (ag->row_created == 0) { 00750 /* 00751 * restore old values 00752 */ 00753 context->tad->cb->row_copy(ag->existing_row, ag->undo_info); 00754 context->tad->cb->delete_row(ag->undo_info); 00755 ag->undo_info = NULL; 00756 } 00757 else { 00758 context->tad->cb->delete_row(ag->existing_row); 00759 ag->existing_row = NULL; 00760 } 00761 break; 00762 00763 default: 00764 snmp_log(LOG_ERR, "unknown mode processing SET for " 00765 "netsnmp_table_array_helper_handler\n"); 00766 rc = SNMP_ERR_GENERR; 00767 break; 00768 } 00769 00770 if (rc) 00771 netsnmp_set_request_error(context->agtreq_info, 00772 ag->list->ri, rc); 00773 00774 } 00775 00776 int 00777 process_set_requests(netsnmp_agent_request_info *agtreq_info, 00778 netsnmp_request_info *requests, 00779 table_container_data * tad, char *handler_name) 00780 { 00781 set_context context; 00782 netsnmp_container *request_group; 00783 00784 /* 00785 * create and save structure for set info 00786 */ 00787 request_group = (netsnmp_container*) netsnmp_agent_get_list_data 00788 (agtreq_info, handler_name); 00789 if (request_group == NULL) { 00790 netsnmp_data_list *tmp; 00791 request_group = netsnmp_container_find("request_group:" 00792 "table_container"); 00793 request_group->compare = netsnmp_compare_netsnmp_index; 00794 request_group->ncompare = netsnmp_ncompare_netsnmp_index; 00795 00796 DEBUGMSGTL(("table_array", "Grouping requests by oid\n")); 00797 00798 tmp = netsnmp_create_data_list(handler_name, 00799 request_group, 00800 release_netsnmp_request_groups); 00801 netsnmp_agent_add_list_data(agtreq_info, tmp); 00802 /* 00803 * group requests. 00804 */ 00805 group_requests(agtreq_info, requests, request_group, tad); 00806 } 00807 00808 /* 00809 * process each group one at a time 00810 */ 00811 context.agtreq_info = agtreq_info; 00812 context.tad = tad; 00813 context.status = SNMP_ERR_NOERROR; 00814 CONTAINER_FOR_EACH(request_group, 00815 (netsnmp_container_obj_func*)process_set_group, 00816 &context); 00817 00818 return context.status; 00819 } 00820 00821 00822 /********************************************************************** 00823 ********************************************************************** 00824 * * 00825 * * 00826 * netsnmp_table_array_helper_handler() * 00827 * * 00828 * * 00829 ********************************************************************** 00830 **********************************************************************/ 00831 int 00832 netsnmp_table_array_helper_handler(netsnmp_mib_handler *handler, 00833 netsnmp_handler_registration *reginfo, 00834 netsnmp_agent_request_info *agtreq_info, 00835 netsnmp_request_info *requests) 00836 { 00837 00838 /* 00839 * First off, get our pointer from the handler. This 00840 * lets us get to the table registration information we 00841 * saved in get_table_array_handler(), as well as the 00842 * container where the actual table data is stored. 00843 */ 00844 int rc = SNMP_ERR_NOERROR; 00845 table_container_data *tad = (table_container_data *)handler->myvoid; 00846 00847 if (agtreq_info->mode < 0 || agtreq_info->mode > 5) { 00848 DEBUGMSGTL(("table_array", "Mode %d, Got request:\n", 00849 agtreq_info->mode)); 00850 } else { 00851 DEBUGMSGTL(("table_array", "Mode %s, Got request:\n", 00852 mode_name[agtreq_info->mode])); 00853 } 00854 00855 if (MODE_IS_SET(agtreq_info->mode)) { 00856 /* 00857 * netsnmp_mutex_lock(&tad->lock); 00858 */ 00859 rc = process_set_requests(agtreq_info, requests, 00860 tad, handler->handler_name); 00861 /* 00862 * netsnmp_mutex_unlock(&tad->lock); 00863 */ 00864 } else 00865 rc = process_get_requests(reginfo, agtreq_info, requests, tad); 00866 00867 if (rc != SNMP_ERR_NOERROR) { 00868 DEBUGMSGTL(("table_array", "processing returned rc %d\n", rc)); 00869 } 00870 00871 /* 00872 * Now we've done our processing. If there is another handler below us, 00873 * call them. 00874 */ 00875 if (handler->next) { 00876 rc = netsnmp_call_next_handler(handler, reginfo, agtreq_info, requests); 00877 if (rc != SNMP_ERR_NOERROR) { 00878 DEBUGMSGTL(("table_array", "next handler returned rc %d\n", rc)); 00879 } 00880 } 00881 00882 return rc; 00883 } 00884 #endif
1.3.9.1
Last modified: Thursday, 01-Mar-2007 16:20:06 PST
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.