
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-features.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/watcher.h>
#include <net-snmp/agent/agent_callbacks.h>

#include "agent/extend.h"
#include "utilities/execute.h"
#include "struct.h"

#ifndef USING_UCD_SNMP_EXTENSIBLE_MODULE
#include "util_funcs/header_simple_table.h"
#include "mibdefs.h"
#define SHELLCOMMAND 3
#endif

netsnmp_feature_require(extract_table_row_data)
netsnmp_feature_require(table_data_delete_table)
#ifndef NETSNMP_NO_WRITE_SUPPORT
netsnmp_feature_require(insert_table_row)
#endif /* NETSNMP_NO_WRITE_SUPPORT */

oid  ns_extend_oid[]    = { 1, 3, 6, 1, 4, 1, 8072, 1, 3, 2 };
oid  extend_count_oid[] = { 1, 3, 6, 1, 4, 1, 8072, 1, 3, 2, 1 };
oid  extend_config_oid[] = { 1, 3, 6, 1, 4, 1, 8072, 1, 3, 2, 2 };
oid  extend_out1_oid[]  = { 1, 3, 6, 1, 4, 1, 8072, 1, 3, 2, 3 };
oid  extend_out2_oid[]  = { 1, 3, 6, 1, 4, 1, 8072, 1, 3, 2, 4 };

typedef struct extend_registration_block_s {
    netsnmp_table_data *dinfo;
    oid                *root_oid;
    size_t              oid_len;
    long                num_entries;
    netsnmp_extend     *ehead;
    netsnmp_handler_registration       *reg[4];
    struct extend_registration_block_s *next;
} extend_registration_block;
extend_registration_block *ereg_head = NULL;


#ifndef USING_UCD_SNMP_EXTENSIBLE_MODULE
typedef struct netsnmp_old_extend_s {
    unsigned int idx;
    netsnmp_extend *exec_entry;
    netsnmp_extend *efix_entry;
} netsnmp_old_extend;

unsigned int             num_compatability_entries = 0;
unsigned int             max_compatability_entries = 50;
netsnmp_old_extend *compatability_entries;

char           *cmdlinebuf;
size_t          cmdlinesize;

WriteMethod fixExec2Error;
FindVarMethod var_extensible_old;
oid  old_extensible_variables_oid[] = { NETSNMP_UCDAVIS_MIB, NETSNMP_SHELLMIBNUM, 1 };
#ifndef NETSNMP_NO_WRITE_SUPPORT
struct variable2 old_extensible_variables[] = {
    {MIBINDEX,     ASN_INTEGER,   NETSNMP_OLDAPI_RONLY,
     var_extensible_old, 1, {MIBINDEX}},
    {ERRORNAME,    ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_extensible_old, 1, {ERRORNAME}},
    {SHELLCOMMAND, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_extensible_old, 1, {SHELLCOMMAND}},
    {ERRORFLAG,    ASN_INTEGER,   NETSNMP_OLDAPI_RONLY,
     var_extensible_old, 1, {ERRORFLAG}},
    {ERRORMSG,     ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_extensible_old, 1, {ERRORMSG}},
    {ERRORFIX,     ASN_INTEGER,  NETSNMP_OLDAPI_RWRITE,
     var_extensible_old, 1, {ERRORFIX}},
    {ERRORFIXCMD,  ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_extensible_old, 1, {ERRORFIXCMD}}
};
#else /* !NETSNMP_NO_WRITE_SUPPORT */
struct variable2 old_extensible_variables[] = {
    {MIBINDEX,     ASN_INTEGER,   NETSNMP_OLDAPI_RONLY,
     var_extensible_old, 1, {MIBINDEX}},
    {ERRORNAME,    ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_extensible_old, 1, {ERRORNAME}},
    {SHELLCOMMAND, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_extensible_old, 1, {SHELLCOMMAND}},
    {ERRORFLAG,    ASN_INTEGER,   NETSNMP_OLDAPI_RONLY,
     var_extensible_old, 1, {ERRORFLAG}},
    {ERRORMSG,     ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_extensible_old, 1, {ERRORMSG}},
    {ERRORFIX,     ASN_INTEGER,  NETSNMP_OLDAPI_RONLY,
     var_extensible_old, 1, {ERRORFIX}},
    {ERRORFIXCMD,  ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_extensible_old, 1, {ERRORFIXCMD}}
};
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
#endif


        /*************************
         *
         *  Main initialisation routine
         *
         *************************/

extend_registration_block *
_find_extension_block( oid *name, size_t name_len )
{
    extend_registration_block         *eptr;
    size_t len;
    for ( eptr=ereg_head; eptr; eptr=eptr->next ) {
        len = SNMP_MIN(name_len, eptr->oid_len);
        if (!snmp_oid_compare( name, len, eptr->root_oid, eptr->oid_len))
            return eptr;
    }
    return NULL;
}

extend_registration_block *
_register_extend( oid *base, size_t len )
{
    extend_registration_block         *eptr;
    oid oid_buf[MAX_OID_LEN];

    netsnmp_table_data                *dinfo;
    netsnmp_table_registration_info   *tinfo;
    netsnmp_watcher_info              *winfo;
    netsnmp_handler_registration      *reg = NULL;
    int                                rc;

    for ( eptr=ereg_head; eptr; eptr=eptr->next ) {
        if (!snmp_oid_compare( base, len, eptr->root_oid, eptr->oid_len))
            return eptr;
    }
    if (!eptr) {
        eptr = SNMP_MALLOC_TYPEDEF( extend_registration_block );
        if (!eptr)
            return NULL;
        eptr->root_oid = snmp_duplicate_objid( base, len );
        eptr->oid_len  = len;
        eptr->num_entries = 0;
        eptr->ehead       = NULL;
        eptr->dinfo       = netsnmp_create_table_data( "nsExtendTable" );
        eptr->next        = ereg_head;
        ereg_head         = eptr;
    }

    dinfo = eptr->dinfo;
    memcpy( oid_buf, base, len*sizeof(oid) );

        /*
         * Register the configuration table
         */
    tinfo = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
    netsnmp_table_helper_add_indexes( tinfo, ASN_OCTET_STR, 0 );
    tinfo->min_column = COLUMN_EXTCFG_FIRST_COLUMN;
    tinfo->max_column = COLUMN_EXTCFG_LAST_COLUMN;
    oid_buf[len] = 2;
#ifndef NETSNMP_NO_WRITE_SUPPORT
    reg   = netsnmp_create_handler_registration(
                "nsExtendConfigTable", handle_nsExtendConfigTable, 
                oid_buf, len+1, HANDLER_CAN_RWRITE);
#else /* !NETSNMP_NO_WRITE_SUPPORT */
    reg   = netsnmp_create_handler_registration(
                "nsExtendConfigTable", handle_nsExtendConfigTable, 
                oid_buf, len+1, HANDLER_CAN_RONLY);
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
    rc = netsnmp_register_table_data( reg, dinfo, tinfo );
    if (rc != SNMPERR_SUCCESS) {
        goto bail;
    }
    netsnmp_handler_owns_table_info(reg->handler->next);
    eptr->reg[0] = reg;

        /*
         * Register the main output table
         *   using the same table_data handle.
         * This is sufficient to link the two tables,
         *   and implement the AUGMENTS behaviour
         */
    tinfo = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
    netsnmp_table_helper_add_indexes( tinfo, ASN_OCTET_STR, 0 );
    tinfo->min_column = COLUMN_EXTOUT1_FIRST_COLUMN;
    tinfo->max_column = COLUMN_EXTOUT1_LAST_COLUMN;
    oid_buf[len] = 3;
    reg   = netsnmp_create_handler_registration(
                "nsExtendOut1Table", handle_nsExtendOutput1Table, 
                oid_buf, len+1, HANDLER_CAN_RONLY);
    rc = netsnmp_register_table_data( reg, dinfo, tinfo );
    if (rc != SNMPERR_SUCCESS)
        goto bail;
    netsnmp_handler_owns_table_info(reg->handler->next);
    eptr->reg[1] = reg;

        /*
         * Register the multi-line output table
         *   using a simple table helper.
         * This handles extracting the indexes from
         *   the request OID, but leaves most of
         *   the work to our handler routine.
         * Still, it was nice while it lasted...
         */
    tinfo = SNMP_MALLOC_TYPEDEF( netsnmp_table_registration_info );
    netsnmp_table_helper_add_indexes( tinfo, ASN_OCTET_STR, ASN_INTEGER, 0 );
    tinfo->min_column = COLUMN_EXTOUT2_FIRST_COLUMN;
    tinfo->max_column = COLUMN_EXTOUT2_LAST_COLUMN;
    oid_buf[len] = 4;
    reg   = netsnmp_create_handler_registration(
                "nsExtendOut2Table", handle_nsExtendOutput2Table, 
                oid_buf, len+1, HANDLER_CAN_RONLY);
    rc = netsnmp_register_table( reg, tinfo );
    if (rc != SNMPERR_SUCCESS)
        goto bail;
    netsnmp_handler_owns_table_info(reg->handler->next);
    eptr->reg[2] = reg;

        /*
         * Register a watched scalar to keep track of the number of entries
         */
    oid_buf[len] = 1;
    reg   = netsnmp_create_handler_registration(
                "nsExtendNumEntries", NULL, 
                oid_buf, len+1, HANDLER_CAN_RONLY);
    winfo = netsnmp_create_watcher_info(
                &(eptr->num_entries), sizeof(eptr->num_entries),
                ASN_INTEGER, WATCHER_FIXED_SIZE);
    rc = netsnmp_register_watched_scalar2( reg, winfo );
    if (rc != SNMPERR_SUCCESS)
        goto bail;
    eptr->reg[3] = reg;

    return eptr;

bail:
    if (eptr->reg[3])
        netsnmp_unregister_handler(eptr->reg[3]);
    if (eptr->reg[2])
        netsnmp_unregister_handler(eptr->reg[2]);
    if (eptr->reg[1])
        netsnmp_unregister_handler(eptr->reg[1]);
    if (eptr->reg[0])
        netsnmp_unregister_handler(eptr->reg[0]);
    return NULL;
}

static void
_unregister_extend(extend_registration_block *eptr)
{
    extend_registration_block *prev;

    netsnmp_assert(eptr);
    for (prev = ereg_head; prev && prev->next != eptr; prev = prev->next)
	;
    if (prev) {
        netsnmp_assert(eptr == prev->next);
	prev->next = eptr->next;
    } else {
        netsnmp_assert(eptr == ereg_head);
	ereg_head = eptr->next;
    }

    netsnmp_table_data_delete_table(eptr->dinfo);
    free(eptr->root_oid);
    free(eptr);
}

int
extend_clear_callback(int majorID, int minorID,
                    void *serverarg, void *clientarg)
{
    extend_registration_block *eptr, *enext = NULL;

    for ( eptr=ereg_head; eptr; eptr=enext ) {
        enext=eptr->next;
        netsnmp_unregister_handler( eptr->reg[0] );
        netsnmp_unregister_handler( eptr->reg[1] );
        netsnmp_unregister_handler( eptr->reg[2] );
        netsnmp_unregister_handler( eptr->reg[3] );
        SNMP_FREE(eptr);
    }
    ereg_head = NULL;
    return 0;
}

void init_extend( void )
{
    snmpd_register_config_handler("extend",    extend_parse_config, NULL, NULL);
    snmpd_register_config_handler("extend-sh", extend_parse_config, NULL, NULL);
    snmpd_register_config_handler("extendfix", extend_parse_config, NULL, NULL);
    snmpd_register_config_handler("exec2", extend_parse_config, NULL, NULL);
    snmpd_register_config_handler("sh2",   extend_parse_config, NULL, NULL);
    snmpd_register_config_handler("execFix2", extend_parse_config, NULL, NULL);
    (void)_register_extend( ns_extend_oid, OID_LENGTH(ns_extend_oid));

#ifndef USING_UCD_SNMP_EXTENSIBLE_MODULE
    snmpd_register_config_handler("exec", extend_parse_config, NULL, NULL);
    snmpd_register_config_handler("sh",   extend_parse_config, NULL, NULL);
    snmpd_register_config_handler("execFix", extend_parse_config, NULL, NULL);
    compatability_entries = (netsnmp_old_extend *)
        calloc( max_compatability_entries, sizeof(netsnmp_old_extend));
    REGISTER_MIB("ucd-extensible", old_extensible_variables,
                 variable2, old_extensible_variables_oid);
#endif

    snmp_register_callback(SNMP_CALLBACK_APPLICATION,
                           SNMPD_CALLBACK_PRE_UPDATE_CONFIG,
                           extend_clear_callback, NULL);
}

void
shutdown_extend(void)
{
#ifndef USING_UCD_SNMP_EXTENSIBLE_MODULE
    free(compatability_entries);
    compatability_entries = NULL;
#endif
    while (ereg_head)
	_unregister_extend(ereg_head);
}

        /*************************
         *
         *  Cached-data hooks
         *  see 'cache_handler' helper
         *
         *************************/

