## -*- c -*-
######################################################################
## Do the .h file
######################################################################
@open ${name}.h@
/*
 * Note: this file originally auto-generated by mib2c using
 *  $Id: mib2c.raw-table.conf 17436 2009-03-31 15:12:19Z dts12 $
 */
#ifndef $name.uc_H
#define $name.uc_H

void init_$name(void);

#endif /* $name.uc_H */
######################################################################
## Do the .c file
######################################################################
@open ${name}.c@
/*
 * Note: this file originally auto-generated by mib2c using
 *  $Id: mib2c.raw-table.conf 17436 2009-03-31 15:12:19Z dts12 $
 */

#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"

@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@

/* column number definitions for table $i */
  @foreach $c column@
#define COLUMN_$c.uc		$c.subid
  @end@

    /* 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 nonindex@
    @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@

    int   valid;
};

/* create a new row in the table */
static struct ${i}_entry *
${i}_createEntry( int dummy
  @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;

    /* XXX - insert entry into local data structure */
    return entry;
}

/* remove a row from the table */
static void
${i}_removeEntry(struct ${i}_entry *entry) {
    if (!entry)
        return;    /* Nothing to remove */

    /* XXX - remove entry from local data structure */

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


/** determine the appropriate row for an exact request */
static struct ${i}_entry *
${i}_get_entry( netsnmp_variable_list *indexes ) {
    struct ${i}_entry *row = NULL;

    /* XXX - Use the 'indexes' parameter to retrieve the data
       structure for the requested row, and return this. */
    return row;
}

/** determine the appropriate row for an fuzzy request */
static struct ${i}_entry *
${i}_get_next_entry( netsnmp_handler_registration *reginfo,
                     netsnmp_request_info         *request,
                     int                           column,
                     netsnmp_variable_list        *indexes ) {
    struct ${i}_entry *row = NULL;
    oid             build_space[MAX_OID_LEN];
    size_t          build_space_len = 0;
    size_t          index_oid_len = 0;

    /* XXX - Use the 'indexes' parameter to identify the
             next row in the table.... */

    /* XXX   .... update the 'indexes' parameter with the
             appropriate index values ... */

    /* ... and update the requested OID to match this instance */
    memcpy(build_space, reginfo->rootoid,   /* registered oid */
                        reginfo->rootoid_len * sizeof(oid));
    build_space_len = reginfo->rootoid_len;
    build_space[build_space_len++] = 1;  /* entry */
    build_space[build_space_len++] = column; /* column */
    build_oid_noalloc(build_space + build_space_len,
                      MAX_OID_LEN - build_space_len, &index_oid_len,
                      NULL, 0, indexes);
    snmp_set_var_objid(request->requestvb, build_space,
                       build_space_len + index_oid_len);

    /*  Finally, return the data structure for this row */
    return row;
}


/** handles requests for the $i table */
static 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;
    @if $i.settable@
    int                         ret;
    @end@

    switch (reqinfo->mode) {
        /*
         * Read-support
         */
    case MODE_GET:
        for (request=requests; request; request=request->next) {
            table_info  =     netsnmp_extract_table_info( request);
            table_entry =     ${i}_get_entry( table_info->indexes );
    
            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;

    case MODE_GETNEXT:
        for (request=requests; request; request=request->next) {
            table_info  =     netsnmp_extract_table_info( request);
            table_entry =     ${i}_get_next_entry( reginfo, request,
                                   table_info->colnum, table_info->indexes );
    
            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_info  =     netsnmp_extract_table_info( request);
            table_entry =     ${i}_get_entry( table_info->indexes );
    
            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_info = netsnmp_extract_table_info( request);
            table_entry =     ${i}_get_entry( table_info->indexes );
    
            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_entry = ${i}_createEntry( 0
  @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_entry ) {
                        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_entry ) {
                    table_entry = ${i}_createEntry( 0
  @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_entry ) {
                        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_info  =     netsnmp_extract_table_info( request);
            table_entry =     ${i}_get_entry( table_info->indexes );
    
            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_entry);
                    }
                }
            @end@
            @end@
@else@
            @foreach $c column@
            @if $c.creatable@
            case COLUMN_$c.uc:
            @end@
            @end@
                if ( table_entry && !table_entry->valid ) {
                    ${i}_removeEntry(table_entry);
                }
                break;
@end@
            }
        }
@end@
        break;

    case MODE_SET_ACTION:
        for (request=requests; request; request=request->next) {
            table_info  =     netsnmp_extract_table_info( request);
            table_entry =     ${i}_get_entry( table_info->indexes );
    
            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_info  =     netsnmp_extract_table_info( request);
            table_entry =     ${i}_get_entry( table_info->indexes );
    
            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_info  =     netsnmp_extract_table_info( request);
            table_entry =     ${i}_get_entry( table_info->indexes );
    
            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_entry);
                    }
                }
  @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_entry);
                } 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_info  =     netsnmp_extract_table_info(    request);
            table_entry =     ${i}_get_entry( table_info->indexes );
    
            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_entry);
                }
            @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;
}

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

    reg = netsnmp_create_handler_registration(
              "$i",     ${i}_handler,
              ${i}_oid, OID_LENGTH(${i}_oid),
@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;

    netsnmp_register_table( reg, table_info );

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

@end@
/** 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@
}
