## -*- 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)
{
    static oid ${i}_oid[] = {$i.commaoid};
    size_t ${i}_oid_len   = OID_LENGTH(${i}_oid);
    netsnmp_handler_registration    *reg;
    struct ${i}_entry               *row;
    netsnmp_variable_list           *idxs;
    netsnmp_table_registration_info *table_info;

    reg = netsnmp_create_handler_registration(
              "$i",     ${i}_handler,
              ${i}_oid, ${i}_oid_len,
@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, (u_char*)row->$idx,
                                                      row->${idx}_len);
   @else@
    snmp_set_var_typed_integer( v2, $idx.type, (u_char*)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;

    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,
                                 (u_char*)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@