int
extend_load_cache(netsnmp_cache *cache, void *magic)
{
#ifndef USING_UTILITIES_EXECUTE_MODULE
    NETSNMP_LOGONCE((LOG_WARNING,"support for run_exec_command not available\n"));
    return -1;
#else
    int  out_len = 1024*100;
    char out_buf[ 1024*100 ];
    int  cmd_len = 255*2 + 2;	/* 2 * DisplayStrings */
    char cmd_buf[ 255*2 + 2 ];
    int  ret;
    char *cp;
    char *line_buf[ 1024 ];
    netsnmp_extend *extension = (netsnmp_extend *)magic;

    if (!magic)
        return -1;
    DEBUGMSGTL(( "nsExtendTable:cache", "load %s", extension->token ));
    if ( extension->args )
        snprintf( cmd_buf, cmd_len, "%s %s", extension->command, extension->args );
    else 
        snprintf( cmd_buf, cmd_len, "%s", extension->command );
    if ( extension->flags & NS_EXTEND_FLAGS_SHELL )
        ret = run_shell_command( cmd_buf, extension->input, out_buf, &out_len);
    else
        ret = run_exec_command(  cmd_buf, extension->input, out_buf, &out_len);
    DEBUGMSG(( "nsExtendTable:cache", ": %s : %d\n", cmd_buf, ret));
    if (ret >= 0) {
        if (out_buf[   out_len-1 ] == '\n')
            out_buf[ --out_len   ] =  '\0';	/* Stomp on trailing newline */
        extension->output   = strdup( out_buf );
        extension->out_len  = out_len;
        /*
         * Now we need to pick the output apart into separate lines.
         * Start by counting how many lines we've got, and keeping
         * track of where each line starts in a static buffer
         */
        extension->numlines = 1;
        line_buf[ 0 ] = extension->output;
        for (cp=extension->output; *cp; cp++) {
            if (*cp == '\n') {
                line_buf[ extension->numlines++ ] = cp+1;
            }
        }
        if ( extension->numlines > 1 ) {
            extension->lines = (char**)calloc( sizeof(char *), extension->numlines );
            memcpy( extension->lines, line_buf,
                                       sizeof(char *) * extension->numlines );
        } else {
            extension->lines = &extension->output;
        }
    }
    extension->result = ret;
    return ret;
#endif /* !defined(USING_UTILITIES_EXECUTE_MODULE) */
}

void
extend_free_cache(netsnmp_cache *cache, void *magic)
{
    netsnmp_extend *extension = (netsnmp_extend *)magic;
    if (!magic)
        return;

    DEBUGMSGTL(( "nsExtendTable:cache", "free %s\n", extension->token ));
    if (extension->output) {
        SNMP_FREE(extension->output);
        extension->output = NULL;
    }
    if ( extension->numlines > 1 ) {
        SNMP_FREE(extension->lines);
    }
    extension->lines  = NULL;
    extension->out_len  = 0;
    extension->numlines = 0;
}


        /*************************
         *
         *  Utility routines for setting up a new entry
         *  (either via SET requests, or the config file)
         *
         *************************/

void
_free_extension( netsnmp_extend *extension, extend_registration_block *ereg )
{
    netsnmp_extend *eptr  = NULL;
    netsnmp_extend *eprev = NULL;

    if (!extension)
        return;

    if (ereg) {
        /* Unlink from 'ehead' list */
        for (eptr=ereg->ehead; eptr; eptr=eptr->next) {
            if (eptr == extension)
                break;
            eprev = eptr;
        }
        if (!eptr) {
            snmp_log(LOG_ERR,
                     "extend: fell off end of list before finding extension\n");
            return;
        }
        if (eprev)
            eprev->next = eptr->next;
        else
            ereg->ehead = eptr->next;
        netsnmp_table_data_remove_and_delete_row( ereg->dinfo, extension->row);
    }

    SNMP_FREE( extension->token );
    SNMP_FREE( extension->cache );
    SNMP_FREE( extension->command );
    SNMP_FREE( extension->args  );
    SNMP_FREE( extension->input );
    SNMP_FREE( extension );
    return;
}

netsnmp_extend *
_new_extension( char *exec_name, int exec_flags, extend_registration_block *ereg )
{
    netsnmp_extend     *extension;
    netsnmp_table_row  *row;
    netsnmp_extend     *eptr1, *eptr2; 
    netsnmp_table_data *dinfo = ereg->dinfo;

    if (!exec_name)
        return NULL;
    extension = SNMP_MALLOC_TYPEDEF( netsnmp_extend );
    if (!extension)
        return NULL;
    extension->token    = strdup( exec_name );
    extension->flags    = exec_flags;
    extension->cache    = netsnmp_cache_create( 0, extend_load_cache,
                                                   extend_free_cache, NULL, 0 );
    if (extension->cache)
        extension->cache->magic = extension;

    row = netsnmp_create_table_data_row();
    if (!row || !extension->cache) {
        _free_extension( extension, ereg );
        SNMP_FREE( row );
        return NULL;
    }
    row->data = (void *)extension;
    extension->row = row;
    netsnmp_table_row_add_index( row, ASN_OCTET_STR,
                                 exec_name, strlen(exec_name));
    if ( netsnmp_table_data_add_row( dinfo, row) != SNMPERR_SUCCESS ) {
        /* _free_extension( extension, ereg ); */
        SNMP_FREE( extension );  /* Probably not sufficient */
        SNMP_FREE( row );
        return NULL;
    }

    ereg->num_entries++;
        /*
         *  Now add this structure to a private linked list.
         *  We don't need this for the main tables - the
         *   'table_data' helper will take care of those.
         *  But it's probably easier to handle the multi-line
         *  output table ourselves, for which we need access
         *  to the underlying data.
         *   So we'll keep a list internally as well.
         */
    for ( eptr1 = ereg->ehead, eptr2 = NULL;
          eptr1;
          eptr2 = eptr1, eptr1 = eptr1->next ) {

        if (strlen( eptr1->token )  > strlen( exec_name ))
            break;
        if (strlen( eptr1->token ) == strlen( exec_name ) &&
            strcmp( eptr1->token, exec_name ) > 0 )
            break;
    }
    if ( eptr2 )
        eptr2->next = extension;
    else
        ereg->ehead = extension;
    extension->next = eptr1;
    return extension;
}

