Logo
Home page Net-SNMP

Archive Search:

Require all words?

Site Search:
Google
Main Page | Modules | Data Structures | File List | Data Fields | Related Pages | Examples

table_array.c

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 

Generated on Fri Dec 30 13:47:50 2005 for net-snmp by  doxygen 1.3.9.1

Valid CSS!


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.