📄 expvalue.c
字号:
/* === Constants === */ case '.': /* OID */ i = 0; memset( oid_buf, 0, sizeof(oid_buf)); while ( cp1 && *cp1 == '.' ) { n = _expParse_integer( cp1+1, &cp2 );OID: oid_buf[i++] = n; cp1 = cp2; } var = snmp_varlist_add_variable( &exprAlDente, NULL, 0, ASN_OBJECT_ID, (u_char*)oid_buf, i*sizeof(oid)); break;DIGIT: case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = _expParse_integer( cp1, &cp2 ); if ( cp2 && *cp2 == '.' ) { i = 0; memset( oid_buf, 0, sizeof(oid_buf)); goto OID; } if ( neg ) n = -n; var = snmp_varlist_add_variable( &exprAlDente, NULL, 0, ASN_INTEGER, (u_char*)&n, sizeof(n)); vtail = var; var = NULL; neg = 0; cp1 = cp2; break; case '"': /* String Constant */ for ( cp2 = cp1+1; *cp2; cp2++ ) { if ( *cp2 == '"' ) break; if ( *cp2 == '\\' && *(cp2+1) == '"' ) cp2++; } if ( *cp2 != '"' ) { /* * Unterminated string */ DEBUGMSGTL(("disman:expr:eval", "Unterminated string\n")); snmp_set_var_typed_integer( var, ASN_INTEGER, EXPERRCODE_SYNTAX ); var->type = ASN_NULL; var->data = (void *)(cp2 - exprRaw); return var; } n = cp2 - cp1; var = snmp_varlist_add_variable( &exprAlDente, NULL, 0, ASN_OCTET_STR, (u_char*)cp1+1, n); vtail = var; var = NULL; break; /* === Operators === */ case '-': /* * Could be a unary minus.... */ if (!vtail || vtail->type == ASN_PRIV_OPERATOR) { neg = 1; goto DIGIT; } /* * ... or a (single-character) binary operator. */ /* Fallthrough */ case '+': case '*': case '/': case '%': case '^': case '~': if ( !vtail ) { /* * Can't start an expression with a binary operator */ DEBUGMSGTL(("disman:expr:eval", "Initial binary operator\n")); snmp_set_var_typed_integer( var, ASN_INTEGER, EXPERRCODE_SYNTAX ); var->type = ASN_NULL; var->data = (void *)(cp1 - exprRaw); return var; } n = ops[ *cp1 ]; DEBUGMSGTL(("disman:expr:eval", "Binary operator %c (%d)\n", *cp1, n)); var = snmp_varlist_add_variable( &exprAlDente, NULL, 0, ASN_INTEGER, (u_char*)&n, sizeof(n)); var->type = ASN_PRIV_OPERATOR; vtail = var; cp1++; break; /* * Multi-character binary operators */ case '&': case '|': case '!': case '>': case '<': case '=': if ( !vtail ) { /* * Can't start an expression with a binary operator */ DEBUGMSGTL(("disman:expr:eval", "Initial binary operator\n")); snmp_set_var_typed_integer( var, ASN_INTEGER, EXPERRCODE_SYNTAX ); var->type = ASN_NULL; var->data = (void *)(cp1 - exprRaw); return var; } if ( *(cp1+1) == '=' ) n = ops[ *cp1++ + 20]; else if ( *(cp1+1) == *cp1 ) n = ops[ *cp1++ - 30]; else n = ops[ *cp1 ]; var = snmp_varlist_add_variable( &exprAlDente, NULL, 0, ASN_INTEGER, (u_char*)&n, sizeof(n)); var->type = ASN_PRIV_OPERATOR; vtail = var; cp1++; break; /* === Functions === */ case 'a': /* average/arraySection */ case 'c': /* counter32/counter64 */ case 'e': /* exists */ case 'm': /* maximum/minimum */ case 'o': /* oidBegins/Ends/Contains */ case 's': /* sum / string{B,E,C} */ var = snmp_varlist_add_variable( &exprAlDente, NULL, 0, ASN_OCTET_STR, (u_char*)cp1, 3 ); /* XXX */ var->type = ASN_PRIV_FUNCTION; vtail = var; while (*cp1 >= 'a' && *cp1 <= 'z') cp1++; break; default: if (isalpha( *cp1 )) { /* * Unrecognised function call ? */ DEBUGMSGTL(("disman:expr:eval", "Unrecognised function '%s'\n", cp1)); snmp_set_var_typed_integer( var, ASN_INTEGER, EXPERRCODE_FUNCTION ); var->type = ASN_NULL; var->data = (void *)(cp1 - exprRaw); return var; } else if (!isspace( *cp1 )) { /* * Unrecognised operator ? */ DEBUGMSGTL(("disman:expr:eval", "Unrecognised operator '%c'\n", *cp1)); snmp_set_var_typed_integer( var, ASN_INTEGER, EXPERRCODE_OPERATOR ); var->type = ASN_NULL; var->data = (void *)(cp1 - exprRaw); return var; } cp1++; break; } } /* * ... then we evaluate the resulting simplified ("al dente") * expression, in the usual manner. */ *exprEnd = cp1; var = _expValue_evalExpr2( exprAlDente ); DEBUGMSGTL(( "disman:expr:eval1", "Evaluated to ")); DEBUGMSGVAR(("disman:expr:eval1", var)); DEBUGMSG(( "disman:expr:eval1", "\n"));/* snmp_free_var(exprAlDente); XXX - Crashes */ return var;}netsnmp_variable_list *_expValue_evalExpr2( netsnmp_variable_list *exprAlD ){ netsnmp_variable_list *stack = NULL; netsnmp_variable_list *lval, *rval, *op; netsnmp_variable_list *vp, *vp1 = NULL; DEBUGIF(( "disman:expr:eval2")) { for (vp = exprAlD; vp; vp=vp->next_variable) { if ( vp->type == ASN_PRIV_OPERATOR ) DEBUGMSGTL(( "disman:expr:eval2", "Operator %d\n", *vp->val.integer)); else if ( vp->type == ASN_PRIV_FUNCTION ) DEBUGMSGTL(( "disman:expr:eval2", "Function %s\n", vp->val.string)); else { DEBUGMSGTL(( "disman:expr:eval2", "Operand ")); DEBUGMSGVAR(("disman:expr:eval2", vp)); DEBUGMSG(( "disman:expr:eval2", "\n")); } } } for (vp = exprAlD; vp; vp=vp1) { vp1 = vp->next_variable; if ( vp->type == ASN_PRIV_OPERATOR ) { /* Must *always* follow a value */ if ( !stack || stack->type == ASN_PRIV_OPERATOR ) { snmp_set_var_typed_integer( vp, ASN_INTEGER, EXPERRCODE_SYNTAX ); vp->type = ASN_NULL; snmp_free_var( stack ); return vp; } /* * Evaluate any higher priority operators * already on the stack.... */ while ( stack->next_variable && stack->next_variable->type == ASN_PRIV_OPERATOR && (*stack->next_variable->val.integer > *vp->val.integer)) { rval = stack; op = stack->next_variable; lval = op->next_variable; stack = lval->next_variable; rval = _expValue_evalOperator( lval, op, rval ); rval->next_variable = stack; stack = rval; } /* * ... and then push this operator onto the stack. */ vp->next_variable = stack; stack = vp; } else if ( vp->type == ASN_PRIV_FUNCTION ) { /* Must be first, or follow an operator */ if ( stack && stack->type != ASN_PRIV_OPERATOR ) { snmp_set_var_typed_integer( vp, ASN_INTEGER, EXPERRCODE_SYNTAX ); vp->type = ASN_NULL; snmp_free_var( stack ); return vp; } /* * Evaluate this function (consuming the * appropriate parameters from the token * list), and push the result onto the stack. */ vp = _expValue_evalFunction( vp ); vp1 = vp->next_variable; vp->next_variable = stack; stack = vp; } else { /* Must be first, or follow an operator */ if ( stack && stack->type != ASN_PRIV_OPERATOR ) { snmp_set_var_typed_integer( vp, ASN_INTEGER, EXPERRCODE_SYNTAX ); vp->type = ASN_NULL; snmp_free_var( stack ); return vp; } /* * Push this value onto the stack */ vp->next_variable = stack; stack = vp; } } /* * Now evaluate whatever's left on the stack * and return the final result. */ while ( stack && stack->next_variable ) { rval = stack; op = stack->next_variable; lval = op->next_variable; stack = lval->next_variable; rval = _expValue_evalOperator( lval, op, rval ); rval->next_variable = stack; stack = rval; } return stack;}/* ============= * Main API * ============= */netsnmp_variable_list *expValue_evaluateExpression( struct expExpression *exp, oid *suffix, size_t suffix_len ){ char exprRaw[ EXP_STR3_LEN+1 ]; netsnmp_variable_list *var; netsnmp_variable_list owner_var, name_var, param_var; long n; char *cp; if (!exp) return NULL; /* * Set up a varbind list containing the various index values * (including a placeholder for expObjectIndex). * * This saves having to construct the same index list repeatedly */ memset(&owner_var, 0, sizeof(netsnmp_variable_list)); memset(&name_var, 0, sizeof(netsnmp_variable_list)); memset(¶m_var, 0, sizeof(netsnmp_variable_list)); snmp_set_var_typed_value( &owner_var, ASN_OCTET_STR, (u_char*)exp->expOwner, strlen(exp->expOwner)); snmp_set_var_typed_value( &name_var, ASN_OCTET_STR, (u_char*)exp->expName, strlen(exp->expName)); n = 99; /* dummy value */ snmp_set_var_typed_value( ¶m_var, ASN_INTEGER, (u_char*)&n, sizeof(long)); owner_var.next_variable = &name_var; name_var.next_variable = ¶m_var; /* * Make a working copy of the expression, and evaluate it. */ memset(exprRaw, 0, sizeof(exprRaw)); memcpy(exprRaw, exp->expExpression, sizeof(exprRaw)); var = _expValue_evalExpr( &owner_var, exprRaw, &cp, suffix, suffix_len ); /* * Check for any problems, and record the appropriate error */ if (!cp || *cp != '\0') { /* * When we had finished, there was a lot * of bricks^Wcharacters left over.... */ _expValue_setError( exp, EXPERRCODE_SYNTAX, suffix, suffix_len, NULL ); return NULL; } if (!var) { /* Shouldn't happen */ _expValue_setError( exp, EXPERRCODE_RESOURCE, suffix, suffix_len, NULL ); return NULL; } if (var->type == ASN_NULL) { /* * Error explicitly reported from the evaluation routines. */ _expValue_setError( exp, *(var->val.integer), suffix, suffix_len, var ); return NULL; } if (0 /* COMPARE var->type WITH exp->expValueType */ ) { /* * XXX - Check to see whether the returned type (ASN_XXX) * is compatible with the requested type (an enum) */ /* If not, throw an error */ _expValue_setError( exp, EXPERRCODE_TYPE, suffix, suffix_len, var ); return NULL; } return var;}void_expValue_setError( struct expExpression *exp, int reason, oid *suffix, size_t suffix_len, netsnmp_variable_list *var){ if (!exp) return; exp->expErrorCount++; /* exp->expErrorTime = NOW; */ exp->expErrorIndex = ( var && var->data ? (int)var->data : 0 ); exp->expErrorCode = reason; memset( exp->expErrorInstance, 0, sizeof(exp->expErrorInstance)); memcpy( exp->expErrorInstance, suffix, suffix_len * sizeof(oid)); exp->expErrorInst_len = suffix_len; snmp_free_var( var );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -