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


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


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


struct variable2 mteObjectsTable_variables[] = {
    /*
     * magic number        , variable type , ro/rw , callback fn  , L, oidsuffix 
     */
#define   MTEOBJECTSID          5
    {MTEOBJECTSID, ASN_OBJECT_ID, NETSNMP_OLDAPI_RWRITE,
     var_mteObjectsTable, 2, {1, 3}},
#define   MTEOBJECTSIDWILDCARD  6
    {MTEOBJECTSIDWILDCARD, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
     var_mteObjectsTable, 2, {1, 4}},
#define   MTEOBJECTSENTRYSTATUS  7
    {MTEOBJECTSENTRYSTATUS, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
     var_mteObjectsTable, 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 *mteObjectsTableStorage = NULL;




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


    /*
     * register ourselves with the agent to handle our mib tree 
     */
    REGISTER_MIB("mteObjectsTable", mteObjectsTable_variables, variable2,
                 mteObjectsTable_variables_oid);


    /*
     * register our config handler(s) to deal with registrations 
     */
    snmpd_register_config_handler("mteObjectsTable", parse_mteObjectsTable,
                                  NULL, NULL);


    /*
     * we need to be called back later to store our data 
     */
    snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
                           store_mteObjectsTable, NULL);


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


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


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


    DEBUGMSGTL(("mteObjectsTable", "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_OCTET_STR, (char *) thedata->mteOwner, thedata->mteOwnerLen); /* mteOwner */
    snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, (char *) thedata->mteObjectsName, thedata->mteObjectsNameLen);     /* mteObjectsName */
    snmp_varlist_add_variable(&vars, NULL, 0, ASN_UNSIGNED, (char *) &thedata->mteObjectsIndex, sizeof(thedata->mteObjectsIndex));      /* mteObjectsIndex */



    header_complex_add_data(&mteObjectsTableStorage, vars, thedata);
    DEBUGMSGTL(("mteObjectsTable", "registered an entry\n"));


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


/*
 * parse_mteObjectsTable():
 *   parses .conf file entries needed to configure the mib.
 */
void
parse_mteObjectsTable(const char *token, char *line)
{
    size_t          tmpint;
    struct mteObjectsTable_data *StorageTmp =
        SNMP_MALLOC_STRUCT(mteObjectsTable_data);

    DEBUGMSGTL(("mteObjectsTable", "parsing config...  "));


    if (StorageTmp == NULL) {
        config_perror("malloc failure");
        return;
    }


    line =
        read_config_read_data(ASN_OCTET_STR, line, &StorageTmp->mteOwner,
                              &StorageTmp->mteOwnerLen);
    if (StorageTmp->mteOwner == NULL) {
        config_perror("invalid specification for mteOwner");
        return;
    }

    line =
        read_config_read_data(ASN_OCTET_STR, line,
                              &StorageTmp->mteObjectsName,
                              &StorageTmp->mteObjectsNameLen);
    if (StorageTmp->mteObjectsName == NULL) {
        config_perror("invalid specification for mteObjectsName");
        return;
    }

    line =
        read_config_read_data(ASN_UNSIGNED, line,
                              &StorageTmp->mteObjectsIndex, &tmpint);

    line =
        read_config_read_data(ASN_OBJECT_ID, line,
                              &StorageTmp->mteObjectsID,
                              &StorageTmp->mteObjectsIDLen);
    if (StorageTmp->mteObjectsID == NULL) {
        config_perror("invalid specification for mteObjectsID");
        return;
    }

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

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




    mteObjectsTable_add(StorageTmp);


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




/*
 * store_mteObjectsTable():
 *   stores .conf file entries needed to configure the mib.
 */
int
store_mteObjectsTable(int majorID, int minorID, void *serverarg,
                      void *clientarg)
{
    char            line[SNMP_MAXBUF];
    char           *cptr;
    size_t          tmpint;
    struct mteObjectsTable_data *StorageTmp;
    struct header_complex_index *hcindex;


    DEBUGMSGTL(("mteObjectsTable", "storing data...  "));


    for (hcindex = mteObjectsTableStorage; hcindex != NULL;
         hcindex = hcindex->next) {
        StorageTmp = (struct mteObjectsTable_data *) hcindex->data;

        if (StorageTmp->storagetype != ST_READONLY) {
            memset(line, 0, sizeof(line));
            strcat(line, "mteObjectsTable ");
            cptr = line + strlen(line);


            cptr =
                read_config_store_data(ASN_OCTET_STR, cptr,
                                       &StorageTmp->mteOwner,
                                       &StorageTmp->mteOwnerLen);
            cptr =
                read_config_store_data(ASN_OCTET_STR, cptr,
                                       &StorageTmp->mteObjectsName,
                                       &StorageTmp->mteObjectsNameLen);
            cptr =
                read_config_store_data(ASN_UNSIGNED, cptr,
                                       &StorageTmp->mteObjectsIndex,
                                       &tmpint);
            cptr =
                read_config_store_data(ASN_OBJECT_ID, cptr,
                                       &StorageTmp->mteObjectsID,
                                       &StorageTmp->mteObjectsIDLen);
            cptr =
                read_config_store_data(ASN_INTEGER, cptr,
                                       &StorageTmp->mteObjectsIDWildcard,
                                       &tmpint);
            cptr =
                read_config_store_data(ASN_INTEGER, cptr,
                                       &StorageTmp->mteObjectsEntryStatus,
                                       &tmpint);



            snmpd_store_config(line);
        }
    }
    DEBUGMSGTL(("mteObjectsTable", "done.\n"));
    return SNMPERR_SUCCESS;
}




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


    struct mteObjectsTable_data *StorageTmp = NULL;


    DEBUGMSGTL(("mteObjectsTable",
                "var_mteObjectsTable: Entering...  \n"));
    /*
     * this assumes you have registered all your data properly
     */
    if ((StorageTmp =
         header_complex(mteObjectsTableStorage, vp, name, length, exact,
                        var_len, write_method)) == NULL) {
        if (vp->magic == MTEOBJECTSENTRYSTATUS)
            *write_method = write_mteObjectsEntryStatus;
        return NULL;
    }

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


    case MTEOBJECTSID:
        *write_method = write_mteObjectsID;
        *var_len = (StorageTmp->mteObjectsIDLen) * sizeof(oid);
        return (u_char *) StorageTmp->mteObjectsID;

    case MTEOBJECTSIDWILDCARD:
        *write_method = write_mteObjectsIDWildcard;
        *var_len = sizeof(StorageTmp->mteObjectsIDWildcard);
        return (u_char *) & StorageTmp->mteObjectsIDWildcard;

    case MTEOBJECTSENTRYSTATUS:
        *write_method = write_mteObjectsEntryStatus;
        *var_len = sizeof(StorageTmp->mteObjectsEntryStatus);
        return (u_char *) & StorageTmp->mteObjectsEntryStatus;


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




int
write_mteObjectsID(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 oid     *tmpvar;
    struct mteObjectsTable_data *StorageTmp = NULL;
    static size_t   tmplen;
    size_t          newlen =
        name_len - (sizeof(mteObjectsTable_variables_oid) / sizeof(oid) +
                    3 - 1);


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

    if (StorageTmp && StorageTmp->storagetype == ST_READONLY) {
        return SNMP_ERR_NOTWRITABLE;
    }

    switch (action) {
    case RESERVE1:
        if (var_val_type != ASN_OBJECT_ID) {
            snmp_log(LOG_ERR, "write to mteObjectsID not ASN_OBJECT_ID\n");
            return SNMP_ERR_WRONGTYPE;
        }
        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 objid 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->mteObjectsID;
        tmplen = StorageTmp->mteObjectsIDLen;
        StorageTmp->mteObjectsID = netsnmp_memdup(var_val, var_val_len);
        StorageTmp->mteObjectsIDLen = var_val_len / sizeof(oid);
        break;


    case UNDO:
        /*
         * Back out any changes made in the ACTION case 
         */
        SNMP_FREE(StorageTmp->mteObjectsID);
        StorageTmp->mteObjectsID = tmpvar;
        StorageTmp->mteObjectsIDLen = 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_mteObjectsIDWildcard(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 mteObjectsTable_data *StorageTmp = NULL;
    size_t          newlen =
        name_len - (sizeof(mteObjectsTable_variables_oid) / sizeof(oid) +
                    3 - 1);


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

    if (StorageTmp && StorageTmp->storagetype == ST_READONLY) {
        return SNMP_ERR_NOTWRITABLE;
    }

    switch (action) {
    case RESERVE1:
        if (var_val_type != ASN_INTEGER) {
            snmp_log(LOG_ERR,
                     "write to mteObjectsIDWildcard not ASN_INTEGER\n");
            return SNMP_ERR_WRONGTYPE;
        }
        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 long_ret 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->mteObjectsIDWildcard;
        StorageTmp->mteObjectsIDWildcard = *((long *) var_val);
        break;


    case UNDO:
        /*
         * Back out any changes made in the ACTION case 
         */
        StorageTmp->mteObjectsIDWildcard = tmpvar;
        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! 
         */

        break;
    }
    return SNMP_ERR_NOERROR;
}






int
write_mteObjectsEntryStatus(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 mteObjectsTable_data *StorageTmp = NULL;
    static struct mteObjectsTable_data *StorageNew, *StorageDel;
    size_t          newlen =
        name_len - (sizeof(mteObjectsTable_variables_oid) / sizeof(oid) +
                    3 - 1);
    static int      old_value;
    int             set_value;
    static netsnmp_variable_list *vars, *vp;
    struct header_complex_index *hciptr;


    StorageTmp =
        header_complex(mteObjectsTableStorage, NULL,
                       &name[sizeof(mteObjectsTable_variables_oid) /
                             sizeof(oid) + 3 - 1], &newlen, 1, NULL, NULL);

    if (var_val_type != ASN_INTEGER || var_val == NULL) {
        snmp_log(LOG_ERR,
                 "write to mteObjectsEntryStatus not ASN_INTEGER\n");
        return SNMP_ERR_WRONGTYPE;
    }

    if (StorageTmp && StorageTmp->storagetype == ST_READONLY) {
        return SNMP_ERR_NOTWRITABLE;
    }

    set_value = *((long *) var_val);


    /*
     * check legal range, and notReady is reserved for us, not a user 
     */
    if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY)
        return SNMP_ERR_INCONSISTENTVALUE;


    switch (action) {
    case RESERVE1:
        /*
         * stage one: test validity 
         */
        if (StorageTmp == NULL) {
            /*
             * create the row now? 
             */


            /*
             * ditch illegal values now 
             */
            if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE)
                return SNMP_ERR_INCONSISTENTVALUE;


            /*
             * destroying a non-existent row is actually legal 
             */
            if (set_value == RS_DESTROY) {
                return SNMP_ERR_NOERROR;
            }


            /*
             * illegal creation values 
             */
            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 
             */
        }
        break;




    case RESERVE2:
        /*
         * memory reseveration, final preparation... 
         */
        if (StorageTmp == NULL) {
            /*
             * creation 
             */
            vars = NULL;


            snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0);  /* mteOwner */
            snmp_varlist_add_variable(&vars, NULL, 0, ASN_OCTET_STR, NULL, 0);  /* mteObjectsName */
            snmp_varlist_add_variable(&vars, NULL, 0, ASN_UNSIGNED, NULL, 0);   /* mteObjectsIndex */

            if (header_complex_parse_oid
                (&
                 (name
                  [sizeof(mteObjectsTable_variables_oid) / sizeof(oid) +
                   2]), newlen, vars) != SNMPERR_SUCCESS) {
                /*
                 * XXX: free, zero vars 
                 */
                return SNMP_ERR_INCONSISTENTNAME;
            }
            vp = vars;


            StorageNew = SNMP_MALLOC_STRUCT(mteObjectsTable_data);
            if (StorageNew == NULL)
                return SNMP_ERR_GENERR;
            StorageNew->mteOwner = netsnmp_strdup_and_null(vp->val.string,
                                                           vp->val_len);
            StorageNew->mteOwnerLen = vp->val_len;
            vp = vp->next_variable;
            StorageNew->mteObjectsName  =
                netsnmp_strdup_and_null(vp->val.string,
                                        vp->val_len);
            StorageNew->mteObjectsNameLen = vp->val_len;
            vp = vp->next_variable;
            StorageNew->mteObjectsIndex = *(vp->val.integer);

            /*
             * XXX: fill in default row values here into StorageNew 
             */
            StorageNew->mteObjectsID = calloc(1, sizeof(oid) * sizeof(2));      /* 0.0 */
            StorageNew->mteObjectsIDLen = 2;
            StorageNew->mteObjectsIDWildcard = MTEOBJECTSIDWILDCARD_FALSE;

            StorageNew->mteObjectsEntryStatus = set_value;
            /*
             * XXX: free, zero vars, no longer needed? 
             */
        }


        break;




    case FREE:
        /*
         * XXX: free, zero vars 
         */
        /*
         * Release any resources that have been allocated 
         */
        break;




    case ACTION:
        /*
         * The variable has been stored in set_value 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 
         */


        if (StorageTmp == NULL) {
            /*
             * row creation, so add it 
             */
            if (StorageNew != NULL)
                mteObjectsTable_add(StorageNew);
            /*
             * XXX: ack, and if it is NULL? 
             */
        } else if (set_value != RS_DESTROY) {
            /*
             * set the flag? 
             */
            old_value = StorageTmp->mteObjectsEntryStatus;
            StorageTmp->mteObjectsEntryStatus = *((long *) var_val);
        } else {
            /*
             * destroy...  extract it for now 
             */
            hciptr =
                header_complex_find_entry(mteObjectsTableStorage,
                                          StorageTmp);
            StorageDel =
                header_complex_extract_entry(&mteObjectsTableStorage,
                                             hciptr);
        }
        break;




    case UNDO:
        /*
         * Back out any changes made in the ACTION case 
         */
        if (StorageTmp == NULL) {
            /*
             * row creation, so remove it again 
             */
            hciptr =
                header_complex_find_entry(mteObjectsTableStorage,
                                          StorageTmp);
            StorageDel =
                header_complex_extract_entry(&mteObjectsTableStorage,
                                             hciptr);
            /*
             * XXX: free it 
             */
        } else if (StorageDel != NULL) {
            /*
             * row deletion, so add it again 
             */
            mteObjectsTable_add(StorageDel);
        } else {
            StorageTmp->mteObjectsEntryStatus = old_value;
        }
        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! 
         */
        if (StorageDel != NULL) {
            StorageDel = 0;
            /*
             * XXX: free it, its dead 
             */
        } else {
            if (StorageTmp
                && StorageTmp->mteObjectsEntryStatus == RS_CREATEANDGO) {
                StorageTmp->mteObjectsEntryStatus = RS_ACTIVE;
            } else if (StorageTmp &&
                       StorageTmp->mteObjectsEntryStatus ==
                       RS_CREATEANDWAIT) {
                StorageTmp->mteObjectsEntryStatus = RS_NOTINSERVICE;
            }
        }
        break;
    }
    return SNMP_ERR_NOERROR;
}

void
mte_add_objects(netsnmp_variable_list * vars,
                struct mteTriggerTable_data *item, const char *owner,
                const char *name, oid * suffix, size_t suffix_len)
{
    struct header_complex_index *hcptr = mteObjectsTableStorage;

    DEBUGMSGTL(("mteObjectsTable",
                "Searching for objects to add for owner=%s / name=%s\n",
                owner, name));

    if (vars == NULL || item == NULL || owner == NULL || name == NULL ||
        hcptr == NULL)
        return;

    /*
     * get to end of variable chain 
     */
    while (vars->next_variable != NULL)
        vars = vars->next_variable;


    /*
     * get to start of objects list 
     */
    while (hcptr &&
           (strcmp(((struct mteObjectsTable_data *) hcptr->data)->mteOwner,
                   owner) != 0 ||
            strcmp(((struct mteObjectsTable_data *) hcptr->data)->
                   mteObjectsName, name) != 0))
        hcptr = hcptr->next;

    /*
     * add all objects 
     */
    while (hcptr &&
           strcmp(((struct mteObjectsTable_data *) hcptr->data)->mteOwner,
                  owner) == 0 &&
           strcmp(((struct mteObjectsTable_data *) hcptr->data)->
                  mteObjectsName, name) == 0) {
        /*
         * loop through objects 
         */
        netsnmp_pdu    *pdu = NULL, *response = NULL;
        struct mteObjectsTable_data *node =
            (struct mteObjectsTable_data *) hcptr->data;
        oid             theoid[MAX_OID_LEN];
        size_t          theoid_len;

        /*
         * copy in the suffix 
         */
        memcpy(theoid, node->mteObjectsID,
               node->mteObjectsIDLen * sizeof(oid));
        theoid_len = node->mteObjectsIDLen;
        if (node->mteObjectsIDWildcard == MTEOBJECTSIDWILDCARD_TRUE &&
            suffix && suffix_len > 0) {
            theoid_len += suffix_len;
            if (theoid_len > MAX_OID_LEN) {
                break;          /* XXX: properly send trap or something? */
            }

            memcpy(&theoid[node->mteObjectsIDLen], suffix,
                   suffix_len * sizeof(oid));
        }

        /*
         * retrieve the value 
         */
        pdu = snmp_pdu_create(SNMP_MSG_GET);
        snmp_add_null_var(pdu, theoid, theoid_len);
        response = mte_get_response(item, pdu);

        if (response) {
            if (vars) {
                vars->next_variable = response->variables;
                vars = vars->next_variable;
                DEBUGMSGTL(("mteObjectsTable", "Adding:  "));
                DEBUGMSGOID(("mteObjectsTable", response->variables->name,
                             response->variables->name_length));
                DEBUGMSG(("mteObjectsTable", "\n"));
            } else {
                vars = response->variables;
            }
            /*
             * erase response notion of the values we stole from it 
             */
            response->variables = NULL;
            snmp_free_pdu(response);
        }

        /*
         * move along 
         */
        hcptr = hcptr->next;
    }
    DEBUGMSGTL(("mteObjectsTable", "Done adding objects\n"));
}

int
mte_add_object_to_table(const char *owner, const char *objname,
                        oid * oidname, size_t oidname_len, int iswild)
{
    struct header_complex_index *hcptr = mteObjectsTableStorage, *lastnode;
    static struct mteObjectsTable_data *StorageNew;

    /*
     * malloc initial struct 
     */
    StorageNew = SNMP_MALLOC_STRUCT(mteObjectsTable_data);
    if (StorageNew == NULL)
        return SNMP_ERR_GENERR;
    StorageNew->mteOwner = netsnmp_strdup_and_null(owner, strlen(owner));
    StorageNew->mteOwnerLen = strlen(owner);
    StorageNew->mteObjectsName = netsnmp_strdup_and_null(objname,
                                                         strlen(objname));
    StorageNew->mteObjectsNameLen = strlen(objname);

    /*
     * find the next number 
     */
    /*
     * get to start of objects list 
     */
    while (hcptr &&
           (strcmp(((struct mteObjectsTable_data *) hcptr->data)->mteOwner,
                   owner) != 0 ||
            strcmp(((struct mteObjectsTable_data *) hcptr->data)->
                   mteObjectsName, objname) != 0))
        hcptr = hcptr->next;

    if (hcptr) {
        /*
         * an object existed.  Find the first one past and increment
         * the previous number 
         */
        lastnode = hcptr;
        while (hcptr &&
               strcmp(((struct mteObjectsTable_data *) hcptr->data)->
                      mteOwner, owner) == 0
               && strcmp(((struct mteObjectsTable_data *) hcptr->data)->
                         mteObjectsName, objname) == 0) {
            lastnode = hcptr;
            hcptr = hcptr->next;
        }
        StorageNew->mteObjectsIndex =
            ((struct mteObjectsTable_data *) lastnode->data)->
            mteObjectsIndex + 1;
    } else {
        StorageNew->mteObjectsIndex = 1;
    }

    /*
     * XXX: fill in default row values here into StorageNew 
     */
    StorageNew->mteObjectsID = snmp_duplicate_objid(oidname, oidname_len);
    StorageNew->mteObjectsIDLen = oidname_len;

    if (iswild)
        StorageNew->mteObjectsIDWildcard = MTEOBJECTSIDWILDCARD_TRUE;
    else
        StorageNew->mteObjectsIDWildcard = MTEOBJECTSIDWILDCARD_FALSE;

    StorageNew->mteObjectsEntryStatus = RS_ACTIVE;
    StorageNew->storagetype = ST_READONLY;
    return mteObjectsTable_add(StorageNew);
}
