/*
 * tools.c
 */

#define NETSNMP_TOOLS_C 1 /* dont re-define malloc wrappers here */

#ifdef HAVE_CRTDBG_H
/*
 * Define _CRTDBG_MAP_ALLOC such that in debug builds (when _DEBUG has been
 * defined) e.g. malloc() is rerouted to _malloc_dbg().
 */
#define _CRTDBG_MAP_ALLOC 1
#include <crtdbg.h>
#endif

#include <net-snmp/net-snmp-config.h>

#include <ctype.h>
#include <stdio.h>
#include <sys/types.h>
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
#  include <sys/time.h>
# else
#  include <time.h>
# endif
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef cygwin
#include <windows.h>
#endif

#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_DMALLOC_H
#include <dmalloc.h>
#endif

#include <net-snmp/types.h>
#include <net-snmp/output_api.h>
#include <net-snmp/utilities.h>
#include <net-snmp/library/tools.h>     /* for "internal" definitions */

#include <net-snmp/library/snmp_api.h>
#include <net-snmp/library/mib.h>
#include <net-snmp/library/scapi.h>

/**
 * This function is a wrapper for the strdup function.
 *
 * @note The strdup() implementation calls _malloc_dbg() when linking with
 * MSVCRT??D.dll and malloc() when linking with MSVCRT??.dll
 */
char * netsnmp_strdup( const char * ptr)
{
    return strdup(ptr);
}
/**
 * This function is a wrapper for the calloc function.
 */
void * netsnmp_calloc(size_t nmemb, size_t size)
{
    return calloc(nmemb, size);
}

/**
 * This function is a wrapper for the malloc function.
 */
void * netsnmp_malloc(size_t size)
{
    return malloc(size);
}

/**
 * This function is a wrapper for the realloc function.
 */
void * netsnmp_realloc( void * ptr, size_t size)
{
    return realloc(ptr, size);
}

/**
 * This function is a wrapper for the free function.
 * It calls free only if the calling parameter has a non-zero value.
 */
void netsnmp_free( void * ptr)
{
    if (ptr)
        free(ptr);
}

/**
 * This function increase the size of the buffer pointed at by *buf, which is
 * initially of size *buf_len.  Contents are preserved **AT THE BOTTOM END OF
 * THE BUFFER**.  If memory can be (re-)allocated then it returns 1, else it
 * returns 0.
 * 
 * @param buf  pointer to a buffer pointer
 * @param buf_len      pointer to current size of buffer in bytes
 * 
 * @note
 * The current re-allocation algorithm is to increase the buffer size by
 * whichever is the greater of 256 bytes or the current buffer size, up to
 * a maximum increase of 8192 bytes.  
 */
int
snmp_realloc(u_char ** buf, size_t * buf_len)
{
    u_char         *new_buf = NULL;
    size_t          new_buf_len = 0;

    if (buf == NULL) {
        return 0;
    }

    if (*buf_len <= 255) {
        new_buf_len = *buf_len + 256;
    } else if (*buf_len > 255 && *buf_len <= 8191) {
        new_buf_len = *buf_len * 2;
    } else if (*buf_len > 8191) {
        new_buf_len = *buf_len + 8192;
    }

    if (*buf == NULL) {
        new_buf = (u_char *) malloc(new_buf_len);
    } else {
        new_buf = (u_char *) realloc(*buf, new_buf_len);
    }

    if (new_buf != NULL) {
        *buf = new_buf;
        *buf_len = new_buf_len;
        return 1;
    } else {
        return 0;
    }
}

int
snmp_strcat(u_char ** buf, size_t * buf_len, size_t * out_len,
            int allow_realloc, const u_char * s)
{
    if (buf == NULL || buf_len == NULL || out_len == NULL) {
        return 0;
    }

    if (s == NULL) {
        /*
         * Appending a NULL string always succeeds since it is a NOP.  
         */
        return 1;
    }

    while ((*out_len + strlen((const char *) s) + 1) >= *buf_len) {
        if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
            return 0;
        }
    }

    strcpy((char *) (*buf + *out_len), (const char *) s);
    *out_len += strlen((char *) (*buf + *out_len));
    return 1;
}

/** zeros memory before freeing it.
 *
 *	@param *buf	Pointer at bytes to free.
 *	@param size	Number of bytes in buf.
 */
void
free_zero(void *buf, size_t size)
{
    if (buf) {
        memset(buf, 0, size);
        free(buf);
    }

}                               /* end free_zero() */

/**
 * Returns pointer to allocaed & set buffer on success, size contains
 * number of random bytes filled.  buf is NULL and *size set to KMT
 * error value upon failure.
 *
 *	@param size	Number of bytes to malloc() and fill with random bytes.
 *
 * @return a malloced buffer
 *
 */
u_char         *
malloc_random(size_t * size)
{
    int             rval = SNMPERR_SUCCESS;
    u_char         *buf = (u_char *) calloc(1, *size);

    if (buf) {
        rval = sc_random(buf, size);

        if (rval < 0) {
            free_zero(buf, *size);
            buf = NULL;
        } else {
            *size = rval;
        }
    }

    return buf;

}                               /* end malloc_random() */

/**
 * Duplicates a memory block.
 *
 * @param[in] from Pointer to copy memory from.
 * @param[in] size Size of the data to be copied.
 *      
 * @return Pointer to the duplicated memory block, or NULL if memory allocation
 * failed.
 */
void *netsnmp_memdup(const void *from, size_t size)
{
    void *to = NULL;

    if (from) {
        to = malloc(size);
        if (to)
            memcpy(to, from, size);
    }
    return to;
}                               /* end netsnmp_memdup() */

/** copies a (possible) unterminated string of a given length into a
 *  new buffer and null terminates it as well (new buffer MAY be one
 *  byte longer to account for this */
char           *
netsnmp_strdup_and_null(const u_char * from, size_t from_len)
{
    char         *ret;

    if (from_len == 0 || from[from_len - 1] != '\0') {
        ret = (char *)malloc(from_len + 1);
        if (!ret)
            return NULL;
        ret[from_len] = '\0';
    } else {
        ret = (char *)malloc(from_len);
        if (!ret)
            return NULL;
        ret[from_len - 1] = '\0';
    }
    memcpy(ret, from, from_len);
    return ret;
}

/** converts binary to hexidecimal
 *
 *     @param *input            Binary data.
 *     @param len               Length of binary data.
 *     @param **dest            NULL terminated string equivalent in hex.
 *     @param *dest_len         size of destination buffer
 *     @param allow_realloc     flag indicating if buffer can be realloc'd
 *      
 * @return olen	Length of output string not including NULL terminator.
 */
u_int
netsnmp_binary_to_hex(u_char ** dest, size_t *dest_len, int allow_realloc, 
                      const u_char * input, size_t len)
{
    u_int           olen = (len * 2) + 1;
    u_char         *s, *op;
    const u_char   *ip = input;

    if (dest == NULL || dest_len == NULL || input == NULL)
        return 0;

    if (NULL == *dest) {
        s = (unsigned char *) calloc(1, olen);
        *dest_len = olen;
    }
    else
        s = *dest;

    if (*dest_len < olen) {
        if (!allow_realloc)
            return 0;
        *dest_len = olen;
        if (snmp_realloc(dest, dest_len))
            return 0;
    }

    op = s;
    while (ip - input < (int) len) {
        *op++ = VAL2HEX((*ip >> 4) & 0xf);
        *op++ = VAL2HEX(*ip & 0xf);
        ip++;
    }
    *op = '\0';

    if (s != *dest)
        *dest = s;
    *dest_len = olen;

    return olen;

}                               /* end netsnmp_binary_to_hex() */

/** converts binary to hexidecimal
 *
 *	@param *input		Binary data.
 *	@param len		Length of binary data.
 *	@param **output	NULL terminated string equivalent in hex.
 *      
 * @return olen	Length of output string not including NULL terminator.
 *
 * FIX	Is there already one of these in the UCD SNMP codebase?
 *	The old one should be used, or this one should be moved to
 *	snmplib/snmp_api.c.
 */
u_int
binary_to_hex(const u_char * input, size_t len, char **output)
{
    size_t out_len = 0;

    *output = NULL; /* will alloc new buffer */

    return netsnmp_binary_to_hex((u_char**)output, &out_len, 1, input, len);
}                               /* end binary_to_hex() */




/**
 * hex_to_binary2
 *	@param *input		Printable data in base16.
 *	@param len		Length in bytes of data.
 *	@param **output	Binary data equivalent to input.
 *      
 * @return SNMPERR_GENERR on failure, otherwise length of allocated string.
 *
 * Input of an odd length is right aligned.
 *
 * FIX	Another version of "hex-to-binary" which takes odd length input
 *	strings.  It also allocates the memory to hold the binary data.
 *	Should be integrated with the official hex_to_binary() function.
 */
int
hex_to_binary2(const u_char * input, size_t len, char **output)
{
    u_int           olen = (len / 2) + (len % 2);
    char           *s = (char *) calloc(1, (olen) ? olen : 1), *op = s;
    const u_char   *ip = input;


    *output = NULL;
    *op = 0;
    if (len % 2) {
        if (!isxdigit(*ip))
            goto hex_to_binary2_quit;
        *op++ = HEX2VAL(*ip);
        ip++;
    }

    while (ip - input < (int) len) {
        if (!isxdigit(*ip))
            goto hex_to_binary2_quit;
        *op = HEX2VAL(*ip) << 4;
        ip++;

        if (!isxdigit(*ip))
            goto hex_to_binary2_quit;
        *op++ += HEX2VAL(*ip);
        ip++;
    }

    *output = s;
    return olen;

  hex_to_binary2_quit:
    free_zero(s, olen);
    return -1;

}                               /* end hex_to_binary2() */

int
snmp_decimal_to_binary(u_char ** buf, size_t * buf_len, size_t * out_len,
                       int allow_realloc, const char *decimal)
{
    int             subid = 0;
    const char     *cp = decimal;

    if (buf == NULL || buf_len == NULL || out_len == NULL
        || decimal == NULL) {
        return 0;
    }

    while (*cp != '\0') {
        if (isspace((int) *cp) || *cp == '.') {
            cp++;
            continue;
        }
        if (!isdigit((int) *cp)) {
            return 0;
        }
        if ((subid = atoi(cp)) > 255) {
            return 0;
        }
        if ((*out_len >= *buf_len) &&
            !(allow_realloc && snmp_realloc(buf, buf_len))) {
            return 0;
        }
        *(*buf + *out_len) = (u_char) subid;
        (*out_len)++;
        while (isdigit((int) *cp)) {
            cp++;
        }
    }
    return 1;
}

/**
 * convert an ASCII hex string (with specified delimiters) to binary
 *
 * @param buf     address of a pointer (pointer to pointer) for the output buffer.
 *                If allow_realloc is set, the buffer may be grown via snmp_realloc
 *                to accomodate the data.
 *
 * @param buf_len pointer to a size_t containing the initial size of buf.
 *
 * @param offset On input, a pointer to a size_t indicating an offset into buf.
 *                The  binary data will be stored at this offset.
 *                On output, this pointer will have updated the offset to be
 *                the first byte after the converted data.
 *
 * @param allow_realloc If true, the buffer can be reallocated. If false, and
 *                      the buffer is not large enough to contain the string,
 *                      an error will be returned.
 *
 * @param hex     pointer to hex string to be converted. May be prefixed by
 *                "0x" or "0X".
 *
 * @param delim   point to a string of allowed delimiters between bytes.
 *                If not specified, any non-hex characters will be an error.
 *
 * @retval 1  success
 * @retval 0  error
 */
int
netsnmp_hex_to_binary(u_char ** buf, size_t * buf_len, size_t * offset,
                      int allow_realloc, const char *hex, const char *delim)
{
    unsigned int    subid = 0;
    const char     *cp = hex;

    if (buf == NULL || buf_len == NULL || offset == NULL || hex == NULL) {
        return 0;
    }

    if ((*cp == '0') && ((*(cp + 1) == 'x') || (*(cp + 1) == 'X'))) {
        cp += 2;
    }

    while (*cp != '\0') {
        if (!isxdigit((int) *cp) ||
            !isxdigit((int) *(cp+1))) {
            if ((NULL != delim) && (NULL != strchr(delim, *cp))) {
                cp++;
                continue;
            }
            return 0;
        }
        if (sscanf(cp, "%2x", &subid) == 0) {
            return 0;
        }
        /*
         * if we dont' have enough space, realloc.
         * (snmp_realloc will adjust buf_len to new size)
         */
        if ((*offset >= *buf_len) &&
            !(allow_realloc && snmp_realloc(buf, buf_len))) {
            return 0;
        }
        *(*buf + *offset) = (u_char) subid;
        (*offset)++;
        if (*++cp == '\0') {
            /*
             * Odd number of hex digits is an error.  
             */
            return 0;
        } else {
            cp++;
        }
    }
    return 1;
}

/**
 * convert an ASCII hex string to binary
 *
 * @note This is a wrapper which calls netsnmp_hex_to_binary with a
 * delimiter string of " ".
 *
 * See netsnmp_hex_to_binary for parameter descriptions.
 *
 * @retval 1  success
 * @retval 0  error
 */
int
snmp_hex_to_binary(u_char ** buf, size_t * buf_len, size_t * offset,
                   int allow_realloc, const char *hex)
{
    return netsnmp_hex_to_binary(buf, buf_len, offset, allow_realloc, hex, " ");
}

/*******************************************************************-o-******
 * dump_chunk
 *
 * Parameters:
 *	*title	(May be NULL.)
 *	*buf
 *	 size
 */
void
dump_chunk(const char *debugtoken, const char *title, const u_char * buf,
           int size)
{
    int             printunit = 64;     /* XXX  Make global. */
    char            chunk[SNMP_MAXBUF], *s, *sp;

    if (title && (*title != '\0')) {
        DEBUGMSGTL((debugtoken, "%s\n", title));
    }


    memset(chunk, 0, SNMP_MAXBUF);
    size = binary_to_hex(buf, size, &s);
    sp = s;

    while (size > 0) {
        if (size > printunit) {
            memcpy(chunk, sp, printunit);
            chunk[printunit] = '\0';
            DEBUGMSGTL((debugtoken, "\t%s\n", chunk));
        } else {
            DEBUGMSGTL((debugtoken, "\t%s\n", sp));
        }

        sp += printunit;
        size -= printunit;
    }


    SNMP_FREE(s);

}                               /* end dump_chunk() */




/*******************************************************************-o-******
 * dump_snmpEngineID
 *
 * Parameters:
 *	*estring
 *	*estring_len
 *      
 * Returns:
 *	Allocated memory pointing to a string of buflen char representing
 *	a printf'able form of the snmpEngineID.
 *
 *	-OR- NULL on error.
 *
 *
 * Translates the snmpEngineID TC into a printable string.  From RFC 2271,
 * Section 5 (pp. 36-37):
 *
 * First bit:	0	Bit string structured by means non-SNMPv3.
 *  		1	Structure described by SNMPv3 SnmpEngineID TC.
 *  
 * Bytes 1-4:		Enterprise ID.  (High bit of first byte is ignored.)
 *  
 * Byte 5:	0	(RESERVED by IANA.)
 *  		1	IPv4 address.		(   4 octets)
 *  		2	IPv6 address.		(  16 octets)
 *  		3	MAC address.		(   6 octets)
 *  		4	Locally defined text.	(0-27 octets)
 *  		5	Locally defined octets.	(0-27 octets)
 *  		6-127	(RESERVED for enterprise.)
 *  
 * Bytes 6-32:		(Determined by byte 5.)
 *  
 *
 * Non-printable characters are given in hex.  Text is given in quotes.
 * IP and MAC addresses are given in standard (UN*X) conventions.  Sections
 * are comma separated.
 *
 * esp, remaining_len and s trace the state of the constructed buffer.
 * s will be defined if there is something to return, and it will point
 * to the end of the constructed buffer.
 *
 *
 * ASSUME  "Text" means printable characters.
 *
 * XXX	Must the snmpEngineID always have a minimum length of 12?
 *	(Cf. part 2 of the TC definition.)
 * XXX	Does not enforce upper-bound of 32 bytes.
 * XXX	Need a switch to decide whether to use DNS name instead of a simple
 *	IP address.
 *
 * FIX	Use something other than snprint_hexstring which doesn't add 
 *	trailing spaces and (sometimes embedded) newlines...
 */
#ifdef NETSNMP_ENABLE_TESTING_CODE
char           *
dump_snmpEngineID(const u_char * estring, size_t * estring_len)
{
#define eb(b)	( *(esp+b) & 0xff )

    int             rval = SNMPERR_SUCCESS, gotviolation = 0, slen = 0;
    u_int           remaining_len;

    char            buf[SNMP_MAXBUF], *s = NULL, *t;
    const u_char   *esp = estring;

    struct in_addr  iaddr;



    /*
     * Sanity check.
     */
    if (!estring || (*estring_len <= 0)) {
        QUITFUN(SNMPERR_GENERR, dump_snmpEngineID_quit);
    }
    remaining_len = *estring_len;
    memset(buf, 0, SNMP_MAXBUF);



    /*
     * Test first bit.  Return immediately with a hex string, or
     * begin by formatting the enterprise ID.
     */
    if (!(*esp & 0x80)) {
        snprint_hexstring(buf, SNMP_MAXBUF, esp, remaining_len);
        s = strchr(buf, '\0');
        s -= 1;
        goto dump_snmpEngineID_quit;
    }

    s = buf;
    s += sprintf(s, "enterprise %d, ", ((*(esp + 0) & 0x7f) << 24) |
                 ((*(esp + 1) & 0xff) << 16) |
                 ((*(esp + 2) & 0xff) << 8) | ((*(esp + 3) & 0xff)));
    /*
     * XXX  Ick. 
     */

    if (remaining_len < 5) {    /* XXX  Violating string. */
        goto dump_snmpEngineID_quit;
    }

    esp += 4;                   /* Incremented one more in the switch below. */
    remaining_len -= 5;



    /*
     * Act on the fifth byte.
     */
    switch ((int) *esp++) {
    case 1:                    /* IPv4 address. */

        if (remaining_len < 4)
            goto dump_snmpEngineID_violation;
        memcpy(&iaddr.s_addr, esp, 4);

        if (!(t = inet_ntoa(iaddr)))
            goto dump_snmpEngineID_violation;
        s += sprintf(s, "%s", t);

        esp += 4;
        remaining_len -= 4;
        break;

    case 2:                    /* IPv6 address. */

        if (remaining_len < 16)
            goto dump_snmpEngineID_violation;

        s += sprintf(s,
                     "%02X%02X %02X%02X %02X%02X %02X%02X::"
                     "%02X%02X %02X%02X %02X%02X %02X%02X",
                     eb(0), eb(1), eb(2), eb(3),
                     eb(4), eb(5), eb(6), eb(7),
                     eb(8), eb(9), eb(10), eb(11),
                     eb(12), eb(13), eb(14), eb(15));

        esp += 16;
        remaining_len -= 16;
        break;

    case 3:                    /* MAC address. */

        if (remaining_len < 6)
            goto dump_snmpEngineID_violation;

        s += sprintf(s, "%02X:%02X:%02X:%02X:%02X:%02X",
                     eb(0), eb(1), eb(2), eb(3), eb(4), eb(5));

        esp += 6;
        remaining_len -= 6;
        break;

    case 4:                    /* Text. */

        s += sprintf(s, "\"%.*s\"", (int) (sizeof(buf)-strlen(buf)-3), esp);
        goto dump_snmpEngineID_quit;
        break;

     /*NOTREACHED*/ case 5:    /* Octets. */

        snprint_hexstring(s, (SNMP_MAXBUF - (s-buf)),
                          esp, remaining_len);
        s = strchr(buf, '\0');
        s -= 1;
        goto dump_snmpEngineID_quit;
        break;

       /*NOTREACHED*/ dump_snmpEngineID_violation:
    case 0:                    /* Violation of RESERVED, 
                                 * *   -OR- of expected length.
                                 */
        gotviolation = 1;
        s += sprintf(s, "!!! ");

    default:                   /* Unknown encoding. */

        if (!gotviolation) {
            s += sprintf(s, "??? ");
        }
        snprint_hexstring(s, (SNMP_MAXBUF - (s-buf)),
                          esp, remaining_len);
        s = strchr(buf, '\0');
        s -= 1;

        goto dump_snmpEngineID_quit;

    }                           /* endswitch */



    /*
     * Cases 1-3 (IP and MAC addresses) should not have trailing
     * octets, but perhaps they do.  Throw them in too.  XXX
     */
    if (remaining_len > 0) {
        s += sprintf(s, " (??? ");

        snprint_hexstring(s, (SNMP_MAXBUF - (s-buf)),
                          esp, remaining_len);
        s = strchr(buf, '\0');
        s -= 1;

        s += sprintf(s, ")");
    }



  dump_snmpEngineID_quit:
    if (s) {
        slen = s - buf + 1;
        s = calloc(1, slen);
        memcpy(s, buf, (slen) - 1);
    }

    memset(buf, 0, SNMP_MAXBUF);        /* XXX -- Overkill? XXX: Yes! */

    return s;

#undef eb
}                               /* end dump_snmpEngineID() */
#endif                          /* NETSNMP_ENABLE_TESTING_CODE */


/**
 * create a new time marker.
 * NOTE: Caller must free time marker when no longer needed.
 */
marker_t
atime_newMarker(void)
{
    marker_t        pm = (marker_t) calloc(1, sizeof(struct timeval));
    gettimeofday((struct timeval *) pm, NULL);
    return pm;
}

/**
 * set a time marker.
 */
void
atime_setMarker(marker_t pm)
{
    if (!pm)
        return;

    gettimeofday((struct timeval *) pm, NULL);
}


/**
 * Returns the difference (in msec) between the two markers
 */
long
atime_diff(const_marker_t first, const_marker_t second)
{
    struct timeval diff;

    NETSNMP_TIMERSUB((const struct timeval *) second, (const struct timeval *) first, &diff);

    return (diff.tv_sec * 1000 + diff.tv_usec / 1000);
}

/**
 * Returns the difference (in u_long msec) between the two markers
 */
u_long
uatime_diff(const_marker_t first, const_marker_t second)
{
    struct timeval diff;

    NETSNMP_TIMERSUB((const struct timeval *) second, (const struct timeval *) first, &diff);

    return (((u_long) diff.tv_sec) * 1000 + diff.tv_usec / 1000);
}

/**
 * Returns the difference (in u_long 1/100th secs) between the two markers
 * (functionally this is what sysUpTime needs)
 */
u_long
uatime_hdiff(const_marker_t first, const_marker_t second)
{
    struct timeval diff;

    NETSNMP_TIMERSUB((const struct timeval *) second, (const struct timeval *) first, &diff);
    return ((u_long) diff.tv_sec) * 100 + diff.tv_usec / 10000;
}

/**
 * Test: Has (marked time plus delta) exceeded current time ?
 * Returns 0 if test fails or cannot be tested (no marker).
 */
int
atime_ready(const_marker_t pm, int delta_ms)
{
    marker_t        now;
    long            diff;
    if (!pm)
        return 0;

    now = atime_newMarker();

    diff = atime_diff(pm, now);
    free(now);
    if (diff < delta_ms)
        return 0;

    return 1;
}

/**
 * Test: Has (marked time plus delta) exceeded current time ?
 * Returns 0 if test fails or cannot be tested (no marker).
 */
int
uatime_ready(const_marker_t pm, unsigned int delta_ms)
{
    marker_t        now;
    u_long          diff;
    if (!pm)
        return 0;

    now = atime_newMarker();

    diff = uatime_diff(pm, now);
    free(now);
    if (diff < delta_ms)
        return 0;

    return 1;
}


        /*
         * Time-related utility functions
         */

/**
 * Return the number of timeTicks since the given marker 
 */
int
marker_tticks(const_marker_t pm)
{
    int             res;
    marker_t        now = atime_newMarker();

    res = atime_diff(pm, now);
    free(now);
    return res / 10;            /* atime_diff works in msec, not csec */
}

int
timeval_tticks(const struct timeval *tv)
{
    return marker_tticks((const_marker_t) tv);
}

/**
 * Non Windows:  Returns a pointer to the desired environment variable  
 *               or NULL if the environment variable does not exist.  
 *               
 * Windows:      Returns a pointer to the desired environment variable  
 *               if it exists.  If it does not, the variable is looked up
 *               in the registry in HKCU\\Net-SNMP or HKLM\\Net-SNMP
 *               (whichever it finds first) and stores the result in the 
 *               environment variable.  It then returns a pointer to 
 *               environment variable.
 */

char *netsnmp_getenv(const char *name)
{
#if !defined (WIN32) && !defined (cygwin)
  return (getenv(name));
#else
  char *temp = NULL;  
  HKEY hKey;
  unsigned char * key_value = NULL;
  DWORD key_value_size = 0;
  DWORD key_value_type = 0;
  DWORD getenv_worked = 0;

  DEBUGMSGTL(("read_config", "netsnmp_getenv called with name: %s\n",name));

  if (!(name))
    return NULL;
  
  /* Try environment variable first */ 
  temp = getenv(name);
  if (temp) {
    getenv_worked = 1;
    DEBUGMSGTL(("read_config", "netsnmp_getenv will return from ENV: %s\n",temp));
  }
  
  /* Next try HKCU */
  if (temp == NULL)
  {
    if (getenv("SNMP_IGNORE_WINDOWS_REGISTRY"))
      return NULL;

    if (RegOpenKeyExA(
          HKEY_CURRENT_USER, 
          "SOFTWARE\\Net-SNMP", 
          0, 
          KEY_QUERY_VALUE, 
          &hKey) == ERROR_SUCCESS) {   
      
      if (RegQueryValueExA(
            hKey, 
            name, 
            NULL, 
            &key_value_type, 
            NULL,               /* Just get the size */
            &key_value_size) == ERROR_SUCCESS) {

        if (key_value)
          SNMP_FREE(key_value);

        /* Allocate memory needed +1 to allow RegQueryValueExA to NULL terminate the
         * string data in registry is missing one (which is unlikely).
         */
        key_value = malloc((sizeof(char) * key_value_size)+sizeof(char));
        
        if (RegQueryValueExA(
              hKey, 
              name, 
              NULL, 
              &key_value_type, 
              key_value, 
              &key_value_size) == ERROR_SUCCESS) {
        }
        temp = (char *) key_value;
      }
      RegCloseKey(hKey);
      if (temp)
        DEBUGMSGTL(("read_config", "netsnmp_getenv will return from HKCU: %s\n",temp));
    }
  }

  /* Next try HKLM */
  if (temp == NULL)
  {
    if (RegOpenKeyExA(
          HKEY_LOCAL_MACHINE, 
          "SOFTWARE\\Net-SNMP", 
          0, 
          KEY_QUERY_VALUE, 
          &hKey) == ERROR_SUCCESS) {   
      
      if (RegQueryValueExA(
            hKey, 
            name, 
            NULL, 
            &key_value_type, 
            NULL,               /* Just get the size */
            &key_value_size) == ERROR_SUCCESS) {

        if (key_value)
          SNMP_FREE(key_value);

        /* Allocate memory needed +1 to allow RegQueryValueExA to NULL terminate the
         * string data in registry is missing one (which is unlikely).
         */
        key_value = malloc((sizeof(char) * key_value_size)+sizeof(char));
        
        if (RegQueryValueExA(
              hKey, 
              name, 
              NULL, 
              &key_value_type, 
              key_value, 
              &key_value_size) == ERROR_SUCCESS) {
        }
        temp = (char *) key_value;

      }
      RegCloseKey(hKey);
      if (temp)
        DEBUGMSGTL(("read_config", "netsnmp_getenv will return from HKLM: %s\n",temp));
    }
  }
  
  if (temp && !getenv_worked) {
    setenv(name, temp, 1);
    SNMP_FREE(temp);
  }

  DEBUGMSGTL(("read_config", "netsnmp_getenv returning: %s\n",getenv(name)));

  return(getenv(name));
#endif
}

/**
 * Set an environment variable.
 *
 * This function is only necessary on Windows for the MSVC and MinGW
 * environments. If the process that uses the Net-SNMP DLL (e.g. a Perl
 * interpreter) and the Net-SNMP have been built with a different compiler
 * version then each will have a separate set of environment variables.
 * This function allows to set an environment variable such that it gets
 * noticed by the Net-SNMP DLL.
 */
int netsnmp_setenv(const char *envname, const char *envval, int overwrite)
{
    return setenv(envname, envval, overwrite);
}

/*
 * swap the order of an inet addr string
 */
int
netsnmp_addrstr_hton(char *ptr, size_t len)
{
#ifndef WORDS_BIGENDIAN
    char tmp[8];
    
    if (8 == len) {
        tmp[0] = ptr[6];
        tmp[1] = ptr[7];
        tmp[2] = ptr[4];
        tmp[3] = ptr[5];
        tmp[4] = ptr[2];
        tmp[5] = ptr[3];
        tmp[6] = ptr[0];
        tmp[7] = ptr[1];
        memcpy (ptr, &tmp, 8);
    }
    else if (32 == len) {
        netsnmp_addrstr_hton(ptr   , 8);
        netsnmp_addrstr_hton(ptr+8 , 8);
        netsnmp_addrstr_hton(ptr+16, 8);
        netsnmp_addrstr_hton(ptr+24, 8);
    }
    else
        return -1;
#endif

    return 0;
}
