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

#ifdef NETSNMP_CAN_USE_NLIST
#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif

#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#ifdef HAVE_NLIST_H
#include <nlist.h>
#endif
#if HAVE_KVM_H
#include <kvm.h>
#endif

#include <net-snmp/agent/auto_nlist.h>
#include "autonlist.h"
#include "kernel.h"

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

struct autonlist *nlists = 0;
static void     init_nlist(struct nlist *);

long
auto_nlist_value(const char *string)
{
    struct autonlist **ptr, *it = 0;
    int             cmp;

    if (string == 0)
        return 0;

    ptr = &nlists;
    while (*ptr != 0 && it == 0) {
        cmp = strcmp((*ptr)->symbol, string);
        if (cmp == 0)
            it = *ptr;
        else if (cmp < 0) {
            ptr = &((*ptr)->left);
        } else {
            ptr = &((*ptr)->right);
        }
    }
    if (*ptr == 0) {
#if !(defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7))
        static char *n_name = NULL;
#endif
        *ptr = (struct autonlist *) malloc(sizeof(struct autonlist));
        memset(*ptr, 0, sizeof(struct autonlist));
        it = *ptr;
        it->left = 0;
        it->right = 0;
        it->symbol = (char *) malloc(strlen(string) + 1);
        strcpy(it->symbol, string);
        /*
         * allocate an extra byte for inclusion of a preceding '_' later 
         */
        it->nl[0].n_name = (char *) malloc(strlen(string) + 2);
#if defined(aix4) || defined(aix5) || defined(aix6)
        strcpy(it->nl[0].n_name, string);
        it->nl[0].n_name[strlen(string)+1] = '\0';
#elif defined(freebsd9)
        sprintf(__DECONST(char*, it->nl[0].n_name), "_%s", string);
#else

        if (n_name != NULL)
            free(n_name);

        n_name = malloc(strlen(string) + 2);
        if (n_name == NULL) {
            snmp_log(LOG_ERR, "nlist err: failed to allocate memory");
            return (-1);
        }
        snprintf(n_name, strlen(string) + 2, "_%s", string);
        it->nl[0].n_name = (const char*)n_name;
#endif
        it->nl[1].n_name = 0;
        init_nlist(it->nl);
#if !(defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7) || \
                    defined(netbsd1) || defined(dragonfly))
        if (it->nl[0].n_type == 0) {
#if defined(freebsd9)
            strcpy(__DECONST(char*, it->nl[0].n_name), string);
            __DECONST(char*, it->nl[0].n_name)[strlen(string)+1] = '\0';
#else
            static char *n_name2 = NULL;

            if (n_name2 != NULL)
                free(n_name2);

            n_name2 = malloc(strlen(string) + 1);
            if (n_name2 == NULL) {
                snmp_log(LOG_ERR, "nlist err: failed to allocate memory");
                return (-1);
            }
            strcpy(n_name2, string);
            it->nl[0].n_name = (const char*)n_name2;
#endif
            init_nlist(it->nl);
        }
#endif
        if (it->nl[0].n_type == 0) {
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
					NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                snmp_log(LOG_ERR, "nlist err: neither %s nor _%s found.\n",
                         string, string);
	    }
            return (-1);
        } else {
            DEBUGMSGTL(("auto_nlist:auto_nlist_value",
			"found symbol %s at %lx.\n",
                        it->symbol, it->nl[0].n_value));
            return (it->nl[0].n_value);
        }
    } else
        return (it->nl[0].n_value);
}

int
auto_nlist(const char *string, char *var, size_t size)
{
    long            result;
    int             ret;
    result = auto_nlist_value(string);
    if (result != -1) {
        if (var != NULL) {
            ret = klookup(result, var, size);
            if (!ret)
                snmp_log(LOG_ERR,
                         "auto_nlist failed on %s at location %lx\n",
                         string, result);
            return ret;
        } else
            return 1;
    }
    return 0;
}

static void
init_nlist(struct nlist nl[])
{
    int             ret;
#if HAVE_KVM_OPENFILES
    kvm_t          *kernel;
    char            kvm_errbuf[4096];

    if ((kernel = kvm_openfiles(KERNEL_LOC, NULL, NULL, O_RDONLY, kvm_errbuf))
	== NULL) {
        if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
            return;
	} else {
            snmp_log_perror("kvm_openfiles");
            snmp_log(LOG_ERR, "kvm_openfiles: %s\n", kvm_errbuf);
            exit(1);
        }
    }
    if ((ret = kvm_nlist(kernel, nl)) == -1) {
        if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
            return;
	} else {
            snmp_log_perror("kvm_nlist");
            exit(1);
        }
    }
    kvm_close(kernel);
#else                           /* ! HAVE_KVM_OPENFILES */
#if (defined(aix4) || defined(aix5) || defined(aix6)) && defined(HAVE_KNLIST)
    if (knlist(nl, 1, sizeof(struct nlist)) == -1) {
        DEBUGMSGTL(("auto_nlist:init_nlist", "knlist failed on symbol:  %s\n",
                    nl[0].n_name));
        if (errno == EFAULT) {
            nl[0].n_type = 0;
            nl[0].n_value = 0;
        } else {
            snmp_log_perror("knlist");
            if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
				       NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                return;
	    } else {
                exit(1);
	    }
        }
    }
#else
    if ((ret = nlist(KERNEL_LOC, nl)) == -1) {
        if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
				   NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
            return;
	} else {
            snmp_log_perror("nlist");
            exit(1);
        }
    }
#endif                          /*aix4 */
#endif                          /* ! HAVE_KVM_OPENFILES */
    for (ret = 0; nl[ret].n_name != NULL; ret++) {
#if defined(aix4) || defined(aix5) || defined(aix6)
        if (nl[ret].n_type == 0 && nl[ret].n_value != 0)
            nl[ret].n_type = 1;
#endif
        if (nl[ret].n_type == 0) {
            if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
					NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
                DEBUGMSGTL(("auto_nlist:init_nlist", "nlist err:  %s not found\n",
                            nl[ret].n_name));
	    }
        } else {
            DEBUGMSGTL(("auto_nlist:init_nlist", "nlist: %s 0x%X\n", nl[ret].n_name,
                        (unsigned int) nl[ret].n_value));
        }
    }
}

int
KNLookup(struct nlist nl[], int nl_which, char *buf, size_t s)
{
    struct nlist   *nlp = &nl[nl_which];

    if (nlp->n_value == 0) {
        snmp_log(LOG_ERR, "Accessing non-nlisted variable: %s\n",
                 nlp->n_name);
        nlp->n_value = -1;      /* only one error message ... */
        return 0;
    }
    if (nlp->n_value == -1)
        return 0;

    return klookup(nlp->n_value, buf, s);
}

#ifdef TESTING
void
auto_nlist_print_tree(int indent, struct autonlist *ptr)
{
    char            buf[1024];
    if (indent == -2) {
        snmp_log(LOG_ERR, "nlist tree:\n");
        auto_nlist_print_tree(12, nlists);
    } else {
        if (ptr == 0)
            return;
        sprintf(buf, "%%%ds\n", indent);
        /*
         * DEBUGMSGTL(("auto_nlist", "buf: %s\n",buf)); 
         */
        DEBUGMSGTL(("auto_nlist", buf, ptr->symbol));
        auto_nlist_print_tree(indent + 2, ptr->left);
        auto_nlist_print_tree(indent + 2, ptr->right);
    }
}
#endif
#else                           /* !NETSNMP_CAN_USE_NLIST */
#include <net-snmp/agent/auto_nlist.h>
int
auto_nlist_noop(void)
{
    return 0;
}
#endif                          /* NETSNMP_CAN_USE_NLIST */
