## -*- 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)
{
    static oid ${i}_oid[] = {$i.commaoid};
    netsnmp_table_registration_info *table_info;
    netsnmp_handler_registration *my_handler;
    netsnmp_iterator_info *iinfo;

    /** 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;

    oid *suffix;
    size_t suffix_len;

    /** column and row index encoded portion */
    suffix = requests->requestvb->name + reginfo->rootoid_len + 1;
    suffix_len = requests->requestvb->name_length -
        (reginfo->rootoid_len + 1);
    
    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,
                                                         (const u_char *) 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
**********************************************************************

