## -*- 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;
                                    memdup((u_char **) &ui->ptr,
                                           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
**********************************************************************

