3
* Note: this file originally auto-generated by mib2c using
4
* : mib2c.access_functions.conf,v 1.3 2003/05/31 00:11:57 hardaker Exp $
7
#include <net-snmp/net-snmp-config.h>
8
#include <net-snmp/net-snmp-includes.h>
9
#include <net-snmp/agent/net-snmp-agent-includes.h>
10
#include "netSnmpHostsTable_access.h"
11
#include "netSnmpHostsTable_enums.h"
12
#include <netinet/in.h>
13
#include <arpa/inet.h>
17
#define MAX_HOSTS_LINE 4096
19
/* XXX: make .conf token */
20
#define HOSTS_FILE "/etc/hosts"
22
typedef struct my_loop_info_s {
25
char line[MAX_HOSTS_LINE];
31
typedef struct my_data_info_s {
39
* - these get_ routines MUST return data that will not be freed (ie,
40
* use static variables or persistent data). It will be copied, if
41
* needed, immediately after the get_ routine has been called.
42
* - these SET routines must copy the incoming data and can not take
43
* ownership of the memory passed in by the val pointer.
47
/** returns the first data point within the netSnmpHostsTable table data.
49
Set the my_loop_context variable to the first data point structure
50
of your choice (from which you can find the next one). This could
51
be anything from the first node in a linked list, to an integer
52
pointer containing the beginning of an array variable.
54
Set the my_data_context variable to something to be returned to
55
you later that will provide you with the data to return in a given
56
row. This could be the same pointer as what my_loop_context is
57
set to, or something different.
59
The put_index_data variable contains a list of snmp variable
60
bindings, one for each index in your table. Set the values of
61
each appropriately according to the data matching the first row
62
and return the put_index_data variable at the end of the function.
64
netsnmp_variable_list *
65
netSnmpHostsTable_get_first_data_point(void **my_loop_context,
66
void **my_data_context,
67
netsnmp_variable_list *
69
netsnmp_iterator_info *mydata)
71
my_loop_info *loopctx;
73
loopctx = SNMP_MALLOC_TYPEDEF(my_loop_info);
76
return NULL; /*XXX log err */
78
loopctx->filep = fopen("/etc/hosts","r");
80
if (!loopctx->filep) {
85
/* at this point, we need to get the first name and address from
86
the file. But since our get_next_data_point function does
87
this, we'll use it instead of duplicating code */
88
*my_loop_context = loopctx;
90
return netSnmpHostsTable_get_next_data_point(my_loop_context,
96
/** functionally the same as netSnmpHostsTable_get_first_data_point, but
97
my_loop_context has already been set to a previous value and should
98
be updated to the next in the list. For example, if it was a
99
linked list, you might want to cast it to your local data type and
100
then return my_loop_context->next. The my_data_context pointer
101
should be set to something you need later and the indexes in
102
put_index_data updated again. */
103
netsnmp_variable_list *
104
netSnmpHostsTable_get_next_data_point(void **my_loop_context,
105
void **my_data_context,
106
netsnmp_variable_list *
108
netsnmp_iterator_info *mydata)
110
my_loop_info *loopctx = *my_loop_context;
116
while(loopctx->filep) {
117
if (!loopctx->current_ptr) {
118
if (!fgets(loopctx->line, sizeof(loopctx->line), loopctx->filep)) {
120
fclose(loopctx->filep);
121
loopctx->filep = NULL;
125
loopctx->current_ptr = loopctx->line;
126
loopctx->current_ptr = skip_white(loopctx->current_ptr);
128
if (loopctx->current_ptr == NULL || *loopctx->current_ptr == '#') {
129
loopctx->current_ptr = NULL;
133
loopctx->current_ptr =
134
copy_nword(loopctx->current_ptr, tmpstring, sizeof(tmpstring));
135
loopctx->theaddr = inet_addr(tmpstring);
137
if (!loopctx->current_ptr)
141
loopctx->current_ptr =
142
copy_nword(loopctx->current_ptr, loopctx->hostname, sizeof(loopctx->hostname));
144
snmp_set_var_value(put_index_data, (u_char *) loopctx->hostname,
145
strlen(loopctx->hostname));
146
return put_index_data;
149
/* we're out of data */
150
*my_loop_context = NULL;
155
netSnmpHostsTable_context_convert_function(void *loop_context,
156
netsnmp_iterator_info *iinfo)
158
my_loop_info *loopctx = loop_context;
159
my_data_info *datactx = SNMP_MALLOC_TYPEDEF(my_data_info);
162
datactx->theoldaddr = datactx->theaddr = loopctx->theaddr;
163
datactx->lineno = loopctx->lineno;
164
strcpy(datactx->hostname, loopctx->hostname);
168
/** Create a data_context for non-existent rows that SETs are performed on.
169
* return a void * pointer which will be passed to subsequent get_XXX
170
* and set_XXX functions for data retrival and modification during
173
* The indexs are encoded (in order) into the index_data pointer if it
174
* would be helpful to use that information.
177
netSnmpHostsTable_create_data_context(netsnmp_variable_list * index_data)
179
my_data_info *datactx = SNMP_MALLOC_TYPEDEF(my_data_info);
182
strncpy(datactx->hostname, index_data->val.string,
183
strlen(index_data->val.string));
188
netSnmpHostsTable_data_free(void *data, netsnmp_iterator_info *iinfo)
194
netSnmpHostsTable_loop_free(void *loopctx, netsnmp_iterator_info *iinfo)
199
/** If the implemented set_* functions don't operate directly on the
200
real-live data (which is actually recommended), then this function
201
can be used to take a given my_data_context pointer and "commit" it
202
to whereever the modified data needs to be put back to. For
203
example, if this was a routing table you could publish the modified
204
routes back into the kernel at this point.
206
rowStatus will be set to 1 if new, 0 if not or -1 if it should
209
If you free the data yourself, make sure to *my_data_context = NULL */
211
netSnmpHostsTable_commit_row(void **my_data_context, int new_or_del)
213
/** Add any necessary commit code here */
215
char line[MAX_HOSTS_LINE], line2[MAX_HOSTS_LINE];
216
char myaddr[64], *cp;
217
my_data_info *datactx = *my_data_context;
221
if (datactx->theaddr == datactx->theoldaddr && new_or_del != -1)
222
return SNMP_ERR_NOERROR; /* no change in the value */
224
if ((out = fopen(HOSTS_FILE ".snmp", "w")) == NULL)
225
return SNMP_ERR_COMMITFAILED;
227
if ((in = fopen(HOSTS_FILE, "r")) == NULL)
228
return SNMP_ERR_COMMITFAILED;
230
while(fgets(line, sizeof(line), in)) {
231
copy_nword(line,myaddr,sizeof(myaddr));
232
if (inet_addr(myaddr) == datactx->theaddr && new_or_del != -1) {
234
/* right line to append to */
235
line[strlen(line)-1] = '\0'; /* nuke the new line */
236
fprintf(out, "%s %s\n", line, datactx->hostname);
237
} else if (inet_addr(myaddr) == datactx->theoldaddr) {
238
/* find and remove the name from the current line */
240
cp = copy_nword(line, line2, sizeof(line2)); /* pass the addr */
241
if (strlen(line2) > sizeof(line2)-2) {
245
unlink(HOSTS_FILE ".snmp");
246
return SNMP_ERR_RESOURCEUNAVAILABLE;
248
line2_sz = strlen(line2);
249
line2[line2_sz++] = '\t';
251
cp = copy_nword(cp, &line2[line2_sz], sizeof(line2)-line2_sz);
252
if (strcmp(&line2[line2_sz], datactx->hostname) == 0) {
253
/* a match, so don't add it to line2 (which means
254
don't update the write line2_sz index */
256
if (strlen(line2) > sizeof(line2)-2) {
259
line2_sz = strlen(line2);
260
line2[line2_sz++] = ' ';
265
/* at least one name was still present on the line, so
266
save it to the new file */
267
line2[line2_sz] = '\0';
268
fprintf(out, "%s\n", line2);
275
if (!foundit && new_or_del != -1) {
276
/* couldn't add it to an existing line, so append a new one */
277
fprintf(out, "%d.%d.%d.%d\t%s\n",
278
(0x000000ff & datactx->theaddr),
279
(0x0000ff00 & datactx->theaddr) >> 8,
280
(0x00ff0000 & datactx->theaddr) >> 16,
281
(0xff000000 & datactx->theaddr) >> 24,
284
fclose(out); /* close out first to minimize race condition */
287
* race condition here - someone else could open the file after
288
* we close it but before we can rename it.
290
if (!rename(HOSTS_FILE ".snmp", HOSTS_FILE))
291
return SNMP_ERR_COMMITFAILED;
294
* return no errors. And there shouldn't be any!!! Ever!!! You
295
* should have checked the values long before this.
297
return SNMP_ERR_NOERROR;
302
* User-defined data access functions (per column) for data in table
308
get_netSnmpHostAddressType(void *data_context, size_t * ret_len)
310
static long ret = NETSNMPHOSTADDRESSTYPE_IPV4;
311
*ret_len = sizeof(ret);
316
set_netSnmpHostAddressType(void *data_context, long *val, size_t val_len)
318
return SNMP_ERR_NOERROR; /* always ipv4 */
322
get_netSnmpHostAddress(void *data_context, size_t * ret_len)
324
my_data_info *datainfo = data_context;
325
*ret_len = sizeof(in_addr_t); /* XXX: make sure it's 4 */
326
return (char *) &datainfo->theaddr;
330
set_netSnmpHostAddress(void *data_context, char *val, size_t val_len)
332
my_data_info *datainfo = data_context;
333
memcpy(&datainfo->theaddr, val, val_len);
334
return SNMP_ERR_NOERROR;
338
get_netSnmpHostStorage(void *data_context, size_t * ret_len)
340
static long ret = ST_NONVOLATILE;
341
*ret_len = sizeof(ret);
346
set_netSnmpHostStorage(void *data_context, long *val, size_t val_len)
348
return SNMP_ERR_NOERROR;
352
get_netSnmpHostRowStatus(void *data_context, size_t * ret_len)
354
static long ret = RS_ACTIVE;
355
*ret_len = sizeof(ret);
360
set_netSnmpHostRowStatus(void *data_context, long *val, size_t val_len)
363
return SNMP_ERR_NOERROR;