
/*
 * Note: this file originally auto-generated by mib2c using
 *        : mib2c.access_functions.conf,v 1.3 2003/05/31 00:11:57 hardaker Exp $
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "netSnmpHostsTable_access.h"
#include "netSnmpHostsTable_enums.h"
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>

#define MAX_HOSTS_LINE 4096

/* XXX: make .conf token */
#define HOSTS_FILE "/etc/hosts"

typedef struct my_loop_info_s {
   FILE *filep;
   in_addr_t theaddr;
   char line[MAX_HOSTS_LINE];
   char hostname[64];
   int lineno;
   char *current_ptr;
} my_loop_info;

typedef struct my_data_info_s {
   in_addr_t theaddr;
   in_addr_t theoldaddr;
   char hostname[64];
   int lineno;
} my_data_info;   

/** NOTE:
 * - these get_ routines MUST return data that will not be freed (ie,
 *   use static variables or persistent data).  It will be copied, if
 *   needed, immediately after the get_ routine has been called.
 * - these SET routines must copy the incoming data and can not take
 *   ownership of the memory passed in by the val pointer.
 */


/** returns the first data point within the netSnmpHostsTable table data.

    Set the my_loop_context variable to the first data point structure
    of your choice (from which you can find the next one).  This could
    be anything from the first node in a linked list, to an integer
    pointer containing the beginning of an array variable.

    Set the my_data_context variable to something to be returned to
    you later that will provide you with the data to return in a given
    row.  This could be the same pointer as what my_loop_context is
    set to, or something different.

    The put_index_data variable contains a list of snmp variable
    bindings, one for each index in your table.  Set the values of
    each appropriately according to the data matching the first row
    and return the put_index_data variable at the end of the function.
*/
netsnmp_variable_list *
netSnmpHostsTable_get_first_data_point(void **my_loop_context,
                                       void **my_data_context,
                                       netsnmp_variable_list *
                                       put_index_data,
                                       netsnmp_iterator_info *mydata)
{
    my_loop_info *loopctx;

    loopctx = SNMP_MALLOC_TYPEDEF(my_loop_info);

    if (!loopctx)
        return NULL; /*XXX log err */

    loopctx->filep = fopen("/etc/hosts","r");

    if (!loopctx->filep) {
        free(loopctx);
        return NULL;
    }

    /* at this point, we need to get the first name and address from
       the file.  But since our get_next_data_point function does
       this, we'll use it instead of duplicating code */
    *my_loop_context = loopctx;

    return netSnmpHostsTable_get_next_data_point(my_loop_context,
                                                 my_data_context,
                                                 put_index_data,
                                                 mydata);
}

/** functionally the same as netSnmpHostsTable_get_first_data_point, but
   my_loop_context has already been set to a previous value and should
   be updated to the next in the list.  For example, if it was a
   linked list, you might want to cast it to your local data type and
   then return my_loop_context->next.  The my_data_context pointer
   should be set to something you need later and the indexes in
   put_index_data updated again. */
netsnmp_variable_list *
netSnmpHostsTable_get_next_data_point(void **my_loop_context,
                                      void **my_data_context,
                                      netsnmp_variable_list *
                                      put_index_data,
                                      netsnmp_iterator_info *mydata)
{
    my_loop_info *loopctx = *my_loop_context;
    char tmpstring[64];

    if (!loopctx)
        return NULL;

    while(loopctx->filep) {
        if (!loopctx->current_ptr) {
            if (!fgets(loopctx->line, sizeof(loopctx->line), loopctx->filep)) {
                /* we're done */
                fclose(loopctx->filep);
                loopctx->filep = NULL;
                return NULL;
            }
            loopctx->lineno++;
            loopctx->current_ptr = loopctx->line;
            loopctx->current_ptr = skip_white(loopctx->current_ptr);

            if (loopctx->current_ptr == NULL || *loopctx->current_ptr == '#') {
                loopctx->current_ptr = NULL;
                continue;
            }

            loopctx->current_ptr =
                copy_nword(loopctx->current_ptr, tmpstring, sizeof(tmpstring));
            loopctx->theaddr = inet_addr(tmpstring);

            if (!loopctx->current_ptr)
                continue;
        }

        loopctx->current_ptr =
            copy_nword(loopctx->current_ptr, loopctx->hostname, sizeof(loopctx->hostname));
        
        snmp_set_var_value(put_index_data, (u_char *) loopctx->hostname,
                           strlen(loopctx->hostname));
        return put_index_data;
    }
    
    /* we're out of data */
    *my_loop_context = NULL;
    return NULL;
}

void *
netSnmpHostsTable_context_convert_function(void *loop_context,
                                           netsnmp_iterator_info *iinfo)
{
    my_loop_info *loopctx = loop_context;
    my_data_info *datactx = SNMP_MALLOC_TYPEDEF(my_data_info);
    if (!datactx)
        return NULL;
    datactx->theoldaddr = datactx->theaddr = loopctx->theaddr;
    datactx->lineno = loopctx->lineno;
    strcpy(datactx->hostname, loopctx->hostname);
    return datactx;
}

/** Create a data_context for non-existent rows that SETs are performed on.
 *  return a void * pointer which will be passed to subsequent get_XXX
 *  and set_XXX functions for data retrieval and modification during
 *  this SET request.
 *
 *  The indexs are encoded (in order) into the index_data pointer if it
 *  would be helpful to use that information.
 */
void           *
netSnmpHostsTable_create_data_context(netsnmp_variable_list * index_data)
{
    my_data_info *datactx = SNMP_MALLOC_TYPEDEF(my_data_info);

    if (!datactx)
        return NULL;
    strlcpy(datactx->hostname, (const char *) index_data->val.string,
            sizeof(datactx->hostname));
    return datactx;
}

void
netSnmpHostsTable_data_free(void *data, netsnmp_iterator_info *iinfo)
{
    free(data);
}

void
netSnmpHostsTable_loop_free(void *loopctx, netsnmp_iterator_info *iinfo)
{
    free(loopctx);
}

/** If the implemented set_* functions don't operate directly on the
   real-live data (which is actually recommended), then this function
   can be used to take a given my_data_context pointer and "commit" it
   to whereever the modified data needs to be put back to.  For
   example, if this was a routing table you could publish the modified
   routes back into the kernel at this point.

   rowStatus will be set to 1 if new, 0 if not or -1 if it should
   be deleted.

   If you free the data yourself, make sure to *my_data_context = NULL */
int
netSnmpHostsTable_commit_row(void **my_data_context, int new_or_del)
{
    /** Add any necessary commit code here */
    FILE *in, *out;
    char line[MAX_HOSTS_LINE], line2[MAX_HOSTS_LINE];
    char myaddr[64], *cp;
    my_data_info *datactx = *my_data_context;
    size_t line2_sz;
    int foundit = 0;

    if (datactx->theaddr == datactx->theoldaddr && new_or_del != -1)
        return SNMP_ERR_NOERROR; /* no change in the value */

    if ((out = fopen(HOSTS_FILE ".snmp", "w")) == NULL)
        return SNMP_ERR_COMMITFAILED;
    
    if ((in = fopen(HOSTS_FILE, "r")) == NULL)
        return SNMP_ERR_COMMITFAILED;

    while(fgets(line, sizeof(line), in)) {
        copy_nword(line,myaddr,sizeof(myaddr));
        if (inet_addr(myaddr) == datactx->theaddr && new_or_del != -1) {
            foundit = 1;
            /* right line to append to */
            line[strlen(line)-1] = '\0'; /* nuke the new line */
            fprintf(out, "%s %s\n", line, datactx->hostname);
        } else if (inet_addr(myaddr) == datactx->theoldaddr) {
            /* find and remove the name from the current line */
            int count = 0;
            cp = copy_nword(line, line2, sizeof(line2)); /* pass the addr */
            if (strlen(line2) > sizeof(line2)-2) {
              errorit:
                fclose(in);
                fclose(out);
                unlink(HOSTS_FILE ".snmp");
                return SNMP_ERR_RESOURCEUNAVAILABLE;
            }
            line2_sz = strlen(line2);
            line2[line2_sz++] = '\t';
            while(cp) {
                cp = copy_nword(cp, &line2[line2_sz], sizeof(line2)-line2_sz);
                if (strcmp(&line2[line2_sz], datactx->hostname) == 0) {
                    /* a match, so don't add it to line2 (which means
                       don't update the write line2_sz index */
                } else {
                    if (strlen(line2) > sizeof(line2)-2) {
                        goto errorit;
                    }
                    line2_sz = strlen(line2);
                    line2[line2_sz++] = ' ';
                    count++;
                }
            }
            if (count) {
                /* at least one name was still present on the line, so
                   save it to the new file */
                line2[line2_sz] = '\0';
                fprintf(out, "%s\n", line2);
            }
        } else {
            fputs(line, out);
        }
    }

    if (!foundit && new_or_del != -1) {
        /* couldn't add it to an existing line, so append a new one */
        fprintf(out, "%d.%d.%d.%d\t%s\n",
                (0x000000ff & datactx->theaddr),
                (0x0000ff00 & datactx->theaddr) >> 8,
                (0x00ff0000 & datactx->theaddr) >> 16,
                (0xff000000 & datactx->theaddr) >> 24,
                datactx->hostname);
    }
    fclose(out); /* close out first to minimize race condition */
    fclose(in);
    /*
     * race condition here - someone else could open the file after
     *  we close it but before we can rename it.
     */
    if (!rename(HOSTS_FILE ".snmp", HOSTS_FILE))
        return SNMP_ERR_COMMITFAILED;
        
    /*
     * return no errors.  And there shouldn't be any!!!  Ever!!!  You
     * should have checked the values long before this. 
     */
    return SNMP_ERR_NOERROR;
}


/*
 * User-defined data access functions (per column) for data in table
 * netSnmpHostsTable
 */


long           *
get_netSnmpHostAddressType(void *data_context, size_t * ret_len)
{
    static long ret = NETSNMPHOSTADDRESSTYPE_IPV4;
    *ret_len = sizeof(ret);
    return &ret;
}

int
set_netSnmpHostAddressType(void *data_context, long *val, size_t val_len)
{
    return SNMP_ERR_NOERROR; /* always ipv4 */
}

char           *
get_netSnmpHostAddress(void *data_context, size_t * ret_len)
{
    my_data_info *datainfo = data_context;
    *ret_len = sizeof(in_addr_t);  /* XXX: make sure it's 4 */
    return (char *) &datainfo->theaddr;
}

int
set_netSnmpHostAddress(void *data_context, char *val, size_t val_len)
{
    my_data_info *datainfo = data_context;
    memcpy(&datainfo->theaddr, val, val_len);
    return SNMP_ERR_NOERROR;
}

long           *
get_netSnmpHostStorage(void *data_context, size_t * ret_len)
{
    static long ret = ST_NONVOLATILE;
    *ret_len = sizeof(ret);
    return &ret;
}

int
set_netSnmpHostStorage(void *data_context, long *val, size_t val_len)
{
    return SNMP_ERR_NOERROR;
}

long           *
get_netSnmpHostRowStatus(void *data_context, size_t * ret_len)
{
    static long ret = RS_ACTIVE;
    *ret_len = sizeof(ret);
    return &ret;
}

int
set_netSnmpHostRowStatus(void *data_context, long *val, size_t val_len)
{
    /* XXX */
    return SNMP_ERR_NOERROR;
}
