/*
 * 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 %" 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, 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;
}
