/*
 * 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>
#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 "mteTriggerExistenceTable.h"
#include "mteTriggerTable.h"


/*
 * mteTriggerExistenceTable_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             mteTriggerExistenceTable_variables_oid[] =
    { 1, 3, 6, 1, 2, 1, 88, 1, 2, 4 };


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


#ifndef NETSNMP_NO_WRITE_SUPPORT
struct variable2 mteTriggerExistenceTable_variables[] = {
    /*
     * magic number        , variable type , ro/rw , callback fn  , L, oidsuffix 
     */
#define   MTETRIGGEREXISTENCETEST  3
    {MTETRIGGEREXISTENCETEST, ASN_BIT_STR, NETSNMP_OLDAPI_RWRITE,
     var_mteTriggerExistenceTable, 2, {1, 1}},
#define   MTETRIGGEREXISTENCESTARTUP  4
    {MTETRIGGEREXISTENCESTARTUP, ASN_BIT_STR, NETSNMP_OLDAPI_RWRITE,
     var_mteTriggerExistenceTable, 2, {1, 2}},
#define   MTETRIGGEREXISTENCEOBJECTSOWNER  5
    {MTETRIGGEREXISTENCEOBJECTSOWNER, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
     var_mteTriggerExistenceTable, 2, {1, 3}},
#define   MTETRIGGEREXISTENCEOBJECTS  6
    {MTETRIGGEREXISTENCEOBJECTS, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
     var_mteTriggerExistenceTable, 2, {1, 4}},
#define   MTETRIGGEREXISTENCEEVENTOWNER  7
    {MTETRIGGEREXISTENCEEVENTOWNER, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
     var_mteTriggerExistenceTable, 2, {1, 5}},
#define   MTETRIGGEREXISTENCEEVENT  8
    {MTETRIGGEREXISTENCEEVENT, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
     var_mteTriggerExistenceTable, 2, {1, 6}},
};
#else /* !NETSNMP_NO_WRITE_SUPPORT */
struct variable2 mteTriggerExistenceTable_variables[] = {
    /*
     * magic number        , variable type , ro/rw , callback fn  , L, oidsuffix 
     */
#define   MTETRIGGEREXISTENCETEST  3
    {MTETRIGGEREXISTENCETEST, ASN_BIT_STR, NETSNMP_OLDAPI_RONLY,
     var_mteTriggerExistenceTable, 2, {1, 1}},
#define   MTETRIGGEREXISTENCESTARTUP  4
    {MTETRIGGEREXISTENCESTARTUP, ASN_BIT_STR, NETSNMP_OLDAPI_RONLY,
     var_mteTriggerExistenceTable, 2, {1, 2}},
#define   MTETRIGGEREXISTENCEOBJECTSOWNER  5
    {MTETRIGGEREXISTENCEOBJECTSOWNER, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_mteTriggerExistenceTable, 2, {1, 3}},
#define   MTETRIGGEREXISTENCEOBJECTS  6
    {MTETRIGGEREXISTENCEOBJECTS, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_mteTriggerExistenceTable, 2, {1, 4}},
#define   MTETRIGGEREXISTENCEEVENTOWNER  7
    {MTETRIGGEREXISTENCEEVENTOWNER, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_mteTriggerExistenceTable, 2, {1, 5}},
#define   MTETRIGGEREXISTENCEEVENT  8
    {MTETRIGGEREXISTENCEEVENT, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_mteTriggerExistenceTable, 2, {1, 6}},
};
#endif /* !NETSNMP_NO_WRITE_SUPPORT */

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


/*
 * global storage of our data, saved in and configured by header_complex() 
 */
extern struct header_complex_index *mteTriggerTableStorage;




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


    /*
     * register ourselves with the agent to handle our mib tree 
     */
    REGISTER_MIB("mteTriggerExistenceTable",
                 mteTriggerExistenceTable_variables, variable2,
                 mteTriggerExistenceTable_variables_oid);


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


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

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


    struct mteTriggerTable_data *StorageTmp = NULL;


    DEBUGMSGTL(("mteTriggerExistenceTable",
                "var_mteTriggerExistenceTable: Entering...  \n"));

	/* set default value */
	*write_method = NULL;

    /*
     * this assumes you have registered all your data properly
     */
    if ((StorageTmp =
         header_complex(mteTriggerTableStorage, vp, name, length, exact,
                        var_len, write_method)) == NULL)
        return NULL;

    if (!(StorageTmp->mteTriggerTest[0] & MTETRIGGERTEST_EXISTENCE))
        return NULL;

    /*
     * this is where we do the value assignments for the mib results.
     */
    switch (vp->magic) {


    case MTETRIGGEREXISTENCETEST:
#ifndef NETSNMP_NO_WRITE_SUPPORT
        *write_method = write_mteTriggerExistenceTest;
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
        *var_len = StorageTmp->mteTriggerExistenceTestLen;
        return (u_char *) StorageTmp->mteTriggerExistenceTest;

    case MTETRIGGEREXISTENCESTARTUP:
#ifndef NETSNMP_NO_WRITE_SUPPORT
        *write_method = write_mteTriggerExistenceStartup;
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
        *var_len = StorageTmp->mteTriggerExistenceStartupLen;
        return (u_char *) StorageTmp->mteTriggerExistenceStartup;

    case MTETRIGGEREXISTENCEOBJECTSOWNER:
#ifndef NETSNMP_NO_WRITE_SUPPORT
        *write_method = write_mteTriggerExistenceObjectsOwner;
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
        *var_len = StorageTmp->mteTriggerExistenceObjectsOwnerLen;
        return (u_char *) StorageTmp->mteTriggerExistenceObjectsOwner;

    case MTETRIGGEREXISTENCEOBJECTS:
#ifndef NETSNMP_NO_WRITE_SUPPORT
        *write_method = write_mteTriggerExistenceObjects;
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
        *var_len = StorageTmp->mteTriggerExistenceObjectsLen;
        return (u_char *) StorageTmp->mteTriggerExistenceObjects;

    case MTETRIGGEREXISTENCEEVENTOWNER:
#ifndef NETSNMP_NO_WRITE_SUPPORT
        *write_method = write_mteTriggerExistenceEventOwner;
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
        *var_len = StorageTmp->mteTriggerExistenceEventOwnerLen;
        return (u_char *) StorageTmp->mteTriggerExistenceEventOwner;

    case MTETRIGGEREXISTENCEEVENT:
#ifndef NETSNMP_NO_WRITE_SUPPORT
        *write_method = write_mteTriggerExistenceEvent;
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
        *var_len = StorageTmp->mteTriggerExistenceEventLen;
        return (u_char *) StorageTmp->mteTriggerExistenceEvent;


    default:
        ERROR_MSG("");
    }
    return NULL;
}



#ifndef NETSNMP_NO_WRITE_SUPPORT

int
write_mteTriggerExistenceTest(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 mteTriggerTable_data *StorageTmp = NULL;
    static size_t   tmplen;
    size_t          newlen =
        name_len -
        (sizeof(mteTriggerExistenceTable_variables_oid) / sizeof(oid) + 3 -
         1);


    DEBUGMSGTL(("mteTriggerExistenceTable",
                "write_mteTriggerExistenceTest entering action=%d...  \n",
                action));
    if ((StorageTmp =
         header_complex(mteTriggerTableStorage, NULL,
                        &name[sizeof
                              (mteTriggerExistenceTable_variables_oid) /
                              sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                        NULL)) == NULL)
        return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */


    switch (action) {
    case RESERVE1:
        if (var_val_type != ASN_OCTET_STR) {
            fprintf(stderr,
                    "write to mteTriggerExistenceTest not ASN_OCTET_STR\n");
            return SNMP_ERR_WRONGTYPE;
        }
        if (StorageTmp->storageType != ST_NONVOLATILE)
            return SNMP_ERR_NOTWRITABLE;
        break;


    case RESERVE2:
        /*
         * memory reseveration, final preparation... 
         */
        break;


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


    case ACTION:
        /*
         * The variable has been stored in string for
         * you to use, and you have just been asked to do something with
         * it.  Note that anything done here must be reversable in the UNDO case 
         */
        tmpvar = StorageTmp->mteTriggerExistenceTest;
        tmplen = StorageTmp->mteTriggerExistenceTestLen;
        StorageTmp->mteTriggerExistenceTest =
            netsnmp_memdup(var_val, var_val_len);
        StorageTmp->mteTriggerExistenceTestLen = var_val_len;
        break;


    case UNDO:
        /*
         * Back out any changes made in the ACTION case 
         */
        SNMP_FREE(StorageTmp->mteTriggerExistenceTest);
        StorageTmp->mteTriggerExistenceTest = tmpvar;
        StorageTmp->mteTriggerExistenceTestLen = tmplen;
        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_mteTriggerExistenceStartup(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 mteTriggerTable_data *StorageTmp = NULL;
    static size_t   tmplen;
    size_t          newlen =
        name_len -
        (sizeof(mteTriggerExistenceTable_variables_oid) / sizeof(oid) + 3 -
         1);


    DEBUGMSGTL(("mteTriggerExistenceTable",
                "write_mteTriggerExistenceStartup entering action=%d...  \n",
                action));
    if ((StorageTmp =
         header_complex(mteTriggerTableStorage, NULL,
                        &name[sizeof
                              (mteTriggerExistenceTable_variables_oid) /
                              sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                        NULL)) == NULL)
        return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */


    switch (action) {
    case RESERVE1:
        if (var_val_type != ASN_OCTET_STR) {
            fprintf(stderr,
                    "write to mteTriggerExistenceStartup not ASN_OCTET_STR\n");
            return SNMP_ERR_WRONGTYPE;
        }
        if (StorageTmp->storageType != ST_NONVOLATILE)
            return SNMP_ERR_NOTWRITABLE;
        break;


    case RESERVE2:
        /*
         * memory reseveration, final preparation... 
         */
        break;


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


    case ACTION:
        /*
         * The variable has been stored in string for
         * you to use, and you have just been asked to do something with
         * it.  Note that anything done here must be reversable in the UNDO case 
         */
        tmpvar = StorageTmp->mteTriggerExistenceStartup;
        tmplen = StorageTmp->mteTriggerExistenceStartupLen;
        StorageTmp->mteTriggerExistenceStartup =
            netsnmp_memdup(var_val, var_val_len);
        StorageTmp->mteTriggerExistenceStartupLen = var_val_len;
        break;


    case UNDO:
        /*
         * Back out any changes made in the ACTION case 
         */
        SNMP_FREE(StorageTmp->mteTriggerExistenceStartup);
        StorageTmp->mteTriggerExistenceStartup = tmpvar;
        StorageTmp->mteTriggerExistenceStartupLen = tmplen;
        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_mteTriggerExistenceObjectsOwner(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 mteTriggerTable_data *StorageTmp = NULL;
    static size_t   tmplen;
    size_t          newlen =
        name_len -
        (sizeof(mteTriggerExistenceTable_variables_oid) / sizeof(oid) + 3 -
         1);


    DEBUGMSGTL(("mteTriggerExistenceTable",
                "write_mteTriggerExistenceObjectsOwner entering action=%d...  \n",
                action));
    if ((StorageTmp =
         header_complex(mteTriggerTableStorage, NULL,
                        &name[sizeof
                              (mteTriggerExistenceTable_variables_oid) /
                              sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                        NULL)) == NULL)
        return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */


    switch (action) {
    case RESERVE1:
        if (var_val_type != ASN_OCTET_STR) {
            fprintf(stderr,
                    "write to mteTriggerExistenceObjectsOwner not ASN_OCTET_STR\n");
            return SNMP_ERR_WRONGTYPE;
        }
        if (StorageTmp->storageType != ST_NONVOLATILE)
            return SNMP_ERR_NOTWRITABLE;
        break;


    case RESERVE2:
        /*
         * memory reseveration, final preparation... 
         */
        break;


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


    case ACTION:
        /*
         * The variable has been stored in string for
         * you to use, and you have just been asked to do something with
         * it.  Note that anything done here must be reversable in the UNDO case 
         */
        tmpvar = StorageTmp->mteTriggerExistenceObjectsOwner;
        tmplen = StorageTmp->mteTriggerExistenceObjectsOwnerLen;
        StorageTmp->mteTriggerExistenceObjectsOwner =
            netsnmp_memdup(var_val, var_val_len);
        StorageTmp->mteTriggerExistenceObjectsOwnerLen = var_val_len;
        break;


    case UNDO:
        /*
         * Back out any changes made in the ACTION case 
         */
        SNMP_FREE(StorageTmp->mteTriggerExistenceObjectsOwner);
        StorageTmp->mteTriggerExistenceObjectsOwner = tmpvar;
        StorageTmp->mteTriggerExistenceObjectsOwnerLen = tmplen;
        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_mteTriggerExistenceObjects(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 mteTriggerTable_data *StorageTmp = NULL;
    static size_t   tmplen;
    size_t          newlen =
        name_len -
        (sizeof(mteTriggerExistenceTable_variables_oid) / sizeof(oid) + 3 -
         1);


    DEBUGMSGTL(("mteTriggerExistenceTable",
                "write_mteTriggerExistenceObjects entering action=%d...  \n",
                action));
    if ((StorageTmp =
         header_complex(mteTriggerTableStorage, NULL,
                        &name[sizeof
                              (mteTriggerExistenceTable_variables_oid) /
                              sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                        NULL)) == NULL)
        return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */


    switch (action) {
    case RESERVE1:
        if (var_val_type != ASN_OCTET_STR) {
            fprintf(stderr,
                    "write to mteTriggerExistenceObjects not ASN_OCTET_STR\n");
            return SNMP_ERR_WRONGTYPE;
        }
        if (StorageTmp->storageType != ST_NONVOLATILE)
            return SNMP_ERR_NOTWRITABLE;
        break;


    case RESERVE2:
        /*
         * memory reseveration, final preparation... 
         */
        break;


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


    case ACTION:
        /*
         * The variable has been stored in string for
         * you to use, and you have just been asked to do something with
         * it.  Note that anything done here must be reversable in the UNDO case 
         */
        tmpvar = StorageTmp->mteTriggerExistenceObjects;
        tmplen = StorageTmp->mteTriggerExistenceObjectsLen;
        StorageTmp->mteTriggerExistenceObjects =
            netsnmp_memdup(var_val, var_val_len);
        StorageTmp->mteTriggerExistenceObjectsLen = var_val_len;
        break;


    case UNDO:
        /*
         * Back out any changes made in the ACTION case 
         */
        SNMP_FREE(StorageTmp->mteTriggerExistenceObjects);
        StorageTmp->mteTriggerExistenceObjects = tmpvar;
        StorageTmp->mteTriggerExistenceObjectsLen = tmplen;
        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_mteTriggerExistenceEventOwner(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 mteTriggerTable_data *StorageTmp = NULL;
    static size_t   tmplen;
    size_t          newlen =
        name_len -
        (sizeof(mteTriggerExistenceTable_variables_oid) / sizeof(oid) + 3 -
         1);


    DEBUGMSGTL(("mteTriggerExistenceTable",
                "write_mteTriggerExistenceEventOwner entering action=%d...  \n",
                action));
    if ((StorageTmp =
         header_complex(mteTriggerTableStorage, NULL,
                        &name[sizeof
                              (mteTriggerExistenceTable_variables_oid) /
                              sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                        NULL)) == NULL)
        return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */


    switch (action) {
    case RESERVE1:
        if (var_val_type != ASN_OCTET_STR) {
            fprintf(stderr,
                    "write to mteTriggerExistenceEventOwner not ASN_OCTET_STR\n");
            return SNMP_ERR_WRONGTYPE;
        }
        if (StorageTmp->storageType != ST_NONVOLATILE)
            return SNMP_ERR_NOTWRITABLE;
        break;


    case RESERVE2:
        /*
         * memory reseveration, final preparation... 
         */
        break;


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


    case ACTION:
        /*
         * The variable has been stored in string for
         * you to use, and you have just been asked to do something with
         * it.  Note that anything done here must be reversable in the UNDO case 
         */
        tmpvar = StorageTmp->mteTriggerExistenceEventOwner;
        tmplen = StorageTmp->mteTriggerExistenceEventOwnerLen;
        StorageTmp->mteTriggerExistenceEventOwner =
            netsnmp_memdup(var_val, var_val_len);
        StorageTmp->mteTriggerExistenceEventOwnerLen = var_val_len;
        break;


    case UNDO:
        /*
         * Back out any changes made in the ACTION case 
         */
        SNMP_FREE(StorageTmp->mteTriggerExistenceEventOwner);
        StorageTmp->mteTriggerExistenceEventOwner = tmpvar;
        StorageTmp->mteTriggerExistenceEventOwnerLen = tmplen;
        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_mteTriggerExistenceEvent(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 mteTriggerTable_data *StorageTmp = NULL;
    static size_t   tmplen;
    size_t          newlen =
        name_len -
        (sizeof(mteTriggerExistenceTable_variables_oid) / sizeof(oid) + 3 -
         1);


    DEBUGMSGTL(("mteTriggerExistenceTable",
                "write_mteTriggerExistenceEvent entering action=%d...  \n",
                action));
    if ((StorageTmp =
         header_complex(mteTriggerTableStorage, NULL,
                        &name[sizeof
                              (mteTriggerExistenceTable_variables_oid) /
                              sizeof(oid) + 3 - 1], &newlen, 1, NULL,
                        NULL)) == NULL)
        return SNMP_ERR_NOSUCHNAME;     /* remove if you support creation here */


    switch (action) {
    case RESERVE1:
        if (var_val_type != ASN_OCTET_STR) {
            fprintf(stderr,
                    "write to mteTriggerExistenceEvent not ASN_OCTET_STR\n");
            return SNMP_ERR_WRONGTYPE;
        }
        if (StorageTmp->storageType != ST_NONVOLATILE)
            return SNMP_ERR_NOTWRITABLE;
        break;


    case RESERVE2:
        /*
         * memory reseveration, final preparation... 
         */
        break;


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


    case ACTION:
        /*
         * The variable has been stored in string for
         * you to use, and you have just been asked to do something with
         * it.  Note that anything done here must be reversable in the UNDO case 
         */
        tmpvar = StorageTmp->mteTriggerExistenceEvent;
        tmplen = StorageTmp->mteTriggerExistenceEventLen;
        StorageTmp->mteTriggerExistenceEvent =
            netsnmp_memdup(var_val, var_val_len);
        StorageTmp->mteTriggerExistenceEventLen = var_val_len;
        break;


    case UNDO:
        /*
         * Back out any changes made in the ACTION case 
         */
        SNMP_FREE(StorageTmp->mteTriggerExistenceEvent);
        StorageTmp->mteTriggerExistenceEvent = tmpvar;
        StorageTmp->mteTriggerExistenceEventLen = tmplen;
        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;
}

#endif /* !NETSNMP_NO_WRITE_SUPPORT */
