/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 1.17 $ of : mfd-data-access.m2c,v $ 
 *
 * $Id$
 */
/*
 * 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 <net-snmp/library/vacm.h>

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


#include "snmpNotifyFilterTable_data_access.h"

/** @ingroup interface 
 * @addtogroup data_access data_access: Routines to access data
 *
 * These routines are used to locate the data used to satisfy
 * requests.
 * 
 * @{
 */
/**********************************************************************
 **********************************************************************
 ***
 *** 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
 */

/**
 * initialization for snmpNotifyFilterTable data access
 *
 * This function is called during startup to allow you to
 * allocate any resources you need for the data table.
 *
 * @param snmpNotifyFilterTable_reg
 *        Pointer to snmpNotifyFilterTable_registration
 *
 * @retval MFD_SUCCESS : success.
 * @retval MFD_ERROR   : unrecoverable error.
 */
int
snmpNotifyFilterTable_init_data(snmpNotifyFilterTable_registration *
                                snmpNotifyFilterTable_reg)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_init_data", "called\n"));

    /*
     * TODO:303:o: Initialize snmpNotifyFilterTable data.
     */

    return MFD_SUCCESS;
}                               /* snmpNotifyFilterTable_init_data */

/**
 * container overview
 *
 */

/**
 * container initialization
 *
 * @param container_ptr_ptr A pointer to a container pointer. If you
 *        create a custom container, use this parameter to return it
 *        to the MFD helper. If set to NULL, the MFD helper will
 *        allocate a container for you.
 *
 *  This function is called at startup to allow you to customize certain
 *  aspects of the access method. For the most part, it is for advanced
 *  users. The default code should suffice for most cases. If no custom
 *  container is allocated, the MFD code will create one for your.
 *
 * @remark
 *  This would also be a good place to do any initialization needed
 *  for you data source. For example, opening a connection to another
 *  process that will supply the data, opening a database, etc.
 */
void
snmpNotifyFilterTable_container_init(netsnmp_container **container_ptr_ptr)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_container_init", "called\n"));

    if (NULL == container_ptr_ptr) {
        snmp_log(LOG_ERR,
                 "bad container param to snmpNotifyFilterTable_container_init\n");
        return;
    }

    /*
     * For advanced users, you can use a custom container. If you
     * do not create one, one will be created for you.
     */
    *container_ptr_ptr = NULL;

}                               /* snmpNotifyFilterTable_container_init */

/**
 * container shutdown
 *
 * @param container_ptr A pointer to the container.
 *
 *  This function is called at shutdown to allow you to customize certain
 *  aspects of the access method. For the most part, it is for advanced
 *  users. The default code should suffice for most cases.
 *
 *  This function is called before snmpNotifyFilterTable_container_free().
 *
 * @remark
 *  This would also be a good place to do any cleanup needed
 *  for you data source. For example, closing a connection to another
 *  process that supplied the data, closing a database, etc.
 */
void
snmpNotifyFilterTable_container_shutdown(netsnmp_container *container_ptr)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_container_shutdown", "called\n"));

    if (NULL == container_ptr) {
        snmp_log(LOG_ERR,
                 "bad params to snmpNotifyFilterTable_container_shutdown\n");
        return;
    }

}                               /* snmpNotifyFilterTable_container_shutdown */

/**
 * load initial data
 *
 * TODO:350:M: Implement snmpNotifyFilterTable data load
 *
 * @param container container to which items should be inserted
 *
 * @retval MFD_SUCCESS              : success.
 * @retval MFD_RESOURCE_UNAVAILABLE : Can't access data source
 * @retval MFD_ERROR                : other error.
 *
 *  This function is called to load the index(es) (and data, optionally)
 *  for the every row in the data set.
 *
 * @remark
 *  While loading the data, the only important thing is the indexes.
 *  If access to your data is cheap/fast (e.g. you have a pointer to a
 *  structure in memory), it would make sense to update the data here.
 *  If, however, the accessing the data invovles more work (e.g. parsing
 *  some other existing data, or peforming calculations to derive the data),
 *  then you can limit yourself to setting the indexes and saving any
 *  information you will need later. Then use the saved information in
 *  snmpNotifyFilterTable_row_prep() for populating data.
 *
 * @note
 *  If you need consistency between rows (like you want statistics
 *  for each row to be from the same time frame), you should set all
 *  data here.
 *
 */
int
snmpNotifyFilterTable_container_load(netsnmp_container *container)
{
    snmpNotifyFilterTable_rowreq_ctx *rowreq_ctx;
    size_t          count = 0;

    /*
     * temporary storage for index values
     */
    /*
     * snmpNotifyFilterProfileName(1)/SnmpAdminString/ASN_OCTET_STR/char(char)//L/A/W/e/R/d/H
     */
    char            snmpNotifyFilterProfileName[32];
    size_t          snmpNotifyFilterProfileName_len;
    /*
     * snmpNotifyFilterSubtree(1)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/a/w/e/r/d/h
     */
        /** 128 - 1(entry) - 1(col) - 1(other indexes) = 114 */
    oid             snmpNotifyFilterSubtree[114];
    size_t          snmpNotifyFilterSubtree_len;


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

    /*
     * TODO:351:M: |-> Load/update data in the snmpNotifyFilterTable container.
     * loop over your snmpNotifyFilterTable data, allocate a rowreq context,
     * set the index(es) [and data, optionally] and insert into
     * the container.
     */
    while (1) {
        /*
         * check for end of data; bail out if there is no more data
         */
        if (1)
            break;

        /*
         * TODO:352:M: |   |-> set indexes in new snmpNotifyFilterTable rowreq context.
         * data context will be set from the param (unless NULL,
         *      in which case a new data context will be allocated)
         */
        rowreq_ctx = snmpNotifyFilterTable_allocate_rowreq_ctx(NULL);
        if (NULL == rowreq_ctx) {
            snmp_log(LOG_ERR, "memory allocation failed\n");
            return MFD_RESOURCE_UNAVAILABLE;
        }
        if (MFD_SUCCESS !=
            snmpNotifyFilterTable_indexes_set(rowreq_ctx,
                                              snmpNotifyFilterProfileName,
                                              snmpNotifyFilterProfileName_len,
                                              snmpNotifyFilterSubtree,
                                              snmpNotifyFilterSubtree_len))
        {
            snmp_log(LOG_ERR,
                     "error setting index while loading "
                     "snmpNotifyFilterTable data.\n");
            snmpNotifyFilterTable_release_rowreq_ctx(rowreq_ctx);
            continue;
        }

        /*
         * TODO:352:r: |   |-> populate snmpNotifyFilterTable data context.
         * Populate data context here. (optionally, delay until row prep)
         */
        /*
         * non-TRANSIENT data: no need to copy. set pointer to data 
         */

        /*
         * insert into table container
         */
        CONTAINER_INSERT(container, rowreq_ctx);
        ++count;
    }

    DEBUGMSGT(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_container_load", "inserted %d records\n", count));

    return MFD_SUCCESS;
}                               /* snmpNotifyFilterTable_container_load */

/**
 * container clean up
 *
 * @param container container with all current items
 *
 *  This optional callback is called prior to all
 *  item's being removed from the container. If you
 *  need to do any processing before that, do it here.
 *
 * @note
 *  The MFD helper will take care of releasing all the row contexts.
 *
 */
void
snmpNotifyFilterTable_container_free(netsnmp_container *container)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_container_free", "called\n"));

    /*
     * TODO:380:M: Free snmpNotifyFilterTable container data.
     */
}                               /* snmpNotifyFilterTable_container_free */

/**
 * prepare row for processing.
 *
 *  When the agent has located the row for a request, this function is
 *  called to prepare the row for processing. If you fully populated
 *  the data context during the index setup phase, you may not need to
 *  do anything.
 *
 * @param rowreq_ctx pointer to a context.
 *
 * @retval MFD_SUCCESS     : success.
 * @retval MFD_ERROR       : other error.
 */
int
snmpNotifyFilterTable_row_prep(snmpNotifyFilterTable_rowreq_ctx *
                               rowreq_ctx)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_row_prep", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:390:o: Prepare row for request.
     * If populating row data was delayed, this is the place to
     * fill in the row for this request.
     */

    return MFD_SUCCESS;
}                               /* snmpNotifyFilterTable_row_prep */

/*
 * TODO:420:r: Implement snmpNotifyFilterTable index validation.
 */
/*---------------------------------------------------------------------
 * SNMP-NOTIFICATION-MIB::snmpNotifyFilterProfileEntry.snmpNotifyFilterProfileName
 * snmpNotifyFilterProfileName is subid 1 of snmpNotifyFilterProfileEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.6.3.13.1.2.1.1
 * Description:
The name of the filter profile to be used when generating
         notifications using the corresponding entry in the
         snmpTargetAddrTable.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 1      hashint   1
 *   settable   1
 *   hint: 255t
 *
 * Ranges:  1 - 32;
 *
 * Its syntax is SnmpAdminString (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.  (Max 32)
 */
/**
 * check validity of snmpNotifyFilterProfileName external index portion
 *
 * NOTE: this is not the place to do any checks for the sanity
 *       of multiple indexes. Those types of checks should be done in the
 *       snmpNotifyFilterTable_validate_index() function.
 *
 * @retval MFD_SUCCESS   : the incoming value is legal
 * @retval MFD_ERROR     : the incoming value is NOT legal
 */
int
 
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    snmpNotifyFilterTable_snmpNotifyFilterProfileName_check_index
    (snmpNotifyFilterTable_rowreq_ctx * rowreq_ctx) {
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_snmpNotifyFilterProfileName_check_index", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:424:M: |-> Check snmpNotifyFilterTable external index snmpNotifyFilterProfileName.
     * check that index value in the table context (rowreq_ctx)
     * for the external index snmpNotifyFilterProfileName is legal.
     */

    return MFD_SUCCESS;         /*  external index snmpNotifyFilterProfileName ok */
}                               /* snmpNotifyFilterTable_snmpNotifyFilterProfileName_check_index */

/*---------------------------------------------------------------------
 * SNMP-NOTIFICATION-MIB::snmpNotifyFilterEntry.snmpNotifyFilterSubtree
 * snmpNotifyFilterSubtree is subid 1 of snmpNotifyFilterEntry.
 * Its status is Current, and its access level is NoAccess.
 * OID: .1.3.6.1.6.3.13.1.3.1.1
 * Description:
The MIB subtree which, when combined with the corresponding
         instance of snmpNotifyFilterMask, defines a family of
         subtrees which are included in or excluded from the
         filter profile.
 *
 * Attributes:
 *   accessible 0     isscalar 0     enums  0      hasdefval 0
 *   readable   0     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is OBJECTID (based on perltype OBJECTID)
 * The net-snmp type is ASN_OBJECT_ID. The C type decl is oid (oid)
 * This data type requires a length.
 *
 *
 *
 * NOTE: NODE snmpNotifyFilterSubtree IS NOT ACCESSIBLE
 *
 *
 */
/**
 * check validity of snmpNotifyFilterSubtree index portion
 *
 * @retval MFD_SUCCESS   : the incoming value is legal
 * @retval MFD_ERROR     : the incoming value is NOT legal
 *
 * @note this is not the place to do any checks for the sanity
 *       of multiple indexes. Those types of checks should be done in the
 *       snmpNotifyFilterTable_validate_index() function.
 *
 * @note Also keep in mind that if the index refers to a row in this or
 *       some other table, you can't check for that row here to make
 *       decisions, since that row might not be created yet, but may
 *       be created during the processing this request. If you have
 *       such checks, they should be done in the check_dependencies
 *       function, because any new/deleted/changed rows should be
 *       available then.
 *
 * The following checks have already been done for you:
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 */
int
snmpNotifyFilterSubtree_check_index(snmpNotifyFilterTable_rowreq_ctx *
                                    rowreq_ctx)
{
    DEBUGMSGTL(("verbose:snmpNotifyFilterTable:snmpNotifyFilterSubtree_check_index", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:426:M: |-> Check snmpNotifyFilterTable index snmpNotifyFilterSubtree.
     * check that index value in the table context is legal.
     * (rowreq_ctx->tbl_index.snmpNotifyFilterSubtree)
     */

    return MFD_SUCCESS;         /* snmpNotifyFilterSubtree index ok */
}                               /* snmpNotifyFilterSubtree_check_index */

/**
 * verify specified index is valid.
 *
 * This check is independent of whether or not the values specified for
 * the columns of the new row are valid. Column values and row consistency
 * will be checked later. At this point, only the index values should be
 * checked.
 *
 * All of the individual index validation functions have been called, so this
 * is the place to make sure they are valid as a whole when combined. If
 * you only have one index, then you probably don't need to do anything else
 * here.
 * 
 * @note Keep in mind that if the indexes refer to a row in this or
 *       some other table, you can't check for that row here to make
 *       decisions, since that row might not be created yet, but may
 *       be created during the processing this request. If you have
 *       such checks, they should be done in the check_dependencies
 *       function, because any new/deleted/changed rows should be
 *       available then.
 *
 *
 * @param snmpNotifyFilterTable_reg
 *        Pointer to the user registration data
 * @param rowreq_ctx
 *        Pointer to the users context.
 * @retval MFD_SUCCESS            : success
 * @retval MFD_CANNOT_CREATE_NOW  : index not valid right now
 * @retval MFD_CANNOT_CREATE_EVER : index never valid
 */
int
snmpNotifyFilterTable_validate_index(snmpNotifyFilterTable_registration *
                                     snmpNotifyFilterTable_reg,
                                     snmpNotifyFilterTable_rowreq_ctx *
                                     rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

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

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:430:M: |-> Validate potential snmpNotifyFilterTable index.
     */

    return rc;
}                               /* snmpNotifyFilterTable_validate_index */

/** @} */

/*
 * ugly, inefficient hack: create a dummy viewEntry list from the filter table
 * entries matching a profile name. This lets us use the existing vacm
 * routines for matching oids to views.
 */
struct vacm_viewEntry *
snmpNotifyFilterTable_vacm_view_subtree(const char *profile)
{
    oid             tmp_oid[MAX_OID_LEN];
    netsnmp_index   tmp_idx;
    int             i, j;
    netsnmp_void_array *s;
    struct vacm_viewEntry *tmp;
    snmpNotifyFilterTable_rowreq_ctx *rowreq;
    netsnmp_container *c;

    tmp_idx.len = 0;
    tmp_idx.oids = tmp_oid;

    /*
     * get the container
     */
    c = snmpNotifyFilterTable_container_get();
    if ((NULL == profile) || (NULL == c))
        return NULL;

    /*
     * get the profile subset
     */
    tmp_idx.oids[0] = strlen(profile);
    tmp_idx.len = tmp_idx.oids[0] + 1;
    for (i = 0; i < tmp_idx.len; ++i)
        tmp_idx.oids[i + 1] = profile[i];
    s = c->get_subset(c, &tmp_idx);
    if (NULL == s)
        return NULL;

    /*
     * allocate temporary storage
     */
    tmp = calloc(sizeof(struct vacm_viewEntry), s->size + 1);
    if (NULL == tmp) {
        free(s->array);
        free(s);
        return NULL;
    }

    /*
     * copy data
     */
    for (i = 0, j = 0; i < s->size; ++i) {
        rowreq = (snmpNotifyFilterTable_rowreq_ctx *) s->array[i];

        /*
         * must match profile name exactly, and subset will return
         * longer matches, if they exist.
         */
        if (tmp_idx.oids[0] !=
            rowreq->tbl_idx.snmpNotifyFilterProfileName_len)
            continue;

        /*
         * exact match, copy data
         * vacm_viewEntry viewName and viewSubtree are prefixed with length
         */

        tmp[j].viewName[0] =
            rowreq->tbl_idx.snmpNotifyFilterProfileName_len;
        memcpy(&tmp[j].viewName[1],
               rowreq->tbl_idx.snmpNotifyFilterProfileName,
               tmp[j].viewName[0]);

        tmp[j].viewSubtree[0] =
            rowreq->tbl_idx.snmpNotifyFilterSubtree_len;
        memcpy(&tmp[j].viewSubtree[1],
               rowreq->tbl_idx.snmpNotifyFilterSubtree,
               tmp[j].viewSubtree[0] * sizeof(oid));
        tmp[j].viewSubtreeLen = tmp[j].viewSubtree[0] + 1;

        tmp[j].viewMaskLen = rowreq->data.snmpNotifyFilterMask_len;
        memcpy(tmp[j].viewMask, rowreq->data.snmpNotifyFilterMask,
               tmp[j].viewMaskLen * sizeof(oid));


        tmp[j].viewType = rowreq->data.snmpNotifyFilterType;

        tmp[j].next = &tmp[j + 1];
        ++j;
    }
    if (j)
        tmp[j - 1].next = NULL;
    else {
        SNMP_FREE(tmp);
    }

    free(s->array);
    free(s);

    return tmp;
}
