## -*- c -*-
#
@if "$cache" eq "" @
@open -@
This framework can work in one of two ways:

  1)  Hold a local cached copy of some external data
      which is then used to service incoming requests.

  2)  Query the external data directly for each request.

The first is typically more efficient, but results in
slightly "stale" data (depending on the expiration timeout
for the cache) and greater memory usage.  The second can
provide more up-to-date information, but at the cost of
higher processing overheads.

Which is more appropriate for your needs?
    @prompt $ans Select your choice : @
    @if $ans == 1 @
      @eval $cache = 1@
    @elsif $ans == 2@
      @eval $cache = 0@
    @else@
Invalid answer - generating caching code
      @eval $cache = 1@
    @end@
@else@       #  -S cache={something}
    @if "$cache" ne "1" && "$cache" ne "0" @
@open -@
Invalid value for 'cache' ($cache) - generating caching code
      @eval $cache = 1@
    @end@
@end@

######################################################################
## Do the .h file
######################################################################
@open ${name}.h@
/*
 * Note: this file originally auto-generated by mib2c using
 *  $Id$
 */
#ifndef $name.uc_H
#define $name.uc_H

/* function declarations */
void init_$name(void);
@foreach $i table@
void initialize_table_$i(void);
Netsnmp_Node_Handler ${i}_handler;
Netsnmp_First_Data_Point  ${i}_get_first_data_point;
Netsnmp_Next_Data_Point   ${i}_get_next_data_point;
@if "$cache" == 1 @
NetsnmpCacheLoad ${i}_load;
NetsnmpCacheFree ${i}_free;
#define $i.uc_TIMEOUT  60
@end@
@end@
@foreach $i table@

/* column number definitions for table $i */
    @foreach $c column@
       #define COLUMN_$c.uc		$c.subid
    @end@
@end@
#endif /* $name.uc_H */
######################################################################
## Do the .c file
######################################################################
@open ${name}.c@
/*
 * Note: this file originally auto-generated by mib2c using
 *  $Id$
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "${name}.h"

/** Initializes the $name module */
void
init_$name(void)
{
  /* here we initialize all the tables we're planning on supporting */
  @foreach $i table@
    initialize_table_$i();
  @end@
}

@foreach $i table@
  # Determine the first/last column names
  @eval $first_column = "-"@
  @eval $last_column = "-"@
  @foreach $c column@
    @if $c.readable@
      @if "$first_column" eq "-"@
        @eval $first_column = $c@
      @end@
      @eval $last_column = $c@
    @end@
  @end@

/** Initialize the $i table by defining its contents and how it's structured */
void
initialize_table_$i(void)
{
    const oid ${i}_oid[] = {$i.commaoid};
    const size_t ${i}_oid_len   = OID_LENGTH(${i}_oid);
    netsnmp_handler_registration    *reg;
    netsnmp_iterator_info           *iinfo;
    netsnmp_table_registration_info *table_info;

    DEBUGMSGTL(("${name}:init", "initializing table $i\n"));

    reg = netsnmp_create_handler_registration(
              "$i",     ${i}_handler,
              ${i}_oid, ${i}_oid_len,
@if $i.settable@
              HANDLER_CAN_RWRITE
@else@
              HANDLER_CAN_RONLY
@end@
              );

    table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
    netsnmp_table_helper_add_indexes(table_info,
    @foreach $idx index@
                           $idx.type,  /* index: $idx */
    @end@
                           0);
    table_info->min_column = COLUMN_$first_column.uc;
    table_info->max_column = COLUMN_$last_column.uc;
    
    iinfo = SNMP_MALLOC_TYPEDEF( netsnmp_iterator_info );
    iinfo->get_first_data_point = ${i}_get_first_data_point;
    iinfo->get_next_data_point  = ${i}_get_next_data_point;
    iinfo->table_reginfo        = table_info;
    
    netsnmp_register_table_iterator( reg, iinfo );
@if "$cache" == 1 @
    netsnmp_inject_handler_before( reg, 
        netsnmp_get_cache_handler($i.uc_TIMEOUT,
                                  ${i}_load, ${i}_free,
                                  ${i}_oid, ${i}_oid_len),
            TABLE_ITERATOR_NAME);
@end@

    /* Initialise the contents of the table here */
}

    /* Typical data structure for a row entry */
struct ${i}_entry {
    /* Index values */
    @foreach $idx index@
     @if $idx.needlength@
    $idx.decl $idx[NNN];
    size_t ${idx}_len;
     @else@
    $idx.decl $idx;
     @end@
    @end@

    /* Column values */
    @foreach $c column@
    @if $c.readable@
     @if $c.needlength@
    $c.decl $c[NNN];
    size_t ${c}_len;
     @else@
    $c.decl $c;
     @end@
     @if $c.settable@
      @if !$c.rowstatus@
       @if $c.needlength@
    $c.decl old_$c[NNN];
    size_t old_${c}_len;
       @else@
    $c.decl old_$c;
       @end@
      @end@
     @end@
    @end@
    @end@

    /* Illustrate using a simple linked list */
    int   valid;
    struct ${i}_entry *next;
};

struct ${i}_entry  *${i}_head;

/* create a new row in the (unsorted) table */
struct ${i}_entry *
${i}_createEntry(
  @foreach $idx index@
    @if $idx.needlength@
                 $idx.decl* $idx,
                 size_t ${idx}_len,
    @else@
                 $idx.decl  $idx,
    @end@
  @end@
                ) {
    struct ${i}_entry *entry;

    entry = SNMP_MALLOC_TYPEDEF(struct ${i}_entry);
    if (!entry)
        return NULL;

  @foreach $idx index@
   @if $idx.needlength@
    memcpy(entry->$idx, $idx, ${idx}_len);
    entry->${idx}_len = ${idx}_len;
   @else@
    entry->$idx = $idx;
   @end@
  @end@
    entry->next = ${i}_head;
    ${i}_head = entry;
    return entry;
}

/* remove a row from the table */
void
${i}_removeEntry( struct ${i}_entry *entry ) {
    struct ${i}_entry *ptr, *prev;

    if (!entry)
        return;    /* Nothing to remove */

    for ( ptr  = ${i}_head, prev = NULL;
          ptr != NULL;
          prev = ptr, ptr = ptr->next ) {
        if ( ptr == entry )
            break;
    }
    if ( !ptr )
        return;    /* Can't find it */

    if ( prev == NULL )
        ${i}_head = ptr->next;
    else
        prev->next = ptr->next;

    SNMP_FREE( entry );   /* XXX - release any other internal resources */
}

@if "$cache" == 1 @
/* Example cache handling - set up linked list from a suitable file */
int
${i}_load( netsnmp_cache *cache, void *vmagic ) {
    FILE *fp;
    struct ${i}_entry *this;
    char buf[STRMAX];

    /* The basic load routine template assumes that the data to
       be reported is held in a file - with one row of the file
       for each row of the table.
          If your data is available via a different API, you
       should amend this initial block (and the control of the
       'while' loop) accordingly.
          'XXX' marks where the template is incomplete and
       code will definitely need to be added. */

    fp = fopen( "/data/for/${i}", "r" );
    if ( !fp ) {
        return -1;
    }
    while ( fgets( buf, STRMAX, fp )) {
        this = SNMP_MALLOC_TYPEDEF( struct ${i}_entry );
        /* XXX - Unpick 'buf' to extract the individual field values
                 and then populate the 'this' data structure with them */

        this->next = ${i}_head;
        ${i}_head = this;    /* Iterate helper is fine with unordered lists! */
    }
    fclose(fp);
    return 0;  /* OK */
}

void
${i}_free( netsnmp_cache *cache, void *vmagic ) {
    struct ${i}_entry *this, *that;

    for ( this = ${i}_head; this; this=that ) {
        that = this->next;
        SNMP_FREE( this );   /* XXX - release any other internal resources */
    }
    ${i}_head = NULL;
}
@end@

/* Example iterator hook routines - using 'get_next' to do most of the work */
netsnmp_variable_list *
${i}_get_first_data_point(void **my_loop_context,
                          void **my_data_context,
                          netsnmp_variable_list *put_index_data,
                          netsnmp_iterator_info *mydata)
{
    *my_loop_context = ${i}_head;
    return ${i}_get_next_data_point(my_loop_context, my_data_context,
                                    put_index_data,  mydata );
}

netsnmp_variable_list *
${i}_get_next_data_point(void **my_loop_context,
                          void **my_data_context,
                          netsnmp_variable_list *put_index_data,
                          netsnmp_iterator_info *mydata)
{
    struct ${i}_entry *entry = (struct ${i}_entry *)*my_loop_context;
    netsnmp_variable_list *idx = put_index_data;

    if ( entry ) {
      @foreach $idx index@
        @if $idx.needlength@
        snmp_set_var_value( idx, entry->${idx}, sizeof(entry->${idx}) );
        @else@
        snmp_set_var_typed_integer( idx, $idx.type, entry->${idx} );
        @end@
        idx = idx->next_variable;
      @end@
        *my_data_context = (void *)entry;
        *my_loop_context = (void *)entry->next;
        return put_index_data;
    } else {
        return NULL;
    }
}


/** handles requests for the $i table */
int
${i}_handler(
    netsnmp_mib_handler               *handler,
    netsnmp_handler_registration      *reginfo,
    netsnmp_agent_request_info        *reqinfo,
    netsnmp_request_info              *requests) {

    netsnmp_request_info       *request;
    netsnmp_table_request_info *table_info;
    struct ${i}_entry          *table_entry;

    DEBUGMSGTL(("${name}:handler", "Processing request (%d)\n", reqinfo->mode));

    switch (reqinfo->mode) {
        /*
         * Read-support (also covers GetNext requests)
         */
    case MODE_GET:
        for (request=requests; request; request=request->next) {
            table_entry = (struct ${i}_entry *)
                              netsnmp_extract_iterator_context(request);
            table_info  =     netsnmp_extract_table_info(      request);
    
            switch (table_info->colnum) {
            @foreach $c column@
            @if $c.readable@
            case COLUMN_$c.uc:
                if ( !table_entry ) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_NOSUCHINSTANCE);
                    continue;
                }
            @if $c.needlength@
                snmp_set_var_typed_value( request->requestvb, $c.type,
                                          table_entry->$c,
                                          table_entry->${c}_len);
            @else@
                snmp_set_var_typed_integer( request->requestvb, $c.type,
                                            table_entry->$c);
            @end@
                break;
            @end@
            @end@
            default:
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHOBJECT);
                break;
            }
        }
        break;

@if $i.settable@
        /*
         * Write-support
         */
    case MODE_SET_RESERVE1:
        for (request=requests; request; request=request->next) {
            table_entry = (struct ${i}_entry *)
                              netsnmp_extract_iterator_context(request);
            table_info  =     netsnmp_extract_table_info(      request);
    
            switch (table_info->colnum) {
            @foreach $c column@
            @if $c.settable@
            case COLUMN_$c.uc:
            @if $c.rowstatus@
                ret = netsnmp_check_vb_rowstatus(request->requestvb,
                         (table_entry ? RS_ACTIVE : RS_NONEXISTENT ));
            @else@
            @if $c.needlength@
	        /* or possibly 'netsnmp_check_vb_type_and_size' */
                ret = netsnmp_check_vb_type_and_max_size(
                          request->requestvb, $c.type, sizeof(table_entry->$c));
            @else@
                /* or possibly 'netsnmp_check_vb_int_range' */
                ret = netsnmp_check_vb_int( request->requestvb );
            @end@
            @end@
                if ( ret != SNMP_ERR_NOERROR ) {
                    netsnmp_set_request_error( reqinfo, request, ret );
                    return SNMP_ERR_NOERROR;
                }
                break;
            @end@
            @end@
            default:
                netsnmp_set_request_error( reqinfo, request,
                                           SNMP_ERR_NOTWRITABLE );
                return SNMP_ERR_NOERROR;
            }
        }
        break;

    case MODE_SET_RESERVE2:
