summaryrefslogtreecommitdiff
path: root/agent/mibgroup/examples/netSnmpHostsTable_access.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/mibgroup/examples/netSnmpHostsTable_access.c')
-rw-r--r--agent/mibgroup/examples/netSnmpHostsTable_access.c365
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;
+}