📄 table_data.c
字号:
#include <net-snmp/net-snmp-config.h>#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include <net-snmp/agent/table.h>#include <net-snmp/agent/table_data.h>#include <net-snmp/agent/read_only.h>/** @defgroup table_data table_data * Helps you implement a table with datamatted storage. * @ingroup table * * This helper is obsolete. If you are writing a new module, please * consider using the table_tdata helper instead. * * This helper helps you implement a table where all the indexes are * expected to be stored within the agent itself and not in some * external storage location. It can be used to store a list of * rows, where a row consists of the indexes to the table and a * generic data pointer. You can then implement a subhandler which * is passed the exact row definition and data it must return data * for or accept data for. Complex GETNEXT handling is greatly * simplified in this case. * * @{ *//* ================================== * * Table Data API: Table maintenance * * ================================== *//* * generates the index portion of an table oid from a varlist. */voidnetsnmp_table_data_generate_index_oid(netsnmp_table_row *row){ build_oid(&row->index_oid, &row->index_oid_len, NULL, 0, row->indexes);}/** creates and returns a pointer to table data set */netsnmp_table_data *netsnmp_create_table_data(const char *name){ netsnmp_table_data *table = SNMP_MALLOC_TYPEDEF(netsnmp_table_data); if (name && table) table->name = strdup(name); return table;}/** creates and returns a pointer to table data set */netsnmp_table_row *netsnmp_create_table_data_row(void){ netsnmp_table_row *row = SNMP_MALLOC_TYPEDEF(netsnmp_table_row); return row;}/** clones a data row. DOES NOT CLONE THE CONTAINED DATA. */netsnmp_table_row *netsnmp_table_data_clone_row(netsnmp_table_row *row){ netsnmp_table_row *newrow = NULL; if (!row) return NULL; memdup((u_char **) & newrow, (u_char *) row, sizeof(netsnmp_table_row)); if (!newrow) return NULL; if (row->indexes) { newrow->indexes = snmp_clone_varbind(newrow->indexes); if (!newrow->indexes) return NULL; } if (row->index_oid) { memdup((u_char **) & newrow->index_oid, (u_char *) row->index_oid, row->index_oid_len * sizeof(oid)); if (!newrow->index_oid) return NULL; } return newrow;}/** deletes a row's memory. * returns the void data that it doesn't know how to delete. */void *netsnmp_table_data_delete_row(netsnmp_table_row *row){ void *data; if (!row) return NULL; /* * free the memory we can */ if (row->indexes) snmp_free_varbind(row->indexes); SNMP_FREE(row->index_oid); data = row->data; free(row); /* * return the void * pointer */ return data;}/** * Adds a row of data to a given table (stored in proper lexographical order). * * returns SNMPERR_SUCCESS on successful addition. * or SNMPERR_GENERR on failure (E.G., indexes already existed) */intnetsnmp_table_data_add_row(netsnmp_table_data *table, netsnmp_table_row *row){ int rc, dup = 0; netsnmp_table_row *nextrow = NULL, *prevrow; if (!row || !table) return SNMPERR_GENERR; if (row->indexes) netsnmp_table_data_generate_index_oid(row); /* * we don't store the index info as it * takes up memory. */ if (!table->store_indexes) { snmp_free_varbind(row->indexes); row->indexes = NULL; } if (!row->index_oid) { snmp_log(LOG_ERR, "illegal data attempted to be added to table %s (no index)\n", table->name); return SNMPERR_GENERR; } /* * check for simple append */ if ((prevrow = table->last_row) != NULL) { rc = snmp_oid_compare(prevrow->index_oid, prevrow->index_oid_len, row->index_oid, row->index_oid_len); if (0 == rc) dup = 1; } else rc = 1; /* * if no last row, or newrow < last row, search the table and * insert it into the table in the proper oid-lexographical order */ if (rc > 0) { for (nextrow = table->first_row, prevrow = NULL; nextrow != NULL; prevrow = nextrow, nextrow = nextrow->next) { if (NULL == nextrow->index_oid) { DEBUGMSGT(("table_data_add_data", "row doesn't have index!\n")); /** xxx-rks: remove invalid row? */ continue; } rc = snmp_oid_compare(nextrow->index_oid, nextrow->index_oid_len, row->index_oid, row->index_oid_len); if(rc > 0) break; if (0 == rc) { dup = 1; break; } } } if (dup) { /* * exact match. Duplicate entries illegal */ snmp_log(LOG_WARNING, "duplicate table data attempted to be entered. row exists\n"); return SNMPERR_GENERR; } /* * ok, we have the location of where it should go */ /* * (after prevrow, and before nextrow) */ row->next = nextrow; row->prev = prevrow; if (row->next) row->next->prev = row; if (row->prev) row->prev->next = row; if (NULL == row->prev) /* it's the (new) first row */ table->first_row = row; if (NULL == row->next) /* it's the last row */ table->last_row = row; DEBUGMSGTL(("table_data_add_data", "added something...\n")); return SNMPERR_SUCCESS;}/** swaps out origrow with newrow. This does *not* delete/free anything! */NETSNMP_INLINE voidnetsnmp_table_data_replace_row(netsnmp_table_data *table, netsnmp_table_row *origrow, netsnmp_table_row *newrow){ netsnmp_table_data_remove_row(table, origrow); netsnmp_table_data_add_row(table, newrow);}/** * removes a row of data to a given table and returns it (no free's called) * * returns the row pointer itself on successful removing. * or NULL on failure (bad arguments) */netsnmp_table_row *netsnmp_table_data_remove_row(netsnmp_table_data *table, netsnmp_table_row *row){ if (!row || !table) return NULL; if (row->prev) row->prev->next = row->next; else table->first_row = row->next; if (row->next) row->next->prev = row->prev; else table->last_row = row->prev; return row;}/** * removes and frees a row of data to a given table and returns the void * * * returns the void * data on successful deletion. * or NULL on failure (bad arguments) */void *netsnmp_table_data_remove_and_delete_row(netsnmp_table_data *table, netsnmp_table_row *row){ if (!row || !table) return NULL; /* * remove it from the list */ netsnmp_table_data_remove_row(table, row); return netsnmp_table_data_delete_row(row);} /* ===================================== * Generic API - mostly renamed wrappers * ===================================== */netsnmp_table_data *netsnmp_table_data_create_table(const char *name, long flags){ return netsnmp_create_table_data( name );}voidnetsnmp_table_data_delete_table( netsnmp_table_data *table ){ netsnmp_table_row *row, *nextrow; if (!table) return; for (row = table->first_row; row; row=nextrow) { nextrow = row->next; row->next = NULL; netsnmp_table_data_delete_row(row); /* Can't delete table-specific entry memory */ } table->first_row = NULL; if (table->name) { SNMP_FREE(table->name); table->name = NULL; } SNMP_FREE(table); return;}netsnmp_table_row *netsnmp_table_data_create_row( void* entry ){ netsnmp_table_row *row = SNMP_MALLOC_TYPEDEF(netsnmp_table_row); if (row) row->data = entry; return row;} /* netsnmp_table_data_clone_row() defined above */intnetsnmp_table_data_copy_row( netsnmp_table_row *old_row, netsnmp_table_row *new_row ){ if (!old_row || !new_row) return -1; memcpy(new_row, old_row, sizeof(netsnmp_table_row));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -