/*
 * 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 "snmpNotifyFilterTable.h"


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

#include "snmpNotifyFilterTable_interface.h"

#include <ctype.h>

/**********************************************************************
 **********************************************************************
 ***
 *** Table snmpNotifyFilterTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * SNMP-NOTIFICATION-MIB::snmpNotifyFilterTable is subid 3 of snmpNotifyObjects.
 * Its status is Current.
 * OID: .1.3.6.1.6.3.13.1.3, length: 9
 */
typedef struct snmpNotifyFilterTable_interface_ctx_s {

    netsnmp_container *container;

    snmpNotifyFilterTable_registration *user_ctx;

    netsnmp_table_registration_info tbl_info;

    netsnmp_baby_steps_access_methods access_multiplexer;

    u_int           table_dirty;

} snmpNotifyFilterTable_interface_ctx;

static snmpNotifyFilterTable_interface_ctx snmpNotifyFilterTable_if_ctx;

static void
                _snmpNotifyFilterTable_container_init(snmpNotifyFilterTable_interface_ctx *
                                                      if_ctx);
static void
 
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    _snmpNotifyFilterTable_container_shutdown
    (snmpNotifyFilterTable_interface_ctx * if_ctx);


netsnmp_container *
snmpNotifyFilterTable_container_get(void)
{
    return snmpNotifyFilterTable_if_ctx.container;
}

snmpNotifyFilterTable_registration *
snmpNotifyFilterTable_registration_get(void)
{
    return snmpNotifyFilterTable_if_ctx.user_ctx;
}

snmpNotifyFilterTable_registration *
snmpNotifyFilterTable_registration_set(snmpNotifyFilterTable_registration *
                                       newreg)
{
    snmpNotifyFilterTable_registration *old =
        snmpNotifyFilterTable_if_ctx.user_ctx;
    snmpNotifyFilterTable_if_ctx.user_ctx = newreg;
    return old;
}

int
snmpNotifyFilterTable_container_size(void)
{
    return CONTAINER_SIZE(snmpNotifyFilterTable_if_ctx.container);
}

u_int
snmpNotifyFilterTable_dirty_get(void)
{
    return snmpNotifyFilterTable_if_ctx.table_dirty;
}

void
snmpNotifyFilterTable_dirty_set(u_int status)
{
    DEBUGMSGTL(("snmpNotifyFilterTable:snmpNotifyFilterTable_dirty_set",
                "called. was %d, now %d\n",
                snmpNotifyFilterTable_if_ctx.table_dirty, status));
    snmpNotifyFilterTable_if_ctx.table_dirty = status;
}

/*
 * mfd multiplexer modes
 */
static Netsnmp_Node_Handler _mfd_snmpNotifyFilterTable_pre_request;
static Netsnmp_Node_Handler _mfd_snmpNotifyFilterTable_post_request;
static Netsnmp_Node_Handler _mfd_snmpNotifyFilterTable_object_lookup;
static Netsnmp_Node_Handler _mfd_snmpNotifyFilterTable_get_values;
#ifndef NETSNMP_DISABLE_SET_SUPPORT
static Netsnmp_Node_Handler _mfd_snmpNotifyFilterTable_check_objects;
static Netsnmp_Node_Handler _mfd_snmpNotifyFilterTable_undo_setup;
static Netsnmp_Node_Handler _mfd_snmpNotifyFilterTable_set_values;
static Netsnmp_Node_Handler _mfd_snmpNotifyFilterTable_undo_cleanup;
static Netsnmp_Node_Handler _mfd_snmpNotifyFilterTable_undo_values;
static Netsnmp_Node_Handler _mfd_snmpNotifyFilterTable_commit;
static Netsnmp_Node_Handler _mfd_snmpNotifyFilterTable_undo_commit;
static Netsnmp_Node_Handler _mfd_snmpNotifyFilterTable_irreversible_commit;
static Netsnmp_Node_Handler _mfd_snmpNotifyFilterTable_check_dependencies;

NETSNMP_STATIC_INLINE int
                _snmpNotifyFilterTable_undo_column(snmpNotifyFilterTable_rowreq_ctx *
                                                   rowreq_ctx,
                                                   netsnmp_variable_list *
                                                   var, int column);
#endif

NETSNMP_STATIC_INLINE int
                _snmpNotifyFilterTable_check_indexes(snmpNotifyFilterTable_rowreq_ctx *
                                                     rowreq_ctx);

snmpNotifyFilterTable_data *snmpNotifyFilterTable_allocate_data(void);

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

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_snmpNotifyFilterTable_initialize_interface", "called\n"));


    /*************************************************
     *
     * save interface context for snmpNotifyFilterTable
     */
    /*
     * Setting up the table's definition
     */
    netsnmp_table_helper_add_indexes(tbl_info, ASN_OCTET_STR,
                                                 /** index: snmpNotifyFilterProfileName */
                                     ASN_PRIV_IMPLIED_OBJECT_ID,
                                                 /** index: snmpNotifyFilterSubtree */
                                     0);

    /*
     * Define the minimum and maximum accessible columns.  This
     * optimizes retrieval. 
     */
    tbl_info->min_column = SNMPNOTIFYFILTERTABLE_MIN_COL;
    tbl_info->max_column = SNMPNOTIFYFILTERTABLE_MAX_COL;

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

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

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

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

    /*
     * no wrappers yet
     */
    access_multiplexer->pre_request =
        _mfd_snmpNotifyFilterTable_pre_request;
    access_multiplexer->post_request =
        _mfd_snmpNotifyFilterTable_post_request;


#ifndef NETSNMP_DISABLE_SET_SUPPORT
    /*
     * REQUIRED wrappers for set request handling
     */
    access_multiplexer->object_syntax_checks =
        _mfd_snmpNotifyFilterTable_check_objects;
    access_multiplexer->undo_setup = _mfd_snmpNotifyFilterTable_undo_setup;
    access_multiplexer->undo_cleanup =
        _mfd_snmpNotifyFilterTable_undo_cleanup;
    access_multiplexer->set_values = _mfd_snmpNotifyFilterTable_set_values;
    access_multiplexer->undo_sets = _mfd_snmpNotifyFilterTable_undo_values;

    /*
     * no wrappers yet
     */
    access_multiplexer->commit = _mfd_snmpNotifyFilterTable_commit;
    access_multiplexer->undo_commit =
        _mfd_snmpNotifyFilterTable_undo_commit;
    access_multiplexer->irreversible_commit =
        _mfd_snmpNotifyFilterTable_irreversible_commit;

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

    /*************************************************
     *
     * Create a registration, save our reg data, register table.
     */
    DEBUGMSGTL(("snmpNotifyFilterTable:init_snmpNotifyFilterTable",
                "Registering snmpNotifyFilterTable as a mibs-for-dummies table.\n"));
    handler =
        netsnmp_baby_steps_access_multiplexer_get(access_multiplexer);
    reginfo =
        netsnmp_handler_registration_create("snmpNotifyFilterTable",
                                            handler,
                                            snmpNotifyFilterTable_oid,
                                            snmpNotifyFilterTable_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 snmpNotifyFilterTable\n");
        return;
    }
    reginfo->my_reg_void = &snmpNotifyFilterTable_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,
                                            snmpNotifyFilterTable_if_ctx.
                                            container,
                                            TABLE_CONTAINER_KEY_NETSNMP_INDEX);
    netsnmp_inject_handler(reginfo, handler);

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

    /*
     * register config/persistence callbacks
     */
    snmpNotifyFilterTable_container_init_persistence
        (snmpNotifyFilterTable_if_ctx.container);

}                               /* _snmpNotifyFilterTable_initialize_interface */

/**
 * @internal
 * Shutdown the table snmpNotifyFilterTable
 */
void
 
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    _snmpNotifyFilterTable_shutdown_interface
    (snmpNotifyFilterTable_registration * reg_ptr) {
    /*
     * shutdown the container
     */
    _snmpNotifyFilterTable_container_shutdown
        (&snmpNotifyFilterTable_if_ctx);
}

void
snmpNotifyFilterTable_valid_columns_set(netsnmp_column_info *vc)
{
    snmpNotifyFilterTable_if_ctx.tbl_info.valid_columns = vc;
}                               /* snmpNotifyFilterTable_valid_columns_set */

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

    /*
     * temp storage for parsing indexes
     */
    /*
     * snmpNotifyFilterProfileName(1)/SnmpAdminString/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/H
     */
    netsnmp_variable_list var_snmpNotifyFilterProfileName;
    /*
     * snmpNotifyFilterSubtree(1)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/a/w/e/r/d/h
     */
    netsnmp_variable_list var_snmpNotifyFilterSubtree;

    /*
     * set up varbinds
     */
    memset(&var_snmpNotifyFilterProfileName, 0x00,
           sizeof(var_snmpNotifyFilterProfileName));
    var_snmpNotifyFilterProfileName.type = ASN_OCTET_STR;
    memset(&var_snmpNotifyFilterSubtree, 0x00,
           sizeof(var_snmpNotifyFilterSubtree));
    var_snmpNotifyFilterSubtree.type = ASN_PRIV_IMPLIED_OBJECT_ID;

    /*
     * chain temp index varbinds together
     */
    var_snmpNotifyFilterProfileName.next_variable =
        &var_snmpNotifyFilterSubtree;
    var_snmpNotifyFilterSubtree.next_variable = NULL;


    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_index_to_oid", "called\n"));

    /*
     * snmpNotifyFilterProfileName(1)/SnmpAdminString/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/H 
     */
    snmp_set_var_value(&var_snmpNotifyFilterProfileName,
                       (u_char *) & mib_idx->snmpNotifyFilterProfileName,
                       mib_idx->snmpNotifyFilterProfileName_len *
                       sizeof(mib_idx->snmpNotifyFilterProfileName[0]));

    /*
     * snmpNotifyFilterSubtree(1)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/a/w/e/r/d/h 
     */
    snmp_set_var_value(&var_snmpNotifyFilterSubtree,
                       (u_char *) & mib_idx->snmpNotifyFilterSubtree,
                       mib_idx->snmpNotifyFilterSubtree_len *
                       sizeof(mib_idx->snmpNotifyFilterSubtree[0]));


    err = build_oid_noalloc(oid_idx->oids, oid_idx->len, &oid_idx->len,
                            NULL, 0, &var_snmpNotifyFilterProfileName);
    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_snmpNotifyFilterProfileName);

    return err;
}                               /* snmpNotifyFilterTable_index_to_oid */

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

    /*
     * temp storage for parsing indexes
     */
    /*
     * snmpNotifyFilterProfileName(1)/SnmpAdminString/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/H
     */
    netsnmp_variable_list var_snmpNotifyFilterProfileName;
    /*
     * snmpNotifyFilterSubtree(1)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/a/w/e/r/d/h
     */
    netsnmp_variable_list var_snmpNotifyFilterSubtree;

    /*
     * set up varbinds
     */
    memset(&var_snmpNotifyFilterProfileName, 0x00,
           sizeof(var_snmpNotifyFilterProfileName));
    var_snmpNotifyFilterProfileName.type = ASN_OCTET_STR;
    memset(&var_snmpNotifyFilterSubtree, 0x00,
           sizeof(var_snmpNotifyFilterSubtree));
    var_snmpNotifyFilterSubtree.type = ASN_PRIV_IMPLIED_OBJECT_ID;

    /*
     * chain temp index varbinds together
     */
    var_snmpNotifyFilterProfileName.next_variable =
        &var_snmpNotifyFilterSubtree;
    var_snmpNotifyFilterSubtree.next_variable = NULL;


    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_index_from_oid", "called\n"));

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


    }

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

    return err;
}                               /* snmpNotifyFilterTable_index_from_oid */


/*
 * snmpNotifyFilterTable_allocate_data
 *
 * Purpose: create new snmpNotifyFilterTable_data.
 */
snmpNotifyFilterTable_data *
snmpNotifyFilterTable_allocate_data(void)
{
    snmpNotifyFilterTable_data *rtn =
        SNMP_MALLOC_TYPEDEF(snmpNotifyFilterTable_data);

    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_allocate_data", "called\n"));

    if (NULL == rtn) {
        snmp_log(LOG_ERR, "unable to malloc memory for new "
                 "snmpNotifyFilterTable_data.\n");
    }

    return rtn;
}                               /* snmpNotifyFilterTable_allocate_data */

/*
 * snmpNotifyFilterTable_release_data
 *
 * Purpose: release snmpNotifyFilterTable data.
 */
void
snmpNotifyFilterTable_release_data(snmpNotifyFilterTable_data * data)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_release_data", "called\n"));

    free(data);
}                               /* snmpNotifyFilterTable_release_data */

/*
 *********************************************************************
 * @internal
 * allocate resources for a snmpNotifyFilterTable_rowreq_ctx
 */
snmpNotifyFilterTable_rowreq_ctx *
snmpNotifyFilterTable_allocate_rowreq_ctx(void *user_init_ctx)
{
    snmpNotifyFilterTable_rowreq_ctx *rowreq_ctx =
        SNMP_MALLOC_TYPEDEF(snmpNotifyFilterTable_rowreq_ctx);

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:snmpNotifyFilterTable_allocate_rowreq_ctx", "called\n"));

    if (NULL == rowreq_ctx) {
        snmp_log(LOG_ERR, "Couldn't allocate memory for a "
                 "snmpNotifyFilterTable_rowreq_ctx.\n");
        return NULL;
    }

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

    rowreq_ctx->snmpNotifyFilterTable_data_list = NULL;

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

    return rowreq_ctx;
}                               /* snmpNotifyFilterTable_allocate_rowreq_ctx */

/*
 * @internal
 * release resources for a snmpNotifyFilterTable_rowreq_ctx
 */
void
snmpNotifyFilterTable_release_rowreq_ctx(snmpNotifyFilterTable_rowreq_ctx *
                                         rowreq_ctx)
{
    DEBUGMSGTL(("internal:snmpNotifyFilterTable:snmpNotifyFilterTable_release_rowreq_ctx", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    snmpNotifyFilterTable_rowreq_ctx_cleanup(rowreq_ctx);

    if (rowreq_ctx->undo)
        snmpNotifyFilterTable_release_data(rowreq_ctx->undo);

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

    SNMP_FREE(rowreq_ctx);
}                               /* snmpNotifyFilterTable_release_rowreq_ctx */

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

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_mfd_snmpNotifyFilterTable_pre_request", "called\n"));

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_pre_request */

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

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_mfd_snmpNotifyFilterTable_post_request", "called\n"));

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

    /*
     * wait for last call before calling user
     */
    if (1 != netsnmp_row_merge_status_last(reginfo, agtreq_info)) {
        DEBUGMSGTL(("internal:snmpNotifyFilterTable",
                    "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) && snmpNotifyFilterTable_dirty_get()) {
        /*
         * we shouldn't get here. the undo steps should also clear
         * the dirty flags.
         */
        snmp_log(LOG_WARNING,
                 "snmpNotifyFilterTable dirty flag set in post_request "
                 "but status != SUCCESS.\n");
    }

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_post_request */


/**
 * @internal
 * wrapper
 */
static snmpNotifyFilterTable_rowreq_ctx *
_mfd_snmpNotifyFilterTable_rowreq_from_index(netsnmp_index * oid_idx,
                                             int *rc_ptr)
{
    snmpNotifyFilterTable_rowreq_ctx *rowreq_ctx;
    snmpNotifyFilterTable_mib_index mib_idx;
    int             rc;

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_mfd_snmpNotifyFilterTable_rowreq_from_index", "called\n"));

    if (NULL == rc_ptr)
        rc_ptr = &rc;
    *rc_ptr = MFD_SUCCESS;

    memset(&mib_idx, 0x0, sizeof(mib_idx));

    /*
     * try to parse oid
     */
    *rc_ptr = snmpNotifyFilterTable_index_from_oid(oid_idx, &mib_idx);
    if (MFD_SUCCESS != *rc_ptr) {
        DEBUGMSGT(("snmpNotifyFilterTable", "error parsing index\n"));
        return NULL;
    }

    /*
     * allocate new context
     */
    rowreq_ctx = snmpNotifyFilterTable_allocate_rowreq_ctx(NULL);
    if (NULL == rowreq_ctx) {
        *rc_ptr = MFD_ERROR;
        return NULL;            /* msg already logged */
    }

    memcpy(&rowreq_ctx->tbl_idx, &mib_idx, sizeof(mib_idx));

    /*
     * check indexes
     */
    *rc_ptr = _snmpNotifyFilterTable_check_indexes(rowreq_ctx);
    if (MFD_SUCCESS != *rc_ptr) {
        netsnmp_assert((*rc_ptr == SNMP_ERR_NOCREATION) ||
                       (*rc_ptr == SNMP_ERR_INCONSISTENTNAME));
        snmpNotifyFilterTable_release_rowreq_ctx(rowreq_ctx);
        return NULL;
    }

    /*
     * copy indexes
     */
    rowreq_ctx->oid_idx.len = oid_idx->len;
    memcpy(rowreq_ctx->oid_idx.oids, oid_idx->oids,
           oid_idx->len * sizeof(oid));

    return rowreq_ctx;
}                               /* _mfd_snmpNotifyFilterTable_rowreq_from_index */


/**
 * @internal
 * wrapper
 */
static int
_mfd_snmpNotifyFilterTable_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;
    snmpNotifyFilterTable_rowreq_ctx *rowreq_ctx = (snmpNotifyFilterTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_mfd_snmpNotifyFilterTable_object_lookup", "called\n"));

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

    if (NULL == rowreq_ctx) {
        netsnmp_table_request_info *tblreq_info;
        netsnmp_index   oid_idx;

        tblreq_info = netsnmp_extract_table_info(requests);
        if (NULL == tblreq_info) {
            snmp_log(LOG_ERR, "request had no table info\n");
            return MFD_ERROR;
        }

        /*
         * try create rowreq
         */
        oid_idx.oids = tblreq_info->index_oid;
        oid_idx.len = tblreq_info->index_oid_len;

        rowreq_ctx =
            _mfd_snmpNotifyFilterTable_rowreq_from_index(&oid_idx, &rc);
        if (MFD_SUCCESS == rc) {
            netsnmp_assert(NULL != rowreq_ctx);
            rowreq_ctx->rowreq_flags |= MFD_ROW_CREATED;
            /*
             * add rowreq_ctx to request data lists
             */
            netsnmp_container_table_row_insert(requests, (netsnmp_index *)
                                               rowreq_ctx);
        }
    }

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

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

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

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_mfd_snmpNotifyFilterTable_get_column", "called for %d\n", column));


    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * snmpNotifyFilterMask(2)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/W/e/R/D/h 
         */
    case COLUMN_SNMPNOTIFYFILTERMASK:
        var->type = ASN_OCTET_STR;
        rc = snmpNotifyFilterMask_get(rowreq_ctx,
                                      (char **) &var->val.string,
                                      &var->val_len);
        break;

        /*
         * snmpNotifyFilterType(3)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_SNMPNOTIFYFILTERTYPE:
        var->val_len = sizeof(u_long);
        var->type = ASN_INTEGER;
        rc = snmpNotifyFilterType_get(rowreq_ctx,
                                      (u_long *) var->val.string);
        break;

        /*
         * snmpNotifyFilterStorageType(4)/StorageType/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_SNMPNOTIFYFILTERSTORAGETYPE:
        var->val_len = sizeof(u_long);
        var->type = ASN_INTEGER;
        rc = snmpNotifyFilterStorageType_get(rowreq_ctx,
                                             (u_long *) var->val.string);
        break;

        /*
         * snmpNotifyFilterRowStatus(5)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_SNMPNOTIFYFILTERROWSTATUS:
        var->val_len = sizeof(u_long);
        var->type = ASN_INTEGER;
        rc = snmpNotifyFilterRowStatus_get(rowreq_ctx,
                                           (u_long *) var->val.string);
        break;

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

    return rc;
}                               /* _snmpNotifyFilterTable_get_column */

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

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_mfd_snmpNotifyFilterTable_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 = _snmpNotifyFilterTable_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_snmpNotifyFilterTable_get_values */

NETSNMP_STATIC_INLINE int
_snmpNotifyFilterTable_check_indexes(snmpNotifyFilterTable_rowreq_ctx *
                                     rowreq_ctx)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_snmpNotifyFilterTable_check_indexes", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * check that the corresponding EXTERNAL row exists
     */

    /*
     * (INDEX) snmpNotifyFilterProfileName(1)/SnmpAdminString/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/H 
     */
    rc = snmpNotifyFilterTable_snmpNotifyFilterProfileName_check_index
        (rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;


    /*
     * (INDEX) snmpNotifyFilterSubtree(1)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/a/w/e/r/d/h 
     */
    if (MFD_SUCCESS != rc)
        return rc;
    rc = snmpNotifyFilterSubtree_check_index(rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;

    /*
     * if individual parts look ok, check them as a whole
     */
    return
        snmpNotifyFilterTable_validate_index(snmpNotifyFilterTable_if_ctx.
                                             user_ctx, rowreq_ctx);
}                               /* _snmpNotifyFilterTable_check_indexes */

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

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

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_snmpNotifyFilterTable_check_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {
        /*
         * (INDEX) snmpNotifyFilterSubtree(1)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/a/w/e/r/d/h 
         */
    case COLUMN_SNMPNOTIFYFILTERSUBTREE:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;

        /*
         * snmpNotifyFilterMask(2)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/W/e/R/D/h 
         */
    case COLUMN_SNMPNOTIFYFILTERMASK:
        rc = netsnmp_check_vb_type_and_max_size(var, ASN_OCTET_STR,
                                                sizeof(rowreq_ctx->data.
                                                       snmpNotifyFilterMask));
        /*
         * check defined range(s). 
         */
        if ((SNMPERR_SUCCESS == rc)
            && ((var->val_len < 0) || (var->val_len > 16))
            ) {
            rc = SNMP_ERR_WRONGLENGTH;
        }
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("snmpNotifyFilterTable:_snmpNotifyFilterTable_check_column:snmpNotifyFilterMask", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = snmpNotifyFilterMask_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 snmpNotifyFilterMask_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * snmpNotifyFilterType(3)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_SNMPNOTIFYFILTERTYPE:
        rc = netsnmp_check_vb_type_and_size(var, ASN_INTEGER,
                                            sizeof(rowreq_ctx->data.
                                                   snmpNotifyFilterType));
        /*
         * check that the value is one of defined enums 
         */
        if ((SNMPERR_SUCCESS == rc)
            && (*var->val.integer != SNMPNOTIFYFILTERTYPE_INCLUDED)
            && (*var->val.integer != SNMPNOTIFYFILTERTYPE_EXCLUDED)
            ) {
            rc = SNMP_ERR_WRONGVALUE;
        }
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("snmpNotifyFilterTable:_snmpNotifyFilterTable_check_column:snmpNotifyFilterType", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = snmpNotifyFilterType_check_value(rowreq_ctx,
                                                  *((u_long *) var->val.
                                                    string));
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from snmpNotifyFilterType_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * snmpNotifyFilterStorageType(4)/StorageType/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_SNMPNOTIFYFILTERSTORAGETYPE:
        rc = netsnmp_check_vb_type_and_size(var, ASN_INTEGER,
                                            sizeof(rowreq_ctx->data.
                                                   snmpNotifyFilterStorageType));
        /*
         * check that the value is one of defined enums 
         */
        if ((SNMPERR_SUCCESS == rc)
            && (*var->val.integer != STORAGETYPE_OTHER)
            && (*var->val.integer != STORAGETYPE_VOLATILE)
            && (*var->val.integer != STORAGETYPE_NONVOLATILE)
            && (*var->val.integer != STORAGETYPE_PERMANENT)
            && (*var->val.integer != STORAGETYPE_READONLY)
            ) {
            rc = SNMP_ERR_WRONGVALUE;
        }
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("snmpNotifyFilterTable:_snmpNotifyFilterTable_check_column:snmpNotifyFilterStorageType", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = snmpNotifyFilterStorageType_check_value(rowreq_ctx,
                                                         *((u_long *) var->
                                                           val.string));
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from snmpNotifyFilterStorageType_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * snmpNotifyFilterRowStatus(5)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_SNMPNOTIFYFILTERROWSTATUS:
        rc = netsnmp_check_vb_rowstatus_value(var);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("snmpNotifyFilterTable:_snmpNotifyFilterTable_check_column:snmpNotifyFilterRowStatus", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = snmpNotifyFilterRowStatus_check_value(rowreq_ctx,
                                                       *((u_long *) var->
                                                         val.string));
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from snmpNotifyFilterRowStatus_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 _snmpNotifyFilterTable_check_column\n",
                 column);
    }

    return rc;
}                               /* _snmpNotifyFilterTable_check_column */

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

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_mfd_snmpNotifyFilterTable_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 = _snmpNotifyFilterTable_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_snmpNotifyFilterTable_check_objects */


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

    netsnmp_assert(NULL != rowreq_ctx);

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_check_dependencies */

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

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_snmpNotifyFilterTable_undo_setup_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * snmpNotifyFilterMask(2)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/W/e/R/D/h 
         */
    case COLUMN_SNMPNOTIFYFILTERMASK:
        rowreq_ctx->column_set_flags |= COLUMN_SNMPNOTIFYFILTERMASK_FLAG;
        rc = snmpNotifyFilterMask_undo_setup(rowreq_ctx);
        break;

        /*
         * snmpNotifyFilterType(3)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_SNMPNOTIFYFILTERTYPE:
        rowreq_ctx->column_set_flags |= COLUMN_SNMPNOTIFYFILTERTYPE_FLAG;
        rc = snmpNotifyFilterType_undo_setup(rowreq_ctx);
        break;

        /*
         * snmpNotifyFilterStorageType(4)/StorageType/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_SNMPNOTIFYFILTERSTORAGETYPE:
        rowreq_ctx->column_set_flags |=
            COLUMN_SNMPNOTIFYFILTERSTORAGETYPE_FLAG;
        rc = snmpNotifyFilterStorageType_undo_setup(rowreq_ctx);
        break;

        /*
         * snmpNotifyFilterRowStatus(5)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_SNMPNOTIFYFILTERROWSTATUS:
        rowreq_ctx->column_set_flags |=
            COLUMN_SNMPNOTIFYFILTERROWSTATUS_FLAG;
        rc = snmpNotifyFilterRowStatus_undo_setup(rowreq_ctx);
        break;

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

    return rc;
}                               /* _snmpNotifyFilterTable_undo_setup_column */


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

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_mfd_snmpNotifyFilterTable_undo_setup", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * allocate undo context
     */
    rowreq_ctx->undo = snmpNotifyFilterTable_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 = snmpNotifyFilterTable_undo_setup(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        DEBUGMSGTL(("snmpNotifyFilterTable:mfd", "error %d from "
                    "snmpNotifyFilterTable_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 = _snmpNotifyFilterTable_undo_setup_column(rowreq_ctx,
                                                          tri->colnum);
            if (MFD_SUCCESS != rc) {
                DEBUGMSGTL(("snmpNotifyFilterTable:mfd", "error %d from "
                            "snmpNotifyFilterTable_undo_setup_column\n",
                            rc));
                netsnmp_set_request_error(agtreq_info, requests,
                                          SNMP_VALIDATE_ERR(rc));
            }
        }                       /* for results */
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_undo_setup */

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

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_mfd_snmpNotifyFilterTable_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 = snmpNotifyFilterTable_undo_cleanup(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("snmpNotifyFilterTable:mfd", "error %d from "
                    "snmpNotifyFilterTable_undo_cleanup\n", rc));
    }

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


    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_undo_cleanup */

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

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_snmpNotifyFilterTable_set_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * snmpNotifyFilterMask(2)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/W/e/R/D/h 
         */
    case COLUMN_SNMPNOTIFYFILTERMASK:
        rowreq_ctx->column_set_flags |= COLUMN_SNMPNOTIFYFILTERMASK_FLAG;
        rc = snmpNotifyFilterMask_set(rowreq_ctx, (char *) var->val.string,
                                      var->val_len);
        break;

        /*
         * snmpNotifyFilterType(3)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_SNMPNOTIFYFILTERTYPE:
        rowreq_ctx->column_set_flags |= COLUMN_SNMPNOTIFYFILTERTYPE_FLAG;
        rc = snmpNotifyFilterType_set(rowreq_ctx,
                                      *((u_long *) var->val.string));
        break;

        /*
         * snmpNotifyFilterStorageType(4)/StorageType/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_SNMPNOTIFYFILTERSTORAGETYPE:
        rowreq_ctx->column_set_flags |=
            COLUMN_SNMPNOTIFYFILTERSTORAGETYPE_FLAG;
        rc = snmpNotifyFilterStorageType_set(rowreq_ctx,
                                             *((u_long *) var->val.
                                               string));
        break;

        /*
         * snmpNotifyFilterRowStatus(5)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_SNMPNOTIFYFILTERROWSTATUS:
        rowreq_ctx->column_set_flags |=
            COLUMN_SNMPNOTIFYFILTERROWSTATUS_FLAG;
        rc = snmpNotifyFilterRowStatus_set(rowreq_ctx,
                                           *((u_long *) var->val.string));
        break;

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

    return rc;
}                               /* _snmpNotifyFilterTable_set_column */

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

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_mfd_snmpNotifyFilterTable_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 = _snmpNotifyFilterTable_set_column(rowreq_ctx,
                                               requests->requestvb,
                                               tri->colnum);
        if (MFD_SUCCESS != rc) {
            DEBUGMSGTL(("snmpNotifyFilterTable:mfd", "error %d from "
                        "snmpNotifyFilterTable_set_column\n", rc));
            netsnmp_set_request_error(agtreq_info, requests,
                                      SNMP_VALIDATE_ERR(rc));
        }
    }                           /* for results */

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_set_values */

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

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_mfd_snmpNotifyFilterTable_commit", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rc = snmpNotifyFilterTable_commit(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        DEBUGMSGTL(("snmpNotifyFilterTable:mfd", "error %d from "
                    "snmpNotifyFilterTable_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...
         */
        snmpNotifyFilterTable_dirty_set(snmpNotifyFilterTable_dirty_get() + 1); /* set table dirty flag */
    }

    return SNMP_ERR_NOERROR;
}

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

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_mfd_snmpNotifyFilterTable_undo_commit", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_commit */

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

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_snmpNotifyFilterTable_undo_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * snmpNotifyFilterMask(2)/OCTETSTR/ASN_OCTET_STR/char(char)//L/A/W/e/R/D/h 
         */
    case COLUMN_SNMPNOTIFYFILTERMASK:
        rc = snmpNotifyFilterMask_undo(rowreq_ctx);
        break;

        /*
         * snmpNotifyFilterType(3)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_SNMPNOTIFYFILTERTYPE:
        rc = snmpNotifyFilterType_undo(rowreq_ctx);
        break;

        /*
         * snmpNotifyFilterStorageType(4)/StorageType/ASN_INTEGER/long(u_long)//l/A/W/E/r/D/h 
         */
    case COLUMN_SNMPNOTIFYFILTERSTORAGETYPE:
        rc = snmpNotifyFilterStorageType_undo(rowreq_ctx);
        break;

        /*
         * snmpNotifyFilterRowStatus(5)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_SNMPNOTIFYFILTERROWSTATUS:
        rc = snmpNotifyFilterRowStatus_undo(rowreq_ctx);
        break;

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

    return rc;
}                               /* _snmpNotifyFilterTable_undo_column */

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

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_mfd_snmpNotifyFilterTable_undo_values", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_undo_values */

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

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_mfd_snmpNotifyFilterTable_irreversible:commit", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_irreversible_commit */
#endif

/***********************************************************************
 *
 * DATA ACCESS
 *
 ***********************************************************************/
/**
 * @internal
 */
static void
_container_item_free(snmpNotifyFilterTable_rowreq_ctx * rowreq_ctx,
                     void *context)
{
    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_container_item_free",
                "called\n"));

    if (NULL == rowreq_ctx)
        return;

    snmpNotifyFilterTable_release_rowreq_ctx(rowreq_ctx);
}                               /* _container_item_free */

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

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

    /*
     * call user code
     */
    snmpNotifyFilterTable_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
_snmpNotifyFilterTable_container_init(snmpNotifyFilterTable_interface_ctx *
                                      if_ctx)
{
    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_snmpNotifyFilterTable_container_init", "called\n"));

    /*
     * container init
     */
    snmpNotifyFilterTable_container_init(&if_ctx->container);
    if (NULL == if_ctx->container)
        if_ctx->container =
            netsnmp_container_find
            ("snmpNotifyFilterTable:table_container");
    if (NULL == if_ctx->container) {
        snmp_log(LOG_ERR, "error creating container in "
                 "snmpNotifyFilterTable_container_init\n");
        return;
    }

}                               /* _snmpNotifyFilterTable_container_init */

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

    snmpNotifyFilterTable_container_shutdown(if_ctx->container);

    _container_free(if_ctx->container);

}                               /* _snmpNotifyFilterTable_container_shutdown */

/***********************************************************************
 *
 * PERSISTENCE
 *
 ***********************************************************************/

static int      _snmpNotifyFilterTable_container_save_rows(int majorID,
                                                           int minorID,
                                                           void *serverarg,
                                                           void
                                                           *clientarg);
static void     _snmpNotifyFilterTable_container_row_restore(const char
                                                             *token,
                                                             char *buf);
static int
                _snmpNotifyFilterTable_container_row_save(snmpNotifyFilterTable_rowreq_ctx
                                                          * rowreq_ctx,
                                                          void *type);
static char
 
    
    
    
    
    
    
    
    
    
    
    
    
    
    *_snmpNotifyFilterTable_container_col_restore
    (snmpNotifyFilterTable_rowreq_ctx * rowreq_ctx, u_int col, char *buf);
static char
 
    
    
    
    
    
    
    
    
    
    
    
    
    
    *_snmpNotifyFilterTable_container_col_save
    (snmpNotifyFilterTable_rowreq_ctx * rowreq_ctx, u_int col, char *buf);

static char     row_token[] = "snmpNotifyFilterTable";

/************************************************************
 * *_init_persistence should be called from the main table
 * init routine.
 *
 * If your table depends on rows in another table,
 * you should register your callback after the other table,
 * which should ensure the rows on which you depend are saved
 * (and re-created) before the dependent rows.
 */
void
snmpNotifyFilterTable_container_init_persistence(netsnmp_container
                                                 *container)
{
    int             rc;

    register_config_handler(NULL, row_token,
                            _snmpNotifyFilterTable_container_row_restore,
                            NULL, NULL);
    rc = snmp_register_callback(SNMP_CALLBACK_LIBRARY,
                                SNMP_CALLBACK_STORE_DATA,
                                _snmpNotifyFilterTable_container_save_rows,
                                container);

    if (rc != SNMP_ERR_NOERROR)
        snmp_log(LOG_ERR, "error registering for STORE_DATA callback "
                 "in _snmpNotifyFilterTable_container_init_persistence\n");
}

static int
_snmpNotifyFilterTable_container_save_rows(int majorID, int minorID,
                                           void *serverarg,
                                           void *clientarg)
{
    char            sep[] =
        "##############################################################";
    char            buf[] =
        "#\n" "# snmpNotifyFilterTable persistent data\n" "#";
    char           *type = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
                                                 NETSNMP_DS_LIB_APPTYPE);
    netsnmp_container *c = (netsnmp_container *) clientarg;

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:"
                "_snmpNotifyFilterTable_container_save_rows",
                "saving %" NETSNMP_PRIz "u rows\n", CONTAINER_SIZE(c)));

    read_config_store((char *) type, sep);
    read_config_store((char *) type, buf);

    /*
     * save all rows
     */
    CONTAINER_FOR_EACH(c, (netsnmp_container_obj_func *)
                       _snmpNotifyFilterTable_container_row_save, type);

    read_config_store((char *) type, sep);
    read_config_store((char *) type, "\n");

    /*
     * never fails 
     */
    return SNMPERR_SUCCESS;
}



/************************************************************
 * _snmpNotifyFilterTable_container_row_save
 */
static int
_snmpNotifyFilterTable_container_row_save(snmpNotifyFilterTable_rowreq_ctx
                                          * rowreq_ctx, void *type)
{
    /*
     * Allocate space for a line with all data for a row. An
     * attempt is made to come up with a default maximum size, but
     * there is no guarantee it will be enough. It probably will be,
     * unless you are dealing with large values or you have external
     * indexes.
     *
     * 1) allocate space for each column. Comment out columns you don't
     * intend to save. You may also need to add room for any non-
     * column data you want to store. Remeber, data will be stored in
     * ASCII form, so you need to allow for that. Here are some
     * general guidelines:
     *
     *   Object ID   :  12 * len [ASCII len of max int + 1 for .]
     *   Octet String: (2 * len) + 2 [2 ASCII chars per byte + "0x"]
     *   Integers    :  12 [ASCII len for smallest negative number]
     *
     * 2) You also need to allocate space for the row index. This will
     * be stored as an OID, which means that Octet Strings need to
     * be treated a little differently. Specifically, you will need
     * (4 * len) + 4 [3 ASCII chars per byte + 1 for ., + 4 for len].
     *
     * 3) Also, remember to add space for the identifier and separator
     * characters (for example, each column is prefixed by the
     * column number and a semicolon. To allow for the maximum
     * column values, 12 bytes [11 for oid + 1 for ':'] per
     * column are added).
     */

#define MAX_ROW_SIZE (sizeof(row_token) + 1 +  \
        ( 12 * 128 ) + /* ASN_OBJECT_ID snmpNotifyFilterSubtree and */ \
                       /* ASN_OCTET_STR snmpNotifyFilterProfileName indices */ \
        ( ( 2 * sizeof(rowreq_ctx->data.snmpNotifyFilterMask) ) + 3 ) + /* ASN_OCTET_STR */ \
        ( 12 ) + /* ASN_INTEGER snmpNotifyFilterType */ \
        ( 12 ) + /* ASN_INTEGER snmpNotifyFilterStorageType */ \
        ( 12 ) + /* ASN_INTEGER snmpNotifyFilterRowStatus */ \
        ( SNMPNOTIFYFILTERTABLE_MAX_COL * 12 ) + /* column num prefix + : */ \
    2 /* LINE_TERM_CHAR + \n */ )

    char            buf[MAX_ROW_SIZE], *pos = buf, *max =
        &buf[MAX_ROW_SIZE - 1];
    char           *tmp;
    int             i;

    if (snmpNotifyFilterTable_container_should_save(rowreq_ctx) == 0) {
        return SNMP_ERR_NOERROR;
    }

    /*
     * build the line
     */
    pos += sprintf(pos, "%s ", row_token);
    pos = read_config_save_objid(pos, rowreq_ctx->oid_idx.oids,
                                 rowreq_ctx->oid_idx.len);
    if (NULL == pos) {
        snmp_log(LOG_ERR, "error saving snmpNotifyFilterTable row "
                 "to persistent file\n");
        return SNMP_ERR_GENERR;
    }
    *pos++ = ' ';
    if (pos > max) {
        snmp_log(LOG_ERR, "error saving snmpNotifyFilterTable row "
                 "to persistent file (too long)\n");
        return SNMP_ERR_GENERR;
    }

    /*
     * add each column
     */
    for (i = SNMPNOTIFYFILTERTABLE_MIN_COL;
         i <= SNMPNOTIFYFILTERTABLE_MAX_COL; ++i) {

        if ((0x1 << (i - 1)) & ~SNMPNOTIFYFILTERTABLE_SETTABLE_COLS)
            continue;

        tmp = pos;
        pos =
            _snmpNotifyFilterTable_container_col_save(rowreq_ctx, i, pos);
        if (NULL == pos)
            pos = tmp;
        else
            *pos++ = ' ';
        if (pos > max) {
            snmp_log(LOG_ERR, "error saving snmpNotifyFilterTable row "
                     "to persistent file (too long)\n");
            return SNMP_ERR_GENERR;
        }
    }

    /*
     * if you have non-column data, add it here
     */


    /*
     * store the line
     */
    pos += sprintf(pos, "%c", LINE_TERM_CHAR);
    if (pos > max) {
        snmp_log(LOG_ERR, "error saving snmpNotifyFilterTable row "
                 "to persistent file (too long)\n");
        return SNMP_ERR_GENERR;
    }
    read_config_store((char *) type, buf);

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_snmpNotifyFilterTable_container_row_save", "saving line '%s'\n", buf));

    return SNMP_ERR_NOERROR;
}

static void
_snmpNotifyFilterTable_container_row_restore(const char *token, char *buf)
{
    snmpNotifyFilterTable_rowreq_ctx *rowreq_ctx;
    netsnmp_index   index;
    oid             tmp_oid[MAX_snmpNotifyFilterTable_IDX_LEN];
    u_int           col = 0, found = 0;


    if (strncmp(token, row_token, sizeof(row_token)) != 0) {
        snmp_log(LOG_ERR,
                 "unknown token in _snmpNotifyFilterTable_container_row_restore\n");
        return;
    }

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_snmpNotifyFilterTable_container_row_restore", "parsing line '%s'\n", buf));

    /*
     * pull out index and create default row
     */
    index.oids = tmp_oid;
    index.len = OID_LENGTH(tmp_oid);
    buf = read_config_read_objid(buf, &index.oids, &index.len);
    if (NULL == buf) {
        snmp_log(LOG_ERR, "error reading row index in "
                 "_snmpNotifyFilterTable_container_row_restore\n");
        return;
    }
    rowreq_ctx =
        _mfd_snmpNotifyFilterTable_rowreq_from_index(&index, NULL);
    if (NULL == rowreq_ctx) {
        snmp_log(LOG_ERR, "error creating row index in "
                 "_snmpNotifyFilterTable_container_row_restore\n");
        return;
    }

    /*
     * loop through and get each column
     */
    buf = skip_white(buf);
    while ((NULL != buf) && isdigit((unsigned char)(*buf))) {
        /*
         * extract column, skip ':'
         */
        col = (u_int) strtol(buf, &buf, 10);
        if (NULL == buf)
            break;
        if (*buf != ':') {
            buf = NULL;
            break;
        }
        ++buf;                  /* skip : */

        /*
         * parse value
         */
        DEBUGMSGTL(("_snmpNotifyFilterTable_container_row_restore",
                    "parsing column %d\n", col));
        buf =
            _snmpNotifyFilterTable_container_col_restore(rowreq_ctx, col,
                                                         buf);
        ++found;
    }
    if (0 == found) {
        snmp_log(LOG_ERR,
                 "error parsing snmpNotifyFilterTable row; no columns found");
        snmpNotifyFilterTable_release_rowreq_ctx(rowreq_ctx);
        return;
    }

    /*
     * if you added any non-column data, this is where
     * you should handle it.
     */

    /*
     * if the pointer is NULL and we didn't reach the
     * end of the line, something went wrong. Log message,
     * delete the row and bail.
     */
    if ((buf == NULL) || (*buf != LINE_TERM_CHAR)) {
        snmp_log(LOG_ERR,
                 "error parsing snmpNotifyFilterTable row around column %d",
                 col);
        snmpNotifyFilterTable_release_rowreq_ctx(rowreq_ctx);
        return;
    }

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_snmpNotifyFilterTable_container_row_restore", "inserting row\n"));

    /*
     * copy oid index and insert row
     */
    rowreq_ctx->oid_idx.len = index.len;
    memcpy(rowreq_ctx->oid_idx.oids, index.oids, index.len * sizeof(oid));

    CONTAINER_INSERT(snmpNotifyFilterTable_if_ctx.container, rowreq_ctx);
}

/************************************************************
 * _snmpNotifyFilterTable_container_col_save
 */
static char    *
_snmpNotifyFilterTable_container_col_save(snmpNotifyFilterTable_rowreq_ctx
                                          * rowreq_ctx, u_int col,
                                          char *buf)
{
    if ((NULL == rowreq_ctx) || (NULL == buf)) {
        snmp_log(LOG_ERR, "bad parameter in "
                 "_snmpNotifyFilterTable_container_col_save\n");
        return NULL;
    }

    DEBUGMSGTL(("internal:snmpNotifyFilterTable:_snmpNotifyFilterTable_container_col_save", "processing column %d\n", col));

    /*
     * prefix with column number, so we don't ever depend on
     * order saved.
     */
    buf += sprintf(buf, "%u:", col);

    /*
     * save data for the column
     */
    switch (col) {

    case COLUMN_SNMPNOTIFYFILTERMASK:   /** OCTETSTR = ASN_OCTET_STR */
        buf =
            read_config_save_octet_string(buf,
                                          (u_char *) rowreq_ctx->data.
                                          snmpNotifyFilterMask,
                                          rowreq_ctx->data.
                                          snmpNotifyFilterMask_len);
        break;

    case COLUMN_SNMPNOTIFYFILTERTYPE:   /** INTEGER = ASN_INTEGER */
        buf += sprintf(buf, "%ld", rowreq_ctx->data.snmpNotifyFilterType);
        break;

    case COLUMN_SNMPNOTIFYFILTERSTORAGETYPE:   /** StorageType = ASN_INTEGER */
        buf +=
            sprintf(buf, "%ld",
                    rowreq_ctx->data.snmpNotifyFilterStorageType);
        break;

    case COLUMN_SNMPNOTIFYFILTERROWSTATUS:   /** RowStatus = ASN_INTEGER */
        buf +=
            sprintf(buf, "%ld",
                    rowreq_ctx->data.snmpNotifyFilterRowStatus);
        break;

    default:
            /** We shouldn't get here */
        snmp_log(LOG_ERR, "unknown column %d in "
                 "_snmpNotifyFilterTable_container_col_save\n", col);
        return NULL;
    }

    return buf;
}

/************************************************************
 * _snmpNotifyFilterTable_container_col_restore
 */
static char    *_snmpNotifyFilterTable_container_col_restore
    (snmpNotifyFilterTable_rowreq_ctx * rowreq_ctx, u_int col, char *buf) {
    size_t          len;
    if ((NULL == rowreq_ctx) || (NULL == buf)) {
        snmp_log(LOG_ERR, "bad parameter in "
                 "_snmpNotifyFilterTable_container_col_restore\n");
        return NULL;
    }

    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:_snmpNotifyFilterTable_container_col_restore", "processing column %d\n", col));

    /*
     * restore data for the column
     */
    switch (col) {

    case COLUMN_SNMPNOTIFYFILTERMASK:   /** OCTETSTR = ASN_OCTET_STR */
        rowreq_ctx->data.snmpNotifyFilterMask_len =
            sizeof(rowreq_ctx->data.snmpNotifyFilterMask);
        buf =
            read_config_read_memory(ASN_OCTET_STR, buf,
                                    (char *) &rowreq_ctx->data.
                                    snmpNotifyFilterMask,
                                    (size_t *) & rowreq_ctx->data.
                                    snmpNotifyFilterMask_len);
        break;

    case COLUMN_SNMPNOTIFYFILTERTYPE:   /** INTEGER = ASN_INTEGER */
        len = sizeof(rowreq_ctx->data.snmpNotifyFilterType);
        buf = read_config_read_memory(ASN_INTEGER, buf,
                                      (char *) &rowreq_ctx->data.
                                      snmpNotifyFilterType, &len);
        break;

    case COLUMN_SNMPNOTIFYFILTERSTORAGETYPE:   /** StorageType = ASN_INTEGER */
        len = sizeof(rowreq_ctx->data.snmpNotifyFilterStorageType);
        buf = read_config_read_memory(ASN_INTEGER, buf,
                                      (char *) &rowreq_ctx->data.
                                      snmpNotifyFilterStorageType, &len);
        break;

    case COLUMN_SNMPNOTIFYFILTERROWSTATUS:   /** RowStatus = ASN_INTEGER */
        len = sizeof(rowreq_ctx->data.snmpNotifyFilterRowStatus);
        buf = read_config_read_memory(ASN_INTEGER, buf,
                                      (char *) &rowreq_ctx->data.
                                      snmpNotifyFilterRowStatus, &len);
        break;

    default:
            /** We shouldn't get here */
        snmp_log(LOG_ERR, "unknown column %d in "
                 "_snmpNotifyFilterTable_container_col_restore\n", col);
        return NULL;
    }

    return buf;
}


snmpNotifyFilterTable_rowreq_ctx *
snmpNotifyFilterTable_row_find_by_mib_index(snmpNotifyFilterTable_mib_index
                                            * mib_idx)
{
    snmpNotifyFilterTable_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 = snmpNotifyFilterTable_index_to_oid(&oid_idx, mib_idx);
    if (MFD_SUCCESS != rc)
        return NULL;

    rowreq_ctx = (snmpNotifyFilterTable_rowreq_ctx*)
        CONTAINER_FIND(snmpNotifyFilterTable_if_ctx.container, &oid_idx);

    return rowreq_ctx;
}
