netSnmpHostsTable_access.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:12k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  * Note: this file originally auto-generated by mib2c using
  3.  *        : mib2c.access_functions.conf,v 1.3 2003/05/31 00:11:57 hardaker Exp $
  4.  */
  5. #include <net-snmp/net-snmp-config.h>
  6. #include <net-snmp/net-snmp-includes.h>
  7. #include <net-snmp/agent/net-snmp-agent-includes.h>
  8. #include "netSnmpHostsTable_access.h"
  9. #include "netSnmpHostsTable_enums.h"
  10. #include <netinet/in.h>
  11. #include <arpa/inet.h>
  12. #include <stdio.h>
  13. #include <unistd.h>
  14. #define MAX_HOSTS_LINE 4096
  15. /* XXX: make .conf token */
  16. #define HOSTS_FILE "/etc/hosts"
  17. typedef struct my_loop_info_s {
  18.    FILE *filep;
  19.    in_addr_t theaddr;
  20.    char line[MAX_HOSTS_LINE];
  21.    char hostname[64];
  22.    int lineno;
  23.    char *current_ptr;
  24. } my_loop_info;
  25. typedef struct my_data_info_s {
  26.    in_addr_t theaddr;
  27.    in_addr_t theoldaddr;
  28.    char hostname[64];
  29.    int lineno;
  30. } my_data_info;   
  31. /** NOTE:
  32.  * - these get_ routines MUST return data that will not be freed (ie,
  33.  *   use static variables or persistent data).  It will be copied, if
  34.  *   needed, immediately after the get_ routine has been called.
  35.  * - these SET routines must copy the incoming data and can not take
  36.  *   ownership of the memory passed in by the val pointer.
  37.  */
  38. /** returns the first data point within the netSnmpHostsTable table data.
  39.     Set the my_loop_context variable to the first data point structure
  40.     of your choice (from which you can find the next one).  This could
  41.     be anything from the first node in a linked list, to an integer
  42.     pointer containing the beginning of an array variable.
  43.     Set the my_data_context variable to something to be returned to
  44.     you later that will provide you with the data to return in a given
  45.     row.  This could be the same pointer as what my_loop_context is
  46.     set to, or something different.
  47.     The put_index_data variable contains a list of snmp variable
  48.     bindings, one for each index in your table.  Set the values of
  49.     each appropriately according to the data matching the first row
  50.     and return the put_index_data variable at the end of the function.
  51. */
  52. netsnmp_variable_list *
  53. netSnmpHostsTable_get_first_data_point(void **my_loop_context,
  54.                                        void **my_data_context,
  55.                                        netsnmp_variable_list *
  56.                                        put_index_data,
  57.                                        netsnmp_iterator_info *mydata)
  58. {
  59.     my_loop_info *loopctx;
  60.     loopctx = SNMP_MALLOC_TYPEDEF(my_loop_info);
  61.     if (!loopctx)
  62.         return NULL; /*XXX log err */
  63.     loopctx->filep = fopen("/etc/hosts","r");
  64.     if (!loopctx->filep) {
  65.         free(loopctx);
  66.         return NULL;
  67.     }
  68.     /* at this point, we need to get the first name and address from
  69.        the file.  But since our get_next_data_point function does
  70.        this, we'll use it instead of duplicating code */
  71.     *my_loop_context = loopctx;
  72.     return netSnmpHostsTable_get_next_data_point(my_loop_context,
  73.                                                  my_data_context,
  74.                                                  put_index_data,
  75.                                                  mydata);
  76. }
  77. /** functionally the same as netSnmpHostsTable_get_first_data_point, but
  78.    my_loop_context has already been set to a previous value and should
  79.    be updated to the next in the list.  For example, if it was a
  80.    linked list, you might want to cast it to your local data type and
  81.    then return my_loop_context->next.  The my_data_context pointer
  82.    should be set to something you need later and the indexes in
  83.    put_index_data updated again. */
  84. netsnmp_variable_list *
  85. netSnmpHostsTable_get_next_data_point(void **my_loop_context,
  86.                                       void **my_data_context,
  87.                                       netsnmp_variable_list *
  88.                                       put_index_data,
  89.                                       netsnmp_iterator_info *mydata)
  90. {
  91.     my_loop_info *loopctx = *my_loop_context;
  92.     char tmpstring[64];
  93.     if (!loopctx)
  94.         return NULL;
  95.     while(loopctx->filep) {
  96.         if (!loopctx->current_ptr) {
  97.             if (!fgets(loopctx->line, sizeof(loopctx->line), loopctx->filep)) {
  98.                 /* we're done */
  99.                 fclose(loopctx->filep);
  100.                 loopctx->filep = NULL;
  101.                 return NULL;
  102.             }
  103.             loopctx->lineno++;
  104.             loopctx->current_ptr = loopctx->line;
  105.             loopctx->current_ptr = skip_white(loopctx->current_ptr);
  106.             if (loopctx->current_ptr == NULL || *loopctx->current_ptr == '#') {
  107.                 loopctx->current_ptr = NULL;
  108.                 continue;
  109.             }
  110.             loopctx->current_ptr =
  111.                 copy_nword(loopctx->current_ptr, tmpstring, sizeof(tmpstring));
  112.             loopctx->theaddr = inet_addr(tmpstring);
  113.             if (!loopctx->current_ptr)
  114.                 continue;
  115.         }
  116.         loopctx->current_ptr =
  117.             copy_nword(loopctx->current_ptr, loopctx->hostname, sizeof(loopctx->hostname));
  118.         
  119.         snmp_set_var_value(put_index_data, (u_char *) loopctx->hostname,
  120.                            strlen(loopctx->hostname));
  121.         return put_index_data;
  122.     }
  123.     
  124.     /* we're out of data */
  125.     *my_loop_context = NULL;
  126.     return NULL;
  127. }
  128. void *
  129. netSnmpHostsTable_context_convert_function(void *loop_context,
  130.                                            netsnmp_iterator_info *iinfo)
  131. {
  132.     my_loop_info *loopctx = loop_context;
  133.     my_data_info *datactx = SNMP_MALLOC_TYPEDEF(my_data_info);
  134.     if (!datactx)
  135.         return NULL;
  136.     datactx->theoldaddr = datactx->theaddr = loopctx->theaddr;
  137.     datactx->lineno = loopctx->lineno;
  138.     strcpy(datactx->hostname, loopctx->hostname);
  139.     return datactx;
  140. }
  141. /** Create a data_context for non-existent rows that SETs are performed on.
  142.  *  return a void * pointer which will be passed to subsequent get_XXX
  143.  *  and set_XXX functions for data retrival and modification during
  144.  *  this SET request.
  145.  *
  146.  *  The indexs are encoded (in order) into the index_data pointer if it
  147.  *  would be helpful to use that information.
  148.  */
  149. void           *
  150. netSnmpHostsTable_create_data_context(netsnmp_variable_list * index_data)
  151. {
  152.     my_data_info *datactx = SNMP_MALLOC_TYPEDEF(my_data_info);
  153.     if (!datactx)
  154.         return NULL;
  155.     strncpy(datactx->hostname, index_data->val.string,
  156.             strlen(index_data->val.string));
  157.     return datactx;
  158. }
  159. void
  160. netSnmpHostsTable_data_free(void *data, netsnmp_iterator_info *iinfo)
  161. {
  162.     free(data);
  163. }
  164. void
  165. netSnmpHostsTable_loop_free(void *loopctx, netsnmp_iterator_info *iinfo)
  166. {
  167.     free(loopctx);
  168. }
  169. /** If the implemented set_* functions don't operate directly on the
  170.    real-live data (which is actually recommended), then this function
  171.    can be used to take a given my_data_context pointer and "commit" it
  172.    to whereever the modified data needs to be put back to.  For
  173.    example, if this was a routing table you could publish the modified
  174.    routes back into the kernel at this point.
  175.    rowStatus will be set to 1 if new, 0 if not or -1 if it should
  176.    be deleted.
  177.    If you free the data yourself, make sure to *my_data_context = NULL */
  178. int
  179. netSnmpHostsTable_commit_row(void **my_data_context, int new_or_del)
  180. {
  181.     /** Add any necessary commit code here */
  182.     FILE *in, *out;
  183.     char line[MAX_HOSTS_LINE], line2[MAX_HOSTS_LINE];
  184.     char myaddr[64], *cp;
  185.     my_data_info *datactx = *my_data_context;
  186.     size_t line2_sz;
  187.     int foundit = 0;
  188.     if (datactx->theaddr == datactx->theoldaddr && new_or_del != -1)
  189.         return SNMP_ERR_NOERROR; /* no change in the value */
  190.     if ((out = fopen(HOSTS_FILE ".snmp", "w")) == NULL)
  191.         return SNMP_ERR_COMMITFAILED;
  192.     
  193.     if ((in = fopen(HOSTS_FILE, "r")) == NULL)
  194.         return SNMP_ERR_COMMITFAILED;
  195.     while(fgets(line, sizeof(line), in)) {
  196.         copy_nword(line,myaddr,sizeof(myaddr));
  197.         if (inet_addr(myaddr) == datactx->theaddr && new_or_del != -1) {
  198.             foundit = 1;
  199.             /* right line to append to */
  200.             line[strlen(line)-1] = ''; /* nuke the new line */
  201.             fprintf(out, "%s %sn", line, datactx->hostname);
  202.         } else if (inet_addr(myaddr) == datactx->theoldaddr) {
  203.             /* find and remove the name from the current line */
  204.             int count = 0;
  205.             cp = copy_nword(line, line2, sizeof(line2)); /* pass the addr */
  206.             if (strlen(line2) > sizeof(line2)-2) {
  207.               errorit:
  208.                 fclose(in);
  209.                 fclose(out);
  210.                 unlink(HOSTS_FILE ".snmp");
  211.                 return SNMP_ERR_RESOURCEUNAVAILABLE;
  212.             }
  213.             line2_sz = strlen(line2);
  214.             line2[line2_sz++] = 't';
  215.             while(cp) {
  216.                 cp = copy_nword(cp, &line2[line2_sz], sizeof(line2)-line2_sz);
  217.                 if (strcmp(&line2[line2_sz], datactx->hostname) == 0) {
  218.                     /* a match, so don't add it to line2 (which means
  219.                        don't update the write line2_sz index */
  220.                 } else {
  221.                     if (strlen(line2) > sizeof(line2)-2) {
  222.                         goto errorit;
  223.                     }
  224.                     line2_sz = strlen(line2);
  225.                     line2[line2_sz++] = ' ';
  226.                     count++;
  227.                 }
  228.             }
  229.             if (count) {
  230.                 /* at least one name was still present on the line, so
  231.                    save it to the new file */
  232.                 line2[line2_sz] = '';
  233.                 fprintf(out, "%sn", line2);
  234.             }
  235.         } else {
  236.             fputs(line, out);
  237.         }
  238.     }
  239.     if (!foundit && new_or_del != -1) {
  240.         /* couldn't add it to an existing line, so append a new one */
  241.         fprintf(out, "%d.%d.%d.%dt%sn",
  242.                 (0x000000ff & datactx->theaddr),
  243.                 (0x0000ff00 & datactx->theaddr) >> 8,
  244.                 (0x00ff0000 & datactx->theaddr) >> 16,
  245.                 (0xff000000 & datactx->theaddr) >> 24,
  246.                 datactx->hostname);
  247.     }
  248.     fclose(out); /* close out first to minimize race condition */
  249.     fclose(in);
  250.     /*
  251.      * race condition here - someone else could open the file after
  252.      *  we close it but before we can rename it.
  253.      */
  254.     if (!rename(HOSTS_FILE ".snmp", HOSTS_FILE))
  255.         return SNMP_ERR_COMMITFAILED;
  256.         
  257.     /*
  258.      * return no errors.  And there shouldn't be any!!!  Ever!!!  You
  259.      * should have checked the values long before this. 
  260.      */
  261.     return SNMP_ERR_NOERROR;
  262. }
  263. /*
  264.  * User-defined data access functions (per column) for data in table
  265.  * netSnmpHostsTable
  266.  */
  267. long           *
  268. get_netSnmpHostAddressType(void *data_context, size_t * ret_len)
  269. {
  270.     static long ret = NETSNMPHOSTADDRESSTYPE_IPV4;
  271.     *ret_len = sizeof(ret);
  272.     return &ret;
  273. }
  274. int
  275. set_netSnmpHostAddressType(void *data_context, long *val, size_t val_len)
  276. {
  277.     return SNMP_ERR_NOERROR; /* always ipv4 */
  278. }
  279. char           *
  280. get_netSnmpHostAddress(void *data_context, size_t * ret_len)
  281. {
  282.     my_data_info *datainfo = data_context;
  283.     *ret_len = sizeof(in_addr_t);  /* XXX: make sure it's 4 */
  284.     return (char *) &datainfo->theaddr;
  285. }
  286. int
  287. set_netSnmpHostAddress(void *data_context, char *val, size_t val_len)
  288. {
  289.     my_data_info *datainfo = data_context;
  290.     memcpy(&datainfo->theaddr, val, val_len);
  291.     return SNMP_ERR_NOERROR;
  292. }
  293. long           *
  294. get_netSnmpHostStorage(void *data_context, size_t * ret_len)
  295. {
  296.     static long ret = ST_NONVOLATILE;
  297.     *ret_len = sizeof(ret);
  298.     return &ret;
  299. }
  300. int
  301. set_netSnmpHostStorage(void *data_context, long *val, size_t val_len)
  302. {
  303.     return SNMP_ERR_NOERROR;
  304. }
  305. long           *
  306. get_netSnmpHostRowStatus(void *data_context, size_t * ret_len)
  307. {
  308.     static long ret = RS_ACTIVE;
  309.     *ret_len = sizeof(ret);
  310.     return &ret;
  311. }
  312. int
  313. set_netSnmpHostRowStatus(void *data_context, long *val, size_t val_len)
  314. {
  315.     /* XXX */
  316.     return SNMP_ERR_NOERROR;
  317. }