components/net-snmp/sun/sdk/demo/demo_module_2/demo_module_2.c
changeset 252 ee0fb1eabcbf
equal deleted inserted replaced
251:f527656d334f 252:ee0fb1eabcbf
       
     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
       
     5  * to 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,
       
    10  * Sun 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_2.h"
       
    29 /********************************************************************/
       
    30 /* Implemented simple link list for demo purpose                    */
       
    31 /********************************************************************/
       
    32 
       
    33 fileEntry* fileList = 0;
       
    34 
       
    35 
       
    36 
       
    37 
       
    38 int AddItem (char* fileName) {
       
    39 
       
    40     fileEntry *fprt = fileList;
       
    41     struct stat fAttrib;  /* Need to check if memory is valid */
       
    42     if (!fileName || !strlen(fileName)) {
       
    43         return FALSE;
       
    44     }
       
    45     if (stat(fileName, &fAttrib) == -1) {
       
    46       /* Unable to get the file information, it could be more than file not exists
       
    47         if (errno == ENOENT) {
       
    48 	    return FALSE;
       
    49 	}
       
    50 	return FALSE;
       
    51      */
       
    52         DEBUGMSGTL(("demo_module_2", "Can't access the file %s", fileName));
       
    53     }
       
    54 
       
    55     if (fprt != NULL) {
       
    56 	while (fprt->next != NULL){
       
    57 	    fprt = fprt->next;
       
    58 	}
       
    59 	fprt->next = (fileEntry  *) malloc (sizeof(fileEntry));
       
    60 	fprt->next->findex = fprt->findex + 1;
       
    61 	fprt = fprt->next;
       
    62 	fprt->next = NULL;
       
    63 	strcpy(fprt->fileName, fileName);
       
    64         fprt->fileSize = fAttrib.st_size; 
       
    65 	sprintf(fprt->filePerm, "%d" , fAttrib.st_mode);
       
    66     }
       
    67     else {
       
    68 	fprt = (fileEntry  *) malloc (sizeof(fileEntry));
       
    69 	fprt->next = NULL;
       
    70 	fprt->findex = 1;
       
    71 	strcpy(fprt->fileName, fileName);
       
    72         fprt->fileSize = fAttrib.st_size; 
       
    73 	sprintf(fprt->filePerm, "%d" , fAttrib.st_mode);
       
    74 	fileList = fprt;
       
    75     }
       
    76     return TRUE;
       
    77 }
       
    78 
       
    79 int ChangeItem (int fileIndex, char* fileName) {
       
    80 
       
    81     fileEntry * tempp = fileList, *prev = fileList;
       
    82     if (!fileName || !strlen(fileName)) {
       
    83 	return FALSE;
       
    84     }
       
    85     while (tempp != NULL) {
       
    86 	if (tempp->findex == fileIndex) {
       
    87 	    strcpy(tempp->fileName, fileName);
       
    88 	    return TRUE;
       
    89 	}
       
    90 	prev = tempp;
       
    91 	tempp = tempp->next;
       
    92     }
       
    93 
       
    94     return FALSE;
       
    95 }
       
    96 
       
    97 char* GetFileName( int fIndex){
       
    98     fileEntry *fprt = fileList;
       
    99     while (fprt != NULL){
       
   100 	if (fprt->findex == fIndex) {
       
   101 	    return fprt->fileName;
       
   102 	}
       
   103 	fprt = fprt->next;
       
   104     }
       
   105     return NULL;
       
   106 
       
   107 }
       
   108 
       
   109 /********************************************************************/
       
   110 
       
   111 /** Initialize the me1FileTable table by defining its contents and how it's structured */
       
   112 void
       
   113 initialize_table_me1FileTable(void)
       
   114 {
       
   115     static oid me1FileTable_oid[] = {1,3,6,1,4,1,42,2,2,4,4,1,2,1};
       
   116     netsnmp_table_registration_info *table_info;
       
   117     netsnmp_handler_registration *my_handler;
       
   118     netsnmp_iterator_info *iinfo;
       
   119 
       
   120     /* create the table structure itself */
       
   121     table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
       
   122     iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
       
   123 
       
   124     /* if your table is read only, it's easiest to change the
       
   125        HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */
       
   126     my_handler = netsnmp_create_handler_registration("me1FileTable",
       
   127                                              me1FileTable_handler,
       
   128                                              me1FileTable_oid,
       
   129                                              OID_LENGTH(me1FileTable_oid),
       
   130                                              HANDLER_CAN_RWRITE);
       
   131             
       
   132     if (!my_handler || !table_info || !iinfo){
       
   133         return; /* mallocs failed */
       
   134     }
       
   135 
       
   136     /***************************************************
       
   137      * Setting up the table's definition
       
   138      */
       
   139     netsnmp_table_helper_add_indexes(table_info,
       
   140                                   ASN_UNSIGNED, /* index: me1FileIndex */
       
   141                              0);
       
   142 
       
   143     table_info->min_column = 1;
       
   144     table_info->max_column = 4;
       
   145 
       
   146     /* iterator access routines */
       
   147     iinfo->get_first_data_point = me1FileTable_get_first_data_point;
       
   148     iinfo->get_next_data_point = me1FileTable_get_next_data_point;
       
   149 
       
   150     iinfo->table_reginfo = table_info;
       
   151 
       
   152     /***************************************************
       
   153      * registering the table with the master agent
       
   154      */
       
   155     DEBUGMSGTL(("initialize_table_me1FileTable",
       
   156                 "Registering table me1FileTable as a table iterator\n"));		 
       
   157     netsnmp_register_table_iterator(my_handler, iinfo);
       
   158 }
       
   159 
       
   160 /** Initializes the demo_module_2 module */
       
   161 void
       
   162 init_demo_module_2(void)
       
   163 {
       
   164 
       
   165   /* here we initialize all the tables we're planning on supporting */
       
   166     initialize_table_me1FileTable();
       
   167     if (!AddItem("/etc/hosts"))
       
   168       snmp_log(LOG_ERR, "Failed to add instance in init_demo_module_2\n");
       
   169     if (!AddItem("/etc/passwd"))
       
   170       snmp_log(LOG_ERR, "Failed to add instance in init_demo_module_2\n");
       
   171     if (!AddItem("/etc/cron"))
       
   172       snmp_log(LOG_ERR, "Failed to add instance in init_demo_module_2\n");
       
   173     if (!AddItem("/etc/system"))
       
   174       snmp_log(LOG_ERR, "Failed to add instance in init_demo_module_2\n");
       
   175 }
       
   176 
       
   177 /** returns the first data point within the me1FileTable table data.
       
   178 
       
   179     Set the my_loop_context variable to the first data point structure
       
   180     of your choice (from which you can find the next one).  This could
       
   181     be anything from the first node in a linked list, to an integer
       
   182     pointer containing the beginning of an array variable.
       
   183 
       
   184     Set the my_data_context variable to something to be returned to
       
   185     you later that will provide you with the data to return in a given
       
   186     row.  This could be the same pointer as what my_loop_context is
       
   187     set to, or something different.
       
   188 
       
   189     The put_index_data variable contains a list of snmp variable
       
   190     bindings, one for each index in your table.  Set the values of
       
   191     each appropriately according to the data matching the first row
       
   192     and return the put_index_data variable at the end of the function.
       
   193 */
       
   194 netsnmp_variable_list *
       
   195 me1FileTable_get_first_data_point(void **my_loop_context, void **my_data_context,
       
   196                           netsnmp_variable_list *put_index_data,
       
   197                           netsnmp_iterator_info *mydata)
       
   198 {
       
   199 
       
   200     netsnmp_variable_list *vptr;
       
   201 
       
   202     fileEntry* firstFile = fileList;
       
   203     if (!firstFile) {
       
   204 	return NULL;
       
   205     }
       
   206 
       
   207     *my_loop_context = firstFile;
       
   208     *my_data_context = firstFile;
       
   209 
       
   210 
       
   211     vptr = put_index_data;
       
   212     
       
   213     snmp_set_var_value(vptr, (u_char *) &fileList->findex, sizeof(fileList->findex));
       
   214     vptr = vptr->next_variable;
       
   215 
       
   216     return put_index_data;
       
   217 }
       
   218 
       
   219 /** functionally the same as me1FileTable_get_first_data_point, but
       
   220    my_loop_context has already been set to a previous value and should
       
   221    be updated to the next in the list.  For example, if it was a
       
   222    linked list, you might want to cast it and the return
       
   223    my_loop_context->next.  The my_data_context pointer should be set
       
   224    to something you need later and the indexes in put_index_data
       
   225    updated again. */
       
   226 
       
   227 netsnmp_variable_list *
       
   228 me1FileTable_get_next_data_point(void **my_loop_context, void **my_data_context,
       
   229                          netsnmp_variable_list *put_index_data,
       
   230                          netsnmp_iterator_info *mydata)
       
   231 {
       
   232 
       
   233     netsnmp_variable_list *vptr;
       
   234     fileEntry *nextNode = (fileEntry *) *my_loop_context;
       
   235     nextNode = nextNode->next; 
       
   236 
       
   237     if (!nextNode) {
       
   238 	return NULL;
       
   239     }
       
   240     *my_loop_context = nextNode;
       
   241     *my_data_context = nextNode;
       
   242 
       
   243     vptr = put_index_data;
       
   244     
       
   245     snmp_set_var_value(vptr, (u_char *) &nextNode->findex, sizeof(nextNode->findex));
       
   246     vptr = vptr->next_variable;
       
   247 
       
   248     return put_index_data;
       
   249 }
       
   250 
       
   251 /** handles requests for the me1FileTable table, if anything else needs to be done */
       
   252 int
       
   253 me1FileTable_handler(
       
   254     netsnmp_mib_handler               *handler,
       
   255     netsnmp_handler_registration      *reginfo,
       
   256     netsnmp_agent_request_info        *reqinfo,
       
   257     netsnmp_request_info              *requests) {
       
   258 
       
   259     netsnmp_request_info *request;
       
   260     netsnmp_table_request_info *table_info;
       
   261     netsnmp_variable_list *var;
       
   262     fileEntry *data;
       
   263     char*   fileName = NULL;
       
   264     char* undofn;
       
   265     
       
   266         for(request = requests; request; request = request->next) {
       
   267         var = request->requestvb;
       
   268         if (request->processed != 0)
       
   269             continue;
       
   270 
       
   271         /* perform anything here that you need to do before each
       
   272            request is processed. */
       
   273 
       
   274         /* the following extracts the my_data_context pointer set in
       
   275            the loop functions above.  You can then use the results to
       
   276            help return data for the columns of the me1FileTable table in question */
       
   277         data = (fileEntry *) netsnmp_extract_iterator_context(request);
       
   278         if ( data == NULL) {
       
   279             if (reqinfo->mode == MODE_GET) {
       
   280                 netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
       
   281             } else {
       
   282                 netsnmp_set_request_error(reqinfo, request,
       
   283                                           SNMP_ERR_NOCREATION); 
       
   284             }
       
   285             continue;
       
   286         } else {
       
   287 	    struct stat fAttrib;
       
   288 	    if (stat(GetFileName(data->findex), &fAttrib) != -1) {
       
   289 		data->fileSize = fAttrib.st_size; 
       
   290 		sprintf(data->filePerm, "%o" , fAttrib.st_mode & 0777);
       
   291 	    } else {
       
   292 		data->fileSize = 0; 
       
   293 		sprintf(data->filePerm, "%d" , -1);
       
   294 	    }
       
   295 
       
   296 	}
       
   297 
       
   298         /* extracts the information about the table from the request */
       
   299         table_info = netsnmp_extract_table_info(request);
       
   300         /* table_info->colnum contains the column number requested */
       
   301         /* table_info->indexes contains a linked list of snmp variable
       
   302            bindings for the indexes of the table.  Values in the list
       
   303            have been set corresponding to the indexes of the
       
   304            request */
       
   305         if (table_info==NULL) {
       
   306             continue;
       
   307         }
       
   308 
       
   309         switch(reqinfo->mode) {
       
   310             /* the table_iterator helper should change all GETNEXTs
       
   311                into GETs for you automatically, so you don't have to
       
   312                worry about the GETNEXT case.  Only GETs and SETs need
       
   313                to be dealt with here */
       
   314             case MODE_GET:
       
   315                 switch(table_info->colnum) {
       
   316                     case COLUMN_ME1FILEINDEX:
       
   317 /* ASN_UNSIGNED */
       
   318                         snmp_set_var_typed_value(var, ASN_UNSIGNED, (u_char *) &data->findex, sizeof(data->findex));
       
   319                         break;
       
   320 
       
   321                     case COLUMN_ME1FILENAME:
       
   322                         snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *) data->fileName, strlen(data->fileName));
       
   323                         break;
       
   324 
       
   325                     case COLUMN_ME1FILESIZE:
       
   326                         snmp_set_var_typed_value(var, ASN_UNSIGNED, (u_char *) &data->fileSize, sizeof(data->fileSize));
       
   327                         break;
       
   328 
       
   329                     case COLUMN_ME1FILEPERM:
       
   330                         snmp_set_var_typed_value(var, ASN_OCTET_STR, (u_char *) data->filePerm, strlen(data->filePerm));
       
   331                         break;
       
   332 
       
   333                     default:
       
   334                         /* We shouldn't get here */
       
   335                         snmp_log(LOG_ERR, "problem encountered in me1FileTable_handler: unknown column\n");
       
   336                 }
       
   337                 break;
       
   338 
       
   339             case MODE_SET_RESERVE1:
       
   340                 /* set handling... */
       
   341                 switch(table_info->colnum) {
       
   342 /*
       
   343  *            Check that the value being set is acceptable
       
   344  */
       
   345                 case COLUMN_ME1FILENAME:
       
   346 		    if (var->type != ASN_OCTET_STR) {
       
   347 			DEBUGMSGTL(("me1FileTable", "%x not octet string type", var->type));
       
   348                         netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE); 
       
   349 			return SNMP_ERR_WRONGTYPE;
       
   350 		    }
       
   351                     if (!var->val.string) {
       
   352                         DEBUGMSGTL(("me2FileTable", "Empty file name"));
       
   353                         netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE); 
       
   354                         return SNMP_ERR_WRONGVALUE;
       
   355                     }
       
   356                     break;
       
   357                 default:
       
   358                     /* We shouldn't get here */
       
   359                     snmp_log(LOG_ERR, "problem encountered in me1FileTable_handler: unknown column\n");
       
   360                     netsnmp_set_request_error(reqinfo, request, SNMP_ERR_READONLY); 
       
   361                     return SNMP_ERR_NOTWRITABLE; 
       
   362                 }
       
   363 		break;
       
   364 	    case MODE_SET_RESERVE2:
       
   365 /*
       
   366  *              This is conventially where any necesary
       
   367  *              resources are allocated (e.g. calls to malloc)
       
   368  */
       
   369 
       
   370 /*                 Store old info for undo later  */
       
   371         
       
   372                 undofn = GetFileName(data->findex); 
       
   373                 if (undofn) {
       
   374                     if (!(fileName = strdup(undofn))){
       
   375                         netsnmp_set_request_error(reqinfo, request,
       
   376                                       SNMP_ERR_RESOURCEUNAVAILABLE);
       
   377                     } else
       
   378                          netsnmp_request_add_list_data(request,
       
   379                                         netsnmp_create_data_list
       
   380                                        (ME1FILE_SET_FILENAME, fileName,
       
   381                                         free));
       
   382 
       
   383                 } 
       
   384 		break;
       
   385             case MODE_SET_FREE:
       
   386 /*
       
   387  *             This is where any of the above resources
       
   388  *             are freed again (because one of the other
       
   389  *             values being SET failed for some reason).
       
   390  */
       
   391                 /*The netsnmp_free_list_data should take care of the
       
   392                 alocated resources */
       
   393 		break;
       
   394             case MODE_SET_ACTION:
       
   395 /*
       
   396  *             Set the variable as requested.
       
   397  *             Note that this may need to be reversed,
       
   398  *             so save any information needed to do this.
       
   399  */
       
   400                 if (!ChangeItem(data->findex, (char *)var->val.string)){
       
   401                     netsnmp_set_request_error(reqinfo, request, 
       
   402                                               SNMP_ERR_COMMITFAILED);
       
   403                 }
       
   404 
       
   405                 break;
       
   406 
       
   407             case MODE_SET_COMMIT:
       
   408 /*
       
   409  *             Everything worked, so we can discard any
       
   410  *             saved information, and make the change
       
   411  *             permanent (e.g. write to the config file).
       
   412  *             We also free any allocated resources.
       
   413  *
       
   414  */
       
   415                 /*The netsnmp_free_list_data should take care of the
       
   416                 alocated resources */
       
   417             break;            
       
   418             case MODE_SET_UNDO:
       
   419 /*
       
   420  *             Something failed, so re-set the
       
   421  *             variable to its previous value
       
   422  *             (and free any allocated resources).
       
   423  */
       
   424                 
       
   425                 if(GetFileName(data->findex)){
       
   426                     /*******  Get the saved value ************/
       
   427                     undofn = (char *) netsnmp_request_get_list_data(request,
       
   428                                                            ME1FILE_SET_FILENAME);
       
   429                     if (!ChangeItem(data->findex, undofn)){
       
   430                         netsnmp_set_request_error(reqinfo, request, 
       
   431                                                   SNMP_ERR_UNDOFAILED);
       
   432                     }
       
   433                 }
       
   434                break;
       
   435 
       
   436             default:
       
   437                 snmp_log(LOG_ERR, "problem encountered in me1FileTable_handler: unsupported mode\n");
       
   438         }
       
   439     }
       
   440     return SNMP_ERR_NOERROR;
       
   441 }