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

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

void shutdown_snmpNotifyTable(void)
{
    UNREGISTER_SYSOR_ENTRY(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;
    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++) {
        sprintf(buf, "internal%d", i);
        if (get_addrForName(buf) == 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->name = strdup(buf);
    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(ptr->name);
    ptr->params = strdup(ptr->name);
    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;
    struct snmpNotifyTable_data *nptr;

    for (hptr = snmpNotifyTableStorage; hptr; hptr = nhptr) {
        nptr = (struct snmpNotifyTable_data *) hptr->data;
        nhptr = hptr->next;
        if (nptr->snmpNotifyStorageType == ST_READONLY) {
            header_complex_extract_entry(&snmpNotifyTableStorage, hptr);
            SNMP_FREE(nptr->snmpNotifyName);
            SNMP_FREE(nptr->snmpNotifyTag);
            SNMP_FREE(nptr);
        }
    }
    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"));
}


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


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



    header_complex_add_data(&snmpNotifyTableStorage, vars, thedata);
    DEBUGMSGTL(("snmpNotifyTable", "registered an entry\n"));


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


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


    snmpNotifyTable_add(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) {
    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;
    default:
        *write_method = NULL;
    }

    if (!found) {
        return NULL;
    }

    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("");
    }
    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;

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;
}