void
extend_parse_config(const char *token, char *cptr)
{
    netsnmp_extend *extension;
    char exec_name[STRMAX];
    char exec_name2[STRMAX];     /* For use with UCD execFix directive */
    char exec_command[STRMAX];
    oid  oid_buf[MAX_OID_LEN];
    size_t oid_len;
    extend_registration_block *eptr;
    int  flags;

    cptr = copy_nword(cptr, exec_name,    sizeof(exec_name));
    if ( *exec_name == '.' ) {
        oid_len = MAX_OID_LEN - 2;
        if (0 == read_objid( exec_name, oid_buf, &oid_len )) {
            config_perror("ERROR: Unrecognised OID" );
            return;
        }
        cptr = copy_nword(cptr, exec_name,    sizeof(exec_name));
        if (!strcmp( token, "sh"   ) ||
            !strcmp( token, "exec" )) {
            config_perror("ERROR: This output format has been deprecated - Please use the 'extend' directive instead" );
            return;
        }
    } else {
        memcpy( oid_buf, ns_extend_oid, sizeof(ns_extend_oid));
        oid_len = OID_LENGTH(ns_extend_oid);
    }
    cptr = copy_nword(cptr, exec_command, sizeof(exec_command));
    /* XXX - check 'exec_command' exists & is executable */
    flags = (NS_EXTEND_FLAGS_ACTIVE | NS_EXTEND_FLAGS_CONFIG);
    if (!strcmp( token, "sh"        ) ||
        !strcmp( token, "extend-sh" ) ||
        !strcmp( token, "sh2" ))
        flags |= NS_EXTEND_FLAGS_SHELL;
    if (!strcmp( token, "execFix"   ) ||
        !strcmp( token, "extendfix" ) ||
        !strcmp( token, "execFix2" )) {
        strcpy( exec_name2, exec_name );
        strcat( exec_name, "Fix" );
        flags |= NS_EXTEND_FLAGS_WRITEABLE;
        /* XXX - Check for shell... */
    }

    eptr      = _register_extend( oid_buf, oid_len );
    if (!eptr) {
        snmp_log(LOG_ERR, "Failed to register extend entry '%s' - possibly duplicate name.\n", exec_name );
        return;
    }
    extension = _new_extension( exec_name, flags, eptr );
    if (extension) {
        extension->command  = strdup( exec_command );
        if (cptr)
            extension->args = strdup( cptr );
    } else {
        snmp_log(LOG_ERR, "Failed to register extend entry '%s' - possibly duplicate name.\n", exec_name );
        return;
    }

#ifndef USING_UCD_SNMP_EXTENSIBLE_MODULE
    /*
     *  Compatability with the UCD extTable
     */
    if (!strcmp( token, "execFix"  )) {
        int  i;
        for ( i=0; i < num_compatability_entries; i++ ) {
            if (!strcmp( exec_name2,
                    compatability_entries[i].exec_entry->token))
                break;
        }
        if ( i == num_compatability_entries )
            config_perror("No matching exec entry" );
        else
            compatability_entries[ i ].efix_entry = extension;
            
    } else if (!strcmp( token, "sh"   ) ||
               !strcmp( token, "exec" )) {
        if ( num_compatability_entries == max_compatability_entries ) {
            /* XXX - should really use dynamic allocation */
            netsnmp_old_extend *new_compatability_entries;
            new_compatability_entries = realloc(compatability_entries,
                             max_compatability_entries*2*sizeof(netsnmp_old_extend));
            if (!new_compatability_entries)
                config_perror("No further UCD-compatible entries" );
            else {
                memset(new_compatability_entries+num_compatability_entries, 0,
                        sizeof(netsnmp_old_extend)*max_compatability_entries);
                max_compatability_entries *= 2;
                compatability_entries = new_compatability_entries;
            }
        }
        if (num_compatability_entries != max_compatability_entries)
            compatability_entries[
                num_compatability_entries++ ].exec_entry = extension;
    }
#endif
}

        /*************************
         *
         *  Main table handlers
         *  Most of the work is handled
         *   by the 'table_data' helper.
         *
         *************************/

