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

#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) == NULL) {
        *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 != NULL) {
            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((unsigned char)(*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((unsigned char)(*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)
{
    if (cptr == NULL) {
        DEBUGMSGTL(("snmpTargetAddrEntry",
                    "ERROR snmpTargetAddrEntry: no tag list in config string\n"));
        return (0);
    } else {
        size_t len = strlen(cptr);
        /*
         * spec check for string 0-255 
         */
        if (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((unsigned char)(*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((unsigned char)(*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;
                }
            }
        }
        snmp_store_needed(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;
}
