/*
 * 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_WINSOCK_H
#include <winsock.h>
#endif
#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 oid             snmptrap_oid[];
    extern 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);

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




    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 < 0 || var_val_len > 255) {
            return SNMP_ERR_WRONGLENGTH;
        }
        if (!snmpTagValid(var_val, var_val_len)) {
            return SNMP_ERR_WRONGVALUE;
        }
        break;


    case RESERVE2:
        /*
         * memory reseveration, final preparation... 
         */
        tmpvar = StorageTmp->snmpNotifyTag;
        tmplen = StorageTmp->snmpNotifyTagLen;
        StorageTmp->snmpNotifyTag = 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);
        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 = 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;
        }
        break;
    }
    return SNMP_ERR_NOERROR;
}
