/*
 * 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, RWRITE, var_mteObjectsTable, 2, {1, 3}},
#define   MTEOBJECTSIDWILDCARD  6
    {MTEOBJECTSIDWILDCARD, ASN_INTEGER, RWRITE, var_mteObjectsTable, 2,
     {1, 4}},
#define   MTEOBJECTSENTRYSTATUS  7
    {MTEOBJECTSENTRYSTATUS, ASN_INTEGER, 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);
            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);
    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);
}