int
handle_nsExtendConfigTable(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_extend             *extension;
    extend_registration_block  *eptr;
    int  i;
    int  need_to_validate = 0;

    for ( request=requests; request; request=request->next ) {
        if (request->processed)
            continue;
        table_info = netsnmp_extract_table_info( request );
        extension  = (netsnmp_extend*)netsnmp_extract_table_row_data( request );

        DEBUGMSGTL(( "nsExtendTable:config", "varbind: "));
        DEBUGMSGOID(("nsExtendTable:config", request->requestvb->name,
                                             request->requestvb->name_length));
        DEBUGMSG((   "nsExtendTable:config", " (%s)\n",
                      se_find_label_in_slist("agent_mode", reqinfo->mode)));

        switch (reqinfo->mode) {
        case MODE_GET:
            switch (table_info->colnum) {
            case COLUMN_EXTCFG_COMMAND:
                snmp_set_var_typed_value(
                     request->requestvb, ASN_OCTET_STR,
                     extension->command,
                    (extension->command)?strlen(extension->command):0);
                break;
            case COLUMN_EXTCFG_ARGS:
                snmp_set_var_typed_value(
                     request->requestvb, ASN_OCTET_STR,
                     extension->args,
                    (extension->args)?strlen(extension->args):0);
                break;
            case COLUMN_EXTCFG_INPUT:
                snmp_set_var_typed_value(
                     request->requestvb, ASN_OCTET_STR,
                     extension->input,
                    (extension->input)?strlen(extension->input):0);
                break;
            case COLUMN_EXTCFG_CACHETIME:
                snmp_set_var_typed_value(
                     request->requestvb, ASN_INTEGER,
                    (u_char*)&extension->cache->timeout, sizeof(int));
                break;
            case COLUMN_EXTCFG_EXECTYPE:
                i = ((extension->flags & NS_EXTEND_FLAGS_SHELL) ?
                                         NS_EXTEND_ETYPE_SHELL :
                                         NS_EXTEND_ETYPE_EXEC);
                snmp_set_var_typed_value(
                     request->requestvb, ASN_INTEGER,
                    (u_char*)&i, sizeof(i));
                break;
            case COLUMN_EXTCFG_RUNTYPE:
                i = ((extension->flags & NS_EXTEND_FLAGS_WRITEABLE) ?
                                         NS_EXTEND_RTYPE_RWRITE :
                                         NS_EXTEND_RTYPE_RONLY);
                snmp_set_var_typed_value(
                     request->requestvb, ASN_INTEGER,
                    (u_char*)&i, sizeof(i));
                break;

            case COLUMN_EXTCFG_STORAGE:
                i = ((extension->flags & NS_EXTEND_FLAGS_CONFIG) ?
                                         ST_PERMANENT : ST_VOLATILE);
                snmp_set_var_typed_value(
                     request->requestvb, ASN_INTEGER,
                    (u_char*)&i, sizeof(i));
                break;
            case COLUMN_EXTCFG_STATUS:
                i = ((extension->flags & NS_EXTEND_FLAGS_ACTIVE) ?
                                         RS_ACTIVE :
                                         RS_NOTINSERVICE);
                snmp_set_var_typed_value(
                     request->requestvb, ASN_INTEGER,
                    (u_char*)&i, sizeof(i));
                break;

            default:
                netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
                continue;
            }
            break;

        /**********
         *
         * Start of SET handling
         *
         *   All config objects are potentially writable except
         *     nsExtendStorage which is fixed as either 'permanent'
         *     (if read from a config file) or 'volatile' (if set via SNMP)
         *   The string-based settings of a 'permanent' entry cannot 
         *     be changed - neither can the execution or run type.
         *   Such entries can be (temporarily) marked as inactive,
         *     and the cache timeout adjusted, but these changes are
         *     not persistent.
         *
         **********/

#ifndef NETSNMP_NO_WRITE_SUPPORT
        case MODE_SET_RESERVE1:
            /*
             * Validate the new assignments
             */
            switch (table_info->colnum) {
            case COLUMN_EXTCFG_COMMAND:
                if (request->requestvb->type != ASN_OCTET_STR) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGTYPE);
                    return SNMP_ERR_WRONGTYPE;
                }
                /*
                 * Must have a full path to the command
                 * XXX - Assumes Unix-style paths
                 */
                if (request->requestvb->val_len == 0 ||
                    request->requestvb->val.string[0] != '/') {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGVALUE);
                    return SNMP_ERR_WRONGVALUE;
                }
                /*
                 * XXX - need to check this file exists
                 *       (and is executable)
                 */

                if (extension && extension->flags & NS_EXTEND_FLAGS_CONFIG) {
                    /*
                     * config entries are "permanent" so can't be changed
                     */
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_NOTWRITABLE);
                    return SNMP_ERR_NOTWRITABLE;
                }
                break;

            case COLUMN_EXTCFG_ARGS:
            case COLUMN_EXTCFG_INPUT:
                if (request->requestvb->type != ASN_OCTET_STR) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGTYPE);
                    return SNMP_ERR_WRONGTYPE;
                }

                if (extension && extension->flags & NS_EXTEND_FLAGS_CONFIG) {
                    /*
                     * config entries are "permanent" so can't be changed
                     */
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_NOTWRITABLE);
                    return SNMP_ERR_NOTWRITABLE;
                }
                break;

            case COLUMN_EXTCFG_CACHETIME:
                if (request->requestvb->type != ASN_INTEGER) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGTYPE);
                    return SNMP_ERR_WRONGTYPE;
                }
                i = *request->requestvb->val.integer;
                /*
                 * -1 is a special value indicating "don't cache"
                 *    [[ XXX - should this be 0 ?? ]]
                 * Otherwise, cache times must be non-negative
                 */
                if (i < -1 ) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGVALUE);
                    return SNMP_ERR_WRONGVALUE;
                }
                break;

            case COLUMN_EXTCFG_EXECTYPE:
                if (request->requestvb->type != ASN_INTEGER) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGTYPE);
                    return SNMP_ERR_WRONGTYPE;
                }
                i = *request->requestvb->val.integer;
                if (i<1 || i>2) {  /* 'exec(1)' or 'shell(2)' only */
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGVALUE);
                    return SNMP_ERR_WRONGVALUE;
                }
                if (extension && extension->flags & NS_EXTEND_FLAGS_CONFIG) {
                    /*
                     * config entries are "permanent" so can't be changed
                     */
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_NOTWRITABLE);
                    return SNMP_ERR_NOTWRITABLE;
                }
                break;

            case COLUMN_EXTCFG_RUNTYPE:
                if (request->requestvb->type != ASN_INTEGER) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGTYPE);
                    return SNMP_ERR_WRONGTYPE;
                }
                /*
                 * 'run-on-read(1)', 'run-on-set(2)'
                 *  or 'run-command(3)' only
                 */
                i = *request->requestvb->val.integer;
                if (i<1 || i>3) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGVALUE);
                    return SNMP_ERR_WRONGVALUE;
                }
                /*
                 * 'run-command(3)' can only be used with
                 *  a pre-existing 'run-on-set(2)' entry.
                 */
                if (i==3 && !(extension && (extension->flags & NS_EXTEND_FLAGS_WRITEABLE))) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_INCONSISTENTVALUE);
                    return SNMP_ERR_INCONSISTENTVALUE;
                }
                /*
                 * 'run-command(3)' is the only valid assignment
                 *  for permanent (i.e. config) entries
                 */
                if ((extension && extension->flags & NS_EXTEND_FLAGS_CONFIG)
                    && i!=3 ) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_INCONSISTENTVALUE);
                    return SNMP_ERR_INCONSISTENTVALUE;
                }
                break;

            case COLUMN_EXTCFG_STATUS:
                if (request->requestvb->type != ASN_INTEGER) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGTYPE);
                    return SNMP_ERR_WRONGTYPE;
                }
                i = *request->requestvb->val.integer;
                switch (i) {
                case RS_ACTIVE:
                case RS_NOTINSERVICE:
                    if (!extension) {
                        /* Must be used with existing rows */
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        return SNMP_ERR_INCONSISTENTVALUE;
                    }
                    break;    /* OK */
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    if (extension) {
                        /* Can only be used to create new rows */
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        return SNMP_ERR_INCONSISTENTVALUE;
                    }
                    break;
                case RS_DESTROY:
                    break;
                default:
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGVALUE);
                    return SNMP_ERR_WRONGVALUE;
                }
                break;

            default:
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_ERR_NOTWRITABLE);
                return SNMP_ERR_NOTWRITABLE;
            }
            break;

        case MODE_SET_RESERVE2:
            switch (table_info->colnum) {
            case COLUMN_EXTCFG_STATUS:
                i = *request->requestvb->val.integer;
                switch (i) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    eptr = _find_extension_block( request->requestvb->name,
                                                  request->requestvb->name_length );
                    extension = _new_extension( (char *) table_info->indexes->val.string,
                                                0, eptr );
                    if (!extension) {  /* failed */
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_RESOURCEUNAVAILABLE);
                        return SNMP_ERR_RESOURCEUNAVAILABLE;
                    }
                    netsnmp_insert_table_row( request, extension->row );
                }
            }
            break;

        case MODE_SET_FREE:
            switch (table_info->colnum) {
            case COLUMN_EXTCFG_STATUS:
                i = *request->requestvb->val.integer;
                switch (i) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    eptr = _find_extension_block( request->requestvb->name,
                                                  request->requestvb->name_length );
                    _free_extension( extension, eptr );
                }
            }
            break;

        case MODE_SET_ACTION:
            switch (table_info->colnum) {
            case COLUMN_EXTCFG_COMMAND:
                extension->old_command = extension->command;
                extension->command = netsnmp_strdup_and_null(
                    request->requestvb->val.string,
                    request->requestvb->val_len);
                break;
            case COLUMN_EXTCFG_ARGS:
                extension->old_args = extension->args;
                extension->args = netsnmp_strdup_and_null(
                    request->requestvb->val.string,
                    request->requestvb->val_len);
                break;
            case COLUMN_EXTCFG_INPUT:
                extension->old_input = extension->input;
                extension->input = netsnmp_strdup_and_null(
                    request->requestvb->val.string,
                    request->requestvb->val_len);
                break;
            case COLUMN_EXTCFG_STATUS:
                i = *request->requestvb->val.integer;
                switch (i) {
                case RS_ACTIVE:
                case RS_CREATEANDGO:
                    need_to_validate = 1;
                }
                break;
            }
            break;

        case MODE_SET_UNDO:
            switch (table_info->colnum) {
            case COLUMN_EXTCFG_COMMAND:
                if ( extension && extension->old_command ) {
                    SNMP_FREE(extension->command);
                    extension->command     = extension->old_command;
                    extension->old_command = NULL;
                }
                break;
            case COLUMN_EXTCFG_ARGS:
                if ( extension && extension->old_args ) {
                    SNMP_FREE(extension->args);
                    extension->args     = extension->old_args;
                    extension->old_args = NULL;
                }
                break;
            case COLUMN_EXTCFG_INPUT:
                if ( extension && extension->old_input ) {
                    SNMP_FREE(extension->input);
                    extension->input     = extension->old_input;
                    extension->old_input = NULL;
                }
                break;
            case COLUMN_EXTCFG_STATUS:
                i = *request->requestvb->val.integer;
                switch (i) {
                case RS_CREATEANDGO:
                case RS_CREATEANDWAIT:
                    eptr = _find_extension_block( request->requestvb->name,
                                                  request->requestvb->name_length );
                    _free_extension( extension, eptr );
                }
                break;
            }
            break;

        case MODE_SET_COMMIT:
            switch (table_info->colnum) {
            case COLUMN_EXTCFG_CACHETIME:
                i = *request->requestvb->val.integer;
                extension->cache->timeout = i;
                break;

            case COLUMN_EXTCFG_RUNTYPE:
                i = *request->requestvb->val.integer;
                switch (i) {
                case 1:
                    extension->flags &= ~NS_EXTEND_FLAGS_WRITEABLE;
                    break;
                case 2:
                    extension->flags |=  NS_EXTEND_FLAGS_WRITEABLE;
                    break;
                case 3:
                    (void)netsnmp_cache_check_and_reload( extension->cache );
                    break;
                }
                break;

            case COLUMN_EXTCFG_EXECTYPE:
                i = *request->requestvb->val.integer;
                if ( i == NS_EXTEND_ETYPE_SHELL )
                    extension->flags |=  NS_EXTEND_FLAGS_SHELL;
                else
                    extension->flags &= ~NS_EXTEND_FLAGS_SHELL;
                break;

            case COLUMN_EXTCFG_STATUS:
                i = *request->requestvb->val.integer;
                switch (i) {
                case RS_ACTIVE:
                case RS_CREATEANDGO:
                    extension->flags |= NS_EXTEND_FLAGS_ACTIVE;
                    break;
                case RS_NOTINSERVICE:
                case RS_CREATEANDWAIT:
                    extension->flags &= ~NS_EXTEND_FLAGS_ACTIVE;
                    break;
                case RS_DESTROY:
                    eptr = _find_extension_block( request->requestvb->name,
                                                  request->requestvb->name_length );
                    _free_extension( extension, eptr );
                    break;
                }
            }
            break;
#endif /* !NETSNMP_NO_WRITE_SUPPORT */ 

        default:
            netsnmp_set_request_error(reqinfo, request, SNMP_ERR_GENERR);
            return SNMP_ERR_GENERR;
        }
    }

#ifndef NETSNMP_NO_WRITE_SUPPORT
    /*
     * If we're marking a given row as active,
     *  then we need to check that it's ready.
     */
    if (need_to_validate) {
        for ( request=requests; request; request=request->next ) {
            if (request->processed)
                continue;
            table_info = netsnmp_extract_table_info( request );
            extension  = (netsnmp_extend*)netsnmp_extract_table_row_data( request );
            switch (table_info->colnum) {
            case COLUMN_EXTCFG_STATUS:
                i = *request->requestvb->val.integer;
                if (( i == RS_ACTIVE || i == RS_CREATEANDGO ) &&
                    !(extension && extension->command &&
                      extension->command[0] == '/' /* &&
                      is_executable(extension->command) */)) {
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_INCONSISTENTVALUE);
                    return SNMP_ERR_INCONSISTENTVALUE;
                }
            }
        }
    }
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
    
    return SNMP_ERR_NOERROR;
}


int
handle_nsExtendOutput1Table(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_extend             *extension;
    int len;

    for ( request=requests; request; request=request->next ) {
        if (request->processed)
            continue;
        table_info = netsnmp_extract_table_info( request );
        extension  = (netsnmp_extend*)netsnmp_extract_table_row_data( request );

        DEBUGMSGTL(( "nsExtendTable:output1", "varbind: "));
        DEBUGMSGOID(("nsExtendTable:output1", request->requestvb->name,
                                              request->requestvb->name_length));
        DEBUGMSG((   "nsExtendTable:output1", "\n"));

        switch (reqinfo->mode) {
        case MODE_GET:
            if (!extension || !(extension->flags & NS_EXTEND_FLAGS_ACTIVE)) {
                /*
                 * If this row is inactive, then skip it.
                 */
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHINSTANCE);
                continue;
            }
            if (!(extension->flags & NS_EXTEND_FLAGS_WRITEABLE) &&
                (netsnmp_cache_check_and_reload( extension->cache ) < 0 )) {
                /*
                 * If reloading the output cache of a 'run-on-read'
                 * entry fails, then skip it.
                 */
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHINSTANCE);
                continue;
            }
            if ((extension->flags & NS_EXTEND_FLAGS_WRITEABLE) &&
                (netsnmp_cache_check_expired( extension->cache ) == 1 )) {
                /*
                 * If the output cache of a 'run-on-write'
                 * entry has expired, then skip it.
                 */
                netsnmp_set_request_error(reqinfo, request,
                                          SNMP_NOSUCHINSTANCE);
                continue;
            }

            switch (table_info->colnum) {
            case COLUMN_EXTOUT1_OUTLEN:
                snmp_set_var_typed_value(
                     request->requestvb, ASN_INTEGER,
                    (u_char*)&extension->out_len, sizeof(int));
                break;
            case COLUMN_EXTOUT1_OUTPUT1:
                /* 
                 * If we've got more than one line,
                 * find the length of the first one.
                 * Otherwise find the length of the whole string.
                 */
                if (extension->numlines > 1) {
                    len = (extension->lines[1])-(extension->output) -1;
                } else if (extension->output) {
                    len = strlen(extension->output);
                } else {
                    len = 0;
                }
                snmp_set_var_typed_value(
                     request->requestvb, ASN_OCTET_STR,
                     extension->output, len);
                break;
            case COLUMN_EXTOUT1_OUTPUT2:
                snmp_set_var_typed_value(
                     request->requestvb, ASN_OCTET_STR,
                     extension->output,
                    (extension->output)?extension->out_len:0);
                break;
            case COLUMN_EXTOUT1_NUMLINES:
                snmp_set_var_typed_value(
                     request->requestvb, ASN_INTEGER,
                    (u_char*)&extension->numlines, sizeof(int));
                break;
            case COLUMN_EXTOUT1_RESULT:
                snmp_set_var_typed_value(
                     request->requestvb, ASN_INTEGER,
                    (u_char*)&extension->result, sizeof(int));
                break;
            default:
                netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
                continue;
            }
            break;
        default:
            netsnmp_set_request_error(reqinfo, request, SNMP_ERR_GENERR);
            return SNMP_ERR_GENERR;
        }
    }
    return SNMP_ERR_NOERROR;
}


        /*************************
         *
         *  Multi-line output table handler
         *  Most of the work is handled here.
         *
         *************************/


/*
 *  Locate the appropriate entry for a given request
 */
netsnmp_extend *
_extend_find_entry( netsnmp_request_info       *request,
                    netsnmp_table_request_info *table_info,
                    int mode  )
{
    netsnmp_extend            *eptr;
    extend_registration_block *ereg;
    unsigned int line_idx;
    oid oid_buf[MAX_OID_LEN];
    int oid_len;
    int i;
    char  *token;
    size_t token_len;

    if (!request || !table_info || !table_info->indexes
                 || !table_info->indexes->next_variable) {
        DEBUGMSGTL(( "nsExtendTable:output2", "invalid invocation\n"));
        return NULL;
    }

    ereg = _find_extension_block( request->requestvb->name,
                                  request->requestvb->name_length );

    /***
     *  GET handling - find the exact entry being requested
     ***/
    if ( mode == MODE_GET ) {
        DEBUGMSGTL(( "nsExtendTable:output2", "GET: %s / %ld\n ",
                      table_info->indexes->val.string,
                     *table_info->indexes->next_variable->val.integer));
        for ( eptr = ereg->ehead; eptr; eptr = eptr->next ) {
            if ( !strcmp( eptr->token, (char *) table_info->indexes->val.string ))
                break;
        }

        if ( eptr ) {
            /*
             * Ensure the output is available...
             */
            if (!(eptr->flags & NS_EXTEND_FLAGS_ACTIVE) ||
               (netsnmp_cache_check_and_reload( eptr->cache ) < 0 ))
                return NULL;

            /*
             * ...and check the line requested is valid
             */
            line_idx = *table_info->indexes->next_variable->val.integer;
            if (line_idx < 1 || line_idx > eptr->numlines)
                return NULL;
        }
    }

        /***
         *  GETNEXT handling - find the first suitable entry
         ***/
    else {
        if (!table_info->indexes->val_len ) {
            DEBUGMSGTL(( "nsExtendTable:output2", "GETNEXT: first entry\n"));
            /*
             * Beginning of the table - find the first active
             *  (and successful) entry, and use the first line of it
             */
            for (eptr = ereg->ehead; eptr; eptr = eptr->next ) {
                if ((eptr->flags & NS_EXTEND_FLAGS_ACTIVE) &&
                    (netsnmp_cache_check_and_reload( eptr->cache ) >= 0 )) {
                    line_idx = 1;
                    break;
                }
            }
        } else {
            token     =  (char *) table_info->indexes->val.string;
            token_len =  table_info->indexes->val_len;
            line_idx  = *table_info->indexes->next_variable->val.integer;
            DEBUGMSGTL(( "nsExtendTable:output2", "GETNEXT: %s / %d\n ",
                          token, line_idx ));
            /*
             * Otherwise, find the first entry not earlier
             * than the requested token...
             */
            for (eptr = ereg->ehead; eptr; eptr = eptr->next ) {
                if ( strlen(eptr->token) > token_len )
                    break;
                if ( strlen(eptr->token) == token_len &&
                     strcmp(eptr->token, token) >= 0 )
                    break;
            }
            if (!eptr)
                return NULL;    /* (assuming there is one) */

            /*
             * ... and make sure it's active & the output is available
             * (or use the first following entry that is)
             */
            for (    ; eptr; eptr = eptr->next ) {
                if ((eptr->flags & NS_EXTEND_FLAGS_ACTIVE) &&
                    (netsnmp_cache_check_and_reload( eptr->cache ) >= 0 )) {
                    break;
                }
                line_idx = 1;
            }

            if (!eptr)
                return NULL;    /* (assuming there is one) */

            /*
             *  If we're working with the same entry that was requested,
             *  see whether we've reached the end of the output...
             */
            if (!strcmp( eptr->token, token )) {
                if ( eptr->numlines <= line_idx ) {
                    /*
                     * ... and if so, move on to the first line
                     * of the next (active and successful) entry.
                     */
                    line_idx = 1;
                    for (eptr = eptr->next ; eptr; eptr = eptr->next ) {
                        if ((eptr->flags & NS_EXTEND_FLAGS_ACTIVE) &&
                            (netsnmp_cache_check_and_reload( eptr->cache ) >= 0 )) {
                            break;
                        }
                    }
                } else {
                    /*
                     * Otherwise just use the next line of this entry.
                     */
                    line_idx++;
                }
            }
            else {
                /*
                 * If this is not the same entry that was requested,
                 * then we should return the first line.
                 */
                line_idx = 1;
            }
        }
        if (eptr) {
            DEBUGMSGTL(( "nsExtendTable:output2", "GETNEXT -> %s / %d\n ",
                          eptr->token, line_idx));
            /*
             * Since we're processing a GETNEXT request,
             * now we've found the appropriate entry (and line),
             * we need to update the varbind OID ...
             */
            memset(oid_buf, 0, sizeof(oid_buf));
            oid_len = ereg->oid_len;
            memcpy( oid_buf, ereg->root_oid, oid_len*sizeof(oid));
            oid_buf[ oid_len++ ] = 4;    /* nsExtendOutput2Table */
            oid_buf[ oid_len++ ] = 1;    /* nsExtendOutput2Entry */
            oid_buf[ oid_len++ ] = COLUMN_EXTOUT2_OUTLINE;
                                         /* string token index */
            oid_buf[ oid_len++ ] = strlen(eptr->token);
            for ( i=0; i < (int)strlen(eptr->token); i++ )
                oid_buf[ oid_len+i ] = eptr->token[i];
            oid_len += strlen( eptr->token );
                                         /* plus line number */
            oid_buf[ oid_len++ ] = line_idx;
            snmp_set_var_objid( request->requestvb, oid_buf, oid_len );
            /*
             * ... and index values to match.
             */
            snmp_set_var_value( table_info->indexes,
                                eptr->token, strlen(eptr->token));
            snmp_set_var_value( table_info->indexes->next_variable,
                                (const u_char*)&line_idx, sizeof(line_idx));
        }
    }
    return eptr;  /* Finally, signal success */
}

