📄 extend.c
字号:
* Locate the appropriate entry for a given request */netsnmp_extend *_extend_find_entry( netsnmp_request_info *request, netsnmp_table_request_info *table_info, int mode ){ netsnmp_extend *eptr; extend_registration_block *ereg; int line_idx; oid oid_buf[MAX_OID_LEN]; int oid_len; int i; char *token; int token_len; if (!request || !table_info || !table_info->indexes || !table_info->indexes->next_variable) { DEBUGMSGTL(( "nsExtendTable:output2", "invalid invocation\n")); return NULL; } ereg = _find_extension_block( request->requestvb->name, request->requestvb->name_length ); /*** * GET handling - find the exact entry being requested ***/ if ( mode == MODE_GET ) { DEBUGMSGTL(( "nsExtendTable:output2", "GET: %s / %d\n ", table_info->indexes->val.string, *table_info->indexes->next_variable->val.integer)); for ( eptr = ereg->ehead; eptr; eptr = eptr->next ) { if ( !strcmp( eptr->token, table_info->indexes->val.string )) break; } if ( eptr ) { /* * Ensure the output is available... */ if (!(eptr->flags & NS_EXTEND_FLAGS_ACTIVE) || (netsnmp_cache_check_and_reload( eptr->cache ) < 0 )) return NULL; /* * ...and check the line requested is valid */ line_idx = *table_info->indexes->next_variable->val.integer; if (eptr->numlines < line_idx) return NULL; } return eptr; } /*** * GETNEXT handling - find the first suitable entry ***/ else { if (!table_info->indexes->val_len ) { DEBUGMSGTL(( "nsExtendTable:output2", "GETNEXT: first entry\n")); /* * Beginning of the table - find the first active * (and successful) entry, and use the first line of it */ for (eptr = ereg->ehead; eptr; eptr = eptr->next ) { if ((eptr->flags & NS_EXTEND_FLAGS_ACTIVE) && (netsnmp_cache_check_and_reload( eptr->cache ) >= 0 )) { line_idx = 1; break; } } } else { token = table_info->indexes->val.string; token_len = table_info->indexes->val_len; line_idx = *table_info->indexes->next_variable->val.integer; DEBUGMSGTL(( "nsExtendTable:output2", "GETNEXT: %s / %d\n ", token, line_idx )); /* * Otherwise, find the first entry not earlier * than the requested token... */ for (eptr = ereg->ehead; eptr; eptr = eptr->next ) { if ( strlen(eptr->token) > token_len ) break; if ( strlen(eptr->token) == token_len && strcmp(eptr->token, token) >= 0 ) break; } if (!eptr) return NULL; /* (assuming there is one) */ /* * ... and make sure it's active & the output is available * (or use the first following entry that is) */ for ( ; eptr; eptr = eptr->next ) { if ((eptr->flags & NS_EXTEND_FLAGS_ACTIVE) && (netsnmp_cache_check_and_reload( eptr->cache ) >= 0 )) { break; } line_idx = 1; } if (!eptr) return NULL; /* (assuming there is one) */ /* * If we're working with the same entry that was requested, * see whether we've reached the end of the output... */ if (!strcmp( eptr->token, token )) { if ( eptr->numlines <= line_idx ) { /* * ... and if so, move on to the first line * of the next (active and successful) entry. */ line_idx = 1; for (eptr = eptr->next ; eptr; eptr = eptr->next ) { if ((eptr->flags & NS_EXTEND_FLAGS_ACTIVE) && (netsnmp_cache_check_and_reload( eptr->cache ) >= 0 )) { break; } } } else { /* * Otherwise just use the next line of this entry. */ line_idx++; } } else { /* * If this is not the same entry that was requested, * then we should return the first line. */ line_idx = 1; } } if (eptr) { DEBUGMSGTL(( "nsExtendTable:output2", "GETNEXT -> %s / %d\n ", eptr->token, line_idx)); /* * Since we're processing a GETNEXT request, * now we've found the appropriate entry (and line), * we need to update the varbind OID ... */ memset(oid_buf, 0, sizeof(oid_buf)); oid_len = ereg->oid_len; memcpy( oid_buf, ereg->root_oid, oid_len*sizeof(oid)); oid_buf[ oid_len++ ] = 4; /* nsExtendOutput2Table */ oid_buf[ oid_len++ ] = 1; /* nsExtendOutput2Entry */ oid_buf[ oid_len++ ] = COLUMN_EXTOUT2_OUTLINE; /* string token index */ oid_buf[ oid_len++ ] = strlen(eptr->token); for ( i=0; i < (int)strlen(eptr->token); i++ ) oid_buf[ oid_len+i ] = eptr->token[i]; oid_len += strlen( eptr->token ); /* plus line number */ oid_buf[ oid_len++ ] = line_idx; snmp_set_var_objid( request->requestvb, oid_buf, oid_len ); /* * ... and index values to match. */ snmp_set_var_value( table_info->indexes, eptr->token, strlen(eptr->token)); snmp_set_var_value( table_info->indexes->next_variable, &line_idx, sizeof(line_idx)); } return eptr; /* Finally, signal success */ } return NULL;}/* * Multi-line output handler * Locate the appropriate entry (using _extend_find_entry) * and return the appropriate output line */inthandle_nsExtendOutput2Table(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests){ netsnmp_request_info *request; netsnmp_table_request_info *table_info; netsnmp_extend *extension; char *cp; int line_idx; int len; for ( request=requests; request; request=request->next ) { if (request->processed) continue; table_info = netsnmp_extract_table_info( request ); extension = _extend_find_entry( request, table_info, reqinfo->mode ); DEBUGMSGTL(( "nsExtendTable:output2", "varbind: ")); DEBUGMSGOID(("nsExtendTable:output2", request->requestvb->name, request->requestvb->name_length)); DEBUGMSG(( "nsExtendTable:output2", " (%s)\n", (extension) ? extension->token : "[none]")); if (!extension) { if (reqinfo->mode == MODE_GET) netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE); else netsnmp_set_request_error(reqinfo, request, SNMP_ENDOFMIBVIEW); continue; } switch (reqinfo->mode) { case MODE_GET: case MODE_GETNEXT: switch (table_info->colnum) { case COLUMN_EXTOUT2_OUTLINE: /* * Determine which line we've been asked for.... */ line_idx = *table_info->indexes->next_variable->val.integer; cp = extension->lines[line_idx-1]; /* * ... and how long it is. */ if ( extension->numlines > line_idx ) len = (extension->lines[line_idx])-cp -1; else if (cp) len = strlen(cp); else len = 0; snmp_set_var_typed_value( request->requestvb, ASN_OCTET_STR, cp, len ); break; default: netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); continue; } break; default: netsnmp_set_request_error(reqinfo, request, SNMP_ERR_GENERR); return SNMP_ERR_GENERR; } } return SNMP_ERR_NOERROR;}#ifndef USING_UCD_SNMP_EXTENSIBLE_MODULE /************************* * * Compatability with the UCD extTable * *************************/u_char *var_extensible_old(struct variable * vp, oid * name, size_t * length, int exact, size_t * var_len, WriteMethod ** write_method){ netsnmp_old_extend *exten = NULL; static long long_ret; int idx; if (header_simple_table (vp, name, length, exact, var_len, write_method, num_compatability_entries)) return (NULL); idx = name[*length-1] -1; exten = &compatability_entries[ idx ]; if (exten) { switch (vp->magic) { case MIBINDEX: long_ret = name[*length - 1]; return ((u_char *) (&long_ret)); case ERRORNAME: /* name defined in config file */ *var_len = strlen(exten->exec_entry->token); return ((u_char *) (exten->exec_entry->token)); case SHELLCOMMAND: *var_len = strlen(exten->exec_entry->command); return ((u_char *) (exten->exec_entry->command)); case ERRORFLAG: /* return code from the process */ netsnmp_cache_check_and_reload( exten->exec_entry->cache ); long_ret = exten->exec_entry->result; return ((u_char *) (&long_ret)); case ERRORMSG: /* first line of text returned from the process */ netsnmp_cache_check_and_reload( exten->exec_entry->cache ); if (exten->exec_entry->numlines > 1) { *var_len = (exten->exec_entry->lines[1])- (exten->exec_entry->output) -1; } else if (exten->exec_entry->output) { *var_len = strlen(exten->exec_entry->output); } else { *var_len = 0; } return ((u_char *) (exten->exec_entry->output)); case ERRORFIX: *write_method = fixExec2Error; long_return = 0; return ((u_char *) &long_return); case ERRORFIXCMD: if (exten->efix_entry) { *var_len = strlen(exten->efix_entry->command); return ((u_char *) exten->efix_entry->command); } else { *var_len = 0; return ((u_char *) &long_return); /* Just needs to be non-null! */ } } return NULL; } return NULL;}intfixExec2Error(int action, u_char * var_val, u_char var_val_type, size_t var_val_len, u_char * statP, oid * name, size_t name_len){ netsnmp_old_extend *exten = NULL; int idx; idx = name[name_len-1] -1; exten = &compatability_entries[ idx ]; switch (action) { case MODE_SET_RESERVE1: if (var_val_type != ASN_INTEGER) { snmp_log(LOG_ERR, "Wrong type != int\n"); return SNMP_ERR_WRONGTYPE; } idx = *((long *) var_val); if (idx != 1) { snmp_log(LOG_ERR, "Wrong value != 1\n"); return SNMP_ERR_WRONGVALUE; } if (!exten || !exten->efix_entry) { snmp_log(LOG_ERR, "No command to run\n"); return SNMP_ERR_GENERR; } return SNMP_ERR_NOERROR; case MODE_SET_COMMIT: netsnmp_cache_check_and_reload( exten->efix_entry->cache ); } return SNMP_ERR_NOERROR;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -