/*
 * 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/header_generic.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 = NULL;


/*
 * 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 = NULL;

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

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

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

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

    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) == NULL)
        return;
    else if (tptr == oldEntry) {
        *listPtr = (*listPtr)->next;
        snmpTargetAddrTable_dispose(tptr);
        return;
    } else {
        while (tptr->next != NULL) {
            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 != NULL;
         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 NULL;
}                               /* 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, NETSNMP_OLDAPI_RWRITE,
     var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRTDOMAINCOLUMN}},
    {SNMPTARGETADDRTADDRESS, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
     var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRTADDRESSCOLUMN}},
    {SNMPTARGETADDRTIMEOUT, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
     var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRTIMEOUTCOLUMN}},
    {SNMPTARGETADDRRETRYCOUNT, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
     var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRRETRYCOUNTCOLUMN}},
    {SNMPTARGETADDRTAGLIST, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
     var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRTAGLISTCOLUMN}},
    {SNMPTARGETADDRPARAMS, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
     var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRPARAMSCOLUMN}},
    {SNMPTARGETADDRSTORAGETYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
     var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRSTORAGETYPECOLUMN}},
    {SNMPTARGETADDRROWSTATUS, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
     var_snmpTargetAddrEntry, 1, {SNMPTARGETADDRROWSTATUSCOLUMN}},

};

struct variable2 snmpTargetSpinLock_var[] = {
    {SNMPTARGETSPINLOCK, ASN_INTEGER, NETSNMP_OLDAPI_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 = NULL;
    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,
				  (void (*)(void))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 == NULL) {
        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 == NULL) {
        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 == NULL) {
        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 == NULL) {
        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 == NULL) {
        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 == NULL) {
        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 == NULL) {
        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)
{
    if (cptr == NULL) {
        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)) {
	DEBUGMSGTL(("snmpTargetAddrEntry",
                    "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));
        return (0);
    }
    return (1);
}                               /* snmpTargetAddr_addStorageType */


int
snmpTargetAddr_addRowStatus(struct targetAddrTable_struct *entry,
                            char *cptr)
{
    if (cptr == NULL) {
        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)) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "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));
        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", "%s", 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) != NULL) {
        while (curr_struct != NULL) {
            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)) == NULL) {
        return NULL;
    }

    /*
     * 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 NULL;
        } 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 == NULL)
            return NULL;
        *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) {
            strlcpy(string, temp_struct->tagList, sizeof(string));
            *var_len = strlen(string);
            return (unsigned char *) string;
        } else {
            return NULL;
        }

    case SNMPTARGETADDRPARAMS:
        if (temp_struct->params == NULL)
            return NULL;
        strlcpy(string, temp_struct->params, sizeof(string));
        *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 NULL;
}                               /* 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)) == NULL) {
            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)) == NULL) {
            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)) == NULL) {
            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)) == NULL) {
            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",
                        (int)(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;
}
