/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 1.67 $ of : mfd-interface.m2c,v $ 
 *
 * $Id$
 */
/*
 * *********************************************************************
 * *********************************************************************
 * *********************************************************************
 * ***                                                               ***
 * ***  NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE  ***
 * ***                                                               ***
 * ***                                                               ***
 * ***       THIS FILE DOES NOT CONTAIN ANY USER EDITABLE CODE.      ***
 * ***                                                               ***
 * ***                                                               ***
 * ***       THE GENERATED CODE IS INTERNAL IMPLEMENTATION, AND      ***
 * ***                                                               ***
 * ***                                                               ***
 * ***    IS SUBJECT TO CHANGE WITHOUT WARNING IN FUTURE RELEASES.   ***
 * ***                                                               ***
 * ***                                                               ***
 * *********************************************************************
 * *********************************************************************
 * *********************************************************************
 */

/*
 * standard Net-SNMP includes 
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

/*
 * include our parent header 
 */
#include "usmDHUserKeyTable.h"


#include <net-snmp/agent/table_container.h>
#include <net-snmp/library/container.h>

#include "usmDHUserKeyTable_interface.h"

#include <ctype.h>

/**********************************************************************
 **********************************************************************
 ***
 *** Table usmDHUserKeyTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * SNMP-USM-DH-OBJECTS-MIB::usmDHUserKeyTable is subid 2 of usmDHPublicObjects.
 * Its status is Current.
 * OID: .1.3.6.1.3.101.1.1.2, length: 9
 */
typedef struct usmDHUserKeyTable_interface_ctx_s {

    netsnmp_container *container;
    netsnmp_cache  *cache;

    usmDHUserKeyTable_registration *user_ctx;

    netsnmp_table_registration_info tbl_info;

    netsnmp_baby_steps_access_methods access_multiplexer;

    u_int           table_dirty;

} usmDHUserKeyTable_interface_ctx;

static usmDHUserKeyTable_interface_ctx usmDHUserKeyTable_if_ctx;

static void    
_usmDHUserKeyTable_container_init(usmDHUserKeyTable_interface_ctx *
                                  if_ctx);
static void    
_usmDHUserKeyTable_container_shutdown(usmDHUserKeyTable_interface_ctx *
                                      if_ctx);


netsnmp_container *
usmDHUserKeyTable_container_get(void)
{
    return usmDHUserKeyTable_if_ctx.container;
}

usmDHUserKeyTable_registration *
usmDHUserKeyTable_registration_get(void)
{
    return usmDHUserKeyTable_if_ctx.user_ctx;
}

usmDHUserKeyTable_registration *
usmDHUserKeyTable_registration_set(usmDHUserKeyTable_registration * newreg)
{
    usmDHUserKeyTable_registration *old =
        usmDHUserKeyTable_if_ctx.user_ctx;
    usmDHUserKeyTable_if_ctx.user_ctx = newreg;
    return old;
}

int
usmDHUserKeyTable_container_size(void)
{
    return CONTAINER_SIZE(usmDHUserKeyTable_if_ctx.container);
}

u_int
usmDHUserKeyTable_dirty_get(void)
{
    return usmDHUserKeyTable_if_ctx.table_dirty;
}

void
usmDHUserKeyTable_dirty_set(u_int status)
{
    DEBUGMSGTL(("usmDHUserKeyTable:usmDHUserKeyTable_dirty_set",
                "called. was %d, now %d\n",
                usmDHUserKeyTable_if_ctx.table_dirty, status));
    usmDHUserKeyTable_if_ctx.table_dirty = status;
}

/*
 * mfd multiplexer modes
 */
static Netsnmp_Node_Handler _mfd_usmDHUserKeyTable_pre_request;
static Netsnmp_Node_Handler _mfd_usmDHUserKeyTable_post_request;
static Netsnmp_Node_Handler _mfd_usmDHUserKeyTable_object_lookup;
static Netsnmp_Node_Handler _mfd_usmDHUserKeyTable_get_values;
#ifndef NETSNMP_DISABLE_SET_SUPPORT
static Netsnmp_Node_Handler _mfd_usmDHUserKeyTable_check_objects;
static Netsnmp_Node_Handler _mfd_usmDHUserKeyTable_undo_setup;
static Netsnmp_Node_Handler _mfd_usmDHUserKeyTable_set_values;
static Netsnmp_Node_Handler _mfd_usmDHUserKeyTable_undo_cleanup;
static Netsnmp_Node_Handler _mfd_usmDHUserKeyTable_undo_values;
static Netsnmp_Node_Handler _mfd_usmDHUserKeyTable_commit;
static Netsnmp_Node_Handler _mfd_usmDHUserKeyTable_irreversible_commit;
static Netsnmp_Node_Handler _mfd_usmDHUserKeyTable_undo_commit;
static Netsnmp_Node_Handler _mfd_usmDHUserKeyTable_check_dependencies;

NETSNMP_STATIC_INLINE int
_usmDHUserKeyTable_undo_column(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                                               netsnmp_variable_list * var,
                                               int column);
#endif

/**
 * @internal
 * Initialize the table usmDHUserKeyTable 
 *    (Define its contents and how it's structured)
 */
void
_usmDHUserKeyTable_initialize_interface(usmDHUserKeyTable_registration *
                                        reg_ptr, u_long flags)
{
    netsnmp_baby_steps_access_methods *access_multiplexer =
        &usmDHUserKeyTable_if_ctx.access_multiplexer;
    netsnmp_table_registration_info *tbl_info =
        &usmDHUserKeyTable_if_ctx.tbl_info;
    netsnmp_handler_registration *reginfo;
    netsnmp_mib_handler *handler;
    int             mfd_modes = 0;

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_usmDHUserKeyTable_initialize_interface", "called\n"));


    /*************************************************
     *
     * save interface context for usmDHUserKeyTable
     */
    /*
     * Setting up the table's definition
     */
    netsnmp_table_helper_add_indexes(tbl_info, ASN_OCTET_STR,
                                                 /** index: usmUserEngineID */
                                     ASN_OCTET_STR,
                                                 /** index: usmUserName */
                                     0);

    /*
     * Define the minimum and maximum accessible columns.  This
     * optimizes retrival. 
     */
    tbl_info->min_column = USMDHUSERKEYTABLE_MIN_COL;
    tbl_info->max_column = USMDHUSERKEYTABLE_MAX_COL;

    /*
     * save users context
     */
    usmDHUserKeyTable_if_ctx.user_ctx = reg_ptr;

    /*
     * call data access initialization code
     */
    usmDHUserKeyTable_init_data(reg_ptr);

    /*
     * set up the container
     */
    _usmDHUserKeyTable_container_init(&usmDHUserKeyTable_if_ctx);
    if (NULL == usmDHUserKeyTable_if_ctx.container) {
        snmp_log(LOG_ERR,
                 "could not initialize container for usmDHUserKeyTable\n");
        return;
    }

    /*
     * access_multiplexer: REQUIRED wrapper for get request handling
     */
    access_multiplexer->object_lookup =
        _mfd_usmDHUserKeyTable_object_lookup;
    access_multiplexer->get_values = _mfd_usmDHUserKeyTable_get_values;

    /*
     * no wrappers yet
     */
    access_multiplexer->pre_request = _mfd_usmDHUserKeyTable_pre_request;
    access_multiplexer->post_request = _mfd_usmDHUserKeyTable_post_request;


#ifndef NETSNMP_DISABLE_SET_SUPPORT
    /*
     * REQUIRED wrappers for set request handling
     */
    access_multiplexer->object_syntax_checks =
        _mfd_usmDHUserKeyTable_check_objects;
    access_multiplexer->undo_setup = _mfd_usmDHUserKeyTable_undo_setup;
    access_multiplexer->undo_cleanup = _mfd_usmDHUserKeyTable_undo_cleanup;
    access_multiplexer->set_values = _mfd_usmDHUserKeyTable_set_values;
    access_multiplexer->undo_sets = _mfd_usmDHUserKeyTable_undo_values;

    /*
     * no wrappers yet
     */
    access_multiplexer->commit = _mfd_usmDHUserKeyTable_commit;
    access_multiplexer->undo_commit = _mfd_usmDHUserKeyTable_undo_commit;
    access_multiplexer->irreversible_commit =
        _mfd_usmDHUserKeyTable_irreversible_commit;

    /*
     * REQUIRED for tables with dependencies
     */
    access_multiplexer->consistency_checks =
        _mfd_usmDHUserKeyTable_check_dependencies;
#endif

    /*************************************************
     *
     * Create a registration, save our reg data, register table.
     */
    DEBUGMSGTL(("usmDHUserKeyTable:init_usmDHUserKeyTable",
                "Registering usmDHUserKeyTable as a mibs-for-dummies table.\n"));
    handler =
        netsnmp_baby_steps_access_multiplexer_get(access_multiplexer);
    reginfo =
        netsnmp_handler_registration_create("usmDHUserKeyTable", handler,
                                            usmDHUserKeyTable_oid,
                                            usmDHUserKeyTable_oid_size,
                                            HANDLER_CAN_BABY_STEP
#ifndef NETSNMP_DISABLE_SET_SUPPORT
                                          | HANDLER_CAN_RWRITE
#endif
                                          );
    if (NULL == reginfo) {
        snmp_log(LOG_ERR, "error registering table usmDHUserKeyTable\n");
        return;
    }
    reginfo->my_reg_void = &usmDHUserKeyTable_if_ctx;

    /*************************************************
     *
     * set up baby steps handler, create it and inject it
     */
    if (access_multiplexer->object_lookup)
        mfd_modes |= BABY_STEP_OBJECT_LOOKUP;
    if (access_multiplexer->pre_request)
        mfd_modes |= BABY_STEP_PRE_REQUEST;
    if (access_multiplexer->post_request)
        mfd_modes |= BABY_STEP_POST_REQUEST;

#ifndef NETSNMP_DISABLE_SET_SUPPORT
    if (access_multiplexer->set_values)
        mfd_modes |= BABY_STEP_SET_VALUES;
    if (access_multiplexer->irreversible_commit)
        mfd_modes |= BABY_STEP_IRREVERSIBLE_COMMIT;
    if (access_multiplexer->object_syntax_checks)
        mfd_modes |= BABY_STEP_CHECK_OBJECT;

    if (access_multiplexer->undo_setup)
        mfd_modes |= BABY_STEP_UNDO_SETUP;
    if (access_multiplexer->undo_cleanup)
        mfd_modes |= BABY_STEP_UNDO_CLEANUP;
    if (access_multiplexer->undo_sets)
        mfd_modes |= BABY_STEP_UNDO_SETS;

    if (access_multiplexer->row_creation)
        mfd_modes |= BABY_STEP_ROW_CREATE;
    if (access_multiplexer->consistency_checks)
        mfd_modes |= BABY_STEP_CHECK_CONSISTENCY;
    if (access_multiplexer->commit)
        mfd_modes |= BABY_STEP_COMMIT;
    if (access_multiplexer->undo_commit)
        mfd_modes |= BABY_STEP_UNDO_COMMIT;
#endif

    handler = netsnmp_baby_steps_handler_get(mfd_modes);
    netsnmp_inject_handler(reginfo, handler);

    /*************************************************
     *
     * inject row_merge helper with prefix rootoid_len + 2 (entry.col)
     */
    handler = netsnmp_get_row_merge_handler(reginfo->rootoid_len + 2);
    netsnmp_inject_handler(reginfo, handler);

    /*************************************************
     *
     * inject container_table helper
     */
    handler =
        netsnmp_container_table_handler_get(tbl_info,
                                            usmDHUserKeyTable_if_ctx.
                                            container,
                                            TABLE_CONTAINER_KEY_NETSNMP_INDEX);
    netsnmp_inject_handler(reginfo, handler);

    /*************************************************
     *
     * inject cache helper
     */
    if (NULL != usmDHUserKeyTable_if_ctx.cache) {
        handler =
            netsnmp_cache_handler_get(usmDHUserKeyTable_if_ctx.cache);
        netsnmp_inject_handler(reginfo, handler);
    }

    /*
     * register table
     */
    netsnmp_register_table(reginfo, tbl_info);

}                               /* _usmDHUserKeyTable_initialize_interface */

/**
 * @internal
 * Shutdown the table usmDHUserKeyTable
 */
void
_usmDHUserKeyTable_shutdown_interface(usmDHUserKeyTable_registration *
                                      reg_ptr)
{
    /*
     * shutdown the container
     */
    _usmDHUserKeyTable_container_shutdown(&usmDHUserKeyTable_if_ctx);
}

void
usmDHUserKeyTable_valid_columns_set(netsnmp_column_info *vc)
{
    usmDHUserKeyTable_if_ctx.tbl_info.valid_columns = vc;
}                               /* usmDHUserKeyTable_valid_columns_set */

/**
 * @internal
 * convert the index component stored in the context to an oid
 */
int
usmDHUserKeyTable_index_to_oid(netsnmp_index * oid_idx,
                               usmDHUserKeyTable_mib_index * mib_idx)
{
    int             err = SNMP_ERR_NOERROR;

    /*
     * temp storage for parsing indexes
     */
    /*
     * usmUserEngineID(1)/SnmpEngineID/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
     */
    netsnmp_variable_list var_usmUserEngineID;
    /*
     * usmUserName(2)/SnmpAdminString/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/H
     */
    netsnmp_variable_list var_usmUserName;

    /*
     * set up varbinds
     */
    memset(&var_usmUserEngineID, 0x00, sizeof(var_usmUserEngineID));
    var_usmUserEngineID.type = ASN_OCTET_STR;
    memset(&var_usmUserName, 0x00, sizeof(var_usmUserName));
    var_usmUserName.type = ASN_OCTET_STR;

    /*
     * chain temp index varbinds together
     */
    var_usmUserEngineID.next_variable = &var_usmUserName;
    var_usmUserName.next_variable = NULL;


    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_index_to_oid",
                "called\n"));

    /*
     * usmUserEngineID(1)/SnmpEngineID/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
     */
    snmp_set_var_value(&var_usmUserEngineID,
                       (u_char *) & mib_idx->usmUserEngineID,
                       mib_idx->usmUserEngineID_len *
                       sizeof(mib_idx->usmUserEngineID[0]));

    /*
     * usmUserName(2)/SnmpAdminString/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/H 
     */
    snmp_set_var_value(&var_usmUserName, (u_char *) & mib_idx->usmUserName,
                       mib_idx->usmUserName_len *
                       sizeof(mib_idx->usmUserName[0]));


    err = build_oid_noalloc(oid_idx->oids, oid_idx->len, &oid_idx->len,
                            NULL, 0, &var_usmUserEngineID);
    if (err)
        snmp_log(LOG_ERR, "error %d converting index to oid\n", err);

    /*
     * parsing may have allocated memory. free it.
     */
    snmp_reset_var_buffers(&var_usmUserEngineID);

    return err;
}                               /* usmDHUserKeyTable_index_to_oid */

/**
 * extract usmDHUserKeyTable indexes from a netsnmp_index
 *
 * @retval SNMP_ERR_NOERROR  : no error
 * @retval SNMP_ERR_GENERR   : error
 */
int
usmDHUserKeyTable_index_from_oid(netsnmp_index * oid_idx,
                                 usmDHUserKeyTable_mib_index * mib_idx)
{
    int             err = SNMP_ERR_NOERROR;

    /*
     * temp storage for parsing indexes
     */
    /*
     * usmUserEngineID(1)/SnmpEngineID/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
     */
    netsnmp_variable_list var_usmUserEngineID;
    /*
     * usmUserName(2)/SnmpAdminString/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/H
     */
    netsnmp_variable_list var_usmUserName;

    /*
     * set up varbinds
     */
    memset(&var_usmUserEngineID, 0x00, sizeof(var_usmUserEngineID));
    var_usmUserEngineID.type = ASN_OCTET_STR;
    memset(&var_usmUserName, 0x00, sizeof(var_usmUserName));
    var_usmUserName.type = ASN_OCTET_STR;

    /*
     * chain temp index varbinds together
     */
    var_usmUserEngineID.next_variable = &var_usmUserName;
    var_usmUserName.next_variable = NULL;


    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_index_from_oid", "called\n"));

    /*
     * parse the oid into the individual index components
     */
    err = parse_oid_indexes(oid_idx->oids, oid_idx->len,
                            &var_usmUserEngineID);
    if (err == SNMP_ERR_NOERROR) {
        /*
         * copy out values
         */
        /*
         * NOTE: val_len is in bytes, usmUserEngineID_len might not be
         */
        if (var_usmUserEngineID.val_len > sizeof(mib_idx->usmUserEngineID))
            err = SNMP_ERR_GENERR;
        else {
            memcpy(mib_idx->usmUserEngineID,
                   var_usmUserEngineID.val.string,
                   var_usmUserEngineID.val_len);
            mib_idx->usmUserEngineID_len =
                var_usmUserEngineID.val_len /
                sizeof(mib_idx->usmUserEngineID[0]);
        }
        /*
         * NOTE: val_len is in bytes, usmUserName_len might not be
         */
        if (var_usmUserName.val_len > sizeof(mib_idx->usmUserName))
            err = SNMP_ERR_GENERR;
        else {
            memcpy(mib_idx->usmUserName, var_usmUserName.val.string,
                   var_usmUserName.val_len);
            mib_idx->usmUserName_len =
                var_usmUserName.val_len / sizeof(mib_idx->usmUserName[0]);
        }


    }

    /*
     * parsing may have allocated memory. free it.
     */
    snmp_reset_var_buffers(&var_usmUserEngineID);

    return err;
}                               /* usmDHUserKeyTable_index_from_oid */


/*
 *********************************************************************
 * @internal
 * allocate resources for a usmDHUserKeyTable_rowreq_ctx
 */
usmDHUserKeyTable_rowreq_ctx *
usmDHUserKeyTable_allocate_rowreq_ctx(usmDHUserKeyTable_data * data,
                                      void *user_init_ctx)
{
    usmDHUserKeyTable_rowreq_ctx *rowreq_ctx =
        SNMP_MALLOC_TYPEDEF(usmDHUserKeyTable_rowreq_ctx);

    DEBUGMSGTL(("internal:usmDHUserKeyTable:usmDHUserKeyTable_allocate_rowreq_ctx", "called\n"));

    if (NULL == rowreq_ctx) {
        snmp_log(LOG_ERR, "Couldn't allocate memory for a "
                 "usmDHUserKeyTable_rowreq_ctx.\n");
        return NULL;
    } else {
        if (NULL != data) {
            /*
             * track if we got data from user
             */
            rowreq_ctx->rowreq_flags |= MFD_ROW_DATA_FROM_USER;
            rowreq_ctx->data = data;
        } else if (NULL ==
                   (rowreq_ctx->data =
                    usmDHUserKeyTable_allocate_data())) {
            SNMP_FREE(rowreq_ctx);
            return NULL;
        }
    }

    /*
     * undo context will be allocated when needed (in *_undo_setup)
     */

    rowreq_ctx->oid_idx.oids = rowreq_ctx->oid_tmp;

    rowreq_ctx->usmDHUserKeyTable_data_list = NULL;

    /*
     * if we allocated data, call init routine
     */
    if (!(rowreq_ctx->rowreq_flags & MFD_ROW_DATA_FROM_USER)) {
        if (SNMPERR_SUCCESS !=
            usmDHUserKeyTable_rowreq_ctx_init(rowreq_ctx, user_init_ctx)) {
            usmDHUserKeyTable_release_rowreq_ctx(rowreq_ctx);
            rowreq_ctx = NULL;
        }
    }

    return rowreq_ctx;
}                               /* usmDHUserKeyTable_allocate_rowreq_ctx */

/*
 * @internal
 * release resources for a usmDHUserKeyTable_rowreq_ctx
 */
void
usmDHUserKeyTable_release_rowreq_ctx(usmDHUserKeyTable_rowreq_ctx *
                                     rowreq_ctx)
{
    DEBUGMSGTL(("internal:usmDHUserKeyTable:usmDHUserKeyTable_release_rowreq_ctx", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    usmDHUserKeyTable_rowreq_ctx_cleanup(rowreq_ctx);

    /*
     * for non-transient data, don't free data we got from the user
     */
    if ((rowreq_ctx->data) &&
        !(rowreq_ctx->rowreq_flags & MFD_ROW_DATA_FROM_USER))
        usmDHUserKeyTable_release_data(rowreq_ctx->data);

    if (rowreq_ctx->undo) {
        usmDHUserKeyTable_release_data(rowreq_ctx->undo);
        rowreq_ctx->undo = NULL;
    }

    /*
     * free index oid pointer
     */
    if (rowreq_ctx->oid_idx.oids != rowreq_ctx->oid_tmp)
        free(rowreq_ctx->oid_idx.oids);

    SNMP_FREE(rowreq_ctx);
}                               /* usmDHUserKeyTable_release_rowreq_ctx */

/**
 * @internal
 * wrapper
 */
static int
_mfd_usmDHUserKeyTable_pre_request(netsnmp_mib_handler *handler,
                                   netsnmp_handler_registration *reginfo,
                                   netsnmp_agent_request_info *agtreq_info,
                                   netsnmp_request_info *requests)
{
    int             rc;

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_mfd_usmDHUserKeyTable_pre_request", "called\n"));

    if (1 != netsnmp_row_merge_status_first(reginfo, agtreq_info)) {
        DEBUGMSGTL(("internal:usmDHUserKeyTable",
                    "skipping additional pre_request\n"));
        return SNMP_ERR_NOERROR;
    }

    rc = usmDHUserKeyTable_pre_request(usmDHUserKeyTable_if_ctx.user_ctx);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("usmDHUserKeyTable", "error %d from "
                    "usmDHUserKeyTable_pre_request\n", rc));
        netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_usmDHUserKeyTable_pre_request */

/**
 * @internal
 * wrapper
 */
static int
_mfd_usmDHUserKeyTable_post_request(netsnmp_mib_handler *handler,
                                    netsnmp_handler_registration *reginfo,
                                    netsnmp_agent_request_info
                                    *agtreq_info,
                                    netsnmp_request_info *requests)
{
    usmDHUserKeyTable_rowreq_ctx *rowreq_ctx =
        netsnmp_container_table_row_extract(requests);
    int             rc, packet_rc;

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_mfd_usmDHUserKeyTable_post_request", "called\n"));

    /*
     * release row context, if deleted
     */
    if (rowreq_ctx && (rowreq_ctx->rowreq_flags & MFD_ROW_DELETED))
        usmDHUserKeyTable_release_rowreq_ctx(rowreq_ctx);

    /*
     * wait for last call before calling user
     */
    if (1 != netsnmp_row_merge_status_last(reginfo, agtreq_info)) {
        DEBUGMSGTL(("internal:usmDHUserKeyTable",
                    "waiting for last post_request\n"));
        return SNMP_ERR_NOERROR;
    }

    packet_rc = netsnmp_check_all_requests_error(agtreq_info->asp, 0);
    if ((MFD_SUCCESS != packet_rc) && usmDHUserKeyTable_dirty_get()) {
        /*
         * we shouldn't get here. the undo steps should also clear
         * the dirty flags.
         */
        snmp_log(LOG_WARNING,
                 "usmDHUserKeyTable dirty flag set in post_request "
                 "but status != SUCCESS.\n");
    }

    rc = usmDHUserKeyTable_post_request(usmDHUserKeyTable_if_ctx.user_ctx,
                                        packet_rc);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("usmDHUserKeyTable", "error %d from "
                    "usmDHUserKeyTable_post_request\n", rc));
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_usmDHUserKeyTable_post_request */

/**
 * @internal
 * wrapper
 */
static int
_mfd_usmDHUserKeyTable_object_lookup(netsnmp_mib_handler *handler,
                                     netsnmp_handler_registration *reginfo,
                                     netsnmp_agent_request_info
                                     *agtreq_info,
                                     netsnmp_request_info *requests)
{
    int             rc = SNMP_ERR_NOERROR;
    usmDHUserKeyTable_rowreq_ctx *rowreq_ctx =
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_mfd_usmDHUserKeyTable_object_lookup", "called\n"));

    /*
     * get our context from mfd
     * usmDHUserKeyTable_interface_ctx *if_ctx =
     *             (usmDHUserKeyTable_interface_ctx *)reginfo->my_reg_void;
     */

    if (NULL == rowreq_ctx) {
        rc = SNMP_ERR_NOCREATION;
    }

    if (MFD_SUCCESS != rc)
        netsnmp_request_set_error_all(requests, rc);
    else
        usmDHUserKeyTable_row_prep(rowreq_ctx);

    return SNMP_VALIDATE_ERR(rc);
}                               /* _mfd_usmDHUserKeyTable_object_lookup */

/***********************************************************************
 *
 * GET processing
 *
 ***********************************************************************/
/*
 * @internal
 * Retrieve the value for a particular column
 */
NETSNMP_STATIC_INLINE int
_usmDHUserKeyTable_get_column(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                              netsnmp_variable_list * var, int column)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_mfd_usmDHUserKeyTable_get_column", "called for %d\n", column));


    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * usmDHUserAuthKeyChange(1)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSERAUTHKEYCHANGE:
        var->type = ASN_OCTET_STR;
        rc = usmDHUserAuthKeyChange_get(rowreq_ctx,
                                        (char **) &var->val.string,
                                        &var->val_len);
        break;

        /*
         * usmDHUserOwnAuthKeyChange(2)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSEROWNAUTHKEYCHANGE:
        var->type = ASN_OCTET_STR;
        rc = usmDHUserOwnAuthKeyChange_get(rowreq_ctx,
                                           (char **) &var->val.string,
                                           &var->val_len);
        break;

        /*
         * usmDHUserPrivKeyChange(3)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSERPRIVKEYCHANGE:
        var->type = ASN_OCTET_STR;
        rc = usmDHUserPrivKeyChange_get(rowreq_ctx,
                                        (char **) &var->val.string,
                                        &var->val_len);
        break;

        /*
         * usmDHUserOwnPrivKeyChange(4)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSEROWNPRIVKEYCHANGE:
        var->type = ASN_OCTET_STR;
        rc = usmDHUserOwnPrivKeyChange_get(rowreq_ctx,
                                           (char **) &var->val.string,
                                           &var->val_len);
        break;

    default:
        snmp_log(LOG_ERR,
                 "unknown column %d in _usmDHUserKeyTable_get_column\n",
                 column);
        break;
    }

    return rc;
}                               /* _usmDHUserKeyTable_get_column */

int
_mfd_usmDHUserKeyTable_get_values(netsnmp_mib_handler *handler,
                                  netsnmp_handler_registration *reginfo,
                                  netsnmp_agent_request_info *agtreq_info,
                                  netsnmp_request_info *requests)
{
    usmDHUserKeyTable_rowreq_ctx *rowreq_ctx =
        netsnmp_container_table_row_extract(requests);
    netsnmp_table_request_info *tri;
    u_char         *old_string;
    void            (*dataFreeHook) (void *);
    int             rc;

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_mfd_usmDHUserKeyTable_get_values", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    for (; requests; requests = requests->next) {
        /*
         * save old pointer, so we can free it if replaced
         */
        old_string = requests->requestvb->val.string;
        dataFreeHook = requests->requestvb->dataFreeHook;
        if (NULL == requests->requestvb->val.string) {
            requests->requestvb->val.string = requests->requestvb->buf;
            requests->requestvb->val_len =
                sizeof(requests->requestvb->buf);
        } else if (requests->requestvb->buf ==
                   requests->requestvb->val.string) {
            if (requests->requestvb->val_len !=
                sizeof(requests->requestvb->buf))
                requests->requestvb->val_len =
                    sizeof(requests->requestvb->buf);
        }

        /*
         * get column data
         */
        tri = netsnmp_extract_table_info(requests);
        if (NULL == tri)
            continue;

        rc = _usmDHUserKeyTable_get_column(rowreq_ctx, requests->requestvb,
                                           tri->colnum);
        if (rc) {
            if (MFD_SKIP == rc) {
                requests->requestvb->type = SNMP_NOSUCHINSTANCE;
                rc = SNMP_ERR_NOERROR;
            }
        } else if (NULL == requests->requestvb->val.string) {
            snmp_log(LOG_ERR, "NULL varbind data pointer!\n");
            rc = SNMP_ERR_GENERR;
        }
        if (rc)
            netsnmp_request_set_error(requests, SNMP_VALIDATE_ERR(rc));

        /*
         * if the buffer wasn't used previously for the old data (i.e. it
         * was allcoated memory)  and the get routine replaced the pointer,
         * we need to free the previous pointer.
         */
        if (old_string && (old_string != requests->requestvb->buf) &&
            (requests->requestvb->val.string != old_string)) {
            if (dataFreeHook)
                (*dataFreeHook) (old_string);
            else
                free(old_string);
        }
    }                           /* for results */

    return SNMP_ERR_NOERROR;
}                               /* _mfd_usmDHUserKeyTable_get_values */


#ifndef NETSNMP_DISABLE_SET_SUPPORT
/***********************************************************************
 *
 * SET processing
 *
 ***********************************************************************/

/*----------------------------------------------------------------------
 *
 * SET: Syntax checks
 *
 *---------------------------------------------------------------------*/
/*
 * @internal
 * Check the syntax for a particular column
 */
NETSNMP_STATIC_INLINE int
_usmDHUserKeyTable_check_column(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                                netsnmp_variable_list * var, int column)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_usmDHUserKeyTable_check_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * usmDHUserAuthKeyChange(1)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSERAUTHKEYCHANGE:
        rc = netsnmp_check_vb_type(var, ASN_OCTET_STR);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("usmDHUserKeyTable:_usmDHUserKeyTable_check_column:usmDHUserAuthKeyChange", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = usmDHUserAuthKeyChange_check_value(rowreq_ctx,
                                                    (char *) var->val.
                                                    string, var->val_len);
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from usmDHUserAuthKeyChange_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * usmDHUserOwnAuthKeyChange(2)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSEROWNAUTHKEYCHANGE:
        rc = netsnmp_check_vb_type(var, ASN_OCTET_STR);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("usmDHUserKeyTable:_usmDHUserKeyTable_check_column:usmDHUserOwnAuthKeyChange", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = usmDHUserOwnAuthKeyChange_check_value(rowreq_ctx,
                                                       (char *) var->val.
                                                       string,
                                                       var->val_len);
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from usmDHUserOwnAuthKeyChange_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * usmDHUserPrivKeyChange(3)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSERPRIVKEYCHANGE:
        rc = netsnmp_check_vb_type(var, ASN_OCTET_STR);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("usmDHUserKeyTable:_usmDHUserKeyTable_check_column:usmDHUserPrivKeyChange", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = usmDHUserPrivKeyChange_check_value(rowreq_ctx,
                                                    (char *) var->val.
                                                    string, var->val_len);
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from usmDHUserPrivKeyChange_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * usmDHUserOwnPrivKeyChange(4)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSEROWNPRIVKEYCHANGE:
        rc = netsnmp_check_vb_type(var, ASN_OCTET_STR);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("usmDHUserKeyTable:_usmDHUserKeyTable_check_column:usmDHUserOwnPrivKeyChange", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = usmDHUserOwnPrivKeyChange_check_value(rowreq_ctx,
                                                       (char *) var->val.
                                                       string,
                                                       var->val_len);
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from usmDHUserOwnPrivKeyChange_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

    default:    /** We shouldn't get here */
        rc = SNMP_ERR_GENERR;
        snmp_log(LOG_ERR,
                 "unknown column %d in _usmDHUserKeyTable_check_column\n",
                 column);
    }

    return rc;
}                               /* _usmDHUserKeyTable_check_column */

int
_mfd_usmDHUserKeyTable_check_objects(netsnmp_mib_handler *handler,
                                     netsnmp_handler_registration *reginfo,
                                     netsnmp_agent_request_info
                                     *agtreq_info,
                                     netsnmp_request_info *requests)
{
    usmDHUserKeyTable_rowreq_ctx *rowreq_ctx =
        netsnmp_container_table_row_extract(requests);
    netsnmp_table_request_info *tri;
    int             rc;

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_mfd_usmDHUserKeyTable_check_objects", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    for (; requests; requests = requests->next) {

        /*
         * get column number from table request info, and check that column
         */
        tri = netsnmp_extract_table_info(requests);
        if (NULL == tri)
            continue;

        rc = _usmDHUserKeyTable_check_column(rowreq_ctx,
                                             requests->requestvb,
                                             tri->colnum);
        if (rc) {
            netsnmp_request_set_error(requests, SNMP_VALIDATE_ERR(rc));
            break;
        }

    }                           /* for results */

    return SNMP_ERR_NOERROR;
}                               /* _mfd_usmDHUserKeyTable_check_objects */


/*----------------------------------------------------------------------
 *
 * SET: check dependencies
 *
 *---------------------------------------------------------------------*/
/*
 * @internal
 * Check dependencies wrapper
 */
static int
_mfd_usmDHUserKeyTable_check_dependencies(netsnmp_mib_handler *handler, netsnmp_handler_registration
                                          *reginfo, netsnmp_agent_request_info
                                          *agtreq_info,
                                          netsnmp_request_info *requests)
{
    int             rc;
    usmDHUserKeyTable_rowreq_ctx *rowreq_ctx =
        netsnmp_container_table_row_extract(requests);
    DEBUGMSGTL(("internal:usmDHUserKeyTable:_mfd_usmDHUserKeyTable_check_dependencies", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rc = usmDHUserKeyTable_check_dependencies(rowreq_ctx);
    if (rc) {
        DEBUGMSGTL(("usmDHUserKeyTable:mfd", "error %d from "
                    "usmDHUserKeyTable_check_dependencies\n", rc));
        netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_usmDHUserKeyTable_check_dependencies */

/*----------------------------------------------------------------------
 *
 * SET: Undo setup
 *
 *---------------------------------------------------------------------*/
/*
 * @internal
 * Set the value for a particular column
 */
NETSNMP_STATIC_INLINE int
_usmDHUserKeyTable_undo_setup_column(usmDHUserKeyTable_rowreq_ctx *
                                     rowreq_ctx, int column)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_usmDHUserKeyTable_undo_setup_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * usmDHUserAuthKeyChange(1)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSERAUTHKEYCHANGE:
        rowreq_ctx->column_set_flags |= COLUMN_USMDHUSERAUTHKEYCHANGE_FLAG;
        rc = usmDHUserAuthKeyChange_undo_setup(rowreq_ctx);
        break;

        /*
         * usmDHUserOwnAuthKeyChange(2)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSEROWNAUTHKEYCHANGE:
        rowreq_ctx->column_set_flags |=
            COLUMN_USMDHUSEROWNAUTHKEYCHANGE_FLAG;
        rc = usmDHUserOwnAuthKeyChange_undo_setup(rowreq_ctx);
        break;

        /*
         * usmDHUserPrivKeyChange(3)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSERPRIVKEYCHANGE:
        rowreq_ctx->column_set_flags |= COLUMN_USMDHUSERPRIVKEYCHANGE_FLAG;
        rc = usmDHUserPrivKeyChange_undo_setup(rowreq_ctx);
        break;

        /*
         * usmDHUserOwnPrivKeyChange(4)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSEROWNPRIVKEYCHANGE:
        rowreq_ctx->column_set_flags |=
            COLUMN_USMDHUSEROWNPRIVKEYCHANGE_FLAG;
        rc = usmDHUserOwnPrivKeyChange_undo_setup(rowreq_ctx);
        break;

    default:
        snmp_log(LOG_ERR,
                 "unknown column %d in _usmDHUserKeyTable_undo_setup_column\n",
                 column);
        break;
    }

    return rc;
}                               /* _usmDHUserKeyTable_undo_setup_column */


/**
 * @internal
 * undo setup
 */
int
_mfd_usmDHUserKeyTable_undo_setup(netsnmp_mib_handler *handler,
                                  netsnmp_handler_registration *reginfo,
                                  netsnmp_agent_request_info *agtreq_info,
                                  netsnmp_request_info *requests)
{
    int             rc;
    usmDHUserKeyTable_rowreq_ctx *rowreq_ctx =
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_mfd_usmDHUserKeyTable_undo_setup", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * allocate undo context
     */
    rowreq_ctx->undo = usmDHUserKeyTable_allocate_data();
    if (NULL == rowreq_ctx->undo) {
        /** msg already logged */
        netsnmp_request_set_error_all(requests,
                                      SNMP_ERR_RESOURCEUNAVAILABLE);
        return SNMP_ERR_NOERROR;
    }

    /*
     * row undo setup
     */
    rowreq_ctx->column_set_flags = 0;
    rc = usmDHUserKeyTable_undo_setup(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        DEBUGMSGTL(("usmDHUserKeyTable:mfd", "error %d from "
                    "usmDHUserKeyTable_undo_setup\n", rc));
        netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
    } else {
        /*
         * column undo setup
         */
        netsnmp_table_request_info *tri;
        for (; requests; requests = requests->next) {
            /*
             * set column data
             */
            tri = netsnmp_extract_table_info(requests);
            if (NULL == tri)
                continue;

            rc = _usmDHUserKeyTable_undo_setup_column(rowreq_ctx,
                                                      tri->colnum);
            if (MFD_SUCCESS != rc) {
                DEBUGMSGTL(("usmDHUserKeyTable:mfd", "error %d from "
                            "usmDHUserKeyTable_undo_setup_column\n", rc));
                netsnmp_set_request_error(agtreq_info, requests,
                                          SNMP_VALIDATE_ERR(rc));
            }
        }                       /* for results */
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_usmDHUserKeyTable_undo_setup */

/**
 * @internal
 * undo setup
 */
int
_mfd_usmDHUserKeyTable_undo_cleanup(netsnmp_mib_handler *handler,
                                    netsnmp_handler_registration *reginfo,
                                    netsnmp_agent_request_info
                                    *agtreq_info,
                                    netsnmp_request_info *requests)
{
    usmDHUserKeyTable_rowreq_ctx *rowreq_ctx =
        netsnmp_container_table_row_extract(requests);
    int             rc;

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_mfd_usmDHUserKeyTable_undo_cleanup", "called\n"));

    /*
     * failed row create in early stages has no rowreq_ctx
     */
    if (NULL == rowreq_ctx)
        return MFD_SUCCESS;

    /*
     * call user cleanup
     */
    rc = usmDHUserKeyTable_undo_cleanup(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("usmDHUserKeyTable:mfd", "error %d from "
                    "usmDHUserKeyTable_undo_cleanup\n", rc));
    }

    /*
     * release undo context, if needed
     */
    if (rowreq_ctx->undo) {
        usmDHUserKeyTable_release_data(rowreq_ctx->undo);
        rowreq_ctx->undo = NULL;
    }


    return SNMP_ERR_NOERROR;
}                               /* _mfd_usmDHUserKeyTable_undo_cleanup */

/*----------------------------------------------------------------------
 *
 * SET: Set values
 *
 *---------------------------------------------------------------------*/
/*
 * @internal
 * Set the value for a particular column
 */
NETSNMP_STATIC_INLINE int
_usmDHUserKeyTable_set_column(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                              netsnmp_variable_list * var, int column)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_usmDHUserKeyTable_set_column",
                "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * usmDHUserAuthKeyChange(1)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSERAUTHKEYCHANGE:
        rowreq_ctx->column_set_flags |= COLUMN_USMDHUSERAUTHKEYCHANGE_FLAG;
        rc = usmDHUserAuthKeyChange_set(rowreq_ctx,
                                        (char *) var->val.string,
                                        var->val_len);
        break;

        /*
         * usmDHUserOwnAuthKeyChange(2)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSEROWNAUTHKEYCHANGE:
        rowreq_ctx->column_set_flags |=
            COLUMN_USMDHUSEROWNAUTHKEYCHANGE_FLAG;
        rc = usmDHUserOwnAuthKeyChange_set(rowreq_ctx,
                                           (char *) var->val.string,
                                           var->val_len);
        break;

        /*
         * usmDHUserPrivKeyChange(3)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSERPRIVKEYCHANGE:
        rowreq_ctx->column_set_flags |= COLUMN_USMDHUSERPRIVKEYCHANGE_FLAG;
        rc = usmDHUserPrivKeyChange_set(rowreq_ctx,
                                        (char *) var->val.string,
                                        var->val_len);
        break;

        /*
         * usmDHUserOwnPrivKeyChange(4)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSEROWNPRIVKEYCHANGE:
        rowreq_ctx->column_set_flags |=
            COLUMN_USMDHUSEROWNPRIVKEYCHANGE_FLAG;
        rc = usmDHUserOwnPrivKeyChange_set(rowreq_ctx,
                                           (char *) var->val.string,
                                           var->val_len);
        break;

    default:
        snmp_log(LOG_ERR,
                 "unknown column %d in _usmDHUserKeyTable_set_column\n",
                 column);
        rc = SNMP_ERR_GENERR;
        break;
    }

    return rc;
}                               /* _usmDHUserKeyTable_set_column */

int
_mfd_usmDHUserKeyTable_set_values(netsnmp_mib_handler *handler,
                                  netsnmp_handler_registration *reginfo,
                                  netsnmp_agent_request_info *agtreq_info,
                                  netsnmp_request_info *requests)
{
    usmDHUserKeyTable_rowreq_ctx *rowreq_ctx =
        netsnmp_container_table_row_extract(requests);
    netsnmp_table_request_info *tri;
    int             rc = SNMP_ERR_NOERROR;

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_mfd_usmDHUserKeyTable_set_values", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rowreq_ctx->column_set_flags = 0;
    for (; requests; requests = requests->next) {
        /*
         * set column data
         */
        tri = netsnmp_extract_table_info(requests);
        if (NULL == tri)
            continue;

        rc = _usmDHUserKeyTable_set_column(rowreq_ctx,
                                           requests->requestvb,
                                           tri->colnum);
        if (MFD_SUCCESS != rc) {
            DEBUGMSGTL(("usmDHUserKeyTable:mfd", "error %d from "
                        "usmDHUserKeyTable_set_column\n", rc));
            netsnmp_set_request_error(agtreq_info, requests,
                                      SNMP_VALIDATE_ERR(rc));
        }
    }                           /* for results */

    return SNMP_ERR_NOERROR;
}                               /* _mfd_usmDHUserKeyTable_set_values */

/*----------------------------------------------------------------------
 *
 * SET: commit
 *
 *---------------------------------------------------------------------*/
/**
 * @internal
 * commit the values
 */
int
_mfd_usmDHUserKeyTable_commit(netsnmp_mib_handler *handler,
                              netsnmp_handler_registration *reginfo,
                              netsnmp_agent_request_info *agtreq_info,
                              netsnmp_request_info *requests)
{
    int             rc;
    usmDHUserKeyTable_rowreq_ctx *rowreq_ctx =
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_mfd_usmDHUserKeyTable_commit",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rc = usmDHUserKeyTable_commit(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        DEBUGMSGTL(("usmDHUserKeyTable:mfd", "error %d from "
                    "usmDHUserKeyTable_commit\n", rc));
        netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
    }

    if (rowreq_ctx->rowreq_flags & MFD_ROW_DIRTY) {
        /*
         * if we successfully commited this row, set the dirty flag. Use the
         * current value + 1 (i.e. dirty = # rows changed).
         * this is checked in post_request...
         */
        usmDHUserKeyTable_dirty_set(usmDHUserKeyTable_dirty_get() + 1); /* set table dirty flag */
    }

    return SNMP_ERR_NOERROR;
}

int
_mfd_usmDHUserKeyTable_undo_commit(netsnmp_mib_handler *handler,
                                   netsnmp_handler_registration *reginfo,
                                   netsnmp_agent_request_info *agtreq_info,
                                   netsnmp_request_info *requests)
{
    int             rc;
    usmDHUserKeyTable_rowreq_ctx *rowreq_ctx =
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_mfd_usmDHUserKeyTable_undo_commit", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    if (rowreq_ctx->rowreq_flags & MFD_ROW_DIRTY) {
        u_int           d = usmDHUserKeyTable_dirty_get();

        netsnmp_assert(d != 0);
        if (d)
            usmDHUserKeyTable_dirty_set(d - 1);
    }

    rc = usmDHUserKeyTable_undo_commit(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("usmDHUserKeyTable:mfd", "error %d from "
                    "usmDHUserKeyTable_undo_commit\n", rc));
    }

    if (rowreq_ctx->rowreq_flags & MFD_ROW_DIRTY) {
        snmp_log(LOG_WARNING,
                 "usmDHUserKeyTable row dirty flag still set after undo_commit\n");
        rowreq_ctx->rowreq_flags &= ~MFD_ROW_DIRTY;
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_usmDHUserKeyTable_commit */


/*----------------------------------------------------------------------
 *
 * SET: Undo
 *
 *---------------------------------------------------------------------*/
/**
 * @internal
 * undo the value for a particular column
 */
NETSNMP_STATIC_INLINE int
_usmDHUserKeyTable_undo_column(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                               netsnmp_variable_list * var, int column)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_usmDHUserKeyTable_undo_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * usmDHUserAuthKeyChange(1)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSERAUTHKEYCHANGE:
        rc = usmDHUserAuthKeyChange_undo(rowreq_ctx);
        break;

        /*
         * usmDHUserOwnAuthKeyChange(2)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSEROWNAUTHKEYCHANGE:
        rc = usmDHUserOwnAuthKeyChange_undo(rowreq_ctx);
        break;

        /*
         * usmDHUserPrivKeyChange(3)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSERPRIVKEYCHANGE:
        rc = usmDHUserPrivKeyChange_undo(rowreq_ctx);
        break;

        /*
         * usmDHUserOwnPrivKeyChange(4)/DHKeyChange/ASN_OCTET_STR/char(char)//L/A/W/e/r/d/h 
         */
    case COLUMN_USMDHUSEROWNPRIVKEYCHANGE:
        rc = usmDHUserOwnPrivKeyChange_undo(rowreq_ctx);
        break;

    default:
        snmp_log(LOG_ERR,
                 "unknown column %d in _usmDHUserKeyTable_undo_column\n",
                 column);
        break;
    }

    return rc;
}                               /* _usmDHUserKeyTable_undo_column */

int
_mfd_usmDHUserKeyTable_undo_values(netsnmp_mib_handler *handler,
                                   netsnmp_handler_registration *reginfo,
                                   netsnmp_agent_request_info *agtreq_info,
                                   netsnmp_request_info *requests)
{
    int             rc;
    usmDHUserKeyTable_rowreq_ctx *rowreq_ctx =
        netsnmp_container_table_row_extract(requests);
    netsnmp_table_request_info *tri;

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_mfd_usmDHUserKeyTable_undo_values", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rc = usmDHUserKeyTable_undo(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("usmDHUserKeyTable:mfd", "error %d from "
                    "usmDHUserKeyTable_undo\n", rc));
    }

    for (; requests; requests = requests->next) {
        /*
         * set column data
         */
        tri = netsnmp_extract_table_info(requests);
        if (NULL == tri)
            continue;

        rc = _usmDHUserKeyTable_undo_column(rowreq_ctx,
                                            requests->requestvb,
                                            tri->colnum);
        if (MFD_SUCCESS != rc) {
            /*
             * nothing we can do about it but log it
             */
            DEBUGMSGTL(("usmDHUserKeyTable:mfd", "error %d from "
                        "usmDHUserKeyTable_undo_column\n", rc));
        }
    }                           /* for results */

    return SNMP_ERR_NOERROR;
}                               /* _mfd_usmDHUserKeyTable_undo_values */

/*----------------------------------------------------------------------
 *
 * SET: irreversible commit
 *
 *---------------------------------------------------------------------*/
/**
 * @internal
 * commit irreversible actions
 */
int
_mfd_usmDHUserKeyTable_irreversible_commit(netsnmp_mib_handler *handler, netsnmp_handler_registration
                                           *reginfo, netsnmp_agent_request_info
                                           *agtreq_info,
                                           netsnmp_request_info *requests)
{
    int             rc;
    usmDHUserKeyTable_rowreq_ctx *rowreq_ctx =
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_mfd_usmDHUserKeyTable_irreversible:commit", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rc = usmDHUserKeyTable_irreversible_commit(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        netsnmp_request_set_error_all(requests, SNMP_ERR_COMMITFAILED);
        DEBUGMSGTL(("usmDHUserKeyTable:mfd", "error %d from "
                    "usmDHUserKeyTable_irreversible_commit\n", rc));
    }

    /*
     * check for and handle row creation/deletion
     * and update column exist flags...
     */
    if (rowreq_ctx->rowreq_flags & MFD_ROW_DELETED) {
        CONTAINER_REMOVE(usmDHUserKeyTable_if_ctx.container, rowreq_ctx);
    } else {
        if (rowreq_ctx->column_set_flags) {
            rowreq_ctx->column_set_flags = 0;
        }
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_usmDHUserKeyTable_irreversible_commit */
#endif

/***********************************************************************
 *
 * DATA ACCESS
 *
 ***********************************************************************/
static void     _container_free(netsnmp_container * container);

/**
 * @internal
 */
static int
_cache_load(netsnmp_cache * cache, void *vmagic)
{
    DEBUGMSGTL(("internal:usmDHUserKeyTable:_cache_load", "called\n"));

    if ((NULL == cache) || (NULL == cache->magic)) {
        snmp_log(LOG_ERR,
                 "invalid cache for usmDHUserKeyTable_cache_load\n");
        return -1;
    }

    /** should only be called for an invalid or expired cache */
    netsnmp_assert((0 == cache->valid) || (1 == cache->expired));

    /*
     * call user code
     */
    return usmDHUserKeyTable_container_load((netsnmp_container *) cache->
                                            magic);
}                               /* _cache_load */

/**
 * @internal
 */
static void
_cache_free(netsnmp_cache * cache, void *magic)
{
    netsnmp_container *container;

    DEBUGMSGTL(("internal:usmDHUserKeyTable:_cache_free", "called\n"));

    if ((NULL == cache) || (NULL == cache->magic)) {
        snmp_log(LOG_ERR,
                 "invalid cache in usmDHUserKeyTable_cache_free\n");
        return;
    }

    container = (netsnmp_container *) cache->magic;

    _container_free(container);
}                               /* _cache_free */

/**
 * @internal
 */
static void
_container_item_free(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                     void *context)
{
    DEBUGMSGTL(("internal:usmDHUserKeyTable:_container_item_free",
                "called\n"));

    if (NULL == rowreq_ctx)
        return;

    usmDHUserKeyTable_release_rowreq_ctx(rowreq_ctx);
}                               /* _container_item_free */

/**
 * @internal
 */
static void
_container_free(netsnmp_container * container)
{
    DEBUGMSGTL(("internal:usmDHUserKeyTable:_container_free", "called\n"));

    if (NULL == container) {
        snmp_log(LOG_ERR,
                 "invalid container in usmDHUserKeyTable_container_free\n");
        return;
    }

    /*
     * call user code
     */
    usmDHUserKeyTable_container_free(container);

    /*
     * free all items. inefficient, but easy.
     */
    CONTAINER_CLEAR(container,
                    (netsnmp_container_obj_func *) _container_item_free,
                    NULL);
}                               /* _container_free */

/**
 * @internal
 * initialize the container with functions or wrappers
 */
void
_usmDHUserKeyTable_container_init(usmDHUserKeyTable_interface_ctx * if_ctx)
{
    DEBUGMSGTL(("internal:usmDHUserKeyTable:_usmDHUserKeyTable_container_init", "called\n"));

    /*
     * cache init
     */
    if_ctx->cache = netsnmp_cache_create(30,    /* timeout in seconds */
                                         _cache_load, _cache_free,
                                         usmDHUserKeyTable_oid,
                                         usmDHUserKeyTable_oid_size);

    if (NULL == if_ctx->cache) {
        snmp_log(LOG_ERR, "error creating cache for usmDHUserKeyTable\n");
        return;
    }

    if_ctx->cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;

    usmDHUserKeyTable_container_init(&if_ctx->container, if_ctx->cache);
    if (NULL == if_ctx->container)
        if_ctx->container =
            netsnmp_container_find("usmDHUserKeyTable:table_container");
    if (NULL == if_ctx->container) {
        snmp_log(LOG_ERR, "error creating container in "
                 "usmDHUserKeyTable_container_init\n");
        return;
    }

    if (NULL != if_ctx->cache)
        if_ctx->cache->magic = (void *) if_ctx->container;
}                               /* _usmDHUserKeyTable_container_init */

/**
 * @internal
 * shutdown the container with functions or wrappers
 */
void
_usmDHUserKeyTable_container_shutdown(usmDHUserKeyTable_interface_ctx *
                                      if_ctx)
{
    DEBUGMSGTL(("internal:usmDHUserKeyTable:_usmDHUserKeyTable_container_shutdown", "called\n"));

    usmDHUserKeyTable_container_shutdown(if_ctx->container);

    _container_free(if_ctx->container);

}                               /* _usmDHUserKeyTable_container_shutdown */


usmDHUserKeyTable_rowreq_ctx *
usmDHUserKeyTable_row_find_by_mib_index(usmDHUserKeyTable_mib_index *
                                        mib_idx)
{
    usmDHUserKeyTable_rowreq_ctx *rowreq_ctx;
    oid             oid_tmp[MAX_OID_LEN];
    netsnmp_index   oid_idx;
    int             rc;

    /*
     * set up storage for OID
     */
    oid_idx.oids = oid_tmp;
    oid_idx.len = sizeof(oid_tmp) / sizeof(oid);

    /*
     * convert
     */
    rc = usmDHUserKeyTable_index_to_oid(&oid_idx, mib_idx);
    if (MFD_SUCCESS != rc)
        return NULL;

    rowreq_ctx =
        CONTAINER_FIND(usmDHUserKeyTable_if_ctx.container, &oid_idx);

    return rowreq_ctx;
}