@if $i.creatable@
        for (request=requests; request; request=request->next) {
            table_entry = (struct ${i}_entry *)
                              netsnmp_extract_iterator_context(request);
            table_info  =     netsnmp_extract_table_info(      request);
    
            switch (table_info->colnum) {
@if $i.rowstatus@
            @foreach $c column@
            @if $c.rowstatus@
            case COLUMN_$c.uc:
                switch (*request->requestvb->val.integer) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    table_row = ${i}_createEntry(
  @foreach $idx index@
    @if $idx.needlength@
                        ,  table_info->indexes->val.string
                        ,  table_info->indexes->val_len
    @else@
                        , *table_info->indexes->val.integer
    @end@
  @end@
                        );
                    if (table_row) {
                        netsnmp_insert_iterator_context( request, table_row );
                    } else {
                        netsnmp_set_request_error( reqinfo, request,
                                                   SNMP_ERR_RESOURCEUNAVAILABLE );
                        return SNMP_ERR_NOERROR;
                    }
                }
            @end@
            @end@
@else@
            @foreach $c column@
            @if $c.creatable@
            case COLUMN_$c.uc:
            @end@
            @end@
                if ( !table_row ) {
                    table_row = ${i}_createEntry(
  @foreach $idx index@
    @if $idx.needlength@
                        ,  table_info->indexes->val.string
                        ,  table_info->indexes->val_len
    @else@
                        , *table_info->indexes->val.integer
    @end@
  @end@
                        );
                    if (table_row) {
                        netsnmp_insert_iterator_context( request, table_row );
                    } else {
                        netsnmp_set_request_error( reqinfo, request,
                                                   SNMP_ERR_RESOURCEUNAVAILABLE );
                        return SNMP_ERR_NOERROR;
                    }
                }
                break;
@end@
            }
        }
@end@
        break;

    case MODE_SET_FREE:
@if $i.creatable@
        for (request=requests; request; request=request->next) {
            table_entry = (struct ${i}_entry *)
                              netsnmp_extract_iterator_context(request);
            table_info  =     netsnmp_extract_table_info(      request);
    
            switch (table_info->colnum) {
@if $i.rowstatus@
            @foreach $c column@
            @if $c.rowstatus@
            case COLUMN_$c.uc:
                switch (*request->requestvb->val.integer) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    if (table_entry && !table_entry->valid) {
                        ${i}_removeEntry(table_data, table_row );
                    }
                }
            @end@
            @end@
@else@
            @foreach $c column@
            @if $c.creatable@
            case COLUMN_$c.uc:
            @end@
            @end@
                if ( table_entry && !table_entry->valid ) {
                    ${i}_removeEntry(table_data, table_row );
                }
                break;
@end@
            }
        }
@end@
        break;

    case MODE_SET_ACTION:
        for (request=requests; request; request=request->next) {
            table_entry = (struct ${i}_entry *)
                              netsnmp_extract_iterator_context(request);
            table_info  =     netsnmp_extract_table_info(      request);
    
            switch (table_info->colnum) {
            @foreach $c column@
            @if $c.settable@
            @if !$c.rowstatus@
            case COLUMN_$c.uc:
                @if $c.needlength@
                memcpy( table_entry->old_$c,
                        table_entry->$c,
                        sizeof(table_entry->$c));
                table_entry->old_${c}_len =
                        table_entry->${c}_len;
                memset( table_entry->$c, 0,
                        sizeof(table_entry->$c));
                memcpy( table_entry->$c,
                        request->requestvb->val.string,
                        request->requestvb->val_len);
                table_entry->${c}_len =
                        request->requestvb->val_len;
                @else@
                table_entry->old_$c = table_entry->$c;
                table_entry->$c     = *request->requestvb->val.integer;
                @end@
                break;
            @end@
            @end@
            @end@
            }
        }
@if $i.rowstatus@
        /* Check the internal consistency of an active row */
        for (request=requests; request; request=request->next) {
            table_entry = (struct ${i}_entry *)
                              netsnmp_extract_iterator_context(request);
            table_info  =     netsnmp_extract_table_info(      request);
    
            switch (table_info->colnum) {
            @foreach $c column@
            @if $c.rowstatus@
            case COLUMN_$c.uc:
                switch (*request->requestvb->val.integer) {
                case RS_ACTIVE:
                case RS_CREATEANDGO:
                    if (/* XXX */) {
                        netsnmp_set_request_error( reqinfo, request,
                                                   SNMP_ERR_INCONSISTENTVALUE );
                        return SNMP_ERR_NOERROR;
                    }
                }
            @end@
            @end@
            }
        }
@end@
        break;

    case MODE_SET_UNDO:
        for (request=requests; request; request=request->next) {
            table_entry = (struct ${i}_entry *)
                              netsnmp_extract_iterator_context(request);
            table_info  =     netsnmp_extract_table_info(      request);
    
            switch (table_info->colnum) {
            @foreach $c column@
            @if $c.settable@
            case COLUMN_$c.uc:
@if $i.rowstatus@
  @if $c.rowstatus@
                switch (*request->requestvb->val.integer) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    if (table_entry && !table_entry->valid) {
                        ${i}_removeEntry(table_data, table_row );
                    }
                }
  @else@
                @if $c.needlength@
                memcpy( table_entry->$c,
                        table_entry->old_$c,
                        sizeof(table_entry->$c));
                memset( table_entry->old_$c, 0,
                        sizeof(table_entry->$c));
                table_entry->${c}_len =
                        table_entry->old_${c}_len;
                @else@
                table_entry->$c     = table_entry->old_$c;
                table_entry->old_$c = 0;
                @end@
  @end@
@else@
  @if $c.creatable@
                if ( table_entry && !table_entry->valid ) {
                    ${i}_removeEntry(table_data, table_row );
                } else {
                    @if $c.needlength@
                    memcpy( table_entry->$c,
                            table_entry->old_$c,
                            sizeof(table_entry->$c));
                    memset( table_entry->old_$c, 0,
                            sizeof(table_entry->$c));
                    table_entry->${c}_len =
                            table_entry->old_${c}_len;
                    @else@
                    table_entry->$c     = table_entry->old_$c;
                    table_entry->old_$c = 0;
                    @end@
                }
  @else@
                @if $c.needlength@
                memcpy( table_entry->$c,
                        table_entry->old_$c,
                        sizeof(table_entry->$c));
                memset( table_entry->old_$c, 0,
                        sizeof(table_entry->$c));
                table_entry->${c}_len =
                        table_entry->old_${c}_len;
                @else@
                table_entry->$c     = table_entry->old_$c;
                table_entry->old_$c = 0;
                @end@
  @end@
@end@
                break;
            @end@
            @end@
            }
        }
        break;

    case MODE_SET_COMMIT:
@if $i.creatable@
        for (request=requests; request; request=request->next) {
            table_entry = (struct ${i}_entry *)
                              netsnmp_extract_iterator_context(request);
            table_info  =     netsnmp_extract_table_info(      request);
    
            switch (table_info->colnum) {
@if $i.rowstatus@
            @foreach $c column@
            @if $c.rowstatus@
            case COLUMN_$c.uc:
                switch (*request->requestvb->val.integer) {
                case RS_CREATEANDGO:
                    table_entry->valid = 1;
                    /* Fall-through */
                case RS_ACTIVE:
                    table_entry->$c = RS_ACTIVE;
                    break;

                case RS_CREATEANDWAIT:
                    table_entry->valid = 1;
                    /* Fall-through */
                case RS_NOTINSERVICE:
                    table_entry->$c = RS_NOTINSERVICE;
                    break;

                case RS_DESTROY:
                    ${i}_removeEntry(table_data, table_row );
                }
            @end@
            @end@
@else@
            @foreach $c column@
            @if $c.creatable@
            case COLUMN_$c.uc:
            @end@
            @end@
                if ( table_entry && !table_entry->valid ) {
                    table_entry->valid = 1;
                }
@end@
            }
        }
@end@
        break;
@end@
    }
    return SNMP_ERR_NOERROR;
}
@end@
