/*
 * snmpTargetAddrEntry MIB
 * 
 * This file was generated by mib2c and is intended for use as a mib module
 * for the ucd-snmp snmpd agent. Edited by Michael Baer
 * 
 * last changed 2/2/99.
 */

#include <net-snmp/net-snmp-config.h>
#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#include <stdlib.h>
#include <ctype.h>
#if HAVE_WINSOCK_H
#include <winsock.h>
#endif

#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

#include "snmpTargetAddrEntry.h"
#include "util_funcs.h"

#define snmpTargetAddrOIDLen 11 /*This is base+column, 
                                 * i.e. everything but index */

oid             snmpTargetAddrOID[snmpTargetAddrOIDLen] =
    { 1, 3, 6, 1, 6, 3, 12, 1, 2, 1, 0 };

static unsigned long snmpTargetSpinLock = 0;
static struct targetAddrTable_struct *aAddrTable = 0;


/*
 * Utility routines 
 */
struct targetAddrTable_struct *
get_addrTable(void)
{
    return aAddrTable;
}

struct targetAddrTable_struct *
get_addrForName(char *name)
{
    struct targetAddrTable_struct *ptr;
    for (ptr = aAddrTable; ptr != NULL; ptr = ptr->next) {
        if (ptr->name && strcmp(ptr->name, name) == 0)
            return ptr;
    }
    return NULL;
}


/*
 * TargetAddrTable_create creates and returns a pointer
 * to a targetAddrTable_struct with default values set 
 */
struct targetAddrTable_struct *snmpTargetAddrTable_create(void)
{
    struct targetAddrTable_struct *newEntry;

    newEntry = malloc(sizeof(*newEntry));

    if (newEntry) {
        newEntry->name = 0;

        newEntry->tDomainLen = 0;
        newEntry->tAddress = 0;

        newEntry->timeout = 1500;
        newEntry->retryCount = 3;

        newEntry->tagList = strdup("");
        newEntry->params = 0;

        newEntry->storageType = SNMP_STORAGE_NONVOLATILE;
        newEntry->rowStatus = SNMP_ROW_NONEXISTENT;
        newEntry->sess = NULL;
        newEntry->next = 0;
    }

    return newEntry;
}                               /* snmpTargetAddrTable_create */


/*
 * TargetAddrTable_dispose frees the space allocated to a
 * targetAddrTable_struct 
 */
void
snmpTargetAddrTable_dispose(struct targetAddrTable_struct *reaped)
{
    if (reaped->sess != NULL) {
        snmp_close(reaped->sess);
    }
    SNMP_FREE(reaped->name);
    SNMP_FREE(reaped->tAddress);
    SNMP_FREE(reaped->tagList);
    SNMP_FREE(reaped->params);

    SNMP_FREE(reaped);
}                               /* snmpTargetAddrTable_dispose  */

/*
 * snmpTargetAddrTable_addToList adds a targetAddrTable_struct 
 * to a list passed in. The list is assumed to be in a sorted order,
 * low to high and this procedure inserts a new struct in the proper 
 * location. Sorting uses OID values based on name. A new equal value 
 * overwrites a current one. 
 */
void
snmpTargetAddrTable_addToList(struct targetAddrTable_struct *newEntry,
                              struct targetAddrTable_struct **listPtr)
{
    static struct targetAddrTable_struct *curr_struct, *prev_struct;
    int             i;
    size_t          newOIDLen = 0, currOIDLen = 0;
    oid             newOID[128], currOID[128];

    /*
     * if the list is empty, add the new entry to the top 
     */
    if ((prev_struct = curr_struct = *listPtr) == 0) {
        *listPtr = newEntry;
        return;
    } else {
        /*
         * get the 'OID' value of the new entry 
         */
        newOIDLen = strlen(newEntry->name);
        for (i = 0; i < (int) newOIDLen; i++) {
            newOID[i] = newEntry->name[i];
        }

        /*
         * search through the list for an equal or greater OID value 
         */
        while (curr_struct != 0) {
            currOIDLen = strlen(curr_struct->name);
            for (i = 0; i < (int) currOIDLen; i++) {
                currOID[i] = curr_struct->name[i];
            }

            i = snmp_oid_compare(newOID, newOIDLen, currOID, currOIDLen);
            if (i == 0) {       /* Exact match, overwrite with new struct */
                newEntry->next = curr_struct->next;
                /*
                 * if curr_struct is the top of the list 
                 */
                if (*listPtr == curr_struct)
                    *listPtr = newEntry;
                else
                    prev_struct->next = newEntry;
                snmpTargetAddrTable_dispose(curr_struct);
                return;
            } else if (i < 0) { /* Found a greater OID, insert struct in front of it. */
                newEntry->next = curr_struct;
                /*
                 * if curr_struct is the top of the list 
                 */
                if (*listPtr == curr_struct)
                    *listPtr = newEntry;
                else
                    prev_struct->next = newEntry;
                return;
            }
            prev_struct = curr_struct;
            curr_struct = curr_struct->next;
        }
    }
    /*
     * if we're here, no larger OID was ever found, insert on end of list 
     */
    prev_struct->next = newEntry;
}                               /* snmpTargeAddrTable_addToList  */


void
snmpTargetAddrTable_add(struct targetAddrTable_struct *newEntry)
{
    snmpTargetAddrTable_addToList(newEntry, &aAddrTable);
}


/*
 * snmpTargetAddrTable_remFromList removes a targetAddrTable_struct 
 * from the list passed in 
 */
void
snmpTargetAddrTable_remFromList(struct targetAddrTable_struct *oldEntry,
                                struct targetAddrTable_struct **listPtr)
{
    struct targetAddrTable_struct *tptr;

    if ((tptr = *listPtr) == 0)
        return;
    else if (tptr == oldEntry) {
        *listPtr = (*listPtr)->next;
        snmpTargetAddrTable_dispose(tptr);
        return;
    } else {
        while (tptr->next != 0) {
            if (tptr->next == oldEntry) {
                tptr->next = tptr->next->next;
                snmpTargetAddrTable_dispose(oldEntry);
                return;
            }
            tptr = tptr->next;
        }
    }
}                               /* snmpTargetAddrTable_remFromList  */


/*
 * lookup OID in the link list of Addr Table Entries 
 */
struct targetAddrTable_struct *
search_snmpTargetAddrTable(oid * baseName,
                           size_t baseNameLen,
                           oid * name, size_t * length, int exact)
{
    static struct targetAddrTable_struct *temp_struct;
    int             i;
    size_t          myOIDLen = 0;
    oid             newNum[128];

    /*
     * lookup entry in addrTable linked list, Get Current MIB ID 
     */
    memcpy(newNum, baseName, baseNameLen * sizeof(oid));

    for (temp_struct = aAddrTable; temp_struct != 0;
         temp_struct = temp_struct->next) {
        for (i = 0; i < (int) strlen(temp_struct->name); i++) {
            newNum[baseNameLen + i] = temp_struct->name[i];
        }
        myOIDLen = baseNameLen + strlen(temp_struct->name);
        i = snmp_oid_compare(name, *length, newNum, myOIDLen);
        /*
         * Assumes that the linked list sorted by OID, low to high 
         */
        if ((i == 0 && exact != 0) || (i < 0 && exact == 0)) {
            if (exact == 0) {
                memcpy(name, newNum, myOIDLen * sizeof(oid));
                *length = myOIDLen;
            }
            return temp_struct;
        }
    }
    return (0);
}                               /* search_snmpTargetAddrTable  */


/*
 * snmpTargetAddr_rowStatusCheck is boolean function that checks
 * the status of a row's values in order to determine whether
 * the row should be notReady or notInService.
 */
static int
snmpTargetAddr_rowStatusCheck(const struct targetAddrTable_struct *entry)
{
    return entry->tDomainLen && entry->tAddress && entry->params;
}                               /* snmtpTargetAddrTable_rowStatusCheck */


/*
 * Init routines 
 */

/*
 * this variable defines function callbacks and type return information 
 * for the snmpTargetAddrEntry mib 
 */

struct variable2 snmpTargetAddrEntry_variables[] = {
    {SNMPTARGETADDRTDOMAIN, ASN_OBJECT_ID, RWRITE,
     var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRTDOMAINCOLUMN}},
    {SNMPTARGETADDRTADDRESS, ASN_OCTET_STR, RWRITE,
     var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRTADDRESSCOLUMN}},
    {SNMPTARGETADDRTIMEOUT, ASN_INTEGER, RWRITE,
     var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRTIMEOUTCOLUMN}},
    {SNMPTARGETADDRRETRYCOUNT, ASN_INTEGER, RWRITE,
     var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRRETRYCOUNTCOLUMN}},
    {SNMPTARGETADDRTAGLIST, ASN_OCTET_STR, RWRITE,
     var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRTAGLISTCOLUMN}},
    {SNMPTARGETADDRPARAMS, ASN_OCTET_STR, RWRITE,
     var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRPARAMSCOLUMN}},
    {SNMPTARGETADDRSTORAGETYPE, ASN_INTEGER, RWRITE,
     var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRSTORAGETYPECOLUMN}},
    {SNMPTARGETADDRROWSTATUS, ASN_INTEGER, RWRITE,
     var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRROWSTATUSCOLUMN}},

};

struct variable2 snmpTargetSpinLock_var[] = {
    {SNMPTARGETSPINLOCK, ASN_INTEGER, RWRITE, var_targetSpinLock, 1, {1}}
};

static oid      snmpTargetSpinLock_oid[] = { 1, 3, 6, 1, 6, 3, 12, 1 };

/*
 * now load this mib into the agents mib table 
 */
oid             snmpTargetAddrEntry_variables_oid[] =
    { 1, 3, 6, 1, 6, 3, 12, 1, 2, 1 };


void
init_snmpTargetAddrEntry(void)
{
    aAddrTable = 0;
    DEBUGMSGTL(("snmpTargetAddrEntry", "init\n"));
    REGISTER_MIB("target/snmpTargetAddrEntry",
                 snmpTargetAddrEntry_variables, variable2,
                 snmpTargetAddrEntry_variables_oid);
    REGISTER_MIB("target/snmpTargetSpinLock", snmpTargetSpinLock_var,
                 variable2, snmpTargetSpinLock_oid);

    snmpd_register_config_handler("targetAddr",
                                  snmpd_parse_config_targetAddr, 0, NULL);

    /*
     * we need to be called back later 
     */
    snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
                           store_snmpTargetAddrEntry, NULL);

}                               /* init_snmpTargetAddrEntry */


int
snmpTargetAddr_addName(struct targetAddrTable_struct *entry, char *cptr)
{
    size_t          len;
    if (cptr == 0) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargetAddrEntry: no name in config string\n"));
        return (0);
    } else {
        len = strlen(cptr);
        /*
         * spec check for string 1-32 
         */
        if (len < 1 || len > 32) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "ERROR snmpTargetAddrEntry: name out of range in config string\n"));
            return (0);
        }
        entry->name = strdup(cptr);
    }
    return (1);
}                               /* addName */


int
snmpTargetAddr_addTDomain(struct targetAddrTable_struct *entry, char *cptr)
{
    size_t          len = 128;

    if (cptr == 0) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargetAddrEntry: no tDomain in config string\n"));
        return (0);
    }

    if (!read_objid(cptr, entry->tDomain, &len)) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargetAddrEntry: tDomain unreadable in config string\n"));
        return (0);
    }

    /*
     * spec check for oid 1-128 
     */
    if (len < 1 || len > 128) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargetAddrEntry: tDomain out of range in config string\n"));
        return (0);
    }

    entry->tDomainLen = len;
    return (1);
}                               /* snmpTargetAddr_addTDomain */


int
snmpTargetAddr_addTAddress(struct targetAddrTable_struct *entry,
                           char *cptr, size_t len)
{
    if (cptr == 0) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargetAddrEntry: no tAddress in config string\n"));
        return (0);
    } else {
        /*
         * spec check for string 1-32 
         */
        /*
         * if (len < 1 || len > 32)  {
         * DEBUGMSGTL(("snmpTargetAddrEntry","ERROR snmpTargetAddrEntry: name out of range in config string\n"));
         * return(0);
         * } 
         */
        SNMP_FREE(entry->tAddress);
        entry->tAddress = (u_char *) malloc(len);
        entry->tAddressLen = len;
        memcpy(entry->tAddress, cptr, len);
    }
    return (1);
}                               /* snmpTargetAddr_addTAddress */


int
snmpTargetAddr_addTimeout(struct targetAddrTable_struct *entry, char *cptr)
{
    if (cptr == 0) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargetParamsEntry: no Timeout in config string\n"));
        return (0);
    } else if (!(isdigit(*cptr))) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargeParamsEntry: Timeout is not a digit in config string\n"));
        return (0);
    }
    /*
     * check Timeout >= 0 
     */
    else if ((entry->timeout = (int) strtol(cptr, (char **) NULL, 0)) < 0) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargeParamsEntry: Timeout out of range in config string\n"));
        return (0);
    }
    return (1);
}                               /* snmpTargetAddr_addTimeout  */


int
snmpTargetAddr_addRetryCount(struct targetAddrTable_struct *entry,
                             char *cptr)
{
    if (cptr == 0) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargetParamsEntry: no Retry Count in config string\n"));
        return (0);
    } else if (!(isdigit(*cptr))) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargeParamsEntry: Retry Count is not a digit in config string\n"));
        return (0);
    }
    /*
     * spec check 0..255 
     */
    else {
        entry->retryCount = (int) strtol(cptr, (char **) NULL, 0);
        if ((entry->retryCount < 0) || (entry->retryCount > 255)) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "ERROR snmpTargeParamsEntry: Retry Count is out of range in config string\n"));
            return (0);
        }
    }
    return (1);
}                               /* snmpTargetAddr_addRetryCount  */


int
snmpTargetAddr_addTagList(struct targetAddrTable_struct *entry, char *cptr)
{
    size_t          len;
    if (cptr == 0) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargetAddrEntry: no tag list in config string\n"));
        return (0);
    } else {
        len = strlen(cptr);
        /*
         * spec check for string 0-255 
         */
        if (len < 0 || len > 255) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "ERROR snmpTargetAddrEntry: tag list out of range in config string\n"));
            return (0);
        }
        SNMP_FREE(entry->tagList);
        entry->tagList = strdup(cptr);
    }
    return (1);
}                               /* snmpTargetAddr_addTagList */


int
snmpTargetAddr_addParams(struct targetAddrTable_struct *entry, char *cptr)
{
    size_t          len;
    if (cptr == 0) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargetAddrEntry: no params in config string\n"));
        return (0);
    } else {
        len = strlen(cptr);
        /*
         * spec check for string 1-32 
         */
        if (len < 1 || len > 32) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "ERROR snmpTargetAddrEntry: params out of range in config string\n"));
            return (0);
        }
        entry->params = strdup(cptr);
    }
    return (1);
}                               /* snmpTargetAddr_addParams */


int
snmpTargetAddr_addStorageType(struct targetAddrTable_struct *entry,
                              char *cptr)
{
    char            buff[1024];

    if (cptr == 0) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargetAddrEntry: no storage type in config string\n"));
        return (0);
    } else if (!(isdigit(*cptr))) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargetAddrEntry: storage type is not a digit in config string\n"));
        return (0);
    }
    /*
     * check that storage type is a possible value 
     */
    else if (((entry->storageType = (int) strtol(cptr, (char **) NULL, 0))
              != SNMP_STORAGE_OTHER) &&
             (entry->storageType != SNMP_STORAGE_VOLATILE) &&
             (entry->storageType != SNMP_STORAGE_NONVOLATILE) &&
             (entry->storageType != SNMP_STORAGE_PERMANENT) &&
             (entry->storageType != SNMP_STORAGE_READONLY)) {
        snprintf(buff, sizeof(buff),
                "ERROR snmpTargetAddrEntry: storage type not a valid value of other(%d), volatile(%d), nonvolatile(%d), permanent(%d), or readonly(%d) in config string.\n",
                SNMP_STORAGE_OTHER, SNMP_STORAGE_VOLATILE,
                SNMP_STORAGE_NONVOLATILE, SNMP_STORAGE_PERMANENT,
                SNMP_STORAGE_READONLY);
        buff[ sizeof(buff)-1 ] = 0;
        DEBUGMSGTL(("snmpTargetAddrEntry", buff));

        return (0);
    }
    return (1);
}                               /* snmpTargetAddr_addStorageType */


int
snmpTargetAddr_addRowStatus(struct targetAddrTable_struct *entry,
                            char *cptr)
{
    char            buff[1024];

    if (cptr == 0) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargetAddrEntry: no Row Status in config string\n"));
        return (0);
    } else if (!(isdigit(*cptr))) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargetAddrEntry: Row Status is not a digit in config string\n"));
        return (0);
    }
    /*
     * check that row status is a valid value 
     */
    else if (((entry->rowStatus = (int) strtol(cptr, (char **) NULL, 0))
              != SNMP_ROW_ACTIVE) &&
             (entry->rowStatus != SNMP_ROW_NOTINSERVICE) &&
             (entry->rowStatus != SNMP_ROW_NOTREADY)) {
        snprintf(buff, sizeof(buff),
                "ERROR snmpTargetAddrEntry: Row Status is not a valid value of active(%d), notinservice(%d), or notready(%d) in config string.\n",
                SNMP_ROW_ACTIVE, SNMP_ROW_NOTINSERVICE, SNMP_ROW_NOTREADY);
        buff[ sizeof(buff)-1 ] = 0;
        DEBUGMSGTL(("snmpTargetAddrEntry", buff));

        return (0);
    }
    return (1);
}                               /* snmpTargetAddr_addRowStatus  */


void
snmpd_parse_config_targetAddr(const char *token, char *char_ptr)
{
    char           *cptr = char_ptr, buff[1024];
    struct targetAddrTable_struct *newEntry;
    int             i;

    newEntry = snmpTargetAddrTable_create();

    cptr = copy_nword(cptr, buff, sizeof(buff));
    if (snmpTargetAddr_addName(newEntry, buff) == 0) {
        snmpTargetAddrTable_dispose(newEntry);
        return;
    }
    cptr = copy_nword(cptr, buff, sizeof(buff));
    if (snmpTargetAddr_addTDomain(newEntry, buff) == 0) {
        snmpTargetAddrTable_dispose(newEntry);
        return;
    }
    cptr =
        read_config_read_octet_string(cptr,
                                      (u_char **) & newEntry->tAddress,
                                      &newEntry->tAddressLen);
    if (!cptr || !(newEntry->tAddress)) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargetAddrEntry: no TAddress in config string\n"));
        snmpTargetAddrTable_dispose(newEntry);
        return;
    }
    cptr = copy_nword(cptr, buff, sizeof(buff));
    if (snmpTargetAddr_addTimeout(newEntry, buff) == 0) {
        snmpTargetAddrTable_dispose(newEntry);
        return;
    }
    cptr = copy_nword(cptr, buff, sizeof(buff));
    if (snmpTargetAddr_addRetryCount(newEntry, buff) == 0) {
        snmpTargetAddrTable_dispose(newEntry);
        return;
    }
    cptr = copy_nword(cptr, buff, sizeof(buff));
    if (snmpTargetAddr_addTagList(newEntry, buff) == 0) {
        snmpTargetAddrTable_dispose(newEntry);
        return;
    }
    cptr = copy_nword(cptr, buff, sizeof(buff));
    if (snmpTargetAddr_addParams(newEntry, buff) == 0) {
        snmpTargetAddrTable_dispose(newEntry);
        return;
    }
    cptr = copy_nword(cptr, buff, sizeof(buff));
    if (snmpTargetAddr_addStorageType(newEntry, buff) == 0) {
        snmpTargetAddrTable_dispose(newEntry);
        return;
    }
    cptr = copy_nword(cptr, buff, sizeof(buff));
    if (snmpTargetAddr_addRowStatus(newEntry, buff) == 0) {
        snmpTargetAddrTable_dispose(newEntry);
        return;
    }
    snprintf(buff, sizeof(buff), "snmp_parse_config_targetAddr, read: %s\n",
            newEntry->name);
    buff[ sizeof(buff)-1 ] = 0;
    for (i = 0; i < newEntry->tDomainLen; i++) {
        snprintf(&buff[strlen(buff)], sizeof(buff)-strlen(buff)-1,
                 ".%d", (int) newEntry->tDomain[i]);
        buff[ sizeof(buff)-1 ] = 0;
    }
    snprintf(&buff[strlen(buff)], sizeof(buff)-strlen(buff)-1,
            " %s %d %d %s %s %d %d\n",
            newEntry->tAddress, newEntry->timeout, newEntry->retryCount,
            newEntry->tagList, newEntry->params, newEntry->storageType,
            newEntry->rowStatus);
    buff[ sizeof(buff)-1 ] = 0;
    DEBUGMSGTL(("snmpTargetAddrEntry", buff));

    snmpTargetAddrTable_addToList(newEntry, &aAddrTable);
}                               /* snmpd_parse_config_target */


/*
 * Shutdown routines 
 */


/*
 * store_snmpTargetAddrEntry handles the persistent storage proccess 
 * for this MIB table. It writes out all the non-volatile rows 
 * to permanent storage on a shutdown  
 */
int
store_snmpTargetAddrEntry(int majorID, int minorID, void *serverarg,
                          void *clientarg)
{
    struct targetAddrTable_struct *curr_struct;
    char            line[1024];
    int             i;

    if ((curr_struct = aAddrTable) != 0) {
        while (curr_struct != 0) {
            if ((curr_struct->storageType == SNMP_STORAGE_NONVOLATILE ||
                 curr_struct->storageType == SNMP_STORAGE_PERMANENT)
                &&
                (curr_struct->rowStatus == SNMP_ROW_ACTIVE ||
                 curr_struct->rowStatus == SNMP_ROW_NOTINSERVICE)) {
                snprintf(line, sizeof(line),
                        "targetAddr %s ", curr_struct->name);
                line[ sizeof(line)-1 ] = 0;
                for (i = 0; i < curr_struct->tDomainLen; i++) {
                    snprintf(&line[strlen(line)],
                            sizeof(line)-strlen(line)-1, ".%i",
                            (int) curr_struct->tDomain[i]);
                    line[ sizeof(line)-1 ] = 0;
                }
                strlcat(line, " ", sizeof(line));
                read_config_save_octet_string(&line[strlen(line)],
                                              curr_struct->tAddress,
                                              curr_struct->tAddressLen);

                snprintf(&line[strlen(line)], sizeof(line)-strlen(line)-1,
                        " %i %i \"%s\" %s %i %i",
                        curr_struct->timeout,
                        curr_struct->retryCount, curr_struct->tagList,
                        curr_struct->params, curr_struct->storageType,
                        curr_struct->rowStatus);
                line[ sizeof(line)-1 ] = 0;

                /*
                 * store to file 
                 */
                snmpd_store_config(line);
            }
            curr_struct = curr_struct->next;
        }
    }
    return SNMPERR_SUCCESS;

}                               /*  store_snmpTargetAddrEntry  */


/*
 * MIB table access routines 
 */


u_char         *
var_snmpTargetAddrEntry(struct variable * vp,
                        oid * name,
                        size_t * length,
                        int exact,
                        size_t * var_len, WriteMethod ** write_method)
{

    /*
     * variables we may use later 
     */
    static long     long_ret;
    static char     string[1500];
    static oid      objid[128];
    struct targetAddrTable_struct *temp_struct;
    int             i = 0;

    /*
     * Set up write_method first, in case we return NULL before getting to the
     * switch (vp->magic) below.  In some of these cases, we still want to call
     * the appropriate write_method, if only to have it return the appropriate
     * error.  
     */

    switch (vp->magic) {
    case SNMPTARGETADDRTDOMAIN:
        *write_method = write_snmpTargetAddrTDomain;
        break;
    case SNMPTARGETADDRTADDRESS:
        *write_method = write_snmpTargetAddrTAddress;
        break;
    case SNMPTARGETADDRRETRYCOUNT:
        *write_method = write_snmpTargetAddrRetryCount;
        break;
    case SNMPTARGETADDRTIMEOUT:
        *write_method = write_snmpTargetAddrTimeout;
        break;
    case SNMPTARGETADDRTAGLIST:
        *write_method = write_snmpTargetAddrTagList;
        break;
    case SNMPTARGETADDRPARAMS:
        *write_method = write_snmpTargetAddrParams;
        break;
    case SNMPTARGETADDRSTORAGETYPE:
        *write_method = write_snmpTargetAddrStorageType;
        break;
    case SNMPTARGETADDRROWSTATUS:
        *write_method = write_snmpTargetAddrRowStatus;
        break;
    default:
        *write_method = NULL;
    }

    *var_len = sizeof(long_ret);        /* assume an integer and change later if not */

    /*
     * look for OID in current table 
     */
    if ((temp_struct = search_snmpTargetAddrTable(vp->name, vp->namelen,
                                                  name, length,
                                                  exact)) == 0) {
        return (0);
    }

    /*
     * We found what we were looking for, either the next OID or the exact OID 
     */
    /*
     * this is where we do the value assignments for the mib results. 
     */
    switch (vp->magic) {
    case SNMPTARGETADDRTDOMAIN:
        if (temp_struct->tDomainLen <= 0) {
            return (0);
        } else {
            for (i = 0; i < temp_struct->tDomainLen; i++) {
                objid[i] = temp_struct->tDomain[i];
            }
            *var_len = temp_struct->tDomainLen * sizeof(oid);
        }
        return (unsigned char *) objid;

    case SNMPTARGETADDRTADDRESS:
        if (temp_struct->tAddress == 0)
            return (0);
        *var_len = temp_struct->tAddressLen;
        return (unsigned char *) temp_struct->tAddress;

    case SNMPTARGETADDRTIMEOUT:
        long_ret = temp_struct->timeout;
        return (unsigned char *) &long_ret;

    case SNMPTARGETADDRRETRYCOUNT:
        long_ret = temp_struct->retryCount;
        return (unsigned char *) &long_ret;

    case SNMPTARGETADDRTAGLIST:
        if (temp_struct->tagList != NULL) {
            strcpy(string, temp_struct->tagList);
            *var_len = strlen(string);
            return (unsigned char *) string;
        } else {
            return NULL;
        }

    case SNMPTARGETADDRPARAMS:
        if (temp_struct->params == 0)
            return (0);
        strcpy(string, temp_struct->params);
        *var_len = strlen(string);
        return (unsigned char *) string;

    case SNMPTARGETADDRSTORAGETYPE:
        long_ret = temp_struct->storageType;
        return (unsigned char *) &long_ret;

    case SNMPTARGETADDRROWSTATUS:
        long_ret = temp_struct->rowStatus;
        return (unsigned char *) &long_ret;

    default:
        DEBUGMSGTL(("snmpd",
                    "unknown sub-id %d in var_snmpTargetAddrEntry\n",
                    vp->magic));
    }
    return 0;
}                               /* var_snmpTargetAddrEntry */


int
write_snmpTargetAddrTDomain(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 targetAddrTable_struct *target = NULL;
    static oid      old_oid[MAX_OID_LEN];
    static size_t   old_oid_len;

    if (action == RESERVE1) {
        if (var_val_type != ASN_OBJECT_ID) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrTDomain not ASN_OBJECT_ID\n"));
            return SNMP_ERR_WRONGTYPE;
        }
        if ((var_val_len > (MAX_OID_LEN * sizeof(oid))) ||
            (var_val_len % sizeof(oid) != 0)) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrTDomain: bad length\n"));
            return SNMP_ERR_WRONGLENGTH;
        }
    } else if (action == RESERVE2) {
        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRTDOMAINCOLUMN;
        if ((target =
             search_snmpTargetAddrTable(snmpTargetAddrOID,
                                        snmpTargetAddrOIDLen, name,
                                        &name_len, 1)) == 0) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrTDomain: BAD OID!\n"));
            return SNMP_ERR_INCONSISTENTNAME;
        } else {
            if (target->storageType == SNMP_STORAGE_READONLY) {
                DEBUGMSGTL(("snmpTargetAddrEntry",
                            "write to snmpTargetAddrTDomain: row is read only\n"));
                return SNMP_ERR_NOTWRITABLE;
            }
            if (target->rowStatus == SNMP_ROW_ACTIVE) {
                DEBUGMSGTL(("snmpTargetAddrEntry",
                            "write to snmpTargetAddrTDomain: not allowed in active row.\n"));
                return SNMP_ERR_INCONSISTENTVALUE;
            }

            /*
             * Finally, we're golden, save current value.  
             */

            memcpy(old_oid, target->tDomain,
                   target->tDomainLen * sizeof(oid));
            old_oid_len = target->tDomainLen;

            memcpy((u_char *) target->tDomain, var_val, var_val_len);
            target->tDomainLen = var_val_len / sizeof(oid);

            /*
             * If row is new, check if its status can be updated.  
             */
            if ((target->rowStatus == SNMP_ROW_NOTREADY) &&
                (snmpTargetAddr_rowStatusCheck(target) != 0)) {
                target->rowStatus = SNMP_ROW_NOTINSERVICE;
            }
        }
    } else if (action == FREE || action == UNDO) {
        /*
         * Try to undo the SET here (abnormal usage of FREE clause)  
         */
        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRTDOMAINCOLUMN;
        if ((target =
             search_snmpTargetAddrTable(snmpTargetAddrOID,
                                        snmpTargetAddrOIDLen, name,
                                        &name_len, 1)) != NULL) {
            if (target->storageType != SNMP_STORAGE_READONLY
                && target->rowStatus != SNMP_ROW_ACTIVE) {
                memcpy((u_char *) target->tDomain, (u_char *) old_oid,
                       (old_oid_len * sizeof(oid)));
                target->tDomainLen = old_oid_len;
                if (target->rowStatus == SNMP_ROW_NOTINSERVICE &&
                    snmpTargetAddr_rowStatusCheck(target) == 0) {
                    target->rowStatus = SNMP_ROW_NOTREADY;
                }
            }
        }
    }
    return SNMP_ERR_NOERROR;
}                               /* write_snmpTargetAddrTDomain */


int
write_snmpTargetAddrTAddress(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 targetAddrTable_struct *target = NULL;
    static char    *old_addr = NULL;
    static size_t   old_len = 0;

    if (action == RESERVE1) {
        if (var_val_type != ASN_OCTET_STR) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrTAddress not ASN_OCTET_STR\n"));
            return SNMP_ERR_WRONGTYPE;
        } else if (var_val_len < 1 || var_val_len > 255) {
            return SNMP_ERR_WRONGLENGTH;
        }
    } else if (action == RESERVE2) {
        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRTADDRESSCOLUMN;
        if ((target =
             search_snmpTargetAddrTable(snmpTargetAddrOID,
                                        snmpTargetAddrOIDLen, name,
                                        &name_len, 1)) == 0) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrTAddress: BAD OID!\n"));
            return SNMP_ERR_INCONSISTENTNAME;
        } else {
            if (target->storageType == SNMP_STORAGE_READONLY) {
                DEBUGMSGTL(("snmpTargetAddrEntry",
                            "write to snmpTargetAddrTAddress: row is read only\n"));
                return SNMP_ERR_NOTWRITABLE;
            }
            if (target->rowStatus == SNMP_ROW_ACTIVE) {
                DEBUGMSGTL(("snmpTargetAddrEntry",
                            "write to snmpTargetAddrTAddress: not allowed in active row.\n"));
                return SNMP_ERR_INCONSISTENTVALUE;
            }

            old_addr = (char *) target->tAddress;
            old_len = target->tAddressLen;
            target->tAddress = (u_char *) malloc(var_val_len);
            if (target->tAddress == NULL) {
                return SNMP_ERR_RESOURCEUNAVAILABLE;
            }
            memcpy(target->tAddress, var_val, var_val_len);
            target->tAddressLen = var_val_len;

            /*
             * If row is new, check if its status can be updated.  
             */
            if ((target->rowStatus == SNMP_ROW_NOTREADY) &&
                (snmpTargetAddr_rowStatusCheck(target) != 0)) {
                target->rowStatus = SNMP_ROW_NOTINSERVICE;
            }
        }
    } else if (action == COMMIT) {
        SNMP_FREE(old_addr);
        old_addr = NULL;
    } else if (action == FREE || action == UNDO) {
        /*
         * Try to undo the SET here (abnormal usage of FREE clause)  
         */
        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRTADDRESSCOLUMN;
        if ((target =
             search_snmpTargetAddrTable(snmpTargetAddrOID,
                                        snmpTargetAddrOIDLen, name,
                                        &name_len, 1)) != NULL) {
            if (target->storageType != SNMP_STORAGE_READONLY
                && target->rowStatus != SNMP_ROW_ACTIVE) {
                SNMP_FREE(target->tAddress);
                target->tAddress = (u_char *) old_addr;
                target->tAddressLen = old_len;
                if (target->rowStatus == SNMP_ROW_NOTINSERVICE &&
                    snmpTargetAddr_rowStatusCheck(target) == 0) {
                    target->rowStatus = SNMP_ROW_NOTREADY;
                }
            }
        }
    }

    return SNMP_ERR_NOERROR;
}                               /* write_snmpTargetAddrTAddress */


int
write_snmpTargetAddrTimeout(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)
{
    /*
     * variables we may use later 
     */
    static long     long_ret;
    size_t          size;
    struct targetAddrTable_struct *temp_struct;

    if (action == RESERVE1) {
        if (var_val_type != ASN_INTEGER) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrTimeout not ASN_INTEGER\n"));
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len > (size = sizeof(long_ret))) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrTimeout: bad length\n"));
            return SNMP_ERR_WRONGLENGTH;
        }
        long_ret = *((long *) var_val);
        if (long_ret < 0 || long_ret > 2147483647) {
            return SNMP_ERR_WRONGVALUE;
        }
    } else if (action == RESERVE2) {

        /*
         * spec check range, no spec check 
         */

        /*
         * Find row in linked list and check pertinent status... 
         */
        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRTIMEOUTCOLUMN;
        if ((temp_struct =
             search_snmpTargetAddrTable(snmpTargetAddrOID,
                                        snmpTargetAddrOIDLen, name, &name_len,
                                        1)) == 0) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrTimeout : BAD OID\n"));
            return SNMP_ERR_NOSUCHNAME;
        }
        /*
         * row exists, check if it is changeable 
         */
        if (temp_struct->storageType == SNMP_STORAGE_READONLY) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrTimeout : row is read only\n"));
            return SNMP_ERR_NOTWRITABLE;
        }
    } else if  (action == COMMIT) {
        /*
         * Finally, we're golden, should we save value? 
         */
        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRTIMEOUTCOLUMN;
        if ((temp_struct =
             search_snmpTargetAddrTable(snmpTargetAddrOID,
                                        snmpTargetAddrOIDLen, name, &name_len,
                                        1)) != NULL) {
            temp_struct->timeout = long_ret;
        }
    }

    return SNMP_ERR_NOERROR;
}                               /* write_snmpTargetAddrTimeout */


int
write_snmpTargetAddrRetryCount(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 long     long_ret;
    struct targetAddrTable_struct *target;

    if (action == RESERVE1) {
        if (var_val_type != ASN_INTEGER) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrRetryCount not ASN_INTEGER\n"));
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len != sizeof(long)) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrRetryCount: bad length\n"));
            return SNMP_ERR_WRONGLENGTH;
        }
        long_ret = *((long *) var_val);
        if (long_ret < 0 || long_ret > 255) {
            return SNMP_ERR_WRONGVALUE;
        }
    } else if (action == RESERVE2) {
        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRRETRYCOUNTCOLUMN;
        if ((target = search_snmpTargetAddrTable(snmpTargetAddrOID,
                                                 snmpTargetAddrOIDLen,
                                                 name, &name_len,
                                                 1)) == NULL) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrTimeout: BAD OID\n"));
            return SNMP_ERR_INCONSISTENTNAME;
        } else {
            if (target->storageType == SNMP_STORAGE_READONLY) {
                DEBUGMSGTL(("snmpTargetAddrEntry",
                            "write to snmpTargetAddrRetryCount: row is read only\n"));
                return SNMP_ERR_NOTWRITABLE;
            }
        }
    } else if (action == COMMIT) {
        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRRETRYCOUNTCOLUMN;
        if ((target = search_snmpTargetAddrTable(snmpTargetAddrOID,
                                                 snmpTargetAddrOIDLen,
                                                 name, &name_len,
                                                 1)) != NULL) {
            target->retryCount = long_ret;
        }
    }

    return SNMP_ERR_NOERROR;
}                               /* write_snmpTargetAddrRetryCount */

static int
is_delim(const char c)
{
    return (c == 0x020 || c == 0x09 || c == 0x0d || c == 0x0b);
}

int
snmpTagListValid(const char *tagList, const size_t tagListLen)
{
    size_t          i = 0;
    int             inTag = 0;


    for (i = 0; i < tagListLen; i++) {
        if (is_delim(tagList[i]) && !inTag) {
            /*
             * Either a leading delimiter or two consecutive delimiters.  
             */
            return 0;
        } else if (is_delim(tagList[i]) && inTag) {
            inTag = 0;
        } else if (!is_delim(tagList[i]) && !inTag) {
            inTag = 1;
        }
    }
    if (!inTag) {
        /*
         * Trailing delimiter.  
         */
        return 0;
    }
    return 1;
}

int
write_snmpTargetAddrTagList(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 targetAddrTable_struct *target = NULL;
    static char    *old_tlist;

    if (action == RESERVE1) {
        if (var_val_type != ASN_OCTET_STR) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrTagList not ASN_OCTET_STR\n"));
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len > 255) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrTagList: bad length\n"));
            return SNMP_ERR_WRONGLENGTH;
        }
        if (!snmpTagListValid((char *) var_val, var_val_len)) {
            return SNMP_ERR_WRONGVALUE;
        }
    } else if (action == RESERVE2) {
        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRTAGLISTCOLUMN;
        if ((target =
             search_snmpTargetAddrTable(snmpTargetAddrOID,
                                        snmpTargetAddrOIDLen, name,
                                        &name_len, 1)) == NULL) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrTagList: BAD OID!\n"));
            return SNMP_ERR_INCONSISTENTNAME;
        } else {
            if (target->storageType == SNMP_STORAGE_READONLY) {
                DEBUGMSGTL(("snmpTargetAddrEntry",
                            "write to snmpTargetAddrTagList: row is read only\n"));
                return SNMP_ERR_NOTWRITABLE;
            }
            old_tlist = target->tagList;
            target->tagList = (char *) malloc(var_val_len + 1);
            if (target->tagList == NULL) {
                return SNMP_ERR_RESOURCEUNAVAILABLE;
            }
            memcpy(target->tagList, var_val, var_val_len);
            target->tagList[var_val_len] = '\0';
        }
    } else if (action == COMMIT) {
        SNMP_FREE(old_tlist);
        old_tlist = NULL;
    } else if (action == FREE || action == UNDO) {
        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRTAGLISTCOLUMN;
        if ((target =
             search_snmpTargetAddrTable(snmpTargetAddrOID,
                                        snmpTargetAddrOIDLen, name,
                                        &name_len, 1)) != NULL) {
            if (target->storageType != SNMP_STORAGE_READONLY) {
                SNMP_FREE(target->tagList);
                target->tagList = old_tlist;
            }
        }
    }

    return SNMP_ERR_NOERROR;
}                               /* write_snmpTargetAddrTagList */


int
write_snmpTargetAddrParams(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 targetAddrTable_struct *target = NULL;
    static char    *old_params = NULL;

    if (action == RESERVE1) {
        if (var_val_type != ASN_OCTET_STR) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrParams not ASN_OCTET_STR\n"));
            return SNMP_ERR_WRONGTYPE;
        } else if (var_val_len < 1 || var_val_len > 32) {
            return SNMP_ERR_WRONGLENGTH;
        }
    } else if (action == RESERVE2) {
        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRPARAMSCOLUMN;
        if ((target =
             search_snmpTargetAddrTable(snmpTargetAddrOID,
                                        snmpTargetAddrOIDLen, name,
                                        &name_len, 1)) == 0) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrParams: BAD OID!\n"));
            return SNMP_ERR_INCONSISTENTNAME;
        } else {
            if (target->storageType == SNMP_STORAGE_READONLY) {
                DEBUGMSGTL(("snmpTargetAddrEntry",
                            "write to snmpTargetAddrParams: row is read only\n"));
                return SNMP_ERR_NOTWRITABLE;
            }
            if (target->rowStatus == SNMP_ROW_ACTIVE) {
                DEBUGMSGTL(("snmpTargetAddrEntry",
                            "write to snmpTargetAddrParams: not allowed in active row.\n"));
                return SNMP_ERR_INCONSISTENTVALUE;
            }

            old_params = target->params;
            target->params = malloc(var_val_len + 1);
            if (target->params == NULL) {
                return SNMP_ERR_RESOURCEUNAVAILABLE;
            }
            memcpy(target->params, var_val, var_val_len);
            target->params[var_val_len] = '\0';

            /*
             * If row is new, check if its status can be updated.  
             */
            if ((target->rowStatus == SNMP_ROW_NOTREADY) &&
                (snmpTargetAddr_rowStatusCheck(target) != 0)) {
                target->rowStatus = SNMP_ROW_NOTINSERVICE;
            }
        }
    } else if (action == COMMIT) {
        SNMP_FREE(old_params);
        old_params = NULL;
    } else if (action == FREE || action == UNDO) {
        /*
         * Try to undo the SET here (abnormal usage of FREE clause)  
         */
        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRPARAMSCOLUMN;
        if ((target =
             search_snmpTargetAddrTable(snmpTargetAddrOID,
                                        snmpTargetAddrOIDLen, name,
                                        &name_len, 1)) != NULL) {
            if (target->storageType != SNMP_STORAGE_READONLY
                && target->rowStatus != SNMP_ROW_ACTIVE) {
                SNMP_FREE(target->params);
                target->params = old_params;
                if (target->rowStatus == SNMP_ROW_NOTINSERVICE &&
                    snmpTargetAddr_rowStatusCheck(target) == 0) {
                    target->rowStatus = SNMP_ROW_NOTREADY;
                }
            }
        }
    }

    return SNMP_ERR_NOERROR;
}                               /* write_snmpTargetAddrParams */

int
write_snmpTargetAddrStorageType(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)
{
    long            long_ret = *((long *) var_val);
    struct targetAddrTable_struct *target;

    if (action == RESERVE1) {
        if (var_val_type != ASN_INTEGER) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrStorageType not ASN_INTEGER\n"));
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len != sizeof(long)) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrStorageType: bad length\n"));
            return SNMP_ERR_WRONGLENGTH;
        }
        if (long_ret != SNMP_STORAGE_OTHER &&
            long_ret != SNMP_STORAGE_VOLATILE &&
            long_ret != SNMP_STORAGE_NONVOLATILE) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrStorageType: attempted storage type not a valid"));
            DEBUGMSG(("snmpTargetAddrEntry",
                      " value of other(%d), volatile(%d), or nonvolatile(%d)\n",
                      SNMP_STORAGE_OTHER, SNMP_STORAGE_VOLATILE,
                      SNMP_STORAGE_NONVOLATILE));
            return SNMP_ERR_WRONGVALUE;
        }
    } else if (action == RESERVE2) {
        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRSTORAGETYPECOLUMN;
        if ((target = search_snmpTargetAddrTable(snmpTargetAddrOID,
                                                 snmpTargetAddrOIDLen,
                                                 name, &name_len,
                                                 1)) == NULL) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrStorageType: BAD OID\n"));
            return SNMP_ERR_INCONSISTENTNAME;
        } else {
            if (target->storageType == SNMP_STORAGE_PERMANENT ||
                target->storageType == SNMP_STORAGE_READONLY) {
                DEBUGMSGTL(("snmpTargetAddrEntry",
                            "write to snmpTargetAddrStorageType: row has unchangeable storage status: %d\n",
                            target->storageType));
                return SNMP_ERR_WRONGVALUE;
            }
        }
    } else if (action == COMMIT) {
        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRSTORAGETYPECOLUMN;
        if ((target = search_snmpTargetAddrTable(snmpTargetAddrOID,
                                                 snmpTargetAddrOIDLen,
                                                 name, &name_len,
                                                 1)) != NULL) {
            target->storageType = long_ret;
        }
    }

    return SNMP_ERR_NOERROR;
}                               /* write_snmpTargetAddrStorageType */


/*
 * snmpTargeAddr_createNewRow is called from write_snmpTargetAddrRowStatus
 * when a new row is required. It creates a new row with 
 * the index of the passed in 'name' (i.e. full index OID) and
 * adds it to the linked list. 'name' should be the full OID of the new index. 
 * It passes back 0 if unsuccessfull.
 */
int
snmpTargetAddr_createNewRow(oid * name, size_t name_len)
{
    size_t          newNameLen;
    int             i;
    struct targetAddrTable_struct *temp_struct;

    /*
     * setup a new snmpTargetAddrTable structure and add it to the list 
     */
    newNameLen = name_len - snmpTargetAddrOIDLen;
    if (newNameLen > 0) {
        temp_struct = snmpTargetAddrTable_create();
        if (!temp_struct)
            return SNMP_ERR_GENERR;
        temp_struct->name = (char *) malloc(newNameLen + 1);
        if (temp_struct->name == NULL) {
            SNMP_FREE(temp_struct->tagList);
            SNMP_FREE(temp_struct);
            return 0;
        }

        for (i = 0; i < (int) newNameLen; i++) {
            temp_struct->name[i] = (char) name[i + snmpTargetAddrOIDLen];
        }

        temp_struct->name[newNameLen] = '\0';
        temp_struct->rowStatus = SNMP_ROW_NOTREADY;

        snmpTargetAddrTable_addToList(temp_struct, &aAddrTable);

        return 1;
    }

    return 0;
}                               /* snmpTargetAddr_createNewRow */


/*
 * Assign a value to the Row Status variable 
 */
int
write_snmpTargetAddrRowStatus(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 long     value;
    struct targetAddrTable_struct *target = NULL;

    if (action == RESERVE1) {
        value = *((long *) var_val);
        if (var_val_type != ASN_INTEGER) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrRowStatus not ASN_INTEGER\n"));
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len != sizeof(long)) {
            DEBUGMSGTL(("snmpTargetAddrEntry",
                        "write to snmpTargetAddrRowStatus: bad length\n"));
            return SNMP_ERR_WRONGLENGTH;
        }
        if (value == RS_NOTREADY || value < 1 || value > 6) {
            return SNMP_ERR_WRONGVALUE;
        }

        /*
         * Check index value is reasonable.  
         */

        if (name_len < snmpTargetAddrOIDLen + 1 ||
            name_len > snmpTargetAddrOIDLen + 32) {
            DEBUGMSGTL(("snmpTargetAddrEntry", "bad index length %d\n",
                        name_len - snmpTargetAddrOIDLen));
            return SNMP_ERR_NOCREATION;
        }

        /*
         * Search for struct in linked list.  
         */

        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRROWSTATUSCOLUMN;
        target =
            search_snmpTargetAddrTable(snmpTargetAddrOID,
                                       snmpTargetAddrOIDLen, name,
                                       &name_len, 1);

        if (target != NULL) {
            if (value == RS_CREATEANDGO || value == RS_CREATEANDWAIT) {
                value = RS_NOTREADY;
                return SNMP_ERR_INCONSISTENTVALUE;
            }
            if (target->storageType == SNMP_STORAGE_READONLY) {
                DEBUGMSGTL(("snmpTargetAddrEntry", "row is read only\n"));
                return SNMP_ERR_NOTWRITABLE;
            }
            if (target->storageType == SNMP_STORAGE_PERMANENT) {
                if (value == RS_DESTROY) {
                    DEBUGMSGTL(("snmpTargetAddrEntry",
                                "unable to destroy permanent row\n"));
                    return SNMP_ERR_INCONSISTENTVALUE;
                }
            }
        } else {
            if (value == RS_ACTIVE || value == RS_NOTINSERVICE) {
                return SNMP_ERR_INCONSISTENTVALUE;
            }
            if (value == RS_CREATEANDGO || value == RS_CREATEANDWAIT) {
                if (snmpTargetAddr_createNewRow(name, name_len) == 0) {
                    DEBUGMSGTL(("snmpTargetAddrEntry",
                                "couldn't malloc() new row\n"));
                    return SNMP_ERR_RESOURCEUNAVAILABLE;
                }
            }
        }
    } else if (action == ACTION) {
        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRROWSTATUSCOLUMN;
        target =
            search_snmpTargetAddrTable(snmpTargetAddrOID,
                                       snmpTargetAddrOIDLen, name,
                                       &name_len, 1);

        if (target != NULL) {
            if (value == RS_CREATEANDGO) {
                /*
                 * Check whether all the required objects have been set.  
                 */
                if (snmpTargetAddr_rowStatusCheck(target)) {
                    target->rowStatus = RS_ACTIVE;
                } else {
                    target->rowStatus = RS_NOTREADY;
                }
            } else if (value == RS_CREATEANDWAIT) {
                /*
                 * Check whether all the required objects have been set.  
                 */
                if (snmpTargetAddr_rowStatusCheck(target)) {
                    target->rowStatus = RS_NOTINSERVICE;
                } else {
                    target->rowStatus = RS_NOTREADY;
                }
            } else if (value == RS_ACTIVE) {
                if (target->rowStatus == RS_NOTINSERVICE) {
                    target->rowStatus = RS_ACTIVE;
                } else if (target->rowStatus == RS_NOTREADY) {
                    return SNMP_ERR_INCONSISTENTVALUE;
                }
            } else if (value == RS_NOTINSERVICE) {
                if (target->rowStatus == RS_ACTIVE) {
                    target->rowStatus = RS_NOTINSERVICE;
                } else if (target->rowStatus == RS_NOTREADY) {
                    return SNMP_ERR_INCONSISTENTVALUE;
                }
            }
        }
    } else if (action == COMMIT) {
        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRROWSTATUSCOLUMN;
        target =
            search_snmpTargetAddrTable(snmpTargetAddrOID,
                                       snmpTargetAddrOIDLen, name,
                                       &name_len, 1);
        if (target != NULL) {
            if (value == RS_DESTROY) {
                snmpTargetAddrTable_remFromList(target, &aAddrTable);
            }
            if (value == RS_NOTINSERVICE) {
                if (target->sess != NULL) {
                    snmp_close(target->sess);
                    target->sess = NULL;
                }
            }
        }
    } else if (action == UNDO || action == FREE) {
        snmpTargetAddrOID[snmpTargetAddrOIDLen - 1] =
            SNMPTARGETADDRROWSTATUSCOLUMN;
        target =
            search_snmpTargetAddrTable(snmpTargetAddrOID,
                                       snmpTargetAddrOIDLen, name,
                                       &name_len, 1);
        if (value == RS_CREATEANDGO || value == RS_CREATEANDWAIT) {
            if (target != NULL) {
                snmpTargetAddrTable_remFromList(target, &aAddrTable);
            }
        }
    }
    return SNMP_ERR_NOERROR;
}                               /* write_snmpTargetAddrRowStatus */



int
write_targetSpinLock(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)
{
    if (action == RESERVE1) {
        if (var_val_type != ASN_INTEGER) {
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len != sizeof(unsigned long)) {
            return SNMP_ERR_WRONGLENGTH;
        }
        if (*((unsigned long *) var_val) != snmpTargetSpinLock) {
            return SNMP_ERR_INCONSISTENTVALUE;
        }
    } else if (action == COMMIT) {
        if (snmpTargetSpinLock == 2147483647) {
            snmpTargetSpinLock = 0;
        } else {
            snmpTargetSpinLock++;
        }
    }
    return SNMP_ERR_NOERROR;
}



u_char         *
var_targetSpinLock(struct variable * vp,
                   oid * name,
                   size_t * length,
                   int exact,
                   size_t * var_len, WriteMethod ** write_method)
{
    if (header_generic(vp, name, length, exact, var_len, write_method) ==
        MATCH_FAILED) {
        *write_method = write_targetSpinLock;
        return NULL;
    }
    if (vp->magic == SNMPTARGETSPINLOCK) {
        *write_method = write_targetSpinLock;
        *var_len = sizeof(unsigned long);
        return (u_char *) & (snmpTargetSpinLock);
    }
    return NULL;
}
