diff options
Diffstat (limited to 'agent/mibgroup/examples/netSnmpHostsTable_access.c')
-rw-r--r-- | agent/mibgroup/examples/netSnmpHostsTable_access.c | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/agent/mibgroup/examples/netSnmpHostsTable_access.c b/agent/mibgroup/examples/netSnmpHostsTable_access.c new file mode 100644 index 0000000..3d2e5fb --- /dev/null +++ b/agent/mibgroup/examples/netSnmpHostsTable_access.c @@ -0,0 +1,365 @@ + +/* + * 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; +} |