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

/* function declarations */
void init_$name(void);
@foreach $i table@
void initialize_table_$i(void);
Netsnmp_Node_Handler ${i}_handler;
netsnmp_variable_list *${i}_buildIndexList(struct ${i}_entry *row);
struct ${i}_entry *
${i}_createEntry(
  @foreach $idx index@
    @if $idx.needlength@
                 , $idx.decl* $idx
                 , size_t ${idx}_len
    @else@
                 , $idx.decl  $idx
    @end@
  @end@
                );
@end@
@foreach $i table@

/* column number definitions for table $i */
    @foreach $c column@
       #define COLUMN_$c.uc		$c.subid
    @end@


/* Typical data structure for a row entry */
struct ${i}_entry {
    netsnmp_index oid_index;

    /* Index values */
    @foreach $idx index@
     @if $idx.needlength@
    $idx.decl $idx[NNN];
    size_t ${idx}_len;
     @else@
    $idx.decl $idx;
     @end@
    @end@

    /* Column values */
    @foreach $c column@
    @if $c.readable@
     @if $c.needlength@
    $c.decl $c[NNN];
    size_t ${c}_len;
     @else@
    $c.decl $c;
     @end@
     @if $c.settable@
      @if !$c.rowstatus@
       @if $c.needlength@
    $c.decl old_$c[NNN];
    size_t old_${c}_len;
       @else@
    $c.decl old_$c;
       @end@
      @end@
     @end@
    @end@
    @end@

    int   valid;
};

@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"

/** Initializes the $name module */
void
init_$name(void)
{
  /* here we initialize all the table rows we're planning on supporting */
  @foreach $i table@
    initialize_table_$i();
  @end@
}

@foreach $i table@
  @eval $first_column = "-"@
  @eval $last_column = "-"@
  @foreach $c column@
    @if $c.readable@
      @if "$first_column" eq "-"@
        @eval $first_column = $c@
      @end@
      @eval $last_column = $c@
    @end@
  @end@

/** Initialize an entry in the $i table, including how the table is structured */
void
initialize_table_$i(void)
{
    const oid ${i}_oid[] = {$i.commaoid};
    netsnmp_handler_registration    *reg;
    struct ${i}_entry               *row;
    netsnmp_variable_list           *idxs;
    netsnmp_table_registration_info *table_info;

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

    reg = netsnmp_create_handler_registration(
              "$i",     ${i}_handler,
              ${i}_oid, OID_LENGTH(${i}_oid),
@if $i.settable@
              HANDLER_CAN_RWRITE
@else@
              HANDLER_CAN_RONLY
@end@
              );

    table_info = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
    netsnmp_table_helper_add_indexes(table_info,
    @foreach $idx index@
                           $idx.type,  /* index: $idx */
    @end@
                           0);
    table_info->min_column = COLUMN_$first_column.uc;
    table_info->max_column = COLUMN_$last_column.uc;

    /*
     * Create the row to be registered
     */
    row = ${i}_createEntry(
    @foreach $idx index@
      @if $idx.needlength@
                 ,/* $idx value */ , /* $idx length */
      @else@
                 ,/* $idx value */
      @end@
    @end@
    );
    /*
     * XXX: Set any other readable column values here
     */
    idxs = ${i}_buildIndexList(row);
    netsnmp_table_row_register( reg, table_info, row, idxs );

    /* Repeat for any other rows to be registered */
}

/* create a new row in the table */
struct ${i}_entry *
${i}_createEntry(
  @foreach $idx index@
    @if $idx.needlength@
                 , $idx.decl* $idx
                 , size_t ${idx}_len
    @else@
                 , $idx.decl  $idx
    @end@
  @end@
                ) {
    struct ${i}_entry *entry;

    entry = SNMP_MALLOC_TYPEDEF(struct ${i}_entry);
    if (!entry)
        return NULL;

  @foreach $idx index@
   @if $idx.needlength@
    memcpy(entry->$idx, $idx, ${idx}_len);
    entry->${idx}_len = ${idx}_len;
   @else@
    entry->$idx = $idx;
   @end@
  @end@

    return entry;
}

netsnmp_variable_list *
${i}_buildIndexList(struct ${i}_entry *row)
{
    netsnmp_variable_list *v1 = NULL, *v2;

    if (!row)
        return NULL;

  @eval $first=1@
  @foreach $idx index@
   @if $first==1@
    v1 = SNMP_MALLOC_TYPEDEF(netsnmp_variable_list);
    v2 = v1;
   @else@
    v2->next_variable = SNMP_MALLOC_TYPEDEF(netsnmp_variable_list);
    v2 = v2->next_variable;
   @end@
   @if $idx.needlength@
    snmp_set_var_typed_value( v2, $idx.type, row->$idx, row->${idx}_len);
   @else@
    snmp_set_var_typed_integer( v2, $idx.type, row->$idx);
   @end@
   @eval $first=0@
  @end@

    return v1;
}

/** handles requests for a row of the $i table */
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_table_data         *table_data;
    struct ${i}_entry          *table_entry;
    int                         ret;

    DEBUGMSGTL(("${name}:handler", "Processing request (%d)\n", reqinfo->mode));

    switch (reqinfo->mode) {
        /*
         * Read-support (also covers GetNext requests)
         */
    case MODE_GET:
        for (request=requests; request; request=request->next) {
            table_entry = (struct ${i}_entry *)
                              netsnmp_table_row_extract(request);
    
            switch (request->requestvb->name[$i.oidlength+1]) {
            @foreach $c column@
            @if $c.readable@
            case COLUMN_$c.uc:
            @if $c.needlength@
                snmp_set_var_typed_value( request->requestvb, $c.type,
                                          table_entry->$c,
                                          table_entry->${c}_len);
            @else@
                snmp_set_var_typed_integer( request->requestvb, $c.type,
                                            table_entry->$c);
            @end@
                break;
            @end@
            @end@
            default:
                /* An unsupported/unreadable column (if applicable) */
                snmp_set_var_typed_value( request->requestvb, SNMP_NOSUCHOBJECT,
                                          NULL, 0 );
            }
        }
        break;

@if $i.settable@
        /*
         * Write-support - TODO
         */
@end@
        break;
@end@
    }
    return SNMP_ERR_NOERROR;
}
@end@
