/*
 * 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-features.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>

netsnmp_feature_child_of(snmpNotifyFilterTable_external_access, libnetsnmpmibs)

netsnmp_feature_require(row_merge)
netsnmp_feature_require(baby_steps)
netsnmp_feature_require(table_container_row_insert)
netsnmp_feature_require(check_all_requests_error)
#ifndef NETSNMP_NO_WRITE_SUPPORT
netsnmp_feature_require(check_vb_type_and_max_size)
#endif /* NETSNMP_NO_WRITE_SUPPORT */


netsnmp_feature_child_of(snmpNotifyFilterTable_container_size, snmpNotifyFilterTable_external_access)
netsnmp_feature_child_of(snmpNotifyFilterTable_registration_set, snmpNotifyFilterTable_external_access)
netsnmp_feature_child_of(snmpNotifyFilterTable_registration_get, snmpNotifyFilterTable_external_access)
netsnmp_feature_child_of(snmpNotifyFilterTable_container_get, snmpNotifyFilterTable_external_access)

/**********************************************************************
 **********************************************************************
 ***
 *** 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);

#ifndef NETSNMP_FEATURE_REMOVE_SNMPNOTIFYFILTERTABLE_CONTAINER_GET
netsnmp_container *
snmpNotifyFilterTable_container_get(void)
{
    return snmpNotifyFilterTable_if_ctx.container;
}
#endif /* NETSNMP_FEATURE_REMOVE_SNMPNOTIFYFILTERTABLE_CONTAINER_GET */

#ifndef NETSNMP_FEATURE_REMOVE_SNMPNOTIFYFILTERTABLE_REGISTRATION_GET
snmpNotifyFilterTable_registration *
snmpNotifyFilterTable_registration_get(void)
{
    return snmpNotifyFilterTable_if_ctx.user_ctx;
}
#endif /* NETSNMP_FEATURE_REMOVE_SNMPNOTIFYFILTERTABLE_REGISTRATION_GET */

#ifndef NETSNMP_FEATURE_REMOVE_SNMPNOTIFYFILTERTABLE_REGISTRATION_SET
snmpNotifyFilterTable_registration *
snmpNotifyFilterTable_registration_set(snmpNotifyFilterTable_registration *
                                       newreg)
{
    snmpNotifyFilterTable_registration *old =
        snmpNotifyFilterTable_if_ctx.user_ctx;
    snmpNotifyFilterTable_if_ctx.user_ctx = newreg;
    return old;
}
#endif /* NETSNMP_FEATURE_REMOVE_SNMPNOTIFYFILTERTABLE_REGISTRATION_SET */

#ifndef NETSNMP_FEATURE_REMOVE_SNMPNOTIFYFILTERTABLE_CONTAINER_SIZE
int
snmpNotifyFilterTable_container_size(void)
{
    return CONTAINER_SIZE(snmpNotifyFilterTable_if_ctx.container);
}
#endif /* NETSNMP_FEATURE_REMOVE_SNMPNOTIFYFILTERTABLE_CONTAINER_SIZE */

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

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

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

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

NETSNMP_STATIC_INLINE int
                _snmpNotifyFilterTable_check_indexes(snmpNotifyFilterTable_rowreq_ctx *
                                                     rowreq_ctx);

snmpNotifyFilterTable_data *snmpNotifyFilterTable_allocate_data(void);

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

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


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

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

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

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

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

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

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