/*
 *  Multi-line output handler
 *  Locate the appropriate entry (using _extend_find_entry)
 *  and return the appropriate output line
 */
int
handle_nsExtendOutput2Table(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_extend             *extension;
    char *cp;
    unsigned int line_idx;
    int len;

    for ( request=requests; request; request=request->next ) {
        if (request->processed)
            continue;

        table_info = netsnmp_extract_table_info( request );
        extension  = _extend_find_entry( request, table_info, reqinfo->mode );

        DEBUGMSGTL(( "nsExtendTable:output2", "varbind: "));
        DEBUGMSGOID(("nsExtendTable:output2", request->requestvb->name,
                                              request->requestvb->name_length));
        DEBUGMSG((   "nsExtendTable:output2", " (%s)\n",
                                    (extension) ? extension->token : "[none]"));

        if (!extension) {
            if (reqinfo->mode == MODE_GET)
                netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
            else
                netsnmp_set_request_error(reqinfo, request, SNMP_ENDOFMIBVIEW);
            continue;
        }

        switch (reqinfo->mode) {
        case MODE_GET:
        case MODE_GETNEXT:
            switch (table_info->colnum) {
            case COLUMN_EXTOUT2_OUTLINE:
                /* 
                 * Determine which line we've been asked for....
                 */
                line_idx = *table_info->indexes->next_variable->val.integer;
                if (line_idx < 1 || line_idx > extension->numlines) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
                    continue;
                }
                cp  = extension->lines[line_idx-1];

                /* 
                 * ... and how long it is.
                 */
                if ( extension->numlines > line_idx )
                    len = (extension->lines[line_idx])-cp -1;
                else if (cp)
                    len = strlen(cp);
                else
                    len = 0;

                snmp_set_var_typed_value( request->requestvb,
                                          ASN_OCTET_STR, cp, len );
                break;
            default:
                netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
                continue;
            }
            break;
        default:
            netsnmp_set_request_error(reqinfo, request, SNMP_ERR_GENERR);
            return SNMP_ERR_GENERR;
        }
    }
    return SNMP_ERR_NOERROR;
}

#ifndef USING_UCD_SNMP_EXTENSIBLE_MODULE
        /*************************
         *
         *  Compatability with the UCD extTable
         *
         *************************/

char * _get_cmdline(netsnmp_extend *extend)
{
    size_t          size;
    char           *newbuf;
    const char     *args = extend->args;

    if (args == NULL)
        /* Use empty string for processes without arguments. */
        args = "";

    size = strlen(extend->command) + strlen(args) + 2;
    if (size > cmdlinesize) {
        newbuf = realloc(cmdlinebuf, size);
        if (!newbuf) {
            free(cmdlinebuf);
            cmdlinebuf = NULL;
            cmdlinesize = 0;
            return NULL;
        }
        cmdlinebuf = newbuf;
        cmdlinesize = size;
    }
    sprintf(cmdlinebuf, "%s %s", extend->command, args);
    return cmdlinebuf;
}

u_char *
var_extensible_old(struct variable * vp,
                     oid * name,
                     size_t * length,
                     int exact,
                     size_t * var_len, WriteMethod ** write_method)
{
    netsnmp_old_extend *exten = NULL;
    static long     long_ret;
    unsigned int idx;
    char         *cmdline;

    if (header_simple_table
        (vp, name, length, exact, var_len, write_method, num_compatability_entries))
        return (NULL);

    idx = name[*length-1] -1;
	if (idx > max_compatability_entries)
		return NULL;
    exten = &compatability_entries[ idx ];
    if (exten) {
        switch (vp->magic) {
        case MIBINDEX:
            long_ret = name[*length - 1];
            return ((u_char *) (&long_ret));
        case ERRORNAME:        /* name defined in config file */
            *var_len = strlen(exten->exec_entry->token);
            return ((u_char *) (exten->exec_entry->token));
        case SHELLCOMMAND:
            cmdline = _get_cmdline(exten->exec_entry);
            if (cmdline)
                *var_len = strlen(cmdline);
            return ((u_char *) cmdline);
        case ERRORFLAG:        /* return code from the process */
            netsnmp_cache_check_and_reload( exten->exec_entry->cache );
            long_ret = exten->exec_entry->result;
            return ((u_char *) (&long_ret));
        case ERRORMSG:         /* first line of text returned from the process */
            netsnmp_cache_check_and_reload( exten->exec_entry->cache );
            if (exten->exec_entry->numlines > 1) {
                *var_len = (exten->exec_entry->lines[1])-
                           (exten->exec_entry->output) -1;
            } else if (exten->exec_entry->output) {
                *var_len = strlen(exten->exec_entry->output);
            } else {
                *var_len = 0;
            }
            return ((u_char *) (exten->exec_entry->output));
        case ERRORFIX:
            *write_method = fixExec2Error;
            long_return = 0;
            return ((u_char *) &long_return);

        case ERRORFIXCMD:
            if (exten->efix_entry) {
                cmdline = _get_cmdline(exten->efix_entry);
		if (cmdline)
                    *var_len = strlen(cmdline);
                return ((u_char *) cmdline);
            } else {
                *var_len = 0;
                return ((u_char *) &long_return);  /* Just needs to be non-null! */
            }
        }
        return NULL;
    }
    return NULL;
}


int
fixExec2Error(int action,
             u_char * var_val,
             u_char var_val_type,
             size_t var_val_len,
             u_char * statP, oid * name, size_t name_len)
{
    netsnmp_old_extend *exten = NULL;
    unsigned int idx;

    idx = name[name_len-1] -1;
    exten = &compatability_entries[ idx ];

#ifndef NETSNMP_NO_WRITE_SUPPORT
    switch (action) {
    case MODE_SET_RESERVE1:
        if (var_val_type != ASN_INTEGER) {
            snmp_log(LOG_ERR, "Wrong type != int\n");
            return SNMP_ERR_WRONGTYPE;
        }
        idx = *((long *) var_val);
        if (idx != 1) {
            snmp_log(LOG_ERR, "Wrong value != 1\n");
            return SNMP_ERR_WRONGVALUE;
        }
        if (!exten || !exten->efix_entry) {
            snmp_log(LOG_ERR, "No command to run\n");
            return SNMP_ERR_GENERR;
        }
        return SNMP_ERR_NOERROR;

    case MODE_SET_COMMIT:
        netsnmp_cache_check_and_reload( exten->efix_entry->cache );
    }
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
    return SNMP_ERR_NOERROR;
}
#endif /* USING_UCD_SNMP_EXTENSIBLE_MODULE */
