/*
 * 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 "mibgroup/mibII/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_sysORTable(snmpNotifyFullCompliance, OID_LENGTH(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, RWRITE, var_snmpNotifyTable, 2, {1, 2}},
#define   SNMPNOTIFYTYPE        5
    {SNMPNOTIFYTYPE, ASN_INTEGER, RWRITE, var_snmpNotifyTable, 2, {1, 3}},
#define   SNMPNOTIFYSTORAGETYPE  6
    {SNMPNOTIFYSTORAGETYPE, ASN_INTEGER, RWRITE, var_snmpNotifyTable, 2,
     {1, 4}},
#define   SNMPNOTIFYROWSTATUS   7
    {SNMPNOTIFYROWSTATUS, ASN_INTEGER, 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=%x, vars=%x\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);
        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);
            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);
    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;
}
