nsLogging.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:16k
- #include <net-snmp/net-snmp-config.h>
- #include <net-snmp/net-snmp-includes.h>
- #include <net-snmp/agent/net-snmp-agent-includes.h>
- #include <net-snmp/agent/scalar.h>
- #ifdef HAVE_STRING_H
- #include <string.h>
- #else
- #include <strings.h>
- #endif
- #include <net-snmp/library/snmp_logging.h>
- #include "agent/nsLogging.h"
- #include "util_funcs.h"
- /*
- * OID and columns for the logging table.
- */
- #define NSLOGGING_TYPE 3
- #define NSLOGGING_MAXLEVEL 4
- #define NSLOGGING_STATUS 5
- oid nsLoggingTable_oid[] = { 1, 3, 6, 1, 4, 1, 8072, 1, 7, 2, 1};
- void
- init_nsLogging(void)
- {
- netsnmp_table_registration_info *table_info;
- netsnmp_iterator_info *iinfo;
- /*
- * Register the table.
- * We need to define the column structure and indexing....
- */
- table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
- if (!table_info) {
- return;
- }
- netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER,
- ASN_PRIV_IMPLIED_OCTET_STR, 0);
- table_info->min_column = NSLOGGING_TYPE;
- table_info->max_column = NSLOGGING_STATUS;
- /*
- * .... and the iteration information ....
- */
- iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
- if (!iinfo) {
- return;
- }
- iinfo->get_first_data_point = get_first_logging_entry;
- iinfo->get_next_data_point = get_next_logging_entry;
- iinfo->table_reginfo = table_info;
- /*
- * .... and register the table with the agent.
- */
- netsnmp_register_table_iterator(
- netsnmp_create_handler_registration(
- "tzLoggingTable", handle_nsLoggingTable,
- nsLoggingTable_oid, OID_LENGTH(nsLoggingTable_oid),
- HANDLER_CAN_RWRITE),
- iinfo);
- }
- /*
- * nsLoggingTable handling
- */
- netsnmp_variable_list *
- get_first_logging_entry(void **loop_context, void **data_context,
- netsnmp_variable_list *index,
- netsnmp_iterator_info *data)
- {
- long temp;
- netsnmp_log_handler *logh_head = get_logh_head();
- if ( !logh_head )
- return NULL;
- temp = logh_head->priority;
- snmp_set_var_value(index, (u_char*)&temp,
- sizeof(temp));
- if ( logh_head->token )
- snmp_set_var_value(index->next_variable, (const u_char*)logh_head->token,
- strlen(logh_head->token));
- else
- snmp_set_var_value(index->next_variable, NULL, 0);
- *loop_context = (void*)logh_head;
- *data_context = (void*)logh_head;
- return index;
- }
- netsnmp_variable_list *
- get_next_logging_entry(void **loop_context, void **data_context,
- netsnmp_variable_list *index,
- netsnmp_iterator_info *data)
- {
- long temp;
- netsnmp_log_handler *logh = (netsnmp_log_handler *)*loop_context;
- logh = logh->next;
- if ( !logh )
- return NULL;
- temp = logh->priority;
- snmp_set_var_value(index, (u_char*)&temp,
- sizeof(temp));
- if ( logh->token )
- snmp_set_var_value(index->next_variable, (const u_char*)logh->token,
- strlen(logh->token));
- else
- snmp_set_var_value(index->next_variable, NULL, 0);
- *loop_context = (void*)logh;
- *data_context = (void*)logh;
- return index;
- }
- int
- handle_nsLoggingTable(netsnmp_mib_handler *handler,
- netsnmp_handler_registration *reginfo,
- netsnmp_agent_request_info *reqinfo,
- netsnmp_request_info *requests)
- {
- long temp;
- netsnmp_request_info *request = NULL;
- netsnmp_table_request_info *table_info = NULL;
- netsnmp_log_handler *logh = NULL;
- netsnmp_variable_list *idx = NULL;
- switch (reqinfo->mode) {
- case MODE_GET:
- for (request=requests; request; request=request->next) {
- if (requests->processed != 0)
- continue;
- logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
- table_info = netsnmp_extract_table_info(request);
- switch (table_info->colnum) {
- case NSLOGGING_TYPE:
- if (!logh) {
- netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
- continue;
- }
- temp = logh->type;
- snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
- (u_char*)&temp,
- sizeof(temp));
- break;
- case NSLOGGING_MAXLEVEL:
- if (!logh) {
- netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
- continue;
- }
- temp = logh->pri_max;
- snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
- (u_char*)&temp,
- sizeof(temp));
- break;
- case NSLOGGING_STATUS:
- if (!logh) {
- netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
- continue;
- }
- temp = (logh->type ?
- (logh->enabled ?
- RS_ACTIVE:
- RS_NOTINSERVICE) :
- RS_NOTREADY);
- snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
- (u_char*)&temp, sizeof(temp));
- break;
- default:
- netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
- continue;
- }
- }
- break;
- case MODE_SET_RESERVE1:
- for (request=requests; request; request=request->next) {
- if ( request->status != 0 ) {
- return SNMP_ERR_NOERROR; /* Already got an error */
- }
- logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
- table_info = netsnmp_extract_table_info(request);
- switch (table_info->colnum) {
- case NSLOGGING_TYPE:
- if ( request->requestvb->type != ASN_INTEGER ) {
- netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
- return SNMP_ERR_WRONGTYPE;
- }
- if (*request->requestvb->val.integer < 0 ) {
- netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
- return SNMP_ERR_WRONGVALUE;
- }
- /*
- * It's OK to create a new logging entry
- * (either in one go, or built up using createAndWait)
- * but it's not possible to change the type of an entry
- * once it's been created.
- */
- if (logh && logh->type) {
- netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOTWRITABLE);
- return SNMP_ERR_NOTWRITABLE;
- }
- break;
- case NSLOGGING_MAXLEVEL:
- if ( request->requestvb->type != ASN_INTEGER ) {
- netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
- return SNMP_ERR_WRONGTYPE;
- }
- if (*request->requestvb->val.integer < 0 ||
- *request->requestvb->val.integer > 7 ) {
- netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
- return SNMP_ERR_WRONGVALUE;
- }
- break;
- case NSLOGGING_STATUS:
- if ( request->requestvb->type != ASN_INTEGER ) {
- netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
- return SNMP_ERR_WRONGTYPE;
- }
- switch ( *request->requestvb->val.integer ) {
- case RS_ACTIVE:
- case RS_NOTINSERVICE:
- /*
- * Can only work on existing rows
- */
- if (!logh) {
- netsnmp_set_request_error(reqinfo, request,
- SNMP_ERR_INCONSISTENTVALUE);
- return SNMP_ERR_INCONSISTENTVALUE;
- }
- break;
- case RS_CREATEANDWAIT:
- case RS_CREATEANDGO:
- /*
- * Can only work with new rows
- */
- if (logh) {
- netsnmp_set_request_error(reqinfo, request,
- SNMP_ERR_INCONSISTENTVALUE);
- return SNMP_ERR_INCONSISTENTVALUE;
- }
- /*
- * Normally, we'd create the row at a later stage
- * (probably during the RESERVE2 or ACTION passes)
- *
- * But we need to check that the values are
- * consistent during the ACTION pass (which is the
- * latest that an error can be safely handled),
- * so the values all need to be set up before this
- * (i.e. during the RESERVE2 pass)
- * So the new row needs to be created before that
- * in order to have somewhere to put them.
- *
- * That's why we're doing this here.
- */
- idx = table_info->indexes;
- logh = netsnmp_register_loghandler(
- /* not really, but we need a valid type */
- NETSNMP_LOGHANDLER_STDOUT,
- *idx->val.integer);
- if (!logh) {
- netsnmp_set_request_error(reqinfo, request,
- SNMP_ERR_GENERR); /* ??? */
- return SNMP_ERR_GENERR;
- }
- idx = idx->next_variable;
- logh->type = 0;
- logh->token = strdup(idx->val.string);
- netsnmp_insert_iterator_context(request, (void*)logh);
- break;
- case RS_DESTROY:
- /*
- * Can work with new or existing rows
- */
- break;
- case RS_NOTREADY:
- default:
- netsnmp_set_request_error(reqinfo, request,
- SNMP_ERR_WRONGVALUE);
- return SNMP_ERR_WRONGVALUE;
- }
- break;
- default:
- netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
- return SNMP_NOSUCHOBJECT;
- continue;
- }
- }
- break;
- case MODE_SET_RESERVE2:
- for (request=requests; request; request=request->next) {
- if ( request->status != 0 ) {
- return SNMP_ERR_NOERROR; /* Already got an error */
- }
- logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
- table_info = netsnmp_extract_table_info(request);
- switch (table_info->colnum) {
- case NSLOGGING_TYPE:
- /*
- * If we're creating a row using createAndGo,
- * we need to set the type early, so that we
- * can validate it in the ACTION pass.
- *
- * Remember that we need to be able to reverse this
- */
- if ( logh )
- logh->type = *request->requestvb->val.integer;
- break;
- /*
- * Don't need to handle nsLogToken or nsLogStatus in this pass
- */
- }
- }
- break;
- case MODE_SET_ACTION:
- for (request=requests; request; request=request->next) {
- if (requests->processed != 0)
- continue;
- if ( request->status != 0 ) {
- return SNMP_ERR_NOERROR; /* Already got an error */
- }
- logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
- table_info = netsnmp_extract_table_info(request);
- switch (table_info->colnum) {
- case NSLOGGING_STATUS:
- /*
- * This is where we can check the internal consistency
- * of the request. Basically, for a row to be marked
- * 'active', then there needs to be a valid type value.
- */
- switch ( *request->requestvb->val.integer ) {
- case RS_ACTIVE:
- case RS_CREATEANDGO:
- if ( !logh->type ) {
- netsnmp_set_request_error(reqinfo, request,
- SNMP_ERR_INCONSISTENTVALUE);
- return SNMP_ERR_INCONSISTENTVALUE;
- }
- break;
- }
- break;
- /*
- * Don't need to handle nsLogToken or nsLogType in this pass
- */
- }
- }
- break;
- case MODE_SET_FREE:
- case MODE_SET_UNDO:
- /*
- * If any resources were allocated in either of the
- * two RESERVE passes, they need to be released here,
- * and any assignments (in RESERVE2) reversed.
- *
- * Nothing additional will have been done during ACTION
- * so this same code can do for UNDO as well.
- */
- for (request=requests; request; request=request->next) {
- if (requests->processed != 0)
- continue;
- logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
- table_info = netsnmp_extract_table_info(request);
- switch (table_info->colnum) {
- case NSLOGGING_TYPE:
- /*
- * If we've been setting the type, and the request
- * has failed, then revert to an unset type.
- *
- * We need to be careful here - if the reason it failed is
- * that the type was already set, then we shouldn't "undo"
- * the assignment (since it won't actually have been made).
- *
- * Check the current value against the 'new' one. If they're
- * the same, then this is probably a successful assignment,
- * and the failure was elsewhere, so we need to undo it.
- * (Or else there was an attempt to write the same value!)
- */
- if ( logh && logh->type == *request->requestvb->val.integer )
- logh->type = 0;
- break;
- case NSLOGGING_STATUS:
- temp = *request->requestvb->val.integer;
- if ( logh && ( temp == RS_CREATEANDGO ||
- temp == RS_CREATEANDWAIT)) {
- netsnmp_remove_loghandler( logh );
- }
- break;
- /*
- * Don't need to handle nsLogToken in this pass
- */
- }
- }
- break;
- case MODE_SET_COMMIT:
- for (request=requests; request; request=request->next) {
- if (requests->processed != 0)
- continue;
- if ( request->status != 0 ) {
- return SNMP_ERR_NOERROR; /* Already got an error */
- }
- logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
- if (!logh) {
- netsnmp_set_request_error(reqinfo, request, SNMP_ERR_COMMITFAILED);
- return SNMP_ERR_COMMITFAILED; /* Shouldn't happen! */
- }
- table_info = netsnmp_extract_table_info(request);
- switch (table_info->colnum) {
- case NSLOGGING_MAXLEVEL:
- logh->pri_max = *request->requestvb->val.integer;
- break;
- case NSLOGGING_STATUS:
- switch (*request->requestvb->val.integer) {
- case RS_ACTIVE:
- case RS_CREATEANDGO:
- logh->enabled = 1;
- break;
- case RS_NOTINSERVICE:
- case RS_CREATEANDWAIT:
- logh->enabled = 0;
- break;
- case RS_DESTROY:
- netsnmp_remove_loghandler( logh );
- break;
- }
- break;
- }
- }
- break;
- }
- return SNMP_ERR_NOERROR;
- }