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_data.c

00001 #include <net-snmp/net-snmp-config.h>
00002 
00003 #if HAVE_STRING_H
00004 #include <string.h>
00005 #else
00006 #include <strings.h>
00007 #endif
00008 
00009 #include <net-snmp/net-snmp-includes.h>
00010 #include <net-snmp/agent/net-snmp-agent-includes.h>
00011 
00012 #include <net-snmp/agent/table.h>
00013 #include <net-snmp/agent/table_data.h>
00014 #include <net-snmp/agent/read_only.h>
00015 
00034 /* ==================================
00035  *
00036  * Table Data API: Table maintenance
00037  *
00038  * ================================== */
00039 
00040 /*
00041  * generates the index portion of an table oid from a varlist.
00042  */
00043 void
00044 netsnmp_table_data_generate_index_oid(netsnmp_table_row *row)
00045 {
00046     build_oid(&row->index_oid, &row->index_oid_len, NULL, 0, row->indexes);
00047 }
00048 
00050 netsnmp_table_data *
00051 netsnmp_create_table_data(const char *name)
00052 {
00053     netsnmp_table_data *table = SNMP_MALLOC_TYPEDEF(netsnmp_table_data);
00054     if (name && table)
00055         table->name = strdup(name);
00056     return table;
00057 }
00058 
00060 netsnmp_table_row *
00061 netsnmp_create_table_data_row(void)
00062 {
00063     netsnmp_table_row *row = SNMP_MALLOC_TYPEDEF(netsnmp_table_row);
00064     return row;
00065 }
00066 
00068 netsnmp_table_row *
00069 netsnmp_table_data_clone_row(netsnmp_table_row *row)
00070 {
00071     netsnmp_table_row *newrow = NULL;
00072     if (!row)
00073         return NULL;
00074 
00075     memdup((u_char **) & newrow, (u_char *) row,
00076            sizeof(netsnmp_table_row));
00077     if (!newrow)
00078         return NULL;
00079 
00080     if (row->indexes) {
00081         newrow->indexes = snmp_clone_varbind(newrow->indexes);
00082         if (!newrow->indexes)
00083             return NULL;
00084     }
00085 
00086     if (row->index_oid) {
00087         memdup((u_char **) & newrow->index_oid,
00088                (u_char *) row->index_oid,
00089                row->index_oid_len * sizeof(oid));
00090         if (!newrow->index_oid)
00091             return NULL;
00092     }
00093 
00094     return newrow;
00095 }
00096 
00099 void           *
00100 netsnmp_table_data_delete_row(netsnmp_table_row *row)
00101 {
00102     void           *data;
00103 
00104     if (!row)
00105         return NULL;
00106 
00107     /*
00108      * free the memory we can 
00109      */
00110     if (row->indexes)
00111         snmp_free_varbind(row->indexes);
00112     SNMP_FREE(row->index_oid);
00113     data = row->data;
00114     free(row);
00115 
00116     /*
00117      * return the void * pointer 
00118      */
00119     return data;
00120 }
00121 
00128 int
00129 netsnmp_table_data_add_row(netsnmp_table_data *table,
00130                            netsnmp_table_row *row)
00131 {
00132     int rc, dup = 0;
00133     netsnmp_table_row *nextrow = NULL, *prevrow;
00134 
00135     if (!row || !table)
00136         return SNMPERR_GENERR;
00137 
00138     if (row->indexes)
00139         netsnmp_table_data_generate_index_oid(row);
00140 
00141     /*
00142      * we don't store the index info as it
00143      * takes up memory. 
00144      */
00145     if (!table->store_indexes) {
00146         snmp_free_varbind(row->indexes);
00147         row->indexes = NULL;
00148     }
00149 
00150     if (!row->index_oid) {
00151         snmp_log(LOG_ERR,
00152                  "illegal data attempted to be added to table %s (no index)\n",
00153                  table->name);
00154         return SNMPERR_GENERR;
00155     }
00156 
00157     /*
00158      * check for simple append
00159      */
00160     if ((prevrow = table->last_row) != NULL) {
00161         rc = snmp_oid_compare(prevrow->index_oid, prevrow->index_oid_len,
00162                               row->index_oid, row->index_oid_len);
00163         if (0 == rc)
00164             dup = 1;
00165     }
00166     else
00167         rc = 1;
00168     
00169     /*
00170      * if no last row, or newrow < last row, search the table and
00171      * insert it into the table in the proper oid-lexographical order 
00172      */
00173     if (rc > 0) {
00174         for (nextrow = table->first_row, prevrow = NULL;
00175              nextrow != NULL; prevrow = nextrow, nextrow = nextrow->next) {
00176             if (NULL == nextrow->index_oid) {
00177                 DEBUGMSGT(("table_data_add_data", "row doesn't have index!\n"));
00179                 continue;
00180             }
00181             rc = snmp_oid_compare(nextrow->index_oid, nextrow->index_oid_len,
00182                                   row->index_oid, row->index_oid_len);
00183             if(rc > 0)
00184                 break;
00185             if (0 == rc) {
00186                 dup = 1;
00187                 break;
00188             }
00189         }
00190     }
00191 
00192     if (dup) {
00193         /*
00194          * exact match.  Duplicate entries illegal 
00195          */
00196         snmp_log(LOG_WARNING,
00197                  "duplicate table data attempted to be entered. row exists\n");
00198         return SNMPERR_GENERR;
00199     }
00200 
00201     /*
00202      * ok, we have the location of where it should go 
00203      */
00204     /*
00205      * (after prevrow, and before nextrow) 
00206      */
00207     row->next = nextrow;
00208     row->prev = prevrow;
00209 
00210     if (row->next)
00211         row->next->prev = row;
00212 
00213     if (row->prev)
00214         row->prev->next = row;
00215 
00216     if (NULL == row->prev)      /* it's the (new) first row */
00217         table->first_row = row;
00218     if (NULL == row->next)      /* it's the last row */
00219         table->last_row = row;
00220 
00221     DEBUGMSGTL(("table_data_add_data", "added something...\n"));
00222 
00223     return SNMPERR_SUCCESS;
00224 }
00225 
00227 NETSNMP_INLINE void
00228 netsnmp_table_data_replace_row(netsnmp_table_data *table,
00229                                netsnmp_table_row *origrow,
00230                                netsnmp_table_row *newrow)
00231 {
00232     netsnmp_table_data_remove_row(table, origrow);
00233     netsnmp_table_data_add_row(table, newrow);
00234 }
00235 
00242 netsnmp_table_row *
00243 netsnmp_table_data_remove_row(netsnmp_table_data *table,
00244                               netsnmp_table_row *row)
00245 {
00246     if (!row || !table)
00247         return NULL;
00248 
00249     if (row->prev)
00250         row->prev->next = row->next;
00251     else
00252         table->first_row = row->next;
00253 
00254     if (row->next)
00255         row->next->prev = row->prev;
00256     else
00257         table->last_row = row->prev;
00258 
00259     return row;
00260 }
00261 
00268 void           *
00269 netsnmp_table_data_remove_and_delete_row(netsnmp_table_data *table,
00270                                          netsnmp_table_row *row)
00271 {
00272     if (!row || !table)
00273         return NULL;
00274 
00275     /*
00276      * remove it from the list 
00277      */
00278     netsnmp_table_data_remove_row(table, row);
00279     return netsnmp_table_data_delete_row(row);
00280 }
00281 
00282     /* =====================================
00283      * Generic API - mostly renamed wrappers
00284      * ===================================== */
00285 
00286 netsnmp_table_data *
00287 netsnmp_table_data_create_table(const char *name, long flags)
00288 {
00289     return netsnmp_create_table_data( name );
00290 }
00291 
00292 void
00293 netsnmp_table_data_delete_table( netsnmp_table_data *table )
00294 {
00295     netsnmp_table_row *row, *nextrow;
00296 
00297     if (!table)
00298         return;
00299 
00300     for (row = table->first_row; row; row=nextrow) {
00301         nextrow   = row->next;
00302         row->next = NULL;
00303         netsnmp_table_data_delete_row(row);
00304         /* Can't delete table-specific entry memory */
00305     }
00306     table->first_row = NULL;
00307 
00308     if (table->name) {
00309         SNMP_FREE(table->name);
00310         table->name = NULL;
00311     }
00312     SNMP_FREE(table);
00313     return;
00314 }
00315 
00316 netsnmp_table_row *
00317 netsnmp_table_data_create_row( void* entry )
00318 {
00319     netsnmp_table_row *row = SNMP_MALLOC_TYPEDEF(netsnmp_table_row);
00320     if (row)
00321         row->data = entry;
00322     return row;
00323 }
00324 
00325     /* netsnmp_table_data_clone_row() defined above */
00326 
00327 int
00328 netsnmp_table_data_copy_row( netsnmp_table_row  *old_row,
00329                              netsnmp_table_row  *new_row )
00330 {
00331     if (!old_row || !new_row)
00332         return -1;
00333 
00334     memcpy(new_row, old_row, sizeof(netsnmp_table_row));
00335 
00336     if (old_row->indexes)
00337         new_row->indexes = snmp_clone_varbind(old_row->indexes);
00338     if (old_row->index_oid)
00339         memdup((u_char **) & new_row->index_oid,
00340                (u_char *)    old_row->index_oid,
00341                old_row->index_oid_len * sizeof(oid));
00342     /* XXX - Doesn't copy table-specific row structure */
00343     return 0;
00344 }
00345 
00346     /*
00347      * netsnmp_table_data_delete_row()
00348      * netsnmp_table_data_add_row()
00349      * netsnmp_table_data_replace_row()
00350      * netsnmp_table_data_remove_row()
00351      *     all defined above
00352      */
00353 
00354 void *
00355 netsnmp_table_data_remove_delete_row(netsnmp_table_data *table,
00356                                      netsnmp_table_row *row)
00357 {
00358     return netsnmp_table_data_remove_and_delete_row(table, row);
00359 }
00360 
00361 
00362 /* ==================================
00363  *
00364  * Table Data API: MIB maintenance
00365  *
00366  * ================================== */
00367 
00369 netsnmp_mib_handler *
00370 netsnmp_get_table_data_handler(netsnmp_table_data *table)
00371 {
00372     netsnmp_mib_handler *ret = NULL;
00373 
00374     if (!table) {
00375         snmp_log(LOG_INFO,
00376                  "netsnmp_get_table_data_handler(NULL) called\n");
00377         return NULL;
00378     }
00379 
00380     ret =
00381         netsnmp_create_handler(TABLE_DATA_NAME,
00382                                netsnmp_table_data_helper_handler);
00383     if (ret) {
00384         ret->flags |= MIB_HANDLER_AUTO_NEXT;
00385         ret->myvoid = (void *) table;
00386     }
00387     return ret;
00388 }
00389 
00392 int
00393 netsnmp_register_table_data(netsnmp_handler_registration *reginfo,
00394                             netsnmp_table_data *table,
00395                             netsnmp_table_registration_info *table_info)
00396 {
00397     netsnmp_inject_handler(reginfo, netsnmp_get_table_data_handler(table));
00398     return netsnmp_register_table(reginfo, table_info);
00399 }
00400 
00403 int
00404 netsnmp_register_read_only_table_data(netsnmp_handler_registration *reginfo,
00405                                       netsnmp_table_data *table,
00406                                       netsnmp_table_registration_info *table_info)
00407 {
00408     netsnmp_inject_handler(reginfo, netsnmp_get_read_only_handler());
00409     return netsnmp_register_table_data(reginfo, table, table_info);
00410 }
00411 
00412 /*
00413  * The helper handler that takes care of passing a specific row of
00414  * data down to the lower handler(s).  It sets request->processed if
00415  * the request should not be handled.
00416  */
00417 int
00418 netsnmp_table_data_helper_handler(netsnmp_mib_handler *handler,
00419                                   netsnmp_handler_registration *reginfo,
00420                                   netsnmp_agent_request_info *reqinfo,
00421                                   netsnmp_request_info *requests)
00422 {
00423     netsnmp_table_data *table = (netsnmp_table_data *) handler->myvoid;
00424     netsnmp_request_info *request;
00425     int             valid_request = 0;
00426     netsnmp_table_row *row;
00427     netsnmp_table_request_info *table_info;
00428     netsnmp_table_registration_info *table_reg_info =
00429         netsnmp_find_table_registration_info(reginfo);
00430     int             result, regresult;
00431     int             oldmode;
00432 
00433     for (request = requests; request; request = request->next) {
00434         if (request->processed)
00435             continue;
00436 
00437         table_info = netsnmp_extract_table_info(request);
00438         if (!table_info)
00439             continue;           /* ack */
00440         switch (reqinfo->mode) {
00441         case MODE_GET:
00442         case MODE_GETNEXT:
00443         case MODE_SET_RESERVE1:
00444             netsnmp_request_add_list_data(request,
00445                                       netsnmp_create_data_list(
00446                                           TABLE_DATA_TABLE, table, NULL));
00447         }
00448 
00449         /*
00450          * find the row in question 
00451          */
00452         switch (reqinfo->mode) {
00453         case MODE_GETNEXT:
00454         case MODE_GETBULK:     /* XXXWWW */
00455             if (request->requestvb->type != ASN_NULL)
00456                 continue;
00457             /*
00458              * loop through data till we find the next row 
00459              */
00460             result = snmp_oid_compare(request->requestvb->name,
00461                                       request->requestvb->name_length,
00462                                       reginfo->rootoid,
00463                                       reginfo->rootoid_len);
00464             regresult = snmp_oid_compare(request->requestvb->name,
00465                                          SNMP_MIN(request->requestvb->
00466                                                   name_length,
00467                                                   reginfo->rootoid_len),
00468                                          reginfo->rootoid,
00469                                          reginfo->rootoid_len);
00470             if (regresult == 0
00471                 && request->requestvb->name_length < reginfo->rootoid_len)
00472                 regresult = -1;
00473 
00474             if (result < 0 || 0 == result) {
00475                 /*
00476                  * before us entirely, return the first 
00477                  */
00478                 row = table->first_row;
00479                 table_info->colnum = table_reg_info->min_column;
00480             } else if (regresult == 0 && request->requestvb->name_length ==
00481                        reginfo->rootoid_len + 1 &&
00482                        /* entry node must be 1, but any column is ok */
00483                        request->requestvb->name[reginfo->rootoid_len] == 1) {
00484                 /*
00485                  * exactly to the entry 
00486                  */
00487                 row = table->first_row;
00488                 table_info->colnum = table_reg_info->min_column;
00489             } else if (regresult == 0 && request->requestvb->name_length ==
00490                        reginfo->rootoid_len + 2 &&
00491                        /* entry node must be 1, but any column is ok */
00492                        request->requestvb->name[reginfo->rootoid_len] == 1) {
00493                 /*
00494                  * exactly to the column 
00495                  */
00496                 row = table->first_row;
00497             } else {
00498                 /*
00499                  * loop through all rows looking for the first one
00500                  * that is equal to the request or greater than it 
00501                  */
00502                 for (row = table->first_row; row; row = row->next) {
00503                     /*
00504                      * compare the index of the request to the row 
00505                      */
00506                     result =
00507                         snmp_oid_compare(row->index_oid,
00508                                          row->index_oid_len,
00509                                          request->requestvb->name + 2 +
00510                                          reginfo->rootoid_len,
00511                                          request->requestvb->name_length -
00512                                          2 - reginfo->rootoid_len);
00513                     if (result == 0) {
00514                         /*
00515                          * equal match, return the next row 
00516                          */
00517                         if (row) {
00518                             row = row->next;
00519                         }
00520                         break;
00521                     } else if (result > 0) {
00522                         /*
00523                          * the current row is greater than the
00524                          * request, use it 
00525                          */
00526                         break;
00527                     }
00528                 }
00529             }
00530             if (!row) {
00531                 table_info->colnum++;
00532                 if (table_info->colnum <= table_reg_info->max_column) {
00533                     row = table->first_row;
00534                 }
00535             }
00536             if (row) {
00537                 valid_request = 1;
00538                 netsnmp_request_add_list_data(request,
00539                                               netsnmp_create_data_list
00540                                               (TABLE_DATA_ROW, row,
00541                                                NULL));
00542                 /*
00543                  * Set the name appropriately, so we can pass this
00544                  *  request on as a simple GET request
00545                  */
00546                 netsnmp_table_data_build_result(reginfo, reqinfo, request,
00547                                                 row,
00548                                                 table_info->colnum,
00549                                                 ASN_NULL, NULL, 0);
00550             } else {            /* no decent result found.  Give up. It's beyond us. */
00551                 request->processed = 1;
00552             }
00553             break;
00554 
00555         case MODE_GET:
00556             if (request->requestvb->type != ASN_NULL)
00557                 continue;
00558             /*
00559              * find the row in question 
00560              */
00561             if (request->requestvb->name_length < (reginfo->rootoid_len + 3)) { /* table.entry.column... */
00562                 /*
00563                  * request too short 
00564                  */
00565                 netsnmp_set_request_error(reqinfo, request,
00566                                           SNMP_NOSUCHINSTANCE);
00567                 break;
00568             } else if (NULL ==
00569                        (row =
00570                         netsnmp_table_data_get_from_oid(table,
00571                                                         request->
00572                                                         requestvb->name +
00573                                                         reginfo->
00574                                                         rootoid_len + 2,
00575                                                         request->
00576                                                         requestvb->
00577                                                         name_length -
00578                                                         reginfo->
00579                                                         rootoid_len -
00580                                                         2))) {
00581                 /*
00582                  * no such row 
00583                  */
00584                 netsnmp_set_request_error(reqinfo, request,
00585                                           SNMP_NOSUCHINSTANCE);
00586                 break;
00587             } else {
00588                 valid_request = 1;
00589                 netsnmp_request_add_list_data(request,
00590                                               netsnmp_create_data_list
00591                                               (TABLE_DATA_ROW, row,
00592                                                NULL));
00593             }
00594             break;
00595 
00596         case MODE_SET_RESERVE1:
00597             valid_request = 1;
00598             if (NULL !=
00599                 (row =
00600                  netsnmp_table_data_get_from_oid(table,
00601                                                  request->requestvb->name +
00602                                                  reginfo->rootoid_len + 2,
00603                                                  request->requestvb->
00604                                                  name_length -
00605                                                  reginfo->rootoid_len -
00606                                                  2))) {
00607                 netsnmp_request_add_list_data(request,
00608                                               netsnmp_create_data_list
00609                                               (TABLE_DATA_ROW, row,
00610                                                NULL));
00611             }
00612             break;
00613 
00614         case MODE_SET_RESERVE2:
00615         case MODE_SET_ACTION:
00616         case MODE_SET_COMMIT:
00617         case MODE_SET_FREE:
00618         case MODE_SET_UNDO:
00619             valid_request = 1;
00620 
00621         }
00622     }
00623 
00624     if (valid_request &&
00625        (reqinfo->mode == MODE_GETNEXT || reqinfo->mode == MODE_GETBULK)) {
00626         /*
00627          * If this is a GetNext or GetBulk request, then we've identified
00628          *  the row that ought to include the appropriate next instance.
00629          *  Convert the request into a Get request, so that the lower-level
00630          *  handlers don't need to worry about skipping on, and call these
00631          *  handlers ourselves (so we can undo this again afterwards).
00632          */
00633         oldmode = reqinfo->mode;
00634         reqinfo->mode = MODE_GET;
00635         result = netsnmp_call_next_handler(handler, reginfo, reqinfo,
00636                                          requests);
00637         reqinfo->mode = oldmode;
00638         handler->flags |= MIB_HANDLER_AUTO_NEXT_OVERRIDE_ONCE;
00639         return result;
00640     }
00641     else
00642         /* next handler called automatically - 'AUTO_NEXT' */
00643         return SNMP_ERR_NOERROR;
00644 }
00645 
00647 netsnmp_table_data *
00648 netsnmp_extract_table(netsnmp_request_info *request)
00649 {
00650     return (netsnmp_table_data *)
00651                 netsnmp_request_get_list_data(request, TABLE_DATA_TABLE);
00652 }
00653 
00655 netsnmp_table_row *
00656 netsnmp_extract_table_row(netsnmp_request_info *request)
00657 {
00658     return (netsnmp_table_row *) netsnmp_request_get_list_data(request,
00659                                                                TABLE_DATA_ROW);
00660 }
00661 
00664 void           *
00665 netsnmp_extract_table_row_data(netsnmp_request_info *request)
00666 {
00667     netsnmp_table_row *row;
00668     row = (netsnmp_table_row *) netsnmp_extract_table_row(request);
00669     if (row)
00670         return row->data;
00671     else
00672         return NULL;
00673 }
00674 
00676 NETSNMP_INLINE void
00677 netsnmp_insert_table_row(netsnmp_request_info *request,
00678                          netsnmp_table_row *row)
00679 {
00680     netsnmp_request_info       *req;
00681     netsnmp_table_request_info *table_info = NULL;
00682     netsnmp_variable_list      *this_index = NULL;
00683     netsnmp_variable_list      *that_index = NULL;
00684     oid      base_oid[] = {0, 0};       /* Make sure index OIDs are legal! */
00685     oid      this_oid[MAX_OID_LEN];
00686     oid      that_oid[MAX_OID_LEN];
00687     size_t   this_oid_len, that_oid_len;
00688 
00689     if (!request)
00690         return;
00691 
00692     /*
00693      * We'll add the new row information to any request
00694      * structure with the same index values as the request
00695      * passed in (which includes that one!).
00696      *
00697      * So construct an OID based on these index values.
00698      */
00699 
00700     table_info = netsnmp_extract_table_info(request);
00701     this_index = table_info->indexes;
00702     build_oid_noalloc(this_oid, MAX_OID_LEN, &this_oid_len,
00703                       base_oid, 2, this_index);
00704 
00705     /*
00706      * We need to look through the whole of the request list
00707      * (as received by the current handler), as there's no
00708      * guarantee that this routine will be called by the first
00709      * varbind that refers to this row.
00710      *   In particular, a RowStatus controlled row creation
00711      * may easily occur later in the variable list.
00712      *
00713      * So first, we rewind to the head of the list....
00714      */
00715     for (req=request; req->prev; req=req->prev)
00716         ;
00717 
00718     /*
00719      * ... and then start looking for matching indexes
00720      * (by constructing OIDs from these index values)
00721      */
00722     for (; req; req=req->next) {
00723         table_info = netsnmp_extract_table_info(req);
00724         that_index = table_info->indexes;
00725         build_oid_noalloc(that_oid, MAX_OID_LEN, &that_oid_len,
00726                           base_oid, 2, that_index);
00727       
00728         /*
00729          * This request has the same index values,
00730          * so add the newly-created row information.
00731          */
00732         if (snmp_oid_compare(this_oid, this_oid_len,
00733                              that_oid, that_oid_len) == 0) {
00734             netsnmp_request_add_list_data(req,
00735                 netsnmp_create_data_list(TABLE_DATA_ROW, row, NULL));
00736         }
00737     }
00738 }
00739 
00740 /* builds a result given a row, a varbind to set and the data */
00741 int
00742 netsnmp_table_data_build_result(netsnmp_handler_registration *reginfo,
00743                                 netsnmp_agent_request_info *reqinfo,
00744                                 netsnmp_request_info *request,
00745                                 netsnmp_table_row *row,
00746                                 int column,
00747                                 u_char type,
00748                                 u_char * result_data,
00749                                 size_t result_data_len)
00750 {
00751     oid             build_space[MAX_OID_LEN];
00752 
00753     if (!reginfo || !reqinfo || !request)
00754         return SNMPERR_GENERR;
00755 
00756     if (reqinfo->mode == MODE_GETNEXT || reqinfo->mode == MODE_GETBULK) {
00757         /*
00758          * only need to do this for getnext type cases where oid is changing 
00759          */
00760         memcpy(build_space, reginfo->rootoid,   /* registered oid */
00761                reginfo->rootoid_len * sizeof(oid));
00762         build_space[reginfo->rootoid_len] = 1;  /* entry */
00763         build_space[reginfo->rootoid_len + 1] = column; /* column */
00764         memcpy(build_space + reginfo->rootoid_len + 2,  /* index data */
00765                row->index_oid, row->index_oid_len * sizeof(oid));
00766         snmp_set_var_objid(request->requestvb, build_space,
00767                            reginfo->rootoid_len + 2 + row->index_oid_len);
00768     }
00769     snmp_set_var_typed_value(request->requestvb, type,
00770                              result_data, result_data_len);
00771     return SNMPERR_SUCCESS;     /* WWWXXX: check for bounds */
00772 }
00773 
00774 
00775 /* ==================================
00776  *
00777  * Table Data API: Row operations
00778  *     (table-independent rows)
00779  *
00780  * ================================== */
00781 
00783 netsnmp_table_row *
00784 netsnmp_table_data_get_first_row(netsnmp_table_data *table)
00785 {
00786     if (!table)
00787         return NULL;
00788     return table->first_row;
00789 }
00790 
00792 netsnmp_table_row *
00793 netsnmp_table_data_get_next_row(netsnmp_table_data *table,
00794                                 netsnmp_table_row  *row)
00795 {
00796     if (!row)
00797         return NULL;
00798     return row->next;
00799 }
00800 
00802 netsnmp_table_row *
00803 netsnmp_table_data_get(netsnmp_table_data *table,
00804                        netsnmp_variable_list * indexes)
00805 {
00806     oid             searchfor[MAX_OID_LEN];
00807     size_t          searchfor_len = MAX_OID_LEN;
00808 
00809     build_oid_noalloc(searchfor, MAX_OID_LEN, &searchfor_len, NULL, 0,
00810                       indexes);
00811     return netsnmp_table_data_get_from_oid(table, searchfor,
00812                                            searchfor_len);
00813 }
00814 
00816 netsnmp_table_row *
00817 netsnmp_table_data_get_from_oid(netsnmp_table_data *table,
00818                                 oid * searchfor, size_t searchfor_len)
00819 {
00820     netsnmp_table_row *row;
00821     if (!table)
00822         return NULL;
00823 
00824     for (row = table->first_row; row != NULL; row = row->next) {
00825         if (row->index_oid &&
00826             snmp_oid_compare(searchfor, searchfor_len,
00827                              row->index_oid, row->index_oid_len) == 0)
00828             return row;
00829     }
00830     return NULL;
00831 }
00832 
00833 int
00834 netsnmp_table_data_num_rows(netsnmp_table_data *table)
00835 {
00836     int i=0;
00837     netsnmp_table_row *row;
00838     if (!table)
00839         return 0;
00840     for (row = table->first_row; row; row = row->next) {
00841         i++;
00842     }
00843     return i;
00844 }
00845 
00846     /* =====================================
00847      * Generic API - mostly renamed wrappers
00848      * ===================================== */
00849 
00850 netsnmp_table_row *
00851 netsnmp_table_data_row_first(netsnmp_table_data *table)
00852 {
00853     return netsnmp_table_data_get_first_row(table);
00854 }
00855 
00856 netsnmp_table_row *
00857 netsnmp_table_data_row_get(  netsnmp_table_data *table,
00858                              netsnmp_table_row  *row)
00859 {
00860     if (!table || !row)
00861         return NULL;
00862     return netsnmp_table_data_get_from_oid(table, row->index_oid,
00863                                                   row->index_oid_len);
00864 }
00865 
00866 netsnmp_table_row *
00867 netsnmp_table_data_row_next( netsnmp_table_data *table,
00868                              netsnmp_table_row  *row)
00869 {
00870     return netsnmp_table_data_get_next_row(table, row);
00871 }
00872 
00873 netsnmp_table_row *
00874 netsnmp_table_data_row_get_byoid( netsnmp_table_data *table,
00875                                   oid *instance, size_t len)
00876 {
00877     return netsnmp_table_data_get_from_oid(table, instance, len);
00878 }
00879 
00880 netsnmp_table_row *
00881 netsnmp_table_data_row_next_byoid(netsnmp_table_data *table,
00882                                   oid *instance, size_t len)
00883 {
00884     netsnmp_table_row *row;
00885 
00886     if (!table || !instance)
00887         return NULL;
00888     
00889     for (row = table->first_row; row; row = row->next) {
00890         if (snmp_oid_compare(row->index_oid,
00891                              row->index_oid_len,
00892                              instance, len) > 0)
00893             return row;
00894     }
00895     return NULL;
00896 }
00897 
00898 netsnmp_table_row *
00899 netsnmp_table_data_row_get_byidx( netsnmp_table_data    *table,
00900                                   netsnmp_variable_list *indexes)
00901 {
00902     return netsnmp_table_data_get(table, indexes);
00903 }
00904 
00905 netsnmp_table_row *
00906 netsnmp_table_data_row_next_byidx(netsnmp_table_data    *table,
00907                                   netsnmp_variable_list *indexes)
00908 {
00909     oid    instance[MAX_OID_LEN];
00910     size_t len    = MAX_OID_LEN;
00911 
00912     if (!table || !indexes)
00913         return NULL;
00914 
00915     build_oid_noalloc(instance, MAX_OID_LEN, &len, NULL, 0, indexes);
00916     return netsnmp_table_data_row_next_byoid(table, instance, len);
00917 }
00918 
00919 int
00920 netsnmp_table_data_row_count(netsnmp_table_data *table)
00921 {
00922     return netsnmp_table_data_num_rows(table);
00923 }
00924 
00925 
00926 /* ==================================
00927  *
00928  * Table Data API: Row operations
00929  *     (table-specific rows)
00930  *
00931  * ================================== */
00932 
00933 void *
00934 netsnmp_table_data_entry_first(netsnmp_table_data *table)
00935 {
00936     netsnmp_table_row *row =
00937         netsnmp_table_data_get_first_row(table);
00938     return (row ? row->data : NULL );
00939 }
00940 
00941 void *
00942 netsnmp_table_data_entry_get(  netsnmp_table_data *table,
00943                                netsnmp_table_row  *row)
00944 {
00945     return (row ? row->data : NULL );
00946 }
00947 
00948 void *
00949 netsnmp_table_data_entry_next( netsnmp_table_data *table,
00950                                netsnmp_table_row  *row)
00951 {
00952     row =
00953         netsnmp_table_data_row_next(table, row);
00954     return (row ? row->data : NULL );
00955 }
00956 
00957 void *
00958 netsnmp_table_data_entry_get_byidx( netsnmp_table_data    *table,
00959                                     netsnmp_variable_list *indexes)
00960 {
00961     netsnmp_table_row *row =
00962         netsnmp_table_data_row_get_byidx(table, indexes);
00963     return (row ? row->data : NULL );
00964 }
00965 
00966 void *
00967 netsnmp_table_data_entry_next_byidx(netsnmp_table_data    *table,
00968                                     netsnmp_variable_list *indexes)
00969 {
00970     netsnmp_table_row *row =
00971         netsnmp_table_data_row_next_byidx(table, indexes);
00972     return (row ? row->data : NULL );
00973 }
00974 
00975 void *
00976 netsnmp_table_data_entry_get_byoid( netsnmp_table_data *table,
00977                                     oid *instance, size_t len)
00978 {
00979     netsnmp_table_row *row =
00980         netsnmp_table_data_row_get_byoid(table, instance, len);
00981     return (row ? row->data : NULL );
00982 }
00983 
00984 void *
00985 netsnmp_table_data_entry_next_byoid(netsnmp_table_data *table,
00986                                     oid *instance, size_t len)
00987 {
00988     netsnmp_table_row *row =
00989         netsnmp_table_data_row_next_byoid(table, instance, len);
00990     return (row ? row->data : NULL );
00991 }
00992 
00993     /* =====================================
00994      * Generic API - mostly renamed wrappers
00995      * ===================================== */
00996 
00997 /* ==================================
00998  *
00999  * Table Data API: Index operations
01000  *
01001  * ================================== */
01002 
01003 /*
01004  * @} 
01005  */

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

Valid CSS!


Last modified: Thursday, 01-Mar-2007 16:20:04 PST
For questions regarding web content and site functionality, please write to the net-snmp-users mail list.