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

