net-snmp 5.7
netSnmpHostsTable_access.c
00001 
00002 /*
00003  * Note: this file originally auto-generated by mib2c using
00004  *        : mib2c.access_functions.conf,v 1.3 2003/05/31 00:11:57 hardaker Exp $
00005  */
00006 
00007 #include <net-snmp/net-snmp-config.h>
00008 #include <net-snmp/net-snmp-includes.h>
00009 #include <net-snmp/agent/net-snmp-agent-includes.h>
00010 #include "netSnmpHostsTable_access.h"
00011 #include "netSnmpHostsTable_enums.h"
00012 #include <netinet/in.h>
00013 #include <arpa/inet.h>
00014 #include <stdio.h>
00015 #include <unistd.h>
00016 
00017 #define MAX_HOSTS_LINE 4096
00018 
00019 /* XXX: make .conf token */
00020 #define HOSTS_FILE "/etc/hosts"
00021 
00022 typedef struct my_loop_info_s {
00023    FILE *filep;
00024    in_addr_t theaddr;
00025    char line[MAX_HOSTS_LINE];
00026    char hostname[64];
00027    int lineno;
00028    char *current_ptr;
00029 } my_loop_info;
00030 
00031 typedef struct my_data_info_s {
00032    in_addr_t theaddr;
00033    in_addr_t theoldaddr;
00034    char hostname[64];
00035    int lineno;
00036 } my_data_info;   
00037 
00064 netsnmp_variable_list *
00065 netSnmpHostsTable_get_first_data_point(void **my_loop_context,
00066                                        void **my_data_context,
00067                                        netsnmp_variable_list *
00068                                        put_index_data,
00069                                        netsnmp_iterator_info *mydata)
00070 {
00071     my_loop_info *loopctx;
00072 
00073     loopctx = SNMP_MALLOC_TYPEDEF(my_loop_info);
00074 
00075     if (!loopctx)
00076         return NULL; /*XXX log err */
00077 
00078     loopctx->filep = fopen("/etc/hosts","r");
00079 
00080     if (!loopctx->filep) {
00081         free(loopctx);
00082         return NULL;
00083     }
00084 
00085     /* at this point, we need to get the first name and address from
00086        the file.  But since our get_next_data_point function does
00087        this, we'll use it instead of duplicating code */
00088     *my_loop_context = loopctx;
00089 
00090     return netSnmpHostsTable_get_next_data_point(my_loop_context,
00091                                                  my_data_context,
00092                                                  put_index_data,
00093                                                  mydata);
00094 }
00095 
00103 netsnmp_variable_list *
00104 netSnmpHostsTable_get_next_data_point(void **my_loop_context,
00105                                       void **my_data_context,
00106                                       netsnmp_variable_list *
00107                                       put_index_data,
00108                                       netsnmp_iterator_info *mydata)
00109 {
00110     my_loop_info *loopctx = *my_loop_context;
00111     char tmpstring[64];
00112 
00113     if (!loopctx)
00114         return NULL;
00115 
00116     while(loopctx->filep) {
00117         if (!loopctx->current_ptr) {
00118             if (!fgets(loopctx->line, sizeof(loopctx->line), loopctx->filep)) {
00119                 /* we're done */
00120                 fclose(loopctx->filep);
00121                 loopctx->filep = NULL;
00122                 return NULL;
00123             }
00124             loopctx->lineno++;
00125             loopctx->current_ptr = loopctx->line;
00126             loopctx->current_ptr = skip_white(loopctx->current_ptr);
00127 
00128             if (loopctx->current_ptr == NULL || *loopctx->current_ptr == '#') {
00129                 loopctx->current_ptr = NULL;
00130                 continue;
00131             }
00132 
00133             loopctx->current_ptr =
00134                 copy_nword(loopctx->current_ptr, tmpstring, sizeof(tmpstring));
00135             loopctx->theaddr = inet_addr(tmpstring);
00136 
00137             if (!loopctx->current_ptr)
00138                 continue;
00139         }
00140 
00141         loopctx->current_ptr =
00142             copy_nword(loopctx->current_ptr, loopctx->hostname, sizeof(loopctx->hostname));
00143         
00144         snmp_set_var_value(put_index_data, (u_char *) loopctx->hostname,
00145                            strlen(loopctx->hostname));
00146         return put_index_data;
00147     }
00148     
00149     /* we're out of data */
00150     *my_loop_context = NULL;
00151     return NULL;
00152 }
00153 
00154 void *
00155 netSnmpHostsTable_context_convert_function(void *loop_context,
00156                                            netsnmp_iterator_info *iinfo)
00157 {
00158     my_loop_info *loopctx = loop_context;
00159     my_data_info *datactx = SNMP_MALLOC_TYPEDEF(my_data_info);
00160     if (!datactx)
00161         return NULL;
00162     datactx->theoldaddr = datactx->theaddr = loopctx->theaddr;
00163     datactx->lineno = loopctx->lineno;
00164     strcpy(datactx->hostname, loopctx->hostname);
00165     return datactx;
00166 }
00167 
00176 void           *
00177 netSnmpHostsTable_create_data_context(netsnmp_variable_list * index_data)
00178 {
00179     my_data_info *datactx = SNMP_MALLOC_TYPEDEF(my_data_info);
00180     if (!datactx)
00181         return NULL;
00182     strncpy(datactx->hostname, index_data->val.string,
00183             strlen(index_data->val.string));
00184     return datactx;
00185 }
00186 
00187 void
00188 netSnmpHostsTable_data_free(void *data, netsnmp_iterator_info *iinfo)
00189 {
00190     free(data);
00191 }
00192 
00193 void
00194 netSnmpHostsTable_loop_free(void *loopctx, netsnmp_iterator_info *iinfo)
00195 {
00196     free(loopctx);
00197 }
00198 
00210 int
00211 netSnmpHostsTable_commit_row(void **my_data_context, int new_or_del)
00212 {
00214     FILE *in, *out;
00215     char line[MAX_HOSTS_LINE], line2[MAX_HOSTS_LINE];
00216     char myaddr[64], *cp;
00217     my_data_info *datactx = *my_data_context;
00218     size_t line2_sz;
00219     int foundit = 0;
00220 
00221     if (datactx->theaddr == datactx->theoldaddr && new_or_del != -1)
00222         return SNMP_ERR_NOERROR; /* no change in the value */
00223 
00224     if ((out = fopen(HOSTS_FILE ".snmp", "w")) == NULL)
00225         return SNMP_ERR_COMMITFAILED;
00226     
00227     if ((in = fopen(HOSTS_FILE, "r")) == NULL)
00228         return SNMP_ERR_COMMITFAILED;
00229 
00230     while(fgets(line, sizeof(line), in)) {
00231         copy_nword(line,myaddr,sizeof(myaddr));
00232         if (inet_addr(myaddr) == datactx->theaddr && new_or_del != -1) {
00233             foundit = 1;
00234             /* right line to append to */
00235             line[strlen(line)-1] = '\0'; /* nuke the new line */
00236             fprintf(out, "%s %s\n", line, datactx->hostname);
00237         } else if (inet_addr(myaddr) == datactx->theoldaddr) {
00238             /* find and remove the name from the current line */
00239             int count = 0;
00240             cp = copy_nword(line, line2, sizeof(line2)); /* pass the addr */
00241             if (strlen(line2) > sizeof(line2)-2) {
00242               errorit:
00243                 fclose(in);
00244                 fclose(out);
00245                 unlink(HOSTS_FILE ".snmp");
00246                 return SNMP_ERR_RESOURCEUNAVAILABLE;
00247             }
00248             line2_sz = strlen(line2);
00249             line2[line2_sz++] = '\t';
00250             while(cp) {
00251                 cp = copy_nword(cp, &line2[line2_sz], sizeof(line2)-line2_sz);
00252                 if (strcmp(&line2[line2_sz], datactx->hostname) == 0) {
00253                     /* a match, so don't add it to line2 (which means
00254                        don't update the write line2_sz index */
00255                 } else {
00256                     if (strlen(line2) > sizeof(line2)-2) {
00257                         goto errorit;
00258                     }
00259                     line2_sz = strlen(line2);
00260                     line2[line2_sz++] = ' ';
00261                     count++;
00262                 }
00263             }
00264             if (count) {
00265                 /* at least one name was still present on the line, so
00266                    save it to the new file */
00267                 line2[line2_sz] = '\0';
00268                 fprintf(out, "%s\n", line2);
00269             }
00270         } else {
00271             fputs(line, out);
00272         }
00273     }
00274 
00275     if (!foundit && new_or_del != -1) {
00276         /* couldn't add it to an existing line, so append a new one */
00277         fprintf(out, "%d.%d.%d.%d\t%s\n",
00278                 (0x000000ff & datactx->theaddr),
00279                 (0x0000ff00 & datactx->theaddr) >> 8,
00280                 (0x00ff0000 & datactx->theaddr) >> 16,
00281                 (0xff000000 & datactx->theaddr) >> 24,
00282                 datactx->hostname);
00283     }
00284     fclose(out); /* close out first to minimize race condition */
00285     fclose(in);
00286     /*
00287      * race condition here - someone else could open the file after
00288      *  we close it but before we can rename it.
00289      */
00290     if (!rename(HOSTS_FILE ".snmp", HOSTS_FILE))
00291         return SNMP_ERR_COMMITFAILED;
00292         
00293     /*
00294      * return no errors.  And there shouldn't be any!!!  Ever!!!  You
00295      * should have checked the values long before this. 
00296      */
00297     return SNMP_ERR_NOERROR;
00298 }
00299 
00300 
00301 /*
00302  * User-defined data access functions (per column) for data in table
00303  * netSnmpHostsTable
00304  */
00305 
00306 
00307 long           *
00308 get_netSnmpHostAddressType(void *data_context, size_t * ret_len)
00309 {
00310     static long ret = NETSNMPHOSTADDRESSTYPE_IPV4;
00311     *ret_len = sizeof(ret);
00312     return &ret;
00313 }
00314 
00315 int
00316 set_netSnmpHostAddressType(void *data_context, long *val, size_t val_len)
00317 {
00318     return SNMP_ERR_NOERROR; /* always ipv4 */
00319 }
00320 
00321 char           *
00322 get_netSnmpHostAddress(void *data_context, size_t * ret_len)
00323 {
00324     my_data_info *datainfo = data_context;
00325     *ret_len = sizeof(in_addr_t);  /* XXX: make sure it's 4 */
00326     return (char *) &datainfo->theaddr;
00327 }
00328 
00329 int
00330 set_netSnmpHostAddress(void *data_context, char *val, size_t val_len)
00331 {
00332     my_data_info *datainfo = data_context;
00333     memcpy(&datainfo->theaddr, val, val_len);
00334     return SNMP_ERR_NOERROR;
00335 }
00336 
00337 long           *
00338 get_netSnmpHostStorage(void *data_context, size_t * ret_len)
00339 {
00340     static long ret = ST_NONVOLATILE;
00341     *ret_len = sizeof(ret);
00342     return &ret;
00343 }
00344 
00345 int
00346 set_netSnmpHostStorage(void *data_context, long *val, size_t val_len)
00347 {
00348     return SNMP_ERR_NOERROR;
00349 }
00350 
00351 long           *
00352 get_netSnmpHostRowStatus(void *data_context, size_t * ret_len)
00353 {
00354     static long ret = RS_ACTIVE;
00355     *ret_len = sizeof(ret);
00356     return &ret;
00357 }
00358 
00359 int
00360 set_netSnmpHostRowStatus(void *data_context, long *val, size_t val_len)
00361 {
00362     /* XXX */
00363     return SNMP_ERR_NOERROR;
00364 }