components/net-snmp-57/sun/sdk/demo/demo_module_5/demo_module_5.c
changeset 5867 445e2cf1c845
parent 252 ee0fb1eabcbf
equal deleted inserted replaced
5866:683c5c035a79 5867:445e2cf1c845
       
     1 /*
       
     2  * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
       
     3  * 
       
     4  * U.S. Government Rights - Commercial software. Government users are subject to
       
     5  * the Sun Microsystems, Inc. standard license agreement and applicable
       
     6  * provisions of the FAR and its supplements.
       
     7  * 
       
     8  * 
       
     9  * This distribution may include materials developed by third parties. Sun, Sun
       
    10  * Microsystems, the Sun logo and Solaris are trademarks or registered
       
    11  * trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
       
    12  */
       
    13 
       
    14 
       
    15 /*
       
    16  * Note: this file originally auto-generated by mib2c using :
       
    17  * mib2c.iterate.conf,v 1.1.1.1 2003/03/26 18:12:29 pcarroll Exp $
       
    18  */
       
    19 
       
    20 #include <sys/types.h>
       
    21 #include <sys/stat.h>
       
    22 #include <stdio.h>
       
    23 #include <errno.h>
       
    24 
       
    25 #include <net-snmp/net-snmp-config.h>
       
    26 #include <net-snmp/net-snmp-includes.h>
       
    27 #include <net-snmp/agent/net-snmp-agent-includes.h>
       
    28 #include "demo_module_5.h"
       
    29 #include <net-snmp/agent/agent_trap.h>
       
    30 
       
    31 /*
       
    32  * MAXNAMELEN is the maximum permissible file name defined in param.h 
       
    33  */
       
    34 
       
    35 fileEntry      *fileList = 0;
       
    36 char            file1[MAXNAMELEN], file2[MAXNAMELEN], file3[MAXNAMELEN],
       
    37                 file4[MAXNAMELEN];
       
    38 
       
    39 
       
    40 
       
    41 /** Initialize the me5FileTable table by defining its contents and how it's structured */
       
    42 
       
    43 void
       
    44 initialize_table_me5FileTable(void)
       
    45 {
       
    46     static oid      me5FileTable_oid[] = {1, 3, 6, 1, 4, 1, 42, 2, 2, 4, 4, 5, 2, 1};
       
    47     netsnmp_table_registration_info *table_info;
       
    48     netsnmp_handler_registration *my_handler;
       
    49     netsnmp_iterator_info *iinfo;
       
    50 
       
    51     /* create the table structure itself */
       
    52     table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
       
    53     iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
       
    54 
       
    55     /*
       
    56      * if your table is read only, it's easiest to change the
       
    57      * HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY
       
    58      */
       
    59     my_handler = netsnmp_create_handler_registration("me5FileTable",
       
    60 						     me5FileTable_handler,
       
    61 						     me5FileTable_oid,
       
    62 					       OID_LENGTH(me5FileTable_oid),
       
    63 						     HANDLER_CAN_RWRITE);
       
    64 
       
    65     if (!my_handler || !table_info || !iinfo) {
       
    66 	return;			/* mallocs failed */
       
    67     }
       
    68 
       
    69     /***************************************************
       
    70      * Setting up the table's definition
       
    71      */
       
    72 
       
    73     netsnmp_table_helper_add_indexes(table_info,
       
    74 				     ASN_UNSIGNED,	/* index: me5FileIndex */
       
    75 				     0);
       
    76 
       
    77     table_info->min_column = 1;
       
    78     table_info->max_column = 4;
       
    79 
       
    80     /* iterator access routines */
       
    81     iinfo->get_first_data_point = me5FileTable_get_first_data_point;
       
    82     iinfo->get_next_data_point = me5FileTable_get_next_data_point;
       
    83 
       
    84     iinfo->table_reginfo = table_info;
       
    85 
       
    86     /***************************************************
       
    87      * registering the table with the master agent
       
    88      */
       
    89 
       
    90     DEBUGMSGTL(("initialize_table_me5FileTable",
       
    91 		"Registering table me5FileTable as a table iterator\n"));
       
    92     netsnmp_register_table_iterator(my_handler, iinfo);
       
    93 }
       
    94 
       
    95 
       
    96 /** Initializes the demo_module_5 module */
       
    97 
       
    98 
       
    99 void
       
   100 init_demo_module_5(void)
       
   101 {
       
   102 
       
   103     /* here we initialize all the tables we're planning on supporting */
       
   104 
       
   105 
       
   106     initialize_table_me5FileTable();
       
   107 
       
   108 
       
   109     /*
       
   110      * These are the default files that are monitored by the module if there
       
   111      * is no persistent data (file names to be monitored). This is likely
       
   112      * during the first running on the module, when the .conf file does not
       
   113      * have any file related information.
       
   114      */
       
   115 
       
   116     strcpy(file1, "/etc/hosts");
       
   117     strcpy(file2, "/etc/group");
       
   118     strcpy(file3, "/etc/passwd");
       
   119     strcpy(file4, "/etc/system");
       
   120 
       
   121 
       
   122     /*
       
   123      * Register for tokens from demo_module_5.conf file. The names of the 
       
   124      * tokens are demo5_file1,demo5_file2,demo5_file3,demo5_file4. The function
       
   125      * demo5_load_tokens is called whenever these 4 tokens are encountered in
       
   126      * demo_module_5.conf file.
       
   127      */
       
   128 
       
   129     register_config_handler(DEMO5_CONF_FILE, "demo5_file1",
       
   130 			    demo5_load_tokens, NULL, NULL);
       
   131 
       
   132     register_config_handler(DEMO5_CONF_FILE, "demo5_file2",
       
   133 			    demo5_load_tokens, NULL, NULL);
       
   134 
       
   135     register_config_handler(DEMO5_CONF_FILE, "demo5_file3",
       
   136 			    demo5_load_tokens, NULL, NULL);
       
   137 
       
   138     register_config_handler(DEMO5_CONF_FILE, "demo5_file4",
       
   139 			    demo5_load_tokens, NULL, NULL);
       
   140 
       
   141 
       
   142 
       
   143     /*
       
   144      * Register for a callback when all the configuration files are read. The
       
   145      * callback function here is demo5_post_read_config
       
   146      */
       
   147 
       
   148     snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_POST_READ_CONFIG,
       
   149 			   demo5_post_read_config, NULL);
       
   150 
       
   151 
       
   152 }
       
   153 
       
   154 
       
   155 /** returns the first data point within the me5FileTable table data.
       
   156 
       
   157     Set the my_loop_context variable to the first data point structure
       
   158     of your choice (from which you can find the next one).  This could
       
   159     be anything from the first node in a linked list, to an integer
       
   160     pointer containing the beginning of an array variable.
       
   161 
       
   162     Set the my_data_context variable to something to be returned to
       
   163     you later that will provide you with the data to return in a given
       
   164     row.  This could be the same pointer as what my_loop_context is
       
   165     set to, or something different.
       
   166 
       
   167     The put_index_data variable contains a list of snmp variable
       
   168     bindings, one for each index in your table.  Set the values of
       
   169     each appropriately according to the data matching the first row
       
   170     and return the put_index_data variable at the end of the function.
       
   171 */
       
   172 
       
   173 
       
   174 netsnmp_variable_list *
       
   175 me5FileTable_get_first_data_point(void **my_loop_context, void **my_data_context,
       
   176 				  netsnmp_variable_list * put_index_data,
       
   177 				  netsnmp_iterator_info * mydata)
       
   178 {
       
   179 
       
   180     netsnmp_variable_list *vptr;
       
   181 
       
   182     fileEntry      *firstFile = fileList;
       
   183     if (!firstFile) {
       
   184 	return NULL;
       
   185     }
       
   186     *my_loop_context = firstFile;
       
   187     *my_data_context = firstFile;
       
   188 
       
   189 
       
   190     vptr = put_index_data;
       
   191 
       
   192     snmp_set_var_value(vptr, (u_char *) & fileList->findex, sizeof(fileList->findex));
       
   193     vptr = vptr->next_variable;
       
   194     
       
   195     return put_index_data;
       
   196 }
       
   197 
       
   198 
       
   199 /** functionally the same as me5FileTable_get_first_data_point, but
       
   200    my_loop_context has already been set to a previous value and should
       
   201    be updated to the next in the list.  For example, if it was a
       
   202    linked list, you might want to cast it and the return
       
   203    my_loop_context->next.  The my_data_context pointer should be set
       
   204    to something you need later and the indexes in put_index_data
       
   205    updated again. */
       
   206 
       
   207 
       
   208 
       
   209 netsnmp_variable_list *
       
   210 me5FileTable_get_next_data_point(void **my_loop_context, void **my_data_context,
       
   211 				 netsnmp_variable_list * put_index_data,
       
   212 				 netsnmp_iterator_info * mydata)
       
   213 {
       
   214 
       
   215     netsnmp_variable_list *vptr;
       
   216     fileEntry      *nextNode = (fileEntry *) * my_loop_context;
       
   217     nextNode = nextNode->next;
       
   218 
       
   219     if (!nextNode) {
       
   220 	return NULL;
       
   221     }
       
   222     *my_loop_context = nextNode;
       
   223     *my_data_context = nextNode;
       
   224 
       
   225     vptr = put_index_data;
       
   226 
       
   227 
       
   228     
       
   229     snmp_set_var_value(vptr, (u_char *) & nextNode->findex,
       
   230 	sizeof(nextNode->findex));
       
   231     vptr = vptr->next_variable;
       
   232 
       
   233     return put_index_data;
       
   234 }
       
   235 
       
   236 
       
   237 /** handles requests for the me5FileTable table, if anything else needs to be done */
       
   238 
       
   239 int
       
   240 me5FileTable_handler(
       
   241 		     netsnmp_mib_handler * handler,
       
   242 		     netsnmp_handler_registration * reginfo,
       
   243 		     netsnmp_agent_request_info * reqinfo,
       
   244 		     netsnmp_request_info * requests)
       
   245 {
       
   246 
       
   247     netsnmp_request_info *request;
       
   248     netsnmp_table_request_info *table_info;
       
   249     netsnmp_variable_list *var;
       
   250     fileEntry      *data;
       
   251     char           *fileName = NULL;
       
   252     char           *undofn;
       
   253     int		   len;
       
   254 		
       
   255     char            filebuf[255];
       
   256 
       
   257     for (request = requests; request; request = request->next) {
       
   258 
       
   259 	var = request->requestvb;
       
   260 	if (request->processed != 0)
       
   261 	    continue;
       
   262 
       
   263 	/*
       
   264 	 * the following extracts the my_data_context pointer set in the loop
       
   265 	 * functions above.  You can then use the results to help return data
       
   266 	 * for the columns of the me5FileTable table in question
       
   267 	 */
       
   268 
       
   269 	data = (fileEntry *) netsnmp_extract_iterator_context(request);
       
   270 	if (data == NULL) {
       
   271 	    if (reqinfo->mode == MODE_GET) {
       
   272 		netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
       
   273 	    } else {
       
   274 		netsnmp_set_request_error(reqinfo, request,
       
   275 					  SNMP_ERR_NOCREATION);
       
   276 	    }
       
   277 	    continue;
       
   278 	} else {
       
   279 	    struct stat     fAttrib;
       
   280 	    if (stat(GetFileName(data->findex), &fAttrib) != -1) {
       
   281 		data->fileSize = fAttrib.st_size;
       
   282 		sprintf(data->filePerm, "%o", fAttrib.st_mode & 0777);
       
   283 	    } else {
       
   284 		data->fileSize = 0;
       
   285 		sprintf(data->filePerm, "%d", -1);
       
   286 	    }
       
   287 
       
   288 	}
       
   289 
       
   290 	/* extracts the information about the table from the request */
       
   291 	table_info = netsnmp_extract_table_info(request);
       
   292 	/* table_info->colnum contains the column number requested */
       
   293 	/*
       
   294 	 * table_info->indexes contains a linked list of snmp variable
       
   295 	 * bindings for the indexes of the table.  Values in the list have
       
   296 	 * been set corresponding to the indexes of the request
       
   297 	 */
       
   298 
       
   299 	if (table_info == NULL) {
       
   300 	    continue;
       
   301 		}
       
   302 	switch (reqinfo->mode) {
       
   303 	    /*
       
   304 	     * the table_iterator helper should change all GETNEXTs into GETs
       
   305 	     * for you automatically, so you don't have to worry about the
       
   306 	     * GETNEXT case.  Only GETs and SETs need to be dealt with here
       
   307 	     */
       
   308 	case MODE_GET:
       
   309 	    switch (table_info->colnum) {
       
   310 	    case COLUMN_ME5FILEINDEX:
       
   311 			snmp_set_var_typed_value(var, ASN_UNSIGNED, 
       
   312 			(u_char *) & data->findex,
       
   313 		sizeof(data->findex));	
       
   314 		break;	
       
   315 
       
   316 	    case COLUMN_ME5FILENAME:
       
   317 			snmp_set_var_typed_value(var, ASN_OCTET_STR, 
       
   318 			(u_char *) data->fileName,
       
   319 	strlen(data->fileName));
       
   320 		break;
       
   321 
       
   322 	    case COLUMN_ME5FILESIZE:
       
   323 			snmp_set_var_typed_value(var, ASN_UNSIGNED, 
       
   324 			(u_char *) & data->fileSize,
       
   325 		sizeof(data->fileSize));
       
   326 		break;
       
   327 
       
   328 	    case COLUMN_ME5FILEPERM:
       
   329 		snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *) data->filePerm,
       
   330 		strlen(data->filePerm));
       
   331 		break;
       
   332 
       
   333 	    default:
       
   334 		/* We shouldn't get here */
       
   335 		snmp_log(LOG_ERR, 
       
   336 			"problem encountered in me5FileTable_handler: unknown column\n");
       
   337 	    }
       
   338 	    break;
       
   339 
       
   340 	case MODE_SET_RESERVE1:
       
   341 	    /* set handling... */
       
   342 	    switch (table_info->colnum) {
       
   343 		/*
       
   344 		 * Check that the value being set is acceptable
       
   345 		 */
       
   346 	    case COLUMN_ME5FILENAME:
       
   347 		if (var->type != ASN_OCTET_STR) {
       
   348 		    DEBUGMSGTL(("me5FileTable", "COLUMN NAME\n"));
       
   349 		    DEBUGMSGTL(("me5FileTable", "%x not octet string type", var->type));
       
   350 		    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
       
   351 		    return SNMP_ERR_WRONGTYPE;
       
   352 		}
       
   353 		if (!var->val.string) {
       
   354 		    DEBUGMSGTL(("me2FileTable", "Empty file name"));
       
   355 		    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
       
   356 		    return SNMP_ERR_WRONGVALUE;
       
   357 		}
       
   358 		break;
       
   359 	    default:
       
   360 		/* We shouldn't get here */
       
   361 		snmp_log(LOG_ERR, 
       
   362 			"problem encountered in me5FileTable_handler: unknown column\n");
       
   363 		netsnmp_set_request_error(reqinfo, request, SNMP_ERR_READONLY);
       
   364 		return SNMP_ERR_NOTWRITABLE;
       
   365 	    }
       
   366 	    break;
       
   367 	case MODE_SET_RESERVE2:
       
   368 	    /*
       
   369 	     * This is conventially where any necesary resources are
       
   370 	     * allocated (e.g. calls to malloc)
       
   371 	     */
       
   372 
       
   373 	    /* Store old info for undo later  */
       
   374 
       
   375 	    undofn = GetFileName(data->findex);
       
   376 	    if (undofn) {
       
   377 		if (!(fileName = strdup(undofn))) {
       
   378 		    netsnmp_set_request_error(reqinfo, request,
       
   379 					      SNMP_ERR_RESOURCEUNAVAILABLE);
       
   380 		} else
       
   381 		    netsnmp_request_add_list_data(request,
       
   382 						  netsnmp_create_data_list
       
   383 					    (ME5FILE_SET_FILENAME, fileName,
       
   384 					     free));
       
   385 
       
   386 	    }
       
   387 	    break;
       
   388 	case MODE_SET_FREE:
       
   389 
       
   390 	    /*
       
   391 	     * This is where any of the above resources are freed again
       
   392 	     * (because one of the other values being SET failed for some
       
   393 	     * reason).
       
   394 	     */
       
   395 
       
   396 	    /*
       
   397 	     * The netsnmp_free_list_data should take care of the alocated
       
   398 	     * resources
       
   399 	     */
       
   400 
       
   401 	    break;
       
   402 	case MODE_SET_ACTION:
       
   403 	    /*
       
   404 	     * Set the variable as requested. Note that this may need to be
       
   405 	     * reversed, so save any information needed to do this.
       
   406 	     */
       
   407 	  len =  var->val_len;
       
   408 	  var->val.string[len] = '\0';
       
   409 	  if (!ChangeItem(data->findex, (char *) var->val.string )) {
       
   410 	    netsnmp_set_request_error(reqinfo, request,
       
   411 				      SNMP_ERR_COMMITFAILED);
       
   412 	  }
       
   413 	  break;
       
   414 	  
       
   415 	case MODE_SET_COMMIT:
       
   416 	    /*
       
   417 	     * Everything worked, so we can discard any saved information,
       
   418 	     * and make the change permanent (e.g. write to the config file).
       
   419 	     * We also free any allocated resources.
       
   420 	     * 
       
   421 	     */
       
   422 
       
   423 	    /* Persist the file information */
       
   424 
       
   425 		snprintf(&filebuf[0], MAXNAMELEN, "demo5_file%d %s",
       
   426 		    data->findex, data->fileName);
       
   427 
       
   428 
       
   429 		
       
   430 		read_config_store(DEMO5_CONF_FILE, &filebuf[0]);
       
   431 
       
   432 	    /*
       
   433 	     * The netsnmp_free_list_data should take care of the alocated
       
   434 	     * resources
       
   435 	     */
       
   436 
       
   437 
       
   438 	    break;
       
   439 	case MODE_SET_UNDO:
       
   440 	    /*
       
   441 	     * Something failed, so re-set the variable to its previous value
       
   442 	     * (and free any allocated resources).
       
   443 	     */
       
   444 
       
   445 	    if (GetFileName(data->findex)) {
       
   446 		/*******  Get the saved value ************/
       
   447 		undofn = (char *) netsnmp_request_get_list_data(request,
       
   448 						      ME5FILE_SET_FILENAME);
       
   449 		if (!ChangeItem(data->findex, undofn)) {
       
   450 		    netsnmp_set_request_error(reqinfo, request,
       
   451 					      SNMP_ERR_UNDOFAILED);
       
   452 		}
       
   453 	    }
       
   454 	    break;
       
   455 
       
   456 	default:
       
   457 	    snmp_log(LOG_ERR, 
       
   458 		"problem encountered in me5FileTable_handler: unsupported mode\n");
       
   459 	}
       
   460     }
       
   461 
       
   462     return SNMP_ERR_NOERROR;
       
   463 }
       
   464 
       
   465 /* Function to add a fileName to the linked list of files */
       
   466 
       
   467 int 
       
   468 AddItem(char *fileName)
       
   469 {
       
   470 
       
   471     fileEntry      *fprt = fileList;
       
   472     struct stat     fAttrib;	/* Need to check if memory is valid */
       
   473     if (!fileName || !strlen(fileName)) {
       
   474 	return FALSE;
       
   475     }
       
   476     if (stat(fileName, &fAttrib) == -1) {
       
   477 	/*
       
   478 	 * Unable to get the file information, it could be more than file not
       
   479 	 * exists if (errno == ENOENT) { return FALSE; } return FALSE;
       
   480 	 */
       
   481 	DEBUGMSGTL(("demo_module_5", "Can't access the file %s", fileName));
       
   482     }
       
   483     if (fprt != NULL) {
       
   484 	while (fprt->next != NULL) {
       
   485 	    fprt = fprt->next;
       
   486 	}
       
   487 	fprt->next = (fileEntry *) malloc(sizeof(fileEntry));
       
   488 	fprt->next->findex = fprt->findex + 1;
       
   489 	fprt = fprt->next;
       
   490 	fprt->next = NULL;
       
   491 	strcpy(fprt->fileName, fileName);
       
   492 	fprt->fileSize = fAttrib.st_size;
       
   493 	sprintf(fprt->filePerm, "%d", fAttrib.st_mode);
       
   494     } else {
       
   495 	fprt = (fileEntry *) malloc(sizeof(fileEntry));
       
   496 	fprt->next = NULL;
       
   497 	fprt->findex = 1;
       
   498 	strcpy(fprt->fileName, fileName);
       
   499 	fprt->fileSize = fAttrib.st_size;
       
   500 	sprintf(fprt->filePerm, "%d", fAttrib.st_mode);
       
   501 	fileList = fprt;
       
   502     }
       
   503 
       
   504     return TRUE;
       
   505 }
       
   506 
       
   507 /*
       
   508  * Function to change the file for a particular index. This function is
       
   509  * called when a snmp set request arrives to change the list of files being
       
   510  * monitored.
       
   511  */
       
   512 
       
   513 int 
       
   514 ChangeItem(int fileIndex, char *fileName)
       
   515 {
       
   516 
       
   517     fileEntry      *tempp = fileList;
       
   518 
       
   519     if (!fileName || !strlen(fileName)) {
       
   520 	return FALSE;
       
   521     }
       
   522 
       
   523        while (tempp != NULL) {
       
   524 	if (tempp->findex == fileIndex) {
       
   525 	    strcpy(tempp->fileName, fileName);
       
   526 	    switch(fileIndex) {
       
   527 	    case 1:
       
   528 	      strcpy(file1, fileName);
       
   529 	    case 2:
       
   530 	      strcpy(file2, fileName);
       
   531 	    case 3:
       
   532 	      strcpy(file3, fileName);
       
   533 	    case 4:
       
   534 	      strcpy(file4, fileName);
       
   535 	    }
       
   536 	      return TRUE;
       
   537 	    
       
   538 	}
       
   539 	    tempp = tempp->next;
       
   540 	}
       
   541 	
       
   542 	return FALSE;
       
   543 }
       
   544 
       
   545 /* Function to return the filename corresponding to an index */
       
   546 
       
   547 char           *
       
   548 GetFileName(int fIndex)
       
   549 {
       
   550     fileEntry      *fprt = fileList;
       
   551     while (fprt != NULL) {
       
   552 	if (fprt->findex == fIndex) {
       
   553 	    return fprt->fileName;
       
   554 	}
       
   555 	fprt = fprt->next;
       
   556     }
       
   557     return NULL;
       
   558 
       
   559 }
       
   560 
       
   561 /*
       
   562  * Function that is called whenever interested tokens are encountered in
       
   563  * demo_module_5.conf file. The token values represent the persistent filename
       
   564  * information.
       
   565  */
       
   566 
       
   567 void 
       
   568 demo5_load_tokens(const char *token, char *cptr)
       
   569 {
       
   570 
       
   571     if (strcmp(token, "demo5_file1") == 0) {
       
   572 	strcpy(file1, cptr);
       
   573     } else if (strcmp(token, "demo5_file2") == 0) {
       
   574 	strcpy(file2, cptr);
       
   575     } else if (strcmp(token, "demo5_file3") == 0) {
       
   576 	strcpy(file3, cptr);
       
   577     } else if (strcmp(token, "demo5_file4") == 0) {
       
   578 	strcpy(file4, cptr);
       
   579     } else {
       
   580 	/* Do Nothing */
       
   581     }
       
   582 
       
   583     return;
       
   584 
       
   585 }
       
   586 
       
   587 /*
       
   588  * Function that persists file information. This is called by the agent
       
   589  * whenever data needs to be persisted.
       
   590  */
       
   591 
       
   592 int 
       
   593 demo5_persist_data(int a, int b, void *c, void *d)
       
   594 {
       
   595 
       
   596     char            filebuf[300];
       
   597 
       
   598 
       
   599     sprintf(filebuf, "demo5_file1 %s", file1);
       
   600     read_config_store(DEMO5_CONF_FILE, filebuf);
       
   601 
       
   602 
       
   603     sprintf(filebuf, "demo5_file2 %s", file2);
       
   604     read_config_store(DEMO5_CONF_FILE, filebuf);
       
   605 
       
   606 
       
   607     sprintf(filebuf, "demo5_file3 %s", file3);
       
   608     read_config_store(DEMO5_CONF_FILE, filebuf);
       
   609 
       
   610 
       
   611     sprintf(filebuf, "demo5_file4 %s", file4);
       
   612     read_config_store(DEMO5_CONF_FILE, filebuf);
       
   613 
       
   614 }
       
   615 
       
   616 /*
       
   617  * Callback function that is called after all the configuration files are
       
   618  * read by the agent. See init_demo_module_5 function to see how this
       
   619  * callback is specified.
       
   620  * 
       
   621  * When this function is called, any persistent file information would have been
       
   622  * read into the module. These files are added to the file list.
       
   623  * 
       
   624  * The callback function to persist data (demo5_persist_data) is registered.
       
   625  */
       
   626 
       
   627 int 
       
   628 demo5_post_read_config(int a, int b, void *c, void *d)
       
   629 {
       
   630 
       
   631     if (!AddItem(file1))
       
   632 	snmp_log(LOG_ERR, "Failed to add instance in init_demo_module_5\n");
       
   633     if (!AddItem(file2))
       
   634 	snmp_log(LOG_ERR, "Failed to add instance in init_demo_module_5\n");
       
   635     if (!AddItem(file3))
       
   636 	snmp_log(LOG_ERR, "Failed to add instance in init_demo_module_5\n");
       
   637     if (!AddItem(file4))
       
   638 	snmp_log(LOG_ERR, "Failed to add instance in init_demo_module_5\n");
       
   639 
       
   640 
       
   641     snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
       
   642 			   demo5_persist_data, NULL);
       
   643 
       
   644 
       
   645 }
       
   646