📄 mfd-access-unsorted-external-defines.m2i
字号:
############################################################# -*- c -*-## generic include for XXX. Do not use directly.#### $Id: mfd-access-unsorted-external-defines.m2i 11972 2005-03-02 19:35:44Z rstory $##########################################################################@eval $mfd_aue_wrap_param = "wrap_ctx"@@eval $mfd_aue_wrap_param_type = "${context}_interface_ctx *"@@eval $mfd_aue_wrap_param_decl = "$mfd_aue_wrap_param_type $mfd_aue_wrap_param"@##@eval $mfd_aue_param = "${context}_reg"@@eval $mfd_aue_param_type = "${context}_registration *"@@eval $mfd_aue_param_decl = "$mfd_aue_param_type $mfd_aue_param"@@eval $mfd_aue_param_cmt = "$mfd_aue_param Pointer to a $mfd_aue_param_type"##@if $m2c_mark_boundary == 1@/** START code generated by $RCSfile$ $Revision: 11972 $ */@end@##//######################################################################//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@##//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@if $m2c_processing_type eq 'h'@##@if $m2c_include_examples == 1@$example_start/* ********************************************************************* * Since we have no idea how you really access your data, we'll go with * a worst case example: a flat text file. @ if $m2c_data_transient != 2@ @ print Example code is for fully transient data. Either turn off@ @ print m2c_include_examples or set m2c_data_transient to 2.@ @ exit@ @ end@ */#define MAX_LINE_SIZE 256$example_end@end@/** * loop context * * TODO: * define loop context structure * * Since the actual loop is in the MFD handler, a loop contex parameter * is provided to help you keep track of where you are in between calls * to functions that you wrote and the master MFD handler calls. The * structure of this context is user defineable, and is defined in the * file ${table}_data_access.h. * * E.G., if your data is stored in a linked list, the obvious thing you * want to know from one function call to the next is your current * position in the linked list. Thus the easiest context to use is a * pointer within the linked list. For an array, the current index to * that array would be easiest. * * The funtion calls are actually passed a reference to the loop * context, to allow the loop context to be allocated memory. Here are * some simple examples definitions for various data formats. These * definitions are used in examples later on. * */typedef struct ${context}_loop_context_s { /* * temporary context used during iteration */ ${context}_rowreq_ctx *rowreq_ctx;@if $m2c_include_examples == 1@ /* * this example code is based on a data source that is a * text file to be read and parsed. */ FILE *filep; char line[MAX_LINE_SIZE];@end@} ${context}_loop_context;/* * define a reference to the loop context * * NOTE: DO NOT ADD ITEMS TO THIS STRUCTURE! */typedef struct ${context}_ref_loop_ctx_s { ${context}_loop_context *loop_ctx;} ${context}_ref_loop_ctx;int ${context}_loop_get_first( $mfd_aue_param_decl, ${context}_ref_loop_ctx *loop_ctx_ref, ${context}_ref_rowreq_ctx *rowreq_ctx_ref);int ${context}_loop_get_next( $mfd_aue_param_decl, ${context}_ref_loop_ctx *loop_ctx_ref, ${context}_ref_rowreq_ctx *rowreq_ctx_ref);int ${context}_loop_get_data( $mfd_aue_param_decl, ${context}_ref_loop_ctx *loop_ctx_ref, ${context}_ref_rowreq_ctx *rowreq_ctx_ref);int ${context}_loop_save_position($mfd_aue_param_decl, ${context}_ref_loop_ctx *loop_ctx_ref, ${context}_ref_loop_ctx *save_loop_ctx_ref, int reuse);int ${context}_loop_cleanup_context( $mfd_aue_param_decl, ${context}_ref_loop_ctx *ref);##@end@ // m2c_processing_type eq 'h'##########################################################################//######################################################################//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@##//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@if $m2c_processing_type eq 'i'@/** * @internal * wrapper around clean up a loop reference */static int_${context}_loop_cleanup_context( $mfd_aue_wrap_param_decl, ${context}_ref_loop_ctx *ref){ DEBUGMSGTL(("internal:${context}:_${context}_loop_cleanup_context","called\n")); return ${context}_loop_cleanup_context($mfd_aue_wrap_param->user_ctx, ref);} /* _${context}_loop_cleanup_context *//** * @internal * wrapper around save position */static int_${context}_loop_save_position( $mfd_aue_wrap_param_decl, ${context}_ref_loop_ctx *ref, ${context}_ref_loop_ctx *ref_copy, int reuse){ DEBUGMSGTL(("internal:${context}:_${context}_loop_save_position","called\n")); return ${context}_loop_save_position($mfd_aue_wrap_param->user_ctx, ref, ref_copy, reuse);} /* _${context}_loop_save_position *//** * @internal * wrapper around user get_first to setup the index oid */static int_${context}_loop_get_first_wrapper($mfd_aue_wrap_param_decl, ${context}_ref_loop_ctx * loop_ctx_ref, ${context}_ref_rowreq_ctx * rowreq_ctx_ref){ int rc; DEBUGMSGTL(("internal:${context}:_${context}_loop_get_first_wrapper","called\n")); rc = ${context}_loop_get_first($mfd_aue_wrap_param->user_ctx, loop_ctx_ref, rowreq_ctx_ref); /* * convert index to OID */ if(SNMPERR_SUCCESS == rc ) { netsnmp_assert((NULL != rowreq_ctx_ref) && (rowreq_ctx_ref->rowreq_ctx->oid_idx.oids == rowreq_ctx_ref->rowreq_ctx->oid_tmp)); rowreq_ctx_ref->rowreq_ctx->oid_idx.len = sizeof(rowreq_ctx_ref->rowreq_ctx->oid_tmp); rc = ${context}_index_to_oid(&rowreq_ctx_ref->rowreq_ctx->oid_idx, &rowreq_ctx_ref->rowreq_ctx->tbl_idx); netsnmp_assert(rowreq_ctx_ref->rowreq_ctx->oid_idx.len != sizeof(rowreq_ctx_ref->rowreq_ctx->oid_tmp)); } return rc;} /* _${context}_loop_get_first_wrapper *//** * @internal * wrapper around user get_next to setup the index oid */static int_${context}_loop_get_next_wrapper($mfd_aue_wrap_param_decl, ${context}_ref_loop_ctx * loop_ctx_ref, ${context}_ref_rowreq_ctx * rowreq_ctx_ref){ int rc; DEBUGMSGTL(("internal:${context}:_${context}_loop_get_next_wrapper","called\n")); rc = ${context}_loop_get_next($mfd_aue_wrap_param->user_ctx, loop_ctx_ref, rowreq_ctx_ref); /* * convert index to OID */ if(SNMPERR_SUCCESS == rc ) { netsnmp_assert((NULL != rowreq_ctx_ref) && (rowreq_ctx_ref->rowreq_ctx->oid_idx.oids == rowreq_ctx_ref->rowreq_ctx->oid_tmp)); rowreq_ctx_ref->rowreq_ctx->oid_idx.len = sizeof(rowreq_ctx_ref->rowreq_ctx->oid_tmp); rc = ${context}_index_to_oid(&rowreq_ctx_ref->rowreq_ctx->oid_idx, &rowreq_ctx_ref->rowreq_ctx->tbl_idx); netsnmp_assert(rowreq_ctx_ref->rowreq_ctx->oid_idx.len != sizeof(rowreq_ctx_ref->rowreq_ctx->oid_tmp)); } return rc;} /* _${context}_loop_get_next_wrapper */@if $m2c_data_transient != 0@ # /** * @internal * get data wrapper to allocate context for the user */static int_${context}_loop_get_data_wrapper($mfd_aue_wrap_param_decl, ${context}_ref_loop_ctx * loop_ctx_ref, ${context}_ref_rowreq_ctx * rowreq_ctx_ref){// ${context}_rowreq_ctx *orig_ctx = rowreq_ctx_ref->rowreq_ctx; DEBUGMSGTL(("internal:${context}:_${context}_loop_get_data_wrapper","called\n")); return ${context}_loop_get_data($mfd_aue_wrap_param->user_ctx, loop_ctx_ref, rowreq_ctx_ref);} /* _${context}_loop_get_data_wrapper */@end@ // transient != 0/** * @internal * initialize the iterator container with functions or wrappers */void_${context}_container_init(${context}_interface_ctx *if_ctx){ DEBUGMSGTL(("internal:${context}:_${context}_container_init","called\n")); if_ctx->container = netsnmp_container_iterator_get(/** registration */ if_ctx, /** compare */ NULL, /** get_first */ (Netsnmp_Iterator_Loop_Key*)_${context}_loop_get_first_wrapper, /** get_next */ (Netsnmp_Iterator_Loop_Key*)_${context}_loop_get_next_wrapper, /** get_data */@if $m2c_data_transient != 0@ # (Netsnmp_Iterator_Loop_Data*)_${context}_loop_get_data_wrapper,@else@ NULL,@end@ /** save_pos */ (Netsnmp_Iterator_Ctx_Dup*)_${context}_loop_save_position, /** init_context */ (Netsnmp_Iterator_Ctx*)NULL, /** cleanup_context */ (Netsnmp_Iterator_Ctx*)_${context}_loop_cleanup_context, /** free_user_ctx */ NULL, /** sorted */ 0);} /* _${context}_container_init */##@end@ // m2c_processing_type eq 'i'##########################################################################//######################################################################//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@##//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@if $m2c_processing_type eq 'c'@/** * unsorted-external overview * * The unsorted external data access code works by calling a few simple * functions to get the index value for each row. Once the agent determines * which row is needed to process an incoming request, another function * is called to retrieve the data for that row. * * A simplified version of the pseudo-code looks like this: * * ${context}_loop_get_first(loop,data) * while( no_error ) { * if( best_match(data, key) * ${context}_loop_save_position(loop,pos); * ${context}_loop_get_next(loop,data) * } * ${context}_loop_get_data(pos,data) * ${context}_loop_cleanup_context(loop) *//*********************************************************************** * * ITERATION * ***********************************************************************//** * get the first data index * * Summary * ------- * This function is called to initialize the iterator loop context for a * new iteration loop and return the index(es) for the first * ${context}_data in the data set. * * Note that during the loop, the only important thing is the indexes. * If access to your data is cheap/fast (e.g. you have a pointer to a * structure in memory), it would make sense to update the data here. * If, however, the accessing the data invovles more work (e.g. parsing * some other existing data, or peforming calculations to derive the data), * then you should limit yourself to setting the indexes. Extracting the * can be put off until the desired row is found. See the notes on * ${context}_loop_get_data(). * * Note that this function does not correspond to a SNMP GET pdu, and * you should return data items in whatever order they are already in. * (In fact, if your data is already ordered in the same order as the * SNMP indexes, you shouldn't be using the unsorted-access code). * * This function should update the table index (rowreq_ctx_ref->rowreq_ctx->tbl_idx) * values for the raw data (rowreq_ctx_ref->rowreq_ctx->data). * * More Details * ------------ * If there is currently no data available, return MFD_END_OF_DATA. * Otherwise, you should set rowreq_ctx_ref->rowreq_ctx and its indexes. * * rowreq_ctx_ref->rowreq_ctx will be NULL. You should allocate a new context * for this loop. [Alternatively, you could allocate one in * ${context}_loop_init_context, save it in your * ${context}_ref_loop_ctx, and use it here.] * * Once you have your context pointer, you should set the index (or indexes) * in rowreq_ctx_ref->rowreq_ctx->tbl_idx to the appropriate value for this row. [If you * use your loop_ctx_ref cleverly, you might be able to put this work in * ${context}_loop_get_next, and simply call that function.] * * @param $mfd_aue_param_cmt * @param loop_ctx_ref Pointer to your loop reference. * @param rowreq_ctx_ref Pointer to a context reference. * * @retval MFD_SUCCESS : success. * @retval MFD_END_OF_DATA : no data available * @retval MFD_ERROR : error. */int${context}_loop_get_first( $mfd_aue_param_decl, ${context}_ref_loop_ctx *loop_ctx_ref, ${context}_ref_rowreq_ctx *rowreq_ctx_ref){ DEBUGMSGTL(("verbose:${context}:${context}_loop_get_first","called\n")); netsnmp_assert(rowreq_ctx_ref); netsnmp_assert(loop_ctx_ref); /* * allocate memory for new structure */ loop_ctx_ref->loop_ctx = SNMP_MALLOC_TYPEDEF(${context}_loop_context); if(NULL == loop_ctx_ref->loop_ctx) return MFD_ERROR; /* * allocate a temporary context to use during iteration */@ eval $m2c_tmp = ""@@ if ($m2c_data_allocate == 1) || ($m2c_data_init == 1)@@ eval $m2c_tmp = "NULL"@@ if ($m2c_data_allocate == 1) && ($m2c_data_init == 1)@@ eval $m2c_tmp = "$m2c_tmp, NULL"@@ @end@@ end@ loop_ctx_ref->loop_ctx->rowreq_ctx = ${context}_allocate_rowreq_ctx($m2c_tmp); if(NULL == loop_ctx_ref->loop_ctx->rowreq_ctx) { SNMP_FREE(loop_ctx_ref->loop_ctx); return MFD_RESOURCE_UNAVAILABLE; } /* * TODO: * set up loop context */@if $m2c_include_examples == 1@$example_start /* * open our data file. */ loop_ctx_ref->loop_ctx->filep = fopen("/etc/dummy.conf", "r"); if(NULL == loop_ctx_ref->loop_ctx->filep) { return MFD_RESOURCE_UNAVAILABLE; }$example_end@end@@ifconf ${table}_update_idx.m2i@@ include ${table}_update_idx.m2i@@else@@ if $m2c_include_examples == 1@$example_start /* * in this example, after opening the file, get next does the same thing * as get first, we let's just call get next... */ return ${context}_loop_get_next($mfd_aue_param, loop_ctx_ref, rowreq_ctx_ref);$example_end@ else@ /* * we just need the index for now. Reuse the one in the loop context's * temporary row request context. (rowreq_ctx_ref->rowreq_ctx->tbl_idx) */ rowreq_ctx_ref->rowreq_ctx = loop_ctx_ref->loop_ctx->rowreq_ctx; /* * TODO: * set local vars for index from loop_ctx_ref->loop_ctx * this can be done in one of two ways: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -