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

#include <unistd.h>
#include <fcntl.h>

/*
 * Try to use an initial size that will cover default cases. We aren't talking
 * about huge files, so why fiddle about with reallocs?
 * I checked /proc/meminfo sizes on 3 different systems: 598, 644, 654
 * 
 * On newer systems, the size is up to around 930 (2.6.27 kernel)
 *   or 1160  (2.6.28 kernel)
 */
#define MEMINFO_INIT_SIZE   1279
#define MEMINFO_STEP_SIZE   256
#define MEMINFO_FILE   "/proc/meminfo"

    /*
     * Load the latest memory usage statistics
     */
int netsnmp_mem_arch_load( netsnmp_cache *cache, void *magic ) {
    int          statfd;
    static char *buff  = NULL;
    static int   bsize = 0;
    static int   first = 1;
    ssize_t      bytes_read;
    char        *b;
    unsigned long memtotal = 0,  memfree = 0, memshared = 0,
                  buffers = 0,   cached = 0,
                  swaptotal = 0, swapfree = 0;

    netsnmp_memory_info *mem;

    /*
     * Retrieve the memory information from the underlying O/S...
     */
    if ((statfd = open(MEMINFO_FILE, O_RDONLY, 0)) == -1) {
        snmp_log_perror(MEMINFO_FILE);
        return -1;
    }
    if (bsize == 0) {
        bsize = MEMINFO_INIT_SIZE;
        buff = malloc(bsize+1);
        if (NULL == buff) {
            snmp_log(LOG_ERR, "malloc failed\n");
            close(statfd);
            return -1;
        }
    }
    while ((bytes_read = read(statfd, buff, bsize)) == bsize) {
        b = realloc(buff, bsize + MEMINFO_STEP_SIZE + 1);
        if (NULL == b) {
            snmp_log(LOG_ERR, "malloc failed\n");
            close(statfd);
            return -1;
        }
        buff = b;
        bsize += MEMINFO_STEP_SIZE;
        DEBUGMSGTL(("mem", "/proc/meminfo buffer increased to %d\n", bsize));
        close(statfd);
        statfd = open(MEMINFO_FILE, O_RDONLY, 0);
        if (statfd == -1) {
            snmp_log_perror(MEMINFO_FILE);
            return -1;
        }
    }
    close(statfd);
    if (bytes_read <= 0) {
        snmp_log_perror(MEMINFO_FILE);
    } else {
        buff[bytes_read] = '\0';
    }

    /*
     * ... parse this into a more useable form...
     */
    b = strstr(buff, "MemTotal: ");
    if (b) 
        sscanf(b, "MemTotal: %lu", &memtotal);
    else {
        if (first)
            snmp_log(LOG_ERR, "No MemTotal line in /proc/meminfo\n");
    }
    b = strstr(buff, "MemFree: ");
    if (b) 
        sscanf(b, "MemFree: %lu", &memfree);
    else {
        if (first)
            snmp_log(LOG_ERR, "No MemFree line in /proc/meminfo\n");
    }
    if (0 == netsnmp_os_prematch("Linux","2.4")) {
        b = strstr(buff, "MemShared: ");
        if (b)
            sscanf(b, "MemShared: %lu", &memshared);
        else if (first)
            snmp_log(LOG_ERR, "No MemShared line in /proc/meminfo\n");
    }
    else {
        b = strstr(buff, "Shmem: ");
        if (b)
            sscanf(b, "Shmem: %lu", &memshared);
        else if (first)
            snmp_log(LOG_ERR, "No Shmem line in /proc/meminfo\n");
    }
    b = strstr(buff, "Buffers: ");
    if (b)
        sscanf(b, "Buffers: %lu", &buffers);
    else {
        if (first)
            snmp_log(LOG_ERR, "No Buffers line in /proc/meminfo\n");
    }
    b = strstr(buff, "Cached: ");
    if (b)
        sscanf(b, "Cached: %lu", &cached);
    else {
        if (first)
            snmp_log(LOG_ERR, "No Cached line in /proc/meminfo\n");
    }
    b = strstr(buff, "SwapTotal: ");
    if (b)
        sscanf(b, "SwapTotal: %lu", &swaptotal);
    else {
        if (first)
            snmp_log(LOG_ERR, "No SwapTotal line in /proc/meminfo\n");
    }
    b = strstr(buff, "SwapFree: ");
    if (b)
        sscanf(b, "SwapFree: %lu", &swapfree);
    else {
        if (first)
            snmp_log(LOG_ERR, "No SwapFree line in /proc/meminfo\n");
    }
    first = 0;


    /*
     * ... and save this in a standard form.
     */
    mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_PHYSMEM, 1 );
    if (!mem) {
        snmp_log_perror("No Physical Memory info entry");
    } else {
        if (!mem->descr)
             mem->descr = strdup("Physical memory");
        mem->units = 1024;
        mem->size  = memtotal;
        mem->free  = memfree;
        mem->other = -1;
    }

    mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_VIRTMEM, 1 );
    if (!mem) {
        snmp_log_perror("No Virtual Memory info entry");
    } else {
        if (!mem->descr)
             mem->descr = strdup("Virtual memory");
        mem->units = 1024;
        mem->size  = memtotal+swaptotal;
        mem->free  = memfree +swapfree;
        mem->other = -1;
    }

    mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SHARED, 1 );
    if (!mem) {
        snmp_log_perror("No Shared Memory info entry");
    } else {
        if (!mem->descr)
             mem->descr = strdup("Shared memory");
        mem->units = 1024;
        mem->size  = memshared;
        mem->free  = 0;    /* All in use */
        mem->other = -1;
    }

    mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_CACHED, 1 );
    if (!mem) {
        snmp_log_perror("No Cached Memory info entry");
    } else {
        if (!mem->descr)
             mem->descr = strdup("Cached memory");
        mem->units = 1024;
        mem->size  = cached;
        mem->free  = 0;     /* Report cached size/used as equal */
        mem->other = -1;
    }

    mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SWAP, 1 );
    if (!mem) {
        snmp_log_perror("No Swap info entry");
    } else {
        if (!mem->descr)
             mem->descr = strdup("Swap space");
        mem->units = 1024;
        mem->size  = swaptotal;
        mem->free  = swapfree;
        mem->other = -1;
    }

    mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_MBUF, 1 );
    if (!mem) {
        snmp_log_perror("No Buffer, etc info entry");
    } else {
        if (!mem->descr)
             mem->descr = strdup("Memory buffers");
        mem->units = 1024;
        mem->size  = memtotal;  /* Traditionally we've always regarded
                                   all memory as potentially available
                                   for memory buffers. */
        mem->free  = memtotal - buffers;
        mem->other = -1;
    }

    return 0;
}