#if !(defined(NETSNMP_NO_WRITE_SUPPORT) || defined(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 /* NETSNMP_NO_WRITE_SUPPORT || NETSNMP_DISABLE_SET_SUPPORT */

    /*************************************************
     *
     * 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
#if !(defined(NETSNMP_NO_WRITE_SUPPORT) || defined(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;

#if !(defined(NETSNMP_NO_WRITE_SUPPORT) || defined(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 /* NETSNMP_NO_WRITE_SUPPORT || NETSNMP_DISABLE_SET_SUPPORT */

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

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

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

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

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

}                               /* _snmpNotifyFilterTable_initialize_interface */

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

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

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

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

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

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


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

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

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


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

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

    return err;
}                               /* snmpNotifyFilterTable_index_to_oid */

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

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

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

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


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

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


    }

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

    return err;
}                               /* snmpNotifyFilterTable_index_from_oid */


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

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

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

    return rtn;
}                               /* snmpNotifyFilterTable_allocate_data */

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

    free(data);
}                               /* snmpNotifyFilterTable_release_data */

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

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

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

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

    rowreq_ctx->snmpNotifyFilterTable_data_list = NULL;

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

    return rowreq_ctx;
}                               /* snmpNotifyFilterTable_allocate_rowreq_ctx */

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

    netsnmp_assert(NULL != rowreq_ctx);

    snmpNotifyFilterTable_rowreq_ctx_cleanup(rowreq_ctx);

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

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

    SNMP_FREE(rowreq_ctx);
}                               /* snmpNotifyFilterTable_release_rowreq_ctx */

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

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_pre_request */

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

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

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

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_post_request */


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

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

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

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

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

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

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

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

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

    return rowreq_ctx;
}                               /* _mfd_snmpNotifyFilterTable_rowreq_from_index */


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

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

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

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

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

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

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

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

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

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

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


    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

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

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

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

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

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

    return rc;
}                               /* _snmpNotifyFilterTable_get_column */

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

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

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_get_values */

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

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

    netsnmp_assert(NULL != rowreq_ctx);

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

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


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

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

#if !(defined(NETSNMP_NO_WRITE_SUPPORT) || defined(NETSNMP_DISABLE_SET_SUPPORT))
/***********************************************************************
 *
 * SET processing
 *
 ***********************************************************************/

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

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

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

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

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

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

    return rc;
}                               /* _snmpNotifyFilterTable_check_column */

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

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

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

    }                           /* for results */

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_check_objects */


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

    netsnmp_assert(NULL != rowreq_ctx);

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_check_dependencies */

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

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

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

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

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

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

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

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

    return rc;
}                               /* _snmpNotifyFilterTable_undo_setup_column */


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

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

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_undo_setup */

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

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

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

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

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


    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_undo_cleanup */

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

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

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

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

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

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

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

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

    return rc;
}                               /* _snmpNotifyFilterTable_set_column */

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

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

    netsnmp_assert(NULL != rowreq_ctx);

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_set_values */

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

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

    netsnmp_assert(NULL != rowreq_ctx);

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

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

    return SNMP_ERR_NOERROR;
}

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

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

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_commit */

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

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

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

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

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

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

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

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

    return rc;
}                               /* _snmpNotifyFilterTable_undo_column */

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

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

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_undo_values */

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

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

    netsnmp_assert(NULL != rowreq_ctx);

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_snmpNotifyFilterTable_irreversible_commit */
#endif /* NETSNMP_NO_WRITE_SUPPORT || NETSNMP_DISABLE_SET_SUPPORT */

/***********************************************************************
 *
 * 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)
{
    netsnmp_container **container_p;
    int             rc;

    register_config_handler(NULL, row_token,
                            _snmpNotifyFilterTable_container_row_restore,
                            NULL, NULL);
    container_p = netsnmp_memdup(&container, sizeof(container));
    netsnmp_assert(container_p);
    rc = snmp_register_callback(SNMP_CALLBACK_LIBRARY,
                                SNMP_CALLBACK_STORE_DATA,
                                _snmpNotifyFilterTable_container_save_rows,
                                container_p);

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

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

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

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

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

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

    /*
     * never fails 
     */
    return SNMPERR_SUCCESS;
}



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

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

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

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

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

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

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

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

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


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

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

    return SNMP_ERR_NOERROR;
}

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


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

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

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

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

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

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

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

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

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

    CONTAINER_INSERT(snmpNotifyFilterTable_if_ctx.container, rowreq_ctx);
}

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

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

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

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

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

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

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

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

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

    return buf;
}

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

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

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

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

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

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

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

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

    return buf;
}


#ifndef NETSNMP_FEATURE_REMOVE_SNMPNOTIFYFILTERTABLE_EXTERNAL_ACCESS
snmpNotifyFilterTable_rowreq_ctx *
snmpNotifyFilterTable_row_find_by_mib_index(snmpNotifyFilterTable_mib_index
                                            * mib_idx)
{
    snmpNotifyFilterTable_rowreq_ctx *rowreq_ctx;
    oid             oid_tmp[MAX_OID_LEN];
    netsnmp_index   oid_idx;
    int             rc;

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

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

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

    return rowreq_ctx;
}
#endif /* NETSNMP_FEATURE_REMOVE_SNMPNOTIFYFILTERTABLE_EXTERNAL_ACCESS */
