📄 table_array.c
字号:
/* * table_array.c * $Id: table_array.c,v 5.23.2.1 2004/12/10 03:39:39 rstory Exp $ */#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_array.h>#include <net-snmp/library/container.h>#include <net-snmp/library/snmp_assert.h>#if HAVE_DMALLOC_H#include <dmalloc.h>#endif/* * snmp.h:#define SNMP_MSG_INTERNAL_SET_BEGIN -1 * snmp.h:#define SNMP_MSG_INTERNAL_SET_RESERVE1 0 * snmp.h:#define SNMP_MSG_INTERNAL_SET_RESERVE2 1 * snmp.h:#define SNMP_MSG_INTERNAL_SET_ACTION 2 * snmp.h:#define SNMP_MSG_INTERNAL_SET_COMMIT 3 * snmp.h:#define SNMP_MSG_INTERNAL_SET_FREE 4 * snmp.h:#define SNMP_MSG_INTERNAL_SET_UNDO 5 */static const char *mode_name[] = { "Reserve 1", "Reserve 2", "Action", "Commit", "Free", "Undo"};/* * PRIVATE structure for holding important info for each table. */typedef struct table_container_data_s { /** registration info for the table */ netsnmp_table_registration_info *tblreg_info; /** container for the table rows */ netsnmp_container *table; /* * mutex_type lock; */ /** do we want to group rows with the same index * together when calling callbacks? */ int group_rows; /** callbacks for this table */ netsnmp_table_array_callbacks *cb;} table_container_data;/** @defgroup table_array table_array: Helps you implement a table when data can be stored locally. The data is stored in a sorted array, using a binary search for lookups. * @ingroup table * * The table_array handler is used (automatically) in conjuntion * with the @link table table@endlink handler. It is primarily * intended to be used with the mib2c configuration file * mib2c.array-user.conf. * * The code generated by mib2c is useful when you have control of * the data for each row. If you cannot control when rows are added * and deleted (or at least be notified of changes to row data), * then this handler is probably not for you. * * This handler makes use of callbacks (function pointers) to * handle various tasks. Code is generated for each callback, * but will need to be reviewed and flushed out by the user. * * NOTE NOTE NOTE: Once place where mib2c is somewhat lacking * is with regards to tables with external indices. If your * table makes use of one or more external indices, please * review the generated code very carefully for comments * regarding external indices. * * NOTE NOTE NOTE: This helper, the API and callbacks are still * being tested and may change. * * The generated code will define a structure for storage of table * related data. This structure must be used, as it contains the index * OID for the row, which is used for keeping the array sorted. You can * add addition fields or data to the structure for your own use. * * The generated code will also have code to handle SNMP-SET processing. * If your table does not support any SET operations, simply comment * out the #define <PREFIX>_SET_HANDLING (where <PREFIX> is your * table name) in the header file. * * SET processing modifies the row in-place. The duplicate_row * callback will be called to save a copy of the original row. * In the event of a failure before the commite phase, the * row_copy callback will be called to restore the original row * from the copy. * * Code will be generated to handle row creation. This code may be * disabled by commenting out the #define <PREFIX>_ROW_CREATION * in the header file. * * If your table contains a RowStatus object, by default the * code will not allow object in an active row to be modified. * To allow active rows to be modified, remove the comment block * around the #define <PREFIX>_CAN_MODIFY_ACTIVE_ROW in the header * file. * * Code will be generated to maintain a secondary index for all * rows, stored in a binary tree. This is very useful for finding * rows by a key other than the OID index. By default, the functions * for maintaining this tree will be based on a character string. * NOTE: this will likely be made into a more generic mechanism, * using new callback methods, in the near future. * * The generated code contains many TODO comments. Make sure you * check each one to see if it applies to your code. Examples include * checking indices for syntax (ranges, etc), initializing default * values in newly created rows, checking for row activation and * deactivation requirements, etc. * * @{ *//********************************************************************** ********************************************************************** * * * * * PUBLIC Registration functions * * * * * ********************************************************************** **********************************************************************//** register specified callbacks for the specified table/oid. If the group_rows parameter is set, the row related callbacks will be called once for each unique row index. Otherwise, each callback will be called only once, for all objects.*/intnetsnmp_table_container_register(netsnmp_handler_registration *reginfo, netsnmp_table_registration_info *tabreg, netsnmp_table_array_callbacks *cb, netsnmp_container *container, int group_rows){ table_container_data *tad = SNMP_MALLOC_TYPEDEF(table_container_data); if (!tad) return SNMPERR_GENERR; tad->tblreg_info = tabreg; /* we need it too, but it really is not ours */ if (!cb) { snmp_log(LOG_ERR, "table_array registration with no callbacks\n" ); return SNMPERR_GENERR; } /* * check for required callbacks */ if ((cb->can_set && ((NULL==cb->duplicate_row) || (NULL==cb->delete_row) || (NULL==cb->row_copy)) )) { snmp_log(LOG_ERR, "table_array registration with incomplete " "callback structure.\n"); return SNMPERR_GENERR; } if (NULL==container) tad->table = netsnmp_container_find("table_array"); else tad->table = container; if (NULL==container->compare) container->compare = netsnmp_compare_netsnmp_index; if (NULL==container->ncompare) container->ncompare = netsnmp_ncompare_netsnmp_index; tad->cb = cb; reginfo->handler->myvoid = tad; return netsnmp_register_table(reginfo, tabreg);}/** find the handler for the table_array helper. */netsnmp_mib_handler *netsnmp_find_table_array_handler(netsnmp_handler_registration *reginfo){ netsnmp_mib_handler *mh; if (!reginfo) return NULL; mh = reginfo->handler; while (mh) { if (mh->access_method == netsnmp_table_array_helper_handler) break; mh = mh->next; } return mh;}/** find the context data used by the table_array helper */netsnmp_container *netsnmp_extract_array_context(netsnmp_request_info *request){ return netsnmp_request_get_list_data(request, TABLE_ARRAY_NAME);}/** this function is called to validate RowStatus transitions. */intnetsnmp_table_array_check_row_status(netsnmp_table_array_callbacks *cb, netsnmp_request_group *ag, long *rs_new, long *rs_old){ netsnmp_index *row_ctx; netsnmp_index *undo_ctx; if (!ag || !cb) return SNMPERR_GENERR; row_ctx = ag->existing_row; undo_ctx = ag->undo_info; /* * xxx-rks: revisit row delete scenario */ if (row_ctx) { /* * either a new row, or change to old row */ /* * is it set to active? */ if (RS_IS_GOING_ACTIVE(*rs_new)) { /* * is it ready to be active? */ if ((NULL==cb->can_activate) || cb->can_activate(undo_ctx, row_ctx, ag)) *rs_new = RS_ACTIVE; else return SNMP_ERR_INCONSISTENTVALUE; } else { /* * not going active */ if (undo_ctx) { /* * change */ if (RS_IS_ACTIVE(*rs_old)) { /* * check pre-reqs for deactivation */ if (cb->can_deactivate && !cb->can_deactivate(undo_ctx, row_ctx, ag)) { return SNMP_ERR_INCONSISTENTVALUE; } } } else { /* * new row */ } if (*rs_new != RS_DESTROY) { if ((NULL==cb->can_activate) || cb->can_activate(undo_ctx, row_ctx, ag)) *rs_new = RS_NOTINSERVICE; else *rs_new = RS_NOTREADY; } else { if (cb->can_delete && !cb->can_delete(undo_ctx, row_ctx, ag)) { return SNMP_ERR_INCONSISTENTVALUE; } ag->row_deleted = 1; } } } else { /* * check pre-reqs for delete row */ if (cb->can_delete && !cb->can_delete(undo_ctx, row_ctx, ag)) { return SNMP_ERR_INCONSISTENTVALUE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -