## -*- 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 retrieval. */
    @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
**********************************************************************

