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


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

};
/*
 * (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"));
    /*
     * 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:
        *write_method = write_mteTriggerExistenceTest;
        *var_len = StorageTmp->mteTriggerExistenceTestLen;
        return (u_char *) StorageTmp->mteTriggerExistenceTest;

    case MTETRIGGEREXISTENCESTARTUP:
        *write_method = write_mteTriggerExistenceStartup;
        *var_len = StorageTmp->mteTriggerExistenceStartupLen;
        return (u_char *) StorageTmp->mteTriggerExistenceStartup;

    case MTETRIGGEREXISTENCEOBJECTSOWNER:
        *write_method = write_mteTriggerExistenceObjectsOwner;
        *var_len = StorageTmp->mteTriggerExistenceObjectsOwnerLen;
        return (u_char *) StorageTmp->mteTriggerExistenceObjectsOwner;

    case MTETRIGGEREXISTENCEOBJECTS:
        *write_method = write_mteTriggerExistenceObjects;
        *var_len = StorageTmp->mteTriggerExistenceObjectsLen;
        return (u_char *) StorageTmp->mteTriggerExistenceObjects;

    case MTETRIGGEREXISTENCEEVENTOWNER:
        *write_method = write_mteTriggerExistenceEventOwner;
        *var_len = StorageTmp->mteTriggerExistenceEventOwnerLen;
        return (u_char *) StorageTmp->mteTriggerExistenceEventOwner;

    case MTETRIGGEREXISTENCEEVENT:
        *write_method = write_mteTriggerExistenceEvent;
        *var_len = StorageTmp->mteTriggerExistenceEventLen;
        return (u_char *) StorageTmp->mteTriggerExistenceEvent;


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




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