/*
 * 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 retrival. 
     */
    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 =
        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 =
        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 =
        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 =
        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 =
        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 =
        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 =
        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 =
        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 =
        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 =
        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 =
        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 =
        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 %d 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, remeber to add space for the identifier and seperator
     * 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(*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 =
        CONTAINER_FIND(snmpNotifyFilterTable_if_ctx.container, &oid_idx);

    return rowreq_ctx;
}
