mib2c.array-user.conf
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:37k
源码类别:
SNMP编程
开发平台:
Unix_Linux
- ## -*- c -*-
- ##
- ## For documentation on the code generated by this configuration file,
- ## see the file agent/helpers/table_array.c.
- ##
- ######################################################################
- ## Do the .h file
- ## @perleval $vars{shortname} =~ s/([A-Z])[a-z]+/$1/g@
- ######################################################################
- @foreach $i table@
- @open ${i}.h@
- @eval $hack = "Id"
- /*
- * Note: this file originally auto-generated by mib2c using
- * $Id: mib2c.array-user.conf,v 5.24.2.2 2005/04/26 22:13:28 rstory Exp $
- *
- * $$hack:$
- *
- * Yes, there is lots of code here that you might not use. But it is much
- * easier to remove code than to add it!
- */
- #ifndef $i.uc_H
- #define $i.uc_H
- #ifdef __cplusplus
- extern "C" {
- #endif
- #include <net-snmp/net-snmp-config.h>
- #include <net-snmp/library/container.h>
- #include <net-snmp/agent/table_array.h>
- @eval $ext_index = 0@
- @foreach $idx index@
- @if "$idx" ne ""@
- @eval $found = "external"@
- @foreach $c column@
- @if "$idx" eq "$c"@
- @eval $found = "internal"@
- @end@
- @end@
- /** Index $idx is $found */
- @if "$found" eq "external"@
- @eval $ext_index = 1@
- @end@
- @end@
- @end@
- typedef struct ${i}_context_s {
- netsnmp_index index; /** THIS MUST BE FIRST!!! */
- /*************************************************************
- * You can store data internally in this structure.
- *
- * TODO: You will probably have to fix a few types here...
- */
- @if $ext_index != 0@
- /** TODO: add storage for external index(s)! */
- @end@
- @foreach $c column@
- /** $c.syntax = $c.type */
- @eval $have_type = 0@
- @if "$c.type" eq "ASN_OCTET_STR"@
- @eval $have_type = 1@
- @eval $o_len = "65535"@
- @if "$c.syntax" eq "DisplayString"@
- @eval $o_len = "255"@
- @end@
- @if "$c.syntax" eq "SnmpAdminString"@
- @eval $o_len = "255"@
- @end@
- unsigned char $c[$o_len];
- long ${c}_len;
- @end@
- @if "$c.type" eq "ASN_OBJECT_ID"@
- @eval $have_type = 1@
- oid $c[MAX_OID_LEN];
- long ${c}_len;
- @end@
- @if "$c.type" eq "ASN_UNSIGNED"@
- @eval $have_type = 1@
- unsigned long $c;
- @end@
- @if "$c.type" eq "ASN_TIMETICKS"@
- @eval $have_type = 1@
- unsigned long $c;
- @end@
- @if "$c.type" eq "ASN_IPADDRESS"@
- @eval $have_type = 1@
- unsigned long $c;
- @end@
- @if "$c.type" eq "ASN_UINTEGER"@
- @eval $have_type = 1@
- unsigned long $c;
- @end@
- @if "$c.type" eq "ASN_INTEGER"@
- @eval $have_type = 1@
- long $c;
- @end@
- @if "$c.type" eq "ASN_COUNTER"@
- @eval $have_type = 1@
- unsigned long $c;
- @end@
- @if $have_type == 0@
- /** TODO: Is this type correct? */
- long $c;
- @end@
- @end@
- /*
- * OR
- *
- * Keep a pointer to your data
- */
- void * data;
- /*
- *add anything else you want here
- */
- } ${i}_context;
- /*************************************************************
- * function declarations
- */
- void init_$i(void);
- void initialize_table_$i(void);
- const ${i}_context * ${i}_get_by_idx(netsnmp_index *);
- const ${i}_context * ${i}_get_by_idx_rs(netsnmp_index *,
- int row_status);
- int ${i}_get_value(netsnmp_request_info *, netsnmp_index *, netsnmp_table_request_info *);
- /*************************************************************
- * oid declarations
- */
- extern oid ${i}_oid[];
- extern size_t ${i}_oid_len;
- #define ${i}_TABLE_OID $i.commaoid
- /*************************************************************
- * column number definitions for table $i
- */
- @eval $minv = 0xffffffff@
- @eval $maxv = 0@
- @foreach $c column@
- #define COLUMN_$c.uc $c.subid
- @if ! $c.noaccess@
- @eval $minv = min($minv, $c.subid)@
- @eval $maxv = max($maxv, $c.subid)@
- @end@
- @if "$c.syntax" eq "RowStatus"@
- @eval $rs_name = "$c"@
- @end@
- @if "$c.syntax" eq "StorageType"@
- @eval $st_name = "$c"@
- @end@
- @end@
- #define ${i}_COL_MIN $minv
- #define ${i}_COL_MAX $maxv
- /* comment out the following line if you don't want a custom sort */
- #define ${i}_CUSTOM_SORT
- @if "$rs_name" ne ""@
- /* uncommend the following line if you allow modifications to an
- * active row */
- /** define ${i}_CAN_MODIFY_ACTIVE_ROW */
- @end@
- @if $i.settable@
- int ${i}_extract_index( ${i}_context * ctx, netsnmp_index * hdr );
- void ${i}_set_reserve1( netsnmp_request_group * );
- void ${i}_set_reserve2( netsnmp_request_group * );
- void ${i}_set_action( netsnmp_request_group * );
- void ${i}_set_commit( netsnmp_request_group * );
- void ${i}_set_free( netsnmp_request_group * );
- void ${i}_set_undo( netsnmp_request_group * );
- ${i}_context * ${i}_duplicate_row( ${i}_context* );
- netsnmp_index * ${i}_delete_row( ${i}_context* );
- @if "$rs_name" ne ""@
- int ${i}_can_activate(${i}_context *undo_ctx,
- ${i}_context *row_ctx,
- netsnmp_request_group * rg);
- int ${i}_can_deactivate(${i}_context *undo_ctx,
- ${i}_context *row_ctx,
- netsnmp_request_group * rg);
- @end@
- int ${i}_can_delete(${i}_context *undo_ctx,
- ${i}_context *row_ctx,
- netsnmp_request_group * rg);
- @if $i.creatable@
- ${i}_context * ${i}_create_row( netsnmp_index* );
- @end@
- @end@
- #ifdef ${i}_CUSTOM_SORT
- ${i}_context * ${i}_get( const char *name, int len );
- #endif
- #ifdef __cplusplus
- }
- #endif
- #endif /** $i.uc_H */
- @end@
- ######################################################################
- ## Do the .c file
- ######################################################################
- @foreach $i table@
- @open ${i}.c@
- @eval $hack = "Id"@
- /*
- * Note: this file originally auto-generated by mib2c using
- * $Id: mib2c.array-user.conf,v 5.24.2.2 2005/04/26 22:13:28 rstory Exp $
- *
- * $$hack:$
- *
- *
- * For help understanding NET-SNMP in general, please check the
- * documentation and FAQ at:
- *
- * http://www.net-snmp.org/
- *
- *
- * For help understanding this code, the agent and how it processes
- * requests, please check the following references.
- *
- * http://www.net-snmp.org/tutorial-5/
- *
- *
- * You can also join the #net-snmp channel on irc.freenode.net
- * and ask for help there.
- *
- *
- * And if all else fails, send a detailed message to the developers
- * describing the problem you are having to:
- *
- * net-snmp-coders@lists.sourceforge.net
- *
- *
- * Yes, there is lots of code here that you might not use. But it is much
- * easier to remove code than to add it!
- */
- #include <net-snmp/net-snmp-config.h>
- #include <net-snmp/net-snmp-includes.h>
- #include <net-snmp/agent/net-snmp-agent-includes.h>
- #include <net-snmp/library/snmp_assert.h>
- #include "${i}.h"
- static netsnmp_handler_registration *my_handler = NULL;
- static netsnmp_table_array_callbacks cb;
- oid ${i}_oid[] = { ${i}_TABLE_OID };
- size_t ${i}_oid_len = OID_LENGTH(${i}_oid);
- #ifdef ${i}_CUSTOM_SORT
- /************************************************************
- * keep binary tree to find context by name
- */
- static int ${i}_cmp( const void *lhs, const void *rhs );
- /************************************************************
- * compare two context pointers here. Return -1 if lhs < rhs,
- * 0 if lhs == rhs, and 1 if lhs > rhs.
- */
- static int
- ${i}_cmp( const void *lhs, const void *rhs )
- {
- ${i}_context *context_l =
- (${i}_context *)lhs;
- ${i}_context *context_r =
- (${i}_context *)rhs;
- /*
- * check primary key, then secondary. Add your own code if
- * there are more than 2 keys
- */
- int rc;
- /*
- * TODO: implement compare. Remove this ifdef code and
- * add your own code here.
- */
- #ifdef TABLE_CONTAINER_TODO
- snmp_log(LOG_ERR,
- "${i}_compare not implemented! Container order undefinedn" );
- return 0;
- #endif
- /*
- * EXAMPLE (assuming you want to sort on a name):
- *
- * rc = strcmp( context_l->xxName, context_r->xxName );
- *
- * if(rc)
- * return rc;
- *
- * TODO: fix secondary keys (or delete if there are none)
- *
- * if(context_l->yy < context_r->yy)
- * return -1;
- *
- * return (context_l->yy == context_r->yy) ? 0 : 1;
- */
- }
- /************************************************************
- * search tree
- */
- /** TODO: set additional indexes as parameters */
- ${i}_context *
- ${i}_get( const char *name, int len )
- {
- ${i}_context tmp;
- /** we should have a custom container */
- netsnmp_assert(cb.container->next != NULL);
- /*
- * TODO: implement compare. Remove this ifdef code and
- * add your own code here.
- */
- #ifdef TABLE_CONTAINER_TODO
- snmp_log(LOG_ERR, "${i}_get not implemented!n" );
- return NULL;
- #endif
- /*
- * EXAMPLE:
- *
- * if(len > sizeof(tmp.xxName))
- * return NULL;
- *
- * strncpy( tmp.xxName, name, sizeof(tmp.xxName) );
- * tmp.xxName_len = len;
- *
- * return CONTAINER_FIND(cb.container->next, &tmp);
- */
- }
- #endif
- /************************************************************
- * Initializes the $i module
- */
- void
- init_$i(void)
- {
- initialize_table_$i();
- /*
- * TODO: perform any startup stuff here, such as
- * populating the table with initial data.
- *
- * ${i}_context * new_row = create_row(index);
- * CONTAINER_INSERT(cb.container,new_row);
- */
- }
- @if $i.settable@
- /************************************************************
- * the *_row_copy routine
- */
- static int ${i}_row_copy(${i}_context * dst,
- ${i}_context * src)
- {
- if(!dst||!src)
- return 1;
- /*
- * copy index, if provided
- */
- if(dst->index.oids)
- free(dst->index.oids);
- if(snmp_clone_mem( (void*)&dst->index.oids, src->index.oids,
- src->index.len * sizeof(oid) )) {
- dst->index.oids = NULL;
- return 1;
- }
- dst->index.len = src->index.len;
- /*
- * copy components into the context structure
- */
- @if $ext_index != 0@
- /** TODO: add code for external index(s)! */
- @end@
- @foreach $c column@
- @eval $have_type = 0@
- @if "$c.type" eq "ASN_OCTET_STR"@
- @eval $have_type = 1@
- memcpy( dst->$c, src->$c, src->${c}_len );
- dst->${c}_len = src->${c}_len;
- @end@
- @if "$c.type" eq "ASN_OBJECT_ID"@
- @eval $have_type = 1@
- memcpy( dst->$c, src->$c, src->${c}_len );
- dst->${c}_len = src->${c}_len;
- @end@
- @if $have_type == 0@
- dst->$c = src->$c;
- @end@
- @end@
- return 0;
- }
- /**
- * the *_extract_index routine
- *
- * This routine is called when a set request is received for an index
- * that was not found in the table container. Here, we parse the oid
- * in the the individual index components and copy those indexes to the
- * context. Then we make sure the indexes for the new row are valid.
- */
- int
- ${i}_extract_index( ${i}_context * ctx, netsnmp_index * hdr )
- {
- /*
- * temporary local storage for extracting oid index
- *
- * extract index uses varbinds (netsnmp_variable_list) to parse
- * the index OID into the individual components for each index part.
- */
- @if $ext_index != 0@
- /** TODO: add storage for external index(s)! */
- @end@
- @eval $first_idx = ""@
- @foreach $idx index@
- @if "$first_idx" eq ""@
- @eval $first_idx = $idx@
- @end@
- netsnmp_variable_list var_$idx;
- @end@
- int err;
- /*
- * copy index, if provided
- */
- if(hdr) {
- netsnmp_assert(ctx->index.oids == NULL);
- if((hdr->len > MAX_OID_LEN) ||
- snmp_clone_mem( (void*)&ctx->index.oids, hdr->oids,
- hdr->len * sizeof(oid) )) {
- return -1;
- }
- ctx->index.len = hdr->len;
- }
- /*
- * initialize variable that will hold each component of the index.
- * If there are multiple indexes for the table, the variable_lists
- * need to be linked together, in order.
- */
- @if $ext_index != 0@
- /** TODO: add code for external index(s)! */
- @end@
- @foreach $idx index@
- memset( &var_$idx, 0x00, sizeof(var_$idx) );
- var_${idx}.type = $idx.type; /* type hint for parse_oid_indexes */
- /** TODO: link this index to the next, or NULL for the last one */
- #ifdef TABLE_CONTAINER_TODO
- snmp_log(LOG_ERR, "${i}_extract_index index list not implemented!n" );
- return 0;
- #else
- var_${idx}.next_variable = &var_XX;
- #endif
- @end@
- /*
- * parse the oid into the individual index components
- */
- err = parse_oid_indexes( hdr->oids, hdr->len, &var_$first_idx );
- if (err == SNMP_ERR_NOERROR) {
- /*
- * copy index components into the context structure
- */
- @foreach $idx index@
- @eval $found = "external"@
- @foreach $c column@
- @if "$idx" eq "$c"@
- @eval $found = "internal"@
- @end@
- @end@
- @if "$found" eq "external"@
- /** skipping external index $idx */
- @end@
- @if "$found" eq "internal"@
- @eval $have_type = 0@
- @if "$idx.type" eq "ASN_OCTET_STR"@
- @eval $have_type = 1@
- if(var_${idx}.val_len > sizeof(ctx->$idx))
- err = -1;
- else
- memcpy( ctx->$idx, var_${idx}.val.string, var_${idx}.val_len );
- ctx->${idx}_len = var_${idx}.val_len;
- @end@
- @if "$idx.type" eq "ASN_OBJECT_ID"@
- @eval $have_type = 1@
- memcpy( ctx->$idx, var_${idx}.val.string, var_${idx}.val_len );
- ctx->${idx}_len = var_${idx}.val_len;
- @end@
- @if $have_type == 0@
- ctx->$idx = *var_${idx}.val.integer;
- @end@
- @end@
- @end@
- @foreach $c index@
- /*
- * TODO: check index for valid values. For EXAMPLE:
- *
- @eval $have_check = 0@
- @if "$c.type" eq "ASN_IPADDRESS"@
- @eval $have_check = 1@
- * if ( XXX_check_ip( *var_${c}.val.integer ) ) {
- @end@
- @if "$c.type" eq "ASN_OBJECT_ID"@
- @eval $have_check = 1@
- * if ( XXX_check_oid( var_${c}.val.objid, var_${c}.val_len /
- sizeof(oid) ) ) {
- @end@
- @if "$c.type" eq "ASN_OCTET_STR"@
- @eval $have_check = 1@
- * if ( XXX_check_value( var_${c}.val.string, XXX ) ) {
- @end@
- @if $have_check != 1@
- * if ( *var_${c}.val.integer != XXX ) {
- @end@
- * err = -1;
- * }
- */
- @end@
- }
- /*
- * parsing may have allocated memory. free it.
- */
- snmp_reset_var_buffers( &var_$first_idx );
- return err;
- }
- @if "$rs_name" ne ""@
- /************************************************************
- * the *_can_activate routine is called
- * when a row is changed to determine if all the values
- * set are consistent with the row's rules for a row status
- * of ACTIVE.
- *
- * return 1 if the row could be ACTIVE
- * return 0 if the row is not ready for the ACTIVE state
- */
- int ${i}_can_activate(${i}_context *undo_ctx,
- ${i}_context *row_ctx,
- netsnmp_request_group * rg)
- {
- /*
- * TODO: check for activation requirements here
- */
- /*
- * be optimistic.
- */
- return 1;
- }
- /************************************************************
- * the *_can_deactivate routine is called when a row that is
- * currently ACTIVE is set to a state other than ACTIVE. If
- * there are conditions in which a row should not be allowed
- * to transition out of the ACTIVE state (such as the row being
- * referred to by another row or table), check for them here.
- *
- * return 1 if the row can be set to a non-ACTIVE state
- * return 0 if the row must remain in the ACTIVE state
- */
- int ${i}_can_deactivate(${i}_context *undo_ctx,
- ${i}_context *row_ctx,
- netsnmp_request_group * rg)
- {
- /*
- * TODO: check for deactivation requirements here
- */
- return 1;
- }
- @end@
- /************************************************************
- * the *_can_delete routine is called to determine if a row
- * can be deleted.
- *
- * return 1 if the row can be deleted
- * return 0 if the row cannot be deleted
- */
- int ${i}_can_delete(${i}_context *undo_ctx,
- ${i}_context *row_ctx,
- netsnmp_request_group * rg)
- {
- @if "$rs_name" ne ""@
- /*
- * probably shouldn't delete a row that we can't
- * deactivate.
- */
- if(${i}_can_deactivate(undo_ctx,row_ctx,rg) != 1)
- return 0;
- @end@
- /*
- * TODO: check for other deletion requirements here
- */
- return 1;
- }
- @if $i.creatable@
- /************************************************************
- * the *_create_row routine is called by the table handler
- * to create a new row for a given index. If you need more
- * information (such as column values) to make a decision
- * on creating rows, you must create an initial row here
- * (to hold the column values), and you can examine the
- * situation in more detail in the *_set_reserve1 or later
- * states of set processing. Simple check for a NULL undo_ctx
- * in those states and do detailed creation checking there.
- *
- * returns a newly allocated ${i}_context
- * structure if the specified indexes are not illegal
- * returns NULL for errors or illegal index values.
- */
- ${i}_context *
- ${i}_create_row( netsnmp_index* hdr)
- {
- ${i}_context * ctx =
- SNMP_MALLOC_TYPEDEF(${i}_context);
- if(!ctx)
- return NULL;
- /*
- * TODO: check indexes, if necessary.
- */
- if(${i}_extract_index( ctx, hdr )) {
- if (NULL != ctx->index.oids)
- free(ctx->index.oids);
- free(ctx);
- return NULL;
- }
- /* netsnmp_mutex_init(ctx->lock);
- netsnmp_mutex_lock(ctx->lock); */
- /*
- * TODO: initialize any default values here. This is also
- * first place you really should allocate any memory for
- * yourself to use. If you allocated memory earlier,
- * make sure you free it for earlier error cases!
- */
- /**
- @foreach $c column@
- @if $c.settable@
- ctx->$c = 0;
- @end@
- @end@
- */
- return ctx;
- }
- @end@
- /************************************************************
- * the *_duplicate row routine
- */
- ${i}_context *
- ${i}_duplicate_row( ${i}_context * row_ctx)
- {
- ${i}_context * dup;
- if(!row_ctx)
- return NULL;
- dup = SNMP_MALLOC_TYPEDEF(${i}_context);
- if(!dup)
- return NULL;
- if(${i}_row_copy(dup,row_ctx)) {
- free(dup);
- dup = NULL;
- }
- return dup;
- }
- /************************************************************
- * the *_delete_row method is called to delete a row.
- */
- netsnmp_index * ${i}_delete_row( ${i}_context * ctx )
- {
- /* netsnmp_mutex_destroy(ctx->lock); */
- if(ctx->index.oids)
- free(ctx->index.oids);
- /*
- * TODO: release any memory you allocated here...
- */
- /*
- * release header
- */
- free( ctx );
- return NULL;
- }
- /************************************************************
- * RESERVE is used to check the syntax of all the variables
- * provided, that the values being set are sensible and consistent,
- * and to allocate any resources required for performing the SET.
- * After this stage, the expectation is that the set ought to
- * succeed, though this is not guaranteed. (In fact, with the UCD
- * agent, this is done in two passes - RESERVE1, and
- * RESERVE2, to allow for dependancies between variables).
- *
- * BEFORE calling this routine, the agent will call duplicate_row
- * to create a copy of the row (unless this is a new row; i.e.
- * row_created == 1).
- *
- * next state -> SET_RESERVE2 || SET_FREE
- */
- void ${i}_set_reserve1( netsnmp_request_group *rg )
- {
- ${i}_context *row_ctx =
- (${i}_context *)rg->existing_row;
- ${i}_context *undo_ctx =
- (${i}_context *)rg->undo_info;
- netsnmp_variable_list *var;
- netsnmp_request_group_item *current;
- int rc;
- @if "$st_name" ne ""@
- /*
- * Block all attempts to modify a readOnly row
- */
- if( row_ctx && (row_ctx->$st_name == SNMP_STORAGE_READONLY) ) {
- netsnmp_set_mode_request_error(MODE_SET_BEGIN, rg->list->ri,
- SNMP_ERR_NOTWRITABLE);
- return;
- }
- @end@
- /*
- * TODO: loop through columns, check syntax and lengths. For
- * columns which have no dependencies, you could also move
- * the value/range checking here to attempt to catch error
- * cases as early as possible.
- */
- for( current = rg->list; current; current = current->next ) {
- var = current->ri->requestvb;
- rc = SNMP_ERR_NOERROR;
- switch(current->tri->colnum) {
- @foreach $c column@
- @if $c.settable@
- case COLUMN_$c.uc:
- /** $c.syntax = $c.type */
- rc = netsnmp_check_vb_type_and_size(var, $c.type,
- sizeof(row_ctx->$c));
- break;
- @end@
- @end@
- default: /** We shouldn't get here */
- rc = SNMP_ERR_GENERR;
- snmp_log(LOG_ERR, "unknown column in "
- "${i}_set_reserve1n");
- }
- if (rc)
- netsnmp_set_mode_request_error(MODE_SET_BEGIN, current->ri, rc );
- rg->status = SNMP_MAX( rg->status, current->ri->status );
- }
- /*
- * done with all the columns. Could check row related
- * requirements here.
- */
- }
- void ${i}_set_reserve2( netsnmp_request_group *rg )
- {
- ${i}_context *row_ctx = (${i}_context *)rg->existing_row;
- ${i}_context *undo_ctx = (${i}_context *)rg->undo_info;
- netsnmp_request_group_item *current;
- netsnmp_variable_list *var;
- int rc;
- rg->rg_void = rg->list->ri;
- /*
- * TODO: loop through columns, check for valid
- * values and any range constraints.
- */
- for( current = rg->list; current; current = current->next ) {
- var = current->ri->requestvb;
- rc = SNMP_ERR_NOERROR;
- switch(current->tri->colnum) {
- @foreach $c column@
- @if $c.settable@
- case COLUMN_$c.uc:
- /** $c.syntax = $c.type */
- @eval $have_check = 0@
- @if "$c" eq "$st_name"@
- @eval $have_check = 1@
- rc = netsnmp_check_vb_storagetype(current->ri->requestvb,
- undo_ctx ?
- undo_ctx->$c:0);
- @end@
- @if "$c" eq "$rs_name"@
- @eval $have_check = 1@
- rc = netsnmp_check_vb_rowstatus(current->ri->requestvb,
- undo_ctx ?
- undo_ctx->$c:0);
- rg->rg_void = current->ri;
- @end@
- @if "$c.syntax" eq "TruthValue"@
- @eval $have_check = 1@
- rc = netsnmp_check_vb_truthvalue(current->ri->requestvb);
- @end@
- @if $have_check == 0@
- /*
- * TODO: routine to check valid values
- *
- * EXAMPLE:
- *
- @if "$c.type" eq "ASN_IPADDRESS"@
- @eval $have_check = 1@
- * if ( XXX_check_ip( *var->val.integer ) ) {
- @end@
- @if "$c.type" eq "ASN_OBJECT_ID"@
- @eval $have_check = 1@
- * if ( XXX_check_oid( var ) ) {
- @end@
- @if "$c.type" eq "ASN_OCTET_STR"@
- @eval $have_check = 1@
- * if ( XXX_check_value( var->val.string, XXX ) ) {
- @end@
- @if $have_check != 1@
- * if ( *var->val.integer != XXX ) {
- @end@
- * rc = SNMP_ERR_INCONSISTENTVALUE;
- * rc = SNMP_ERR_BADVALUE;
- * }
- */
- @end@
- break;
- @end@
- @end@
- default: /** We shouldn't get here */
- netsnmp_assert(0); /** why wasn't this caught in reserve1? */
- }
- if (rc)
- netsnmp_set_mode_request_error(MODE_SET_BEGIN, current->ri, rc);
- }
- /*
- * done with all the columns. Could check row related
- * requirements here.
- */
- }
- /************************************************************
- * Assuming that the RESERVE phases were successful, the next
- * stage is indicated by the action value ACTION. This is used
- * to actually implement the set operation. However, this must
- * either be done into temporary (persistent) storage, or the
- * previous value stored similarly, in case any of the subsequent
- * ACTION calls fail.
- *
- * In your case, changes should be made to row_ctx. A copy of
- * the original row is in undo_ctx.
- */
- void ${i}_set_action( netsnmp_request_group *rg )
- {
- netsnmp_variable_list *var;
- ${i}_context *row_ctx = (${i}_context *)rg->existing_row;
- ${i}_context *undo_ctx = (${i}_context *)rg->undo_info;
- netsnmp_request_group_item *current;
- @if "$rs_name" ne ""@
- int row_err = 0;
- @end@
- /*
- * TODO: loop through columns, copy varbind values
- * to context structure for the row.
- */
- for( current = rg->list; current; current = current->next ) {
- var = current->ri->requestvb;
- switch(current->tri->colnum) {
- @foreach $c column@
- @if $c.settable@
- case COLUMN_$c.uc:
- /** $c.syntax = $c.type */
- @eval $have_type = 0@
- @if "$c.type" eq "ASN_OCTET_STR"@
- @eval $have_type = 1@
- memcpy(row_ctx->$c,var->val.string,var->val_len);
- row_ctx->${c}_len = var->val_len;
- @end@
- @if "$c.type" eq "ASN_OBJECT_ID"@
- @eval $have_type = 1@
- memcpy(row_ctx->$c,var->val.objid,var->val_len);
- row_ctx->${c}_len = var->val_len;
- @end@
- @if $have_type == 0@
- row_ctx->$c = *var->val.integer;
- @end@
- break;
- @end@
- @end@
- default: /** We shouldn't get here */
- netsnmp_assert(0); /** why wasn't this caught in reserve1? */
- }
- }
- /*
- * done with all the columns. Could check row related
- * requirements here.
- */
- @if "$rs_name" ne ""@
- #ifndef ${i}_CAN_MODIFY_ACTIVE_ROW
- if( undo_ctx && RS_IS_ACTIVE(undo_ctx->$rs_name) &&
- row_ctx && RS_IS_ACTIVE(row_ctx->$rs_name) ) {
- row_err = 1;
- }
- #endif
- /*
- * check activation/deactivation
- */
- row_err = netsnmp_table_array_check_row_status(&cb, rg,
- row_ctx ? &row_ctx->$rs_name : NULL,
- undo_ctx ? &undo_ctx->$rs_name : NULL);
- if(row_err) {
- netsnmp_set_mode_request_error(MODE_SET_BEGIN,
- (netsnmp_request_info*)rg->rg_void,
- row_err);
- return;
- }
- @end@
- /*
- * TODO: if you have dependencies on other tables, this would be
- * a good place to check those, too.
- */
- }
- /************************************************************
- * Only once the ACTION phase has completed successfully, can
- * the final COMMIT phase be run. This is used to complete any
- * writes that were done into temporary storage, and then release
- * any allocated resources. Note that all the code in this phase
- * should be "safe" code that cannot possibly fail (cue
- * hysterical laughter). The whole intent of the ACTION/COMMIT
- * division is that all of the fallible code should be done in
- * the ACTION phase, so that it can be backed out if necessary.
- *
- * BEFORE calling this routine, the agent will update the
- * container (inserting a row if row_created == 1, or removing
- * the row if row_deleted == 1).
- *
- * AFTER calling this routine, the agent will delete the
- * undo_info.
- */
- void ${i}_set_commit( netsnmp_request_group *rg )
- {
- netsnmp_variable_list *var;
- ${i}_context *row_ctx = (${i}_context *)rg->existing_row;
- ${i}_context *undo_ctx = (${i}_context *)rg->undo_info;
- netsnmp_request_group_item *current;
- /*
- * loop through columns
- */
- for( current = rg->list; current; current = current->next ) {
- var = current->ri->requestvb;
- switch(current->tri->colnum) {
- @foreach $c column@
- @if $c.settable@
- case COLUMN_$c.uc:
- /** $c.syntax = $c.type */
- break;
- @end@
- @end@
- default: /** We shouldn't get here */
- netsnmp_assert(0); /** why wasn't this caught in reserve1? */
- }
- }
- /*
- * done with all the columns. Could check row related
- * requirements here.
- */
- }
- /************************************************************
- * If either of the RESERVE calls fail, the write routines
- * are called again with the FREE action, to release any resources
- * that have been allocated. The agent will then return a failure
- * response to the requesting application.
- *
- * AFTER calling this routine, the agent will delete undo_info.
- */
- void ${i}_set_free( netsnmp_request_group *rg )
- {
- netsnmp_variable_list *var;
- ${i}_context *row_ctx = (${i}_context *)rg->existing_row;
- ${i}_context *undo_ctx = (${i}_context *)rg->undo_info;
- netsnmp_request_group_item *current;
- /*
- * loop through columns
- */
- for( current = rg->list; current; current = current->next ) {
- var = current->ri->requestvb;
- switch(current->tri->colnum) {
- @foreach $c column@
- @if $c.settable@
- case COLUMN_$c.uc:
- /** $c.syntax = $c.type */
- break;
- @end@
- @end@
- default: /** We shouldn't get here */
- /** should have been logged in reserve1 */
- }
- }
- /*
- * done with all the columns. Could check row related
- * requirements here.
- */
- }
- /************************************************************
- * If the ACTION phase does fail (for example due to an apparently
- * valid, but unacceptable value, or an unforeseen problem), then
- * the list of write routines are called again, with the UNDO
- * action. This requires the routine to reset the value that was
- * changed to its previous value (assuming it was actually changed),
- * and then to release any resources that had been allocated. As
- * with the FREE phase, the agent will then return an indication
- * of the error to the requesting application.
- *
- * BEFORE calling this routine, the agent will update the container
- * (remove any newly inserted row, re-insert any removed row).
- *
- * AFTER calling this routing, the agent will call row_copy
- * to restore the data in existing_row from the date in undo_info.
- * Then undo_info will be deleted (or existing row, if row_created
- * == 1).
- */
- void ${i}_set_undo( netsnmp_request_group *rg )
- {
- netsnmp_variable_list *var;
- ${i}_context *row_ctx = (${i}_context *)rg->existing_row;
- ${i}_context *undo_ctx = (${i}_context *)rg->undo_info;
- netsnmp_request_group_item *current;
- /*
- * loop through columns
- */
- for( current = rg->list; current; current = current->next ) {
- var = current->ri->requestvb;
- switch(current->tri->colnum) {
- @foreach $c column@
- @if $c.settable@
- case COLUMN_$c.uc:
- /** $c.syntax = $c.type */
- break;
- @end@
- @end@
- default: /** We shouldn't get here */
- netsnmp_assert(0); /** why wasn't this caught in reserve1? */
- }
- }
- /*
- * done with all the columns. Could check row related
- * requirements here.
- */
- }
- @end@
- /************************************************************
- *
- * Initialize the $i table by defining its contents and how it's structured
- */
- void
- initialize_table_$i(void)
- {
- netsnmp_table_registration_info *table_info;
- if(my_handler) {
- snmp_log(LOG_ERR, "initialize_table_${i}_handler called againn");
- return;
- }
- memset(&cb, 0x00, sizeof(cb));
- /** create the table structure itself */
- table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
- my_handler = netsnmp_create_handler_registration("$i",
- netsnmp_table_array_helper_handler,
- ${i}_oid,
- ${i}_oid_len,
- @if $i.settable@
- HANDLER_CAN_RWRITE
- @else@
- HANDLER_CAN_RONLY
- @end@
- );
- if (!my_handler || !table_info) {
- snmp_log(LOG_ERR, "malloc failed in "
- "initialize_table_${i}_handlern");
- return; /** mallocs failed */
- }
- /***************************************************
- * Setting up the table's definition
- */
- /*
- * TODO: add any external indexes here.
- */
- @if $ext_index != 0@
- /** TODO: add code for external index(s)! */
- @end@
- /*
- * internal indexes
- */
- @foreach $idx index@
- /** index: $idx */
- netsnmp_table_helper_add_index(table_info, $idx.type);
- @end@
- table_info->min_column = ${i}_COL_MIN;
- table_info->max_column = ${i}_COL_MAX;
- /***************************************************
- * registering the table with the master agent
- */
- cb.get_value = ${i}_get_value;
- cb.container = netsnmp_container_find("${i}_primary:"
- "${i}:"
- "table_container");
- #ifdef ${i}_CUSTOM_SORT
- netsnmp_container_add_index(cb.container,
- netsnmp_container_find("${i}_custom:"
- "${i}:"
- "table_container"));
- cb.container->next->compare = ${i}_cmp;
- #endif
- @if $i.settable@
- cb.can_set = 1;
- @if $i.creatable@
- cb.create_row = (UserRowMethod*)${i}_create_row;
- @end@
- cb.duplicate_row = (UserRowMethod*)${i}_duplicate_row;
- cb.delete_row = (UserRowMethod*)${i}_delete_row;
- cb.row_copy = (Netsnmp_User_Row_Operation *)${i}_row_copy;
- @if "$rs_name" ne ""@
- cb.can_activate = (Netsnmp_User_Row_Action *)${i}_can_activate;
- cb.can_deactivate = (Netsnmp_User_Row_Action *)${i}_can_deactivate;
- @end@
- cb.can_delete = (Netsnmp_User_Row_Action *)${i}_can_delete;
- cb.set_reserve1 = ${i}_set_reserve1;
- cb.set_reserve2 = ${i}_set_reserve2;
- cb.set_action = ${i}_set_action;
- cb.set_commit = ${i}_set_commit;
- cb.set_free = ${i}_set_free;
- cb.set_undo = ${i}_set_undo;
- @end@
- DEBUGMSGTL(("initialize_table_$i",
- "Registering table $i "
- "as a table arrayn"));
- netsnmp_table_container_register(my_handler, table_info, &cb,
- cb.container, 1);
- }
- /************************************************************
- * ${i}_get_value
- *
- * This routine is called for get requests to copy the data
- * from the context to the varbind for the request. If the
- * context has been properly maintained, you don't need to
- * change in code in this fuction.
- */
- int ${i}_get_value(
- netsnmp_request_info *request,
- netsnmp_index *item,
- netsnmp_table_request_info *table_info )
- {
- netsnmp_variable_list *var = request->requestvb;
- ${i}_context *context = (${i}_context *)item;
- switch(table_info->colnum) {
- @foreach $c column@
- @if $c.readable@
- @eval $have_type = 0@
- case COLUMN_$c.uc:
- /** $c.syntax = $c.type */
- @if "$c.type" eq "ASN_OBJECT_ID"@
- @eval $have_type = 1@
- snmp_set_var_typed_value(var, $c.type,
- (char*)&context->$c,
- context->${c}_len );
- @end@
- @if "$c.type" eq "ASN_OCTET_STR"@
- @eval $have_type = 1@
- snmp_set_var_typed_value(var, $c.type,
- (char*)&context->$c,
- context->${c}_len );
- @end@
- @if $have_type == 0@
- snmp_set_var_typed_value(var, $c.type,
- (char*)&context->$c,
- sizeof(context->$c) );
- @end@
- break;
- @end@
- @end@
- default: /** We shouldn't get here */
- snmp_log(LOG_ERR, "unknown column in "
- "${i}_get_valuen");
- return SNMP_ERR_GENERR;
- }
- return SNMP_ERR_NOERROR;
- }
- /************************************************************
- * ${i}_get_by_idx
- */
- const ${i}_context *
- ${i}_get_by_idx(netsnmp_index * hdr)
- {
- return (const ${i}_context *)
- CONTAINER_FIND(cb.container, hdr );
- }
- @end@