## -*- c -*-
######################################################################
## 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

/** other required module components */
config_require(${name}_access)
config_require(${name}_checkfns)

/* function declarations */
void init_$name(void);
@foreach $i table@
void initialize_table_$i(void);
Netsnmp_Node_Handler ${i}_handler;

@end@
@foreach $i table@

/* column number definitions for table $i */
#include "${name}_columns.h"
@run mib2c.column_defines.conf@

/* enum definions */
#include "${name}_enums.h"
@run mib2c.column_enums.conf@

@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"
#include "${name}_checkfns.h"
#include "${name}_access.h"

static netsnmp_oid_stash_node *undoStorage = NULL;
static netsnmp_oid_stash_node *commitStorage = NULL;

struct undoInfo {
   void *ptr;
   size_t len;
};

struct commitInfo {
   void *data_context;
   int have_committed;
   int new_row;
};

void
${name}_free_undoInfo(void *vptr) {
    struct undoInfo *ui = vptr;
    if (!ui)
        return;
    SNMP_FREE(ui->ptr);
    SNMP_FREE(ui);
}

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

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

    /** create the table registration information structures */
    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
    iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);

    my_handler = netsnmp_create_handler_registration("$i",
                                             ${i}_handler,
                                             ${i}_oid,
                                             OID_LENGTH(${i}_oid),
@if $i.settable@
                                             HANDLER_CAN_RWRITE
@else@
                                             HANDLER_CAN_RONLY
@end@
                                             );
            
    if (!my_handler || !table_info || !iinfo) {
        snmp_log(LOG_ERR, "malloc failed in initialize_table_$i");
        return; /** Serious error. */
    }

    /***************************************************
     * Setting up the table's definition
     */
    netsnmp_table_helper_add_indexes(table_info,
    @foreach $idx index@
                                  $idx.type, /** index: $idx */
    @end@
                             0);

    /** Define the minimum and maximum accessible columns.  This
        optimizes retrival. */
    @eval $minv = 0xffffffff@
    @eval $maxv = 0@
    @foreach $c column@
        @if $c.access =~ /(Read|Create)/@
          @eval $minv = min($minv, $c.subid)@
          @eval $maxv = max($maxv, $c.subid)@
        @end@
    @end@
    table_info->min_column = $minv;
    table_info->max_column = $maxv;

    /** iterator access routines */
    iinfo->get_first_data_point = ${i}_get_first_data_point;
    iinfo->get_next_data_point = ${i}_get_next_data_point;

    /** you may wish to set these as well */
#ifdef MAYBE_USE_THESE
    iinfo->make_data_context = ${i}_context_convert_function;
    iinfo->free_data_context = ${i}_data_free;

    /** pick *only* one of these if you use them */
    iinfo->free_loop_context = ${i}_loop_free;
    iinfo->free_loop_context_at_end = ${i}_loop_free;
#endif

    /** tie the two structures together */
    iinfo->table_reginfo = table_info;

    /***************************************************
     * registering the table with the master agent
     */
    DEBUGMSGTL(("initialize_table_$i",
                "Registering table $i as a table iterator\n"));		 
    netsnmp_register_table_iterator(my_handler, iinfo);
}
@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@
}
@foreach $i table@

/** handles requests for the $i table, if anything else needs to be done */
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;
    netsnmp_variable_list *var;
    struct commitInfo *ci = NULL;

    void *data_context = NULL;

    /** column and row index encoded portion */
    const oid * const suffix =
        requests->requestvb->name + reginfo->rootoid_len + 1;
    const size_t suffix_len = requests->requestvb->name_length -
        (reginfo->rootoid_len + 1);
    
    DEBUGMSGTL(("${name}:handler", "Processing request (%d)\n", reqinfo->mode));

    for(request = requests; request; request = request->next) {
        var = request->requestvb;
        if (request->processed != 0)
            continue;

        switch (reqinfo->mode) {
        case MODE_GET:
            data_context =  netsnmp_extract_iterator_context(request);
            if (data_context == NULL) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHINSTANCE);
                continue;
            }
            break;

@if $i.settable@
        case MODE_SET_RESERVE1:
            data_context =  netsnmp_extract_iterator_context(request);
@if !$i.creatable@
            if (data_context == NULL) {
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOCREATION);
                continue;
            }
@end@
            break;

        default: /* == the other SET modes */
            ci = netsnmp_oid_stash_get_data(commitStorage,
                                            suffix+1, suffix_len-1);
            break;
@end@
        }

        /** extracts the information about the table from the request */
        table_info = netsnmp_extract_table_info(request);
        /** table_info->colnum contains the column number requested */
        /** table_info->indexes contains a linked list of snmp variable
           bindings for the indexes of the table.  Values in the list
           have been set corresponding to the indexes of the
           request */
        if (table_info == NULL) {
            continue;
        }

        switch(reqinfo->mode) {
            case MODE_GET:
                switch(table_info->colnum) {
                    @foreach $c column@
                        @if $c.access =~ /(Read|Create)/@
                    case COLUMN_$c.uc:
                            {
                                $c.decl *retval;
                                size_t retval_len = 0;
                                retval = get_$c(data_context, &retval_len);
                                if (retval)
                                    snmp_set_var_typed_value(var, $c.type,
                                                             retval,
                                                             retval_len);
                            }
                        break;

                        @end@
                    @end@
                    default:
                /** We shouldn't get here */
                        snmp_log(LOG_ERR, "problem encountered in ${i}_handler: unknown column\n");
                }
                break;

@if $i.settable@
            case MODE_SET_RESERVE1:
                ci = netsnmp_oid_stash_get_data(commitStorage,
                                                suffix+1, suffix_len-1);
                
                if (!ci) {
                    /** create the commit storage info */
                    ci = SNMP_MALLOC_STRUCT(commitInfo);
                    if (!data_context) {
                        ci->data_context = ${i}_create_data_context(table_info->indexes, table_info->colnum);
                        ci->new_row = 1;
                    } else {
                        ci->data_context = data_context;
                    }
                    netsnmp_oid_stash_add_data(&commitStorage,
                                               suffix+1, suffix_len-1, ci);
                }
            break;
                
            case MODE_SET_RESERVE2:
                switch(table_info->colnum) {
                    @foreach $c column@
                        @if $c.access =~ /(Write|Create)/@
                          case COLUMN_$c.uc:
                            {
                                $c.decl *retval;
                                size_t retval_len = 0;
                                struct undoInfo *ui = NULL;
                                int ret;
                                
                    /** first, get the old value */
                                retval = get_$c(ci->data_context, &retval_len);
                                if (retval) {
                                    ui = SNMP_MALLOC_STRUCT(undoInfo);
                                    ui->len = retval_len;
                                    ui->ptr = netsnmp_memdup(retval, ui->len);
                                }

                    /** check the new value, possibly against the
                        older value for a valid state transition */
                                ret = check_$c(request->requestvb->type,
                                                   ($c.decl *) request->requestvb->val.string,
                                                   request->requestvb->val_len,
                                                   retval, retval_len);
                                if (ret != 0) {
                                    netsnmp_set_request_error(reqinfo, request,
                                                              ret);
                                    ${name}_free_undoInfo(ui);
                                } else if (ui) {
                        /** remember information for undo purposes later */
                                    netsnmp_oid_stash_add_data(&undoStorage,
                                                               suffix,
                                                               suffix_len,
                                                               ui);
                                }
                                
                            }
                            break;
                         @end@
                    @end@
                    default:
                       netsnmp_set_request_error(reqinfo, request,
                                                 SNMP_ERR_NOTWRITABLE);
                       break;
                 }
                break;

            case MODE_SET_ACTION:
            /** save a variable copy */
                switch(table_info->colnum) {
                    @foreach $c column@
                        @if $c.access =~ /(Write|Create)/@
                          case COLUMN_$c.uc:
                            {
                                int ret;
                                ret = set_$c(ci->data_context,
                                             ($c.decl *) request->requestvb->val.string,
                                             request->requestvb->val_len);
                                if (ret) {
                                    netsnmp_set_request_error(reqinfo, request,
                                                              ret);
                                }
                                @if $c.syntax eq "RowStatus"@
                                  if (*request->requestvb->val.integer ==
                                      RS_DESTROY) {
                                          ci->new_row = -1;
                                  }
                                @end@
                            }
                            break;
                         @end@
                    @end@
                 }
                break;

            case MODE_SET_COMMIT:
                if (!ci->have_committed) {
                    /** do this once per row only */
                    ${i}_commit_row(&ci->data_context, ci->new_row);
                    ci->have_committed = 1;
                }
                break;

            case MODE_SET_UNDO:
             /** save a variable copy */
                switch(table_info->colnum) {
                    @foreach $c column@
                        @if $c.access =~ /(Write|Create)/@
                          case COLUMN_$c.uc:
                            {
                                int retval;
                                struct undoInfo *ui;
                                ui = netsnmp_oid_stash_get_data(undoStorage,
                                                                suffix,
                                                                suffix_len);
                                retval = set_$c(ci->data_context, ui->ptr,
                                                ui->len);
                                if (retval) {
                                    netsnmp_set_request_error(reqinfo, request,
                                                              SNMP_ERR_UNDOFAILED);
                                }
                            }
                            break;
                        @end@
                    @end@
                }
                break;
                
            case MODE_SET_FREE:
                break;
@end@

            default:
                snmp_log(LOG_ERR, "problem encountered in ${i}_handler: unsupported mode\n");
        }
    }

@if $i.settable@
    /** clean up after all requset processing has ended */
    switch(reqinfo->mode) {
    case MODE_SET_UNDO:
    case MODE_SET_FREE:
    case MODE_SET_COMMIT:
        /** clear out the undo cache */
        netsnmp_oid_stash_free(&undoStorage, ${name}_free_undoInfo);
        netsnmp_oid_stash_free(&commitStorage, netsnmp_oid_stash_no_free);
    }
@end@

    return SNMP_ERR_NOERROR;
}
@end@
@run mib2c.check_values.conf@
@run mib2c.access_functions.conf@
@open -@

**********************************************************************
NOTE:  The only files you MUST modify should be the following:
  ${name}_access.c
  ${name}_access.h
  ${name}_checkfns_local.h
  ${name}_checkfns_local.c
**********************************************************************

