/*
 * This file was generated by mib2c and is intended for use as
 * a mib module for the ucd-snmp snmpd agent. 
 */


/*
 * This should always be included first before anything else 
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-features.h>

#include <sys/types.h>
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif

/*
 * minimal include directives 
 */
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

#include "header_complex.h"
#include "snmpNotifyTable.h"
#include "snmpNotifyFilterProfileTable.h"
#include "target/snmpTargetParamsEntry.h"
#include "target/snmpTargetAddrEntry.h"
#include "target/target.h"
#include "snmp-notification-mib/snmpNotifyFilterTable/snmpNotifyFilterTable.h"
#include <net-snmp/agent/agent_callbacks.h>
#include <net-snmp/agent/agent_trap.h>
#include <net-snmp/agent/mib_module_config.h>
#include "net-snmp/agent/sysORTable.h"

#ifdef USING_NOTIFICATION_LOG_MIB_NOTIFICATION_LOG_MODULE
#   include "notification-log-mib/notification_log.h"
#endif

#ifndef NETSNMP_NO_WRITE_SUPPORT
netsnmp_feature_require(header_complex_find_entry)
#endif /* NETSNMP_NO_WRITE_SUPPORT */

SNMPCallback    store_snmpNotifyTable;

/*
 * snmpNotifyTable_variables_oid:
 *   this is the top level oid that we want to register under.  This
 *   is essentially a prefix, with the suffix appearing in the
 *   variable below.
 */


oid             snmpNotifyTable_variables_oid[] =
    { 1, 3, 6, 1, 6, 3, 13, 1, 1 };

static oid snmpNotifyFullCompliance[] =
    { SNMP_OID_SNMPMODULES, 13, 3, 1, 3 }; /* SNMP-NOTIFICATION-MIB::snmpNotifyFullCompliance */


/*
 * variable2 snmpNotifyTable_variables:
 *   this variable defines function callbacks and type return information 
 *   for the snmpNotifyTable mib section 
 */


struct variable2 snmpNotifyTable_variables[] = {
    /*
     * magic number        , variable type , ro/rw , callback fn  , L, oidsuffix 
     */
#define   SNMPNOTIFYTAG         4
    {SNMPNOTIFYTAG, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
     var_snmpNotifyTable, 2, {1, 2}},
#define   SNMPNOTIFYTYPE        5
    {SNMPNOTIFYTYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
     var_snmpNotifyTable, 2, {1, 3}},
#define   SNMPNOTIFYSTORAGETYPE  6
    {SNMPNOTIFYSTORAGETYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
     var_snmpNotifyTable, 2, {1, 4}},
#define   SNMPNOTIFYROWSTATUS   7
    {SNMPNOTIFYROWSTATUS, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
     var_snmpNotifyTable, 2, {1, 5}},

};
/*
 * (L = length of the oidsuffix) 
 */


/*
 * global storage of our data, saved in and configured by header_complex() 
 */
static struct header_complex_index *snmpNotifyTableStorage = NULL;

static int
_checkFilter(const char* paramName, netsnmp_pdu *pdu)
{
    /*
     * find appropriate filterProfileEntry
     */
    netsnmp_variable_list *var, *trap_var;
    char                  *profileName;
    size_t                 profileNameLen;
    struct vacm_viewEntry *vp, *head;
    int                    vb_oid_excluded = 0;
    extern const oid       snmptrap_oid[];
    extern const size_t    snmptrap_oid_len;

    netsnmp_assert(NULL != paramName);
    netsnmp_assert(NULL != pdu);

    DEBUGMSGTL(("send_notifications", "checking filters...\n"));

    /*
   A notification originator uses the snmpNotifyFilterTable to filter
   notifications.  A notification filter profile may be associated with
   a particular entry in the snmpTargetParamsTable.  The associated
   filter profile is identified by an entry in the
   snmpNotifyFilterProfileTable whose index is equal to the index of the
   entry in the snmpTargetParamsTable.  If no such entry exists in the
   snmpNotifyFilterProfileTable, no filtering is performed for that
   management target.
    */
    profileName = get_FilterProfileName(paramName, strlen(paramName),
                                        &profileNameLen);
    if (NULL == profileName) {
        DEBUGMSGTL(("send_notifications", "  no matching profile\n"));
        return 0;
    }

    /*
   If such an entry does exist, the value of snmpNotifyFilterProfileName
   of the entry is compared with the corresponding portion of the index
   of all active entries in the snmpNotifyFilterTable.  All such entries
   for which this comparison results in an exact match are used for
   filtering a notification generated using the associated
   snmpTargetParamsEntry.  If no such entries exist, no filtering is
   performed, and a notification may be sent to the management target.
    */
    head = snmpNotifyFilterTable_vacm_view_subtree(profileName);
    if (NULL == head) {
        DEBUGMSGTL(("send_notifications", "  no matching filters\n"));
        return 0;
    }

    /*
   Otherwise, if matching entries do exist, a notification may be sent
   if the NOTIFICATION-TYPE OBJECT IDENTIFIER of the notification (this
   is the value of the element of the variable bindings whose name is
   snmpTrapOID.0, i.e., the second variable binding) is specifically
   included, and none of the object instances to be included in the
   variable-bindings of the notification are specifically excluded by
   the matching entries.
     */
    trap_var = find_varbind_in_list( pdu->variables,
                                snmptrap_oid,
                                snmptrap_oid_len);
    if (NULL != trap_var) {
        /*
                             For a notification name, if none match,
   then the notification name is considered excluded, and the
   notification should not be sent to this management target.
         */
        vp = netsnmp_view_get(head, profileName, trap_var->val.objid,
                              trap_var->val_len / sizeof(oid), VACM_MODE_FIND);
        if ((NULL == vp) || (SNMP_VIEW_INCLUDED != vp->viewType)) {
            DEBUGMSGTL(("send_notifications", "  filtered (snmpTrapOID.0 "));
            DEBUGMSGOID(("send_notifications",trap_var->val.objid,
                         trap_var->val_len / sizeof(oid)));
            DEBUGMSG(("send_notifications", " not included)\n"));
            free(head);
            return 1;
        }
    }

    /*
     * check varbinds
     */
    for(var = pdu->variables; var; var = var->next_variable) {
        /*
                                                               For an
   object instance, if none match, the object instance is considered
   included, and the notification may be sent to this management target.
         */

        if (var == trap_var) {
            continue;
        }

        vp = netsnmp_view_get(head, profileName, var->name,
                              var->name_length, VACM_MODE_FIND);
        if ((NULL != vp) && (SNMP_VIEW_EXCLUDED == vp->viewType)) {
            DEBUGMSGTL(("send_notifications","  filtered (varbind "));
            DEBUGMSGOID(("send_notifications",var->name, var->name_length));
            DEBUGMSG(("send_notifications", " excluded)\n"));
            vb_oid_excluded = 1;
            break;
        }
    }

    free(head);

    return vb_oid_excluded;
}

int
send_notifications(int major, int minor, void *serverarg, void *clientarg)
{
    struct header_complex_index *hptr;
    struct snmpNotifyTable_data *nptr;
    netsnmp_session *sess, *sptr;
    netsnmp_pdu    *template_pdu = (netsnmp_pdu *) serverarg;
    int             count = 0, send = 0;

    DEBUGMSGTL(("send_notifications", "starting: pdu=%p, vars=%p\n",
                template_pdu, template_pdu->variables));

    for (hptr = snmpNotifyTableStorage; hptr; hptr = hptr->next) {
        nptr = (struct snmpNotifyTable_data *) hptr->data;
        if (nptr->snmpNotifyRowStatus != RS_ACTIVE)
            continue;
        if (!nptr->snmpNotifyTag)
            continue;

        sess = get_target_sessions(nptr->snmpNotifyTag, NULL, NULL);

        /*
         * filter appropriately, per section 6 of RFC 3413
         */

        for (sptr = sess; sptr; sptr = sptr->next) {
            send = 0;
#ifndef NETSNMP_DISABLE_SNMPV1
            if (sptr->version == SNMP_VERSION_1 &&
                minor == SNMPD_CALLBACK_SEND_TRAP1) {
                send = 1;
            } else
#endif
            if ((sptr->version == SNMP_VERSION_3
#ifndef NETSNMP_DISABLE_SNMPV2C
                 || sptr->version == SNMP_VERSION_2c
#endif
                ) && minor == SNMPD_CALLBACK_SEND_TRAP2) {
                if (nptr->snmpNotifyType == SNMPNOTIFYTYPE_INFORM) {
                    template_pdu->command = SNMP_MSG_INFORM;
                } else {
                    template_pdu->command = SNMP_MSG_TRAP2;
                }
                send = 1;
            }
            if (send && sess->paramName) {
                int filter = _checkFilter(sess->paramName, template_pdu);
                if (filter)
                    send = 0;
            }
            if (send) {
                send_trap_to_sess(sptr, template_pdu);
                ++count;
            } /* session to send to */
        } /* for(sptr) */
    } /* for(hptr) */

    DEBUGMSGTL(("send_notifications", "sent %d notifications\n", count));

#ifdef USING_NOTIFICATION_LOG_MIB_NOTIFICATION_LOG_MODULE
    if (count)
        log_notification(template_pdu, NULL);
#endif

    return 0;
}

#define MAX_ENTRIES 1024

int
notifyTable_register_notifications(int major, int minor,
                                   void *serverarg, void *clientarg)
{
    struct targetAddrTable_struct *ptr;
    struct targetParamTable_struct *pptr;
    struct snmpNotifyTable_data *nptr;
    int             confirm, i, bufLen;
    char            buf[SNMP_MAXBUF_SMALL];
    netsnmp_transport *t = NULL;
    struct agent_add_trap_args *args =
        (struct agent_add_trap_args *) serverarg;
    netsnmp_session *ss;

    if (!args || !(args->ss)) {
        return (0);
    }
    confirm = args->confirm;
    ss = args->ss;

    /*
     * XXX: START move target creation to target code 
     */
    for (i = 0; i < MAX_ENTRIES; i++) {
        bufLen = sprintf(buf, "internal%d", i);
        if (get_addrForName2(buf, bufLen) == NULL &&
            get_paramEntry(buf) == NULL)
            break;
    }
    if (i == MAX_ENTRIES) {
        snmp_log(LOG_ERR,
                 "Can't register new trap destination: max limit reached: %d",
                 MAX_ENTRIES);
        snmp_sess_close(ss);
        return (0);
    }

    /*
     * address 
     */
    t = snmp_sess_transport(snmp_sess_pointer(ss));
    if (!t) {
        snmp_log(LOG_ERR,
                "Cannot add new trap destination, transport is closed.");
        snmp_sess_close(ss);
        return 0;
    }
    ptr = snmpTargetAddrTable_create();
    ptr->nameData = netsnmp_memdup(buf, bufLen);
    ptr->nameLen = bufLen;
    memcpy(ptr->tDomain, t->domain, t->domain_length * sizeof(oid));
    ptr->tDomainLen = t->domain_length;
    ptr->tAddressLen = t->remote_length;
    ptr->tAddress = t->remote;

    ptr->timeout = ss->timeout / 10000;
    ptr->retryCount = ss->retries;
    SNMP_FREE(ptr->tagList);
    ptr->tagList = strdup(buf); /* strdup ok since buf contains 'internal%d' */
    ptr->params = strdup(buf);
    ptr->storageType = ST_READONLY;
    ptr->rowStatus = RS_ACTIVE;
    ptr->sess = ss;
    DEBUGMSGTL(("trapsess", "adding to trap table\n"));
    snmpTargetAddrTable_add(ptr);

    /*
     * param 
     */
    pptr = snmpTargetParamTable_create();
    pptr->paramName = strdup(buf);
    pptr->mpModel = ss->version;
    if (ss->version == SNMP_VERSION_3) {
        pptr->secModel = ss->securityModel;
        pptr->secLevel = ss->securityLevel;
        pptr->secName = (char *) malloc(ss->securityNameLen + 1);
        if (pptr->secName == NULL) {
            snmpTargetParamTable_dispose(pptr);
            return 0;
        }
        memcpy((void *) pptr->secName, (void *) ss->securityName,
               ss->securityNameLen);
        pptr->secName[ss->securityNameLen] = 0;
    }
#if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
       else {
        pptr->secModel = 
#ifndef NETSNMP_DISABLE_SNMPV1
            ss->version == SNMP_VERSION_1 ?  SNMP_SEC_MODEL_SNMPv1 : 
#endif
                                             SNMP_SEC_MODEL_SNMPv2c;
        pptr->secLevel = SNMP_SEC_LEVEL_NOAUTH;
        pptr->secName = NULL;
        if (ss->community && (ss->community_len > 0)) {
            pptr->secName = (char *) malloc(ss->community_len + 1);
            if (pptr->secName == NULL) {
                snmpTargetParamTable_dispose(pptr);
                return 0;
            }
            memcpy((void *) pptr->secName, (void *) ss->community,
                   ss->community_len);
            pptr->secName[ss->community_len] = 0;
        }
    }
#endif
    pptr->storageType = ST_READONLY;
    pptr->rowStatus = RS_ACTIVE;
    snmpTargetParamTable_add(pptr);
    /*
     * XXX: END move target creation to target code 
     */

    /*
     * notify table 
     */
    nptr = SNMP_MALLOC_STRUCT(snmpNotifyTable_data);
    if (nptr == NULL)
        return 0;
    nptr->snmpNotifyName = strdup(buf);
    nptr->snmpNotifyNameLen = strlen(buf);
    nptr->snmpNotifyTag = strdup(buf);
    nptr->snmpNotifyTagLen = strlen(buf);
    nptr->snmpNotifyType = confirm ?
        SNMPNOTIFYTYPE_INFORM : SNMPNOTIFYTYPE_TRAP;
    nptr->snmpNotifyStorageType = ST_READONLY;
    nptr->snmpNotifyRowStatus = RS_ACTIVE;

    snmpNotifyTable_add(nptr);
    return 0;
}


/*
 * XXX: this really needs to be done for the target mib entries too.
 * But we can only trust that we've added stuff here and we don't want
 * to destroy other valid entries in the target tables, so...  Don't
 * do too many kill -HUPs to your agent as re reading the config file
 * will be a slow memory leak in the target mib. 
 */
int
notifyTable_unregister_notifications(int major, int minor,
                                     void *serverarg, void *clientarg)
{
    struct header_complex_index *hptr, *nhptr;

    for (hptr = snmpNotifyTableStorage; hptr; hptr = nhptr) {
        struct snmpNotifyTable_data *nptr = hptr->data;
        nhptr = hptr->next;
        if (nptr->snmpNotifyStorageType == ST_READONLY) {
            header_complex_extract_entry(&snmpNotifyTableStorage, hptr);
            free(nptr->snmpNotifyName);
            free(nptr->snmpNotifyTag);
            free(nptr);
        }
    }
    snmpNotifyTableStorage = NULL;
    return (0);
}

/*
 * init_snmpNotifyTable():
 *   Initialization routine.  This is called when the agent starts up.
 *   At a minimum, registration of your variables should take place here.
 */
void
init_snmpNotifyTable(void)
{
    DEBUGMSGTL(("snmpNotifyTable", "initializing...  "));


    /*
     * register ourselves with the agent to handle our mib tree 
     */
    REGISTER_MIB("snmpNotifyTable", snmpNotifyTable_variables, variable2,
                 snmpNotifyTable_variables_oid);


    /*
     * register our config handler(s) to deal with registrations 
     */
    snmpd_register_config_handler("snmpNotifyTable", parse_snmpNotifyTable,
                                  NULL, NULL);


    /*
     * we need to be called back later to store our data 
     */
    snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
                           store_snmpNotifyTable, NULL);

#ifndef DISABLE_SNMPV1
    snmp_register_callback(SNMP_CALLBACK_APPLICATION,
                           SNMPD_CALLBACK_SEND_TRAP1, send_notifications,
                           NULL);
#endif
    snmp_register_callback(SNMP_CALLBACK_APPLICATION,
                           SNMPD_CALLBACK_SEND_TRAP2, send_notifications,
                           NULL);
    snmp_register_callback(SNMP_CALLBACK_APPLICATION,
                           SNMPD_CALLBACK_REGISTER_NOTIFICATIONS,
                           notifyTable_register_notifications, NULL);
    snmp_register_callback(SNMP_CALLBACK_APPLICATION,
                           SNMPD_CALLBACK_PRE_UPDATE_CONFIG,
                           notifyTable_unregister_notifications, NULL);

    /*
     * place any other initialization junk you need here 
     */

    REGISTER_SYSOR_ENTRY(snmpNotifyFullCompliance,
        "The MIB modules for managing SNMP Notification, plus filtering.");

    DEBUGMSGTL(("snmpNotifyTable", "done.\n"));
}

void
shutdown_snmpNotifyTable(void)
{
    DEBUGMSGTL(("snmpNotifyTable", "shutting down ... "));

    notifyTable_unregister_notifications(SNMP_CALLBACK_APPLICATION,
                                         SNMPD_CALLBACK_PRE_UPDATE_CONFIG,
                                         NULL,
                                         NULL);

    snmp_unregister_callback(SNMP_CALLBACK_APPLICATION,
                             SNMPD_CALLBACK_PRE_UPDATE_CONFIG,
                             notifyTable_unregister_notifications, NULL, FALSE);
    snmp_unregister_callback(SNMP_CALLBACK_APPLICATION,
                             SNMPD_CALLBACK_REGISTER_NOTIFICATIONS,
                             notifyTable_register_notifications, NULL, FALSE);
    snmp_unregister_callback(SNMP_CALLBACK_APPLICATION,
                             SNMPD_CALLBACK_SEND_TRAP2, send_notifications,
                             NULL, FALSE);
#ifndef DISABLE_SNMPV1
    snmp_unregister_callback(SNMP_CALLBACK_APPLICATION,
                             SNMPD_CALLBACK_SEND_TRAP1, send_notifications,
                             NULL, FALSE);
#endif
    snmp_unregister_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
                             store_snmpNotifyTable, NULL, FALSE);

    UNREGISTER_SYSOR_ENTRY(snmpNotifyFullCompliance);

    DEBUGMSGTL(("snmpNotifyTable", "done.\n"));
}

/*
 * snmpNotifyTable_add(): adds a structure node to our data set 
 */
int
snmpNotifyTable_add(struct snmpNotifyTable_data *thedata)
{
    netsnmp_variable_list *vars = NULL;
    int retVal;	

    DEBUGMSGTL(("snmpNotifyTable", "adding data...  "));
    /*
     * add the index variables to the varbind list, which is 
     * used by header_complex to index the data 
     */


    snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OCTET_STR, (u_char *) thedata->snmpNotifyName, thedata->snmpNotifyNameLen);      /* snmpNotifyName */



    if (header_complex_maybe_add_data(&snmpNotifyTableStorage, vars, thedata, 1)
        != NULL){
    	DEBUGMSGTL(("snmpNotifyTable", "registered an entry\n"));
	retVal = SNMPERR_SUCCESS;
    }else{
        retVal = SNMPERR_GENERR; 
    }	


    DEBUGMSGTL(("snmpNotifyTable", "done.\n"));
    return retVal;
}


/*
 * parse_snmpNotifyTable():
 *   parses .conf file entries needed to configure the mib.
 */
void
parse_snmpNotifyTable(const char *token, char *line)
{
    size_t          tmpint;
    struct snmpNotifyTable_data *StorageTmp =
        SNMP_MALLOC_STRUCT(snmpNotifyTable_data);


    DEBUGMSGTL(("snmpNotifyTable", "parsing config...  "));


    if (StorageTmp == NULL) {
        config_perror("malloc failure");
        return;
    }

    line =
        read_config_read_data(ASN_OCTET_STR, line,
                              &StorageTmp->snmpNotifyName,
                              &StorageTmp->snmpNotifyNameLen);
    if (StorageTmp->snmpNotifyName == NULL) {
        config_perror("invalid specification for snmpNotifyName");
        SNMP_FREE(StorageTmp);
        return;
    }

    line =
        read_config_read_data(ASN_OCTET_STR, line,
                              &StorageTmp->snmpNotifyTag,
                              &StorageTmp->snmpNotifyTagLen);
    if (StorageTmp->snmpNotifyTag == NULL) {
        config_perror("invalid specification for snmpNotifyTag");
        SNMP_FREE(StorageTmp);
        return;
    }

    line =
        read_config_read_data(ASN_INTEGER, line,
                              &StorageTmp->snmpNotifyType, &tmpint);

    line =
        read_config_read_data(ASN_INTEGER, line,
                              &StorageTmp->snmpNotifyStorageType, &tmpint);
    if (!StorageTmp->snmpNotifyStorageType)
        StorageTmp->snmpNotifyStorageType = ST_READONLY;

    line =
        read_config_read_data(ASN_INTEGER, line,
                              &StorageTmp->snmpNotifyRowStatus, &tmpint);
    if (!StorageTmp->snmpNotifyRowStatus)
        StorageTmp->snmpNotifyRowStatus = RS_ACTIVE;


    if (snmpNotifyTable_add(StorageTmp) != SNMPERR_SUCCESS){
        SNMP_FREE(StorageTmp->snmpNotifyName);
        SNMP_FREE(StorageTmp->snmpNotifyTag);
        SNMP_FREE(StorageTmp);
    }


    DEBUGMSGTL(("snmpNotifyTable", "done.\n"));
}




/*
 * store_snmpNotifyTable():
 *   stores .conf file entries needed to configure the mib.
 */
int
store_snmpNotifyTable(int majorID, int minorID, void *serverarg,
                      void *clientarg)
{
    char            line[SNMP_MAXBUF];
    char           *cptr;
    size_t          tmpint;
    struct snmpNotifyTable_data *StorageTmp;
    struct header_complex_index *hcindex;


    DEBUGMSGTL(("snmpNotifyTable", "storing data...  "));


    for (hcindex = snmpNotifyTableStorage; hcindex != NULL;
         hcindex = hcindex->next) {
        StorageTmp = (struct snmpNotifyTable_data *) hcindex->data;

        /*
         * store permanent and nonvolatile rows.
         * XXX should there be a qualification on RowStatus??
         */
        if ((StorageTmp->snmpNotifyStorageType == ST_NONVOLATILE) ||
            (StorageTmp->snmpNotifyStorageType == ST_PERMANENT) ){

            memset(line, 0, sizeof(line));
            strcat(line, "snmpNotifyTable ");
            cptr = line + strlen(line);

            cptr =
                read_config_store_data(ASN_OCTET_STR, cptr,
                                       &StorageTmp->snmpNotifyName,
                                       &StorageTmp->snmpNotifyNameLen);
            cptr =
                read_config_store_data(ASN_OCTET_STR, cptr,
                                       &StorageTmp->snmpNotifyTag,
                                       &StorageTmp->snmpNotifyTagLen);
            cptr =
                read_config_store_data(ASN_INTEGER, cptr,
                                       &StorageTmp->snmpNotifyType,
                                       &tmpint);
            cptr =
                read_config_store_data(ASN_INTEGER, cptr,
                                       &StorageTmp->snmpNotifyStorageType,
                                       &tmpint);
            cptr =
                read_config_store_data(ASN_INTEGER, cptr,
                                       &StorageTmp->snmpNotifyRowStatus,
                                       &tmpint);

            snmpd_store_config(line);
        }
    }
    DEBUGMSGTL(("snmpNotifyTable", "done.\n"));
    return 0;
}




/*
 * var_snmpNotifyTable():
 *   Handle this table separately from the scalar value case.
 *   The workings of this are basically the same as for var_snmpNotifyTable above.
 */
unsigned char  *
var_snmpNotifyTable(struct variable *vp,
                    oid * name,
                    size_t * length,
                    int exact,
                    size_t * var_len, WriteMethod ** write_method)
{
    struct snmpNotifyTable_data *StorageTmp = NULL;
    int             found = 1;

    DEBUGMSGTL(("snmpNotifyTable",
                "var_snmpNotifyTable: Entering...  \n"));
    /*
     * this assumes you have registered all your data properly
     */
    if ((StorageTmp = (struct snmpNotifyTable_data *)
         header_complex((struct header_complex_index *)
                        snmpNotifyTableStorage, vp, name, length, exact,
                        var_len, write_method)) == NULL) {
        found = 0;
    }

    switch (vp->magic) {
#ifndef NETSNMP_NO_WRITE_SUPPORT
    case SNMPNOTIFYTAG:
        *write_method = write_snmpNotifyTag;
        break;
    case SNMPNOTIFYTYPE:
        *write_method = write_snmpNotifyType;
        break;
    case SNMPNOTIFYSTORAGETYPE:
        *write_method = write_snmpNotifyStorageType;
        break;
    case SNMPNOTIFYROWSTATUS:
        *write_method = write_snmpNotifyRowStatus;
        break;
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
    default:
        *write_method = NULL;
    }

    if (!found) {
        return NULL;
    }

#ifndef NETSNMP_NO_READ_SUPPORT
    switch (vp->magic) {
    case SNMPNOTIFYTAG:
        *var_len = StorageTmp->snmpNotifyTagLen;
        return (u_char *) StorageTmp->snmpNotifyTag;

    case SNMPNOTIFYTYPE:
        *var_len = sizeof(StorageTmp->snmpNotifyType);
        return (u_char *) & StorageTmp->snmpNotifyType;

    case SNMPNOTIFYSTORAGETYPE:
        *var_len = sizeof(StorageTmp->snmpNotifyStorageType);
        return (u_char *) & StorageTmp->snmpNotifyStorageType;

    case SNMPNOTIFYROWSTATUS:
        *var_len = sizeof(StorageTmp->snmpNotifyRowStatus);
        return (u_char *) & StorageTmp->snmpNotifyRowStatus;

    default:
        ERROR_MSG("");
    }
#endif /* !NETSNMP_NO_READ_SUPPORT */ 
    return NULL;
}

static int
is_delim(const char c)
{
    return (c == 0x020 || c == 0x09 || c == 0x0d || c == 0x0b);
}

int
snmpTagValid(const char *tag, const size_t tagLen)
{
    size_t          i = 0;


    for (i = 0; i < tagLen; i++) {
        if (is_delim(tag[i])) {
            /*
             * Delimeters aren't allowed.  
             */
            return 0;
        }
    }
    return 1;
}

static struct snmpNotifyTable_data *StorageNew;

#ifndef NETSNMP_NO_WRITE_SUPPORT 

int
write_snmpNotifyTag(int action,
                    u_char * var_val,
                    u_char var_val_type,
                    size_t var_val_len,
                    u_char * statP, oid * name, size_t name_len)
{
    static char    *tmpvar;
    struct snmpNotifyTable_data *StorageTmp = NULL;
    static size_t   tmplen;
    size_t          newlen =
        name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) +
                    3 - 1);


    DEBUGMSGTL(("snmpNotifyTable",
                "write_snmpNotifyTag entering action=%d...  \n", action));
    if (action != RESERVE1 &&
        (StorageTmp = (struct snmpNotifyTable_data *)
         header_complex((struct header_complex_index *)
                        snmpNotifyTableStorage, NULL,
                        &name[sizeof(snmpNotifyTable_variables_oid) /
                              sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                        NULL)) == NULL) {
        if ((StorageTmp = StorageNew) == NULL)
            return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */
    }


    switch (action) {
    case RESERVE1:
        if (var_val_type != ASN_OCTET_STR) {
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len > 255) {
            return SNMP_ERR_WRONGLENGTH;
        }
        if (!snmpTagValid((char *) var_val, var_val_len)) {
            return SNMP_ERR_WRONGVALUE;
        }
        break;


    case RESERVE2:
        /*
         * memory reseveration, final preparation... 
         */
        tmpvar = StorageTmp->snmpNotifyTag;
        tmplen = StorageTmp->snmpNotifyTagLen;
        StorageTmp->snmpNotifyTag = (char*)calloc(1, var_val_len + 1);
        if (NULL == StorageTmp->snmpNotifyTag)
            return SNMP_ERR_RESOURCEUNAVAILABLE;
        break;


    case FREE:
        /*
         * Release any resources that have been allocated 
         */
        break;


    case ACTION:
        memcpy(StorageTmp->snmpNotifyTag, var_val, var_val_len);
        StorageTmp->snmpNotifyTagLen = var_val_len;
        break;


    case UNDO:
        /*
         * Back out any changes made in the ACTION case 
         */
        SNMP_FREE(StorageTmp->snmpNotifyTag);
        StorageTmp->snmpNotifyTag = tmpvar;
        StorageTmp->snmpNotifyTagLen = tmplen;
        tmpvar = NULL;
        break;


    case COMMIT:
        /*
         * Things are working well, so it's now safe to make the change
         * permanently.  Make sure that anything done here can't fail! 
         */
        SNMP_FREE(tmpvar);
        snmp_store_needed(NULL);
        break;
    }

    return SNMP_ERR_NOERROR;
}



int
write_snmpNotifyType(int action,
                     u_char * var_val,
                     u_char var_val_type,
                     size_t var_val_len,
                     u_char * statP, oid * name, size_t name_len)
{
    static int      tmpvar;
    struct snmpNotifyTable_data *StorageTmp = NULL;
    long            value = *((long *) var_val);
    size_t          newlen =
        name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) +
                    3 - 1);


    DEBUGMSGTL(("snmpNotifyTable",
                "write_snmpNotifyType entering action=%d...  \n", action));
    if (action != RESERVE1 &&
        (StorageTmp = (struct snmpNotifyTable_data *)
         header_complex((struct header_complex_index *)
                        snmpNotifyTableStorage, NULL,
                        &name[sizeof(snmpNotifyTable_variables_oid) /
                              sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                        NULL)) == NULL) {
        if ((StorageTmp = StorageNew) == NULL)
            return SNMP_ERR_NOSUCHNAME;
    }

    switch (action) {
    case RESERVE1:
        if (var_val_type != ASN_INTEGER) {
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len != sizeof(long)) {
            return SNMP_ERR_WRONGLENGTH;
        }
        if (value < 1 || value > 2) {
            return SNMP_ERR_WRONGVALUE;
        }
        break;

    case ACTION:
        tmpvar = StorageTmp->snmpNotifyType;
        StorageTmp->snmpNotifyType = value;
        break;

    case UNDO:
        /*
         * Back out any changes made in the ACTION case 
         */
        StorageTmp->snmpNotifyType = tmpvar;
        break;
    }

    return SNMP_ERR_NOERROR;
}



int
write_snmpNotifyStorageType(int action,
                            u_char * var_val,
                            u_char var_val_type,
                            size_t var_val_len,
                            u_char * statP, oid * name, size_t name_len)
{
    static int      tmpvar;
    long            value = *((long *) var_val);
    struct snmpNotifyTable_data *StorageTmp = NULL;
    size_t          newlen =
        name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) +
                    3 - 1);


    DEBUGMSGTL(("snmpNotifyTable",
                "write_snmpNotifyStorageType entering action=%d...  \n",
                action));
    if (action != RESERVE1 &&
        (StorageTmp = (struct snmpNotifyTable_data *)
         header_complex((struct header_complex_index *)
                        snmpNotifyTableStorage, NULL,
                        &name[sizeof(snmpNotifyTable_variables_oid) /
                              sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                        NULL)) == NULL) {
        if ((StorageTmp = StorageNew) == NULL)
            return SNMP_ERR_NOSUCHNAME;
    }


    switch (action) {
    case RESERVE1:
        if (var_val_type != ASN_INTEGER) {
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len != sizeof(long)) {
            return SNMP_ERR_WRONGLENGTH;
        }
        if (value != SNMP_STORAGE_OTHER && value != SNMP_STORAGE_VOLATILE
            && value != SNMP_STORAGE_NONVOLATILE) {
            return SNMP_ERR_WRONGVALUE;
        }
        break;

    case ACTION:
        tmpvar = StorageTmp->snmpNotifyStorageType;
        StorageTmp->snmpNotifyStorageType = value;
        break;

    case UNDO:
        StorageTmp->snmpNotifyStorageType = tmpvar;
        break;
    }
    return SNMP_ERR_NOERROR;
}



int
write_snmpNotifyRowStatus(int action,
                          u_char * var_val,
                          u_char var_val_type,
                          size_t var_val_len,
                          u_char * statP, oid * name, size_t name_len)
{
    struct snmpNotifyTable_data *StorageTmp = NULL;
    static struct snmpNotifyTable_data *StorageDel;
    size_t          newlen =
        name_len - (sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) +
                    3 - 1);
    static int      old_value;
    int             set_value = *((long *) var_val);
    static netsnmp_variable_list *vars, *vp;
    struct header_complex_index *hciptr;


    DEBUGMSGTL(("snmpNotifyTable",
                "write_snmpNotifyRowStatus entering action=%d...  \n",
                action));
    StorageTmp = (struct snmpNotifyTable_data *)
        header_complex((struct header_complex_index *)
                       snmpNotifyTableStorage, NULL,
                       &name[sizeof(snmpNotifyTable_variables_oid) /
                             sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL);

    switch (action) {
    case RESERVE1:
        if (var_val_type != ASN_INTEGER || var_val == NULL) {
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len != sizeof(long)) {
            return SNMP_ERR_WRONGLENGTH;
        }
        if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY) {
            return SNMP_ERR_WRONGVALUE;
        }
        if (StorageTmp == NULL) {
            /*
             * create the row now? 
             */
            /*
             * ditch illegal values now 
             */
            if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) {
                return SNMP_ERR_INCONSISTENTVALUE;
            }
        } else {
            /*
             * row exists.  Check for a valid state change 
             */
            if (set_value == RS_CREATEANDGO
                || set_value == RS_CREATEANDWAIT) {
                /*
                 * can't create a row that exists 
                 */
                return SNMP_ERR_INCONSISTENTVALUE;
            }
            /*
             * XXX: interaction with row storage type needed 
             */
        }

        /*
         * memory reseveration, final preparation... 
         */
        if (StorageTmp == NULL &&
            (set_value == RS_CREATEANDGO
             || set_value == RS_CREATEANDWAIT)) {
            /*
             * creation 
             */
            vars = NULL;

            snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OCTET_STR, NULL, 0);     /* snmpNotifyName */

            if (header_complex_parse_oid
                (&
                 (name
                  [sizeof(snmpNotifyTable_variables_oid) / sizeof(oid) +
                   2]), newlen, vars) != SNMPERR_SUCCESS) {
                /*
                 * XXX: free, zero vars 
                 */
                snmp_free_var(vars);
                return SNMP_ERR_INCONSISTENTNAME;
            }
            vp = vars;


            StorageNew = SNMP_MALLOC_STRUCT(snmpNotifyTable_data);
            if (StorageNew == NULL) {
                return SNMP_ERR_RESOURCEUNAVAILABLE;
            }
            StorageNew->snmpNotifyName = (char*)calloc( 1, vp->val_len + 1 );
            if (StorageNew->snmpNotifyName == NULL) {
                return SNMP_ERR_RESOURCEUNAVAILABLE;
            }
            memcpy(StorageNew->snmpNotifyName, vp->val.string, vp->val_len);
            StorageNew->snmpNotifyNameLen = vp->val_len;
            vp = vp->next_variable;

            /*
             * default values 
             */
            StorageNew->snmpNotifyStorageType = ST_NONVOLATILE;
            StorageNew->snmpNotifyType = SNMPNOTIFYTYPE_TRAP;
            StorageNew->snmpNotifyTagLen = 0;
            StorageNew->snmpNotifyTag = (char *) calloc(sizeof(char), 1);
            if (StorageNew->snmpNotifyTag == NULL) {
                return SNMP_ERR_RESOURCEUNAVAILABLE;
            }

            StorageNew->snmpNotifyRowStatus = set_value;
            snmp_free_var(vars);
        }
        break;

    case RESERVE2:
        break;

    case FREE:
        if (StorageNew != NULL) {
            SNMP_FREE(StorageNew->snmpNotifyTag);
            SNMP_FREE(StorageNew->snmpNotifyName);
            free(StorageNew);
            StorageNew = NULL;
        }
        break;

    case ACTION:
        if (StorageTmp == NULL && (set_value == RS_CREATEANDGO ||
                                   set_value == RS_CREATEANDWAIT)) {
            /*
             * row creation, so add it 
             */
            if (StorageNew != NULL) {
                snmpNotifyTable_add(StorageNew);
            }
        } else if (set_value != RS_DESTROY) {
            /*
             * set the flag? 
             */
            if (StorageTmp == NULL)
                return SNMP_ERR_GENERR; /* should never ever get here */
            
            old_value = StorageTmp->snmpNotifyRowStatus;
            StorageTmp->snmpNotifyRowStatus = *((long *) var_val);
        } else {
            /*
             * destroy...  extract it for now 
             */
            if (StorageTmp) {
                hciptr = header_complex_find_entry(snmpNotifyTableStorage,
                                                   StorageTmp);
                StorageDel = (struct snmpNotifyTable_data *)
                    header_complex_extract_entry((struct
                                                  header_complex_index **)
                                                 &snmpNotifyTableStorage,
                                                 hciptr);
            }
        }
        break;

    case UNDO:
        /*
         * Back out any changes made in the ACTION case 
         */
        if (StorageTmp == NULL && (set_value == RS_CREATEANDGO ||
                                   set_value == RS_CREATEANDWAIT)) {
            /*
             * row creation, so remove it again 
             */
            hciptr = header_complex_find_entry(snmpNotifyTableStorage,
                                               StorageNew);
            StorageDel = (struct snmpNotifyTable_data *)
                header_complex_extract_entry((struct header_complex_index
                                              **) &snmpNotifyTableStorage,
                                             hciptr);
            /*
             * XXX: free it 
             */
        } else if (StorageDel != NULL) {
            /*
             * row deletion, so add it again 
             */
            snmpNotifyTable_add(StorageDel);
        } else if (set_value != RS_DESTROY) {
            if (StorageTmp)
                StorageTmp->snmpNotifyRowStatus = old_value;
        }
        break;

    case COMMIT:
        if (StorageDel != NULL) {
            SNMP_FREE(StorageDel->snmpNotifyTag);
            SNMP_FREE(StorageDel->snmpNotifyName);
            free(StorageDel);
            StorageDel = NULL;
        }
        if (StorageTmp
            && StorageTmp->snmpNotifyRowStatus == RS_CREATEANDGO) {
            StorageTmp->snmpNotifyRowStatus = RS_ACTIVE;
            StorageNew = NULL;
        } else if (StorageTmp &&
                   StorageTmp->snmpNotifyRowStatus == RS_CREATEANDWAIT) {
            StorageTmp->snmpNotifyRowStatus = RS_NOTINSERVICE;
            StorageNew = NULL;
        }
        snmp_store_needed(NULL);
        break;
    }
    return SNMP_ERR_NOERROR;
}
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
