⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expvalue.c

📁 开发snmp的开发包有两个开放的SNMP开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * DisMan Expression MIB: *    Core implementation of expression evaluation */#include <net-snmp/net-snmp-config.h>#include <net-snmp/net-snmp-includes.h>#include <net-snmp/agent/net-snmp-agent-includes.h>#include "disman/expr/expExpression.h"#include "disman/expr/expObject.h"#include "disman/expr/expValue.h"#include <ctype.h>void _expValue_setError( struct expExpression *exp, int reason,                         oid *suffix, size_t suffix_len,                         netsnmp_variable_list *var);#define ASN_PRIV_OPERATOR    (ASN_PRIVATE | 0x0f)#define ASN_PRIV_FUNCTION    (ASN_PRIVATE | 0x0e)int ops[128];   /* mapping from operator characters to numeric                   tokens (ordered by priority). */init_expValue(void){DEBUGMSGTL(("disman:expr:eval", "Init expValue"));        /* Single-character operators */    ops['+'] = EXP_OPERATOR_ADD;    ops['-'] = EXP_OPERATOR_SUBTRACT;    ops['*'] = EXP_OPERATOR_MULTIPLY;    ops['/'] = EXP_OPERATOR_DIVIDE;    ops['%'] = EXP_OPERATOR_REMAINDER;    ops['^'] = EXP_OPERATOR_BITXOR;    ops['~'] = EXP_OPERATOR_BITNEGATE;    ops['|'] = EXP_OPERATOR_BITOR;    ops['&'] = EXP_OPERATOR_BITAND;    ops['!'] = EXP_OPERATOR_NOT;    ops['<'] = EXP_OPERATOR_LESS;    ops['>'] = EXP_OPERATOR_GREAT;                                         /*                                          * Arbitrary offsets, chosen so                                          * the three blocks don't overlap.                                          */        /* "X=" operators */    ops['='+20] = EXP_OPERATOR_EQUAL;    ops['!'+20] = EXP_OPERATOR_NOTEQ;    ops['<'+20] = EXP_OPERATOR_LESSEQ;    ops['>'+20] = EXP_OPERATOR_GREATEQ;        /* "XX" operators */    ops['|'-30] = EXP_OPERATOR_OR;    ops['&'-30] = EXP_OPERATOR_AND;    ops['<'-30] = EXP_OPERATOR_LSHIFT;    ops['>'-30] = EXP_OPERATOR_RSHIFT;}    /*     * Insert the value of the specified object parameter,     * using the instance 'suffix' for wildcarded objects.     */netsnmp_variable_list *_expValue_evalParam( netsnmp_variable_list *expIdx, int param,                     oid *suffix, size_t suffix_len ){    netsnmp_variable_list *var = SNMP_MALLOC_TYPEDEF( netsnmp_variable_list );    struct expObject  *obj;    netsnmp_variable_list *val_var  = NULL, *oval_var = NULL;  /* values  */    netsnmp_variable_list *dd_var   = NULL,  *odd_var = NULL;  /* deltaDs */    netsnmp_variable_list *cond_var = NULL;               /* conditionals */    int n;    /*     * Retrieve the expObject entry for the requested parameter.     */    if ( !var || !expIdx || !expIdx->next_variable ||                 !expIdx->next_variable->next_variable )        return NULL;    *expIdx->next_variable->next_variable->val.integer = param;    obj = (struct expObject *)               netsnmp_tdata_row_entry(                   netsnmp_tdata_row_get_byidx( expObject_table_data, expIdx ));    if (!obj) {        /*         * No such parameter configured for this expression         */        snmp_set_var_typed_integer( var, ASN_INTEGER, EXPERRCODE_INDEX );        var->type = ASN_NULL;        return var;    }    if ( obj->expObjectSampleType != EXPSAMPLETYPE_ABSOLUTE &&         obj->old_vars == NULL ) {        /*         * Can't calculate delta values until the second pass         */        snmp_set_var_typed_integer( var, ASN_INTEGER, EXPERRCODE_RESOURCE );        var->type = ASN_NULL;        return var;    }    /*     * For a wildcarded object, search for the matching suffix.     */    val_var = obj->vars;    if ( obj->flags & EXP_OBJ_FLAG_OWILD ) {        if ( !suffix ) {            /*             * If there's no suffix to match against, throw an error.             * An exact expression with a wildcarded object is invalid.             *   XXX - Or just use first entry?             */            snmp_set_var_typed_integer( var, ASN_INTEGER, EXPERRCODE_INDEX );            var->type = ASN_NULL;            return var;        }        /*         * Otherwise, we'll walk *all* wildcarded values in parallel.         * This relies on the various varbind lists being set up with         *   exactly the same entries.  A little extra preparation         *   during the data gathering simplifies things significantly!         */        if ( obj->expObjectSampleType != EXPSAMPLETYPE_ABSOLUTE )            oval_var = obj->old_vars;        if ( obj->flags & EXP_OBJ_FLAG_DWILD ) {            dd_var   = obj->dvars;            odd_var  = obj->old_dvars;        }        if ( obj->flags & EXP_OBJ_FLAG_CWILD )            cond_var = obj->cvars;               n = obj->expObjectID_len;        while ( val_var ) {            if ( snmp_oid_compare( val_var->name+n, val_var->name_length-n,                                   suffix, suffix_len ))                break;            val_var = val_var->next_variable;            if (oval_var)                oval_var = oval_var->next_variable;            if (dd_var) {                dd_var   =  dd_var->next_variable;                odd_var  = odd_var->next_variable;            }            if (cond_var)                cond_var = cond_var->next_variable;        }    }    if (!val_var) {        /*         * No matching entry         */        snmp_set_var_typed_integer( var, ASN_INTEGER, EXPERRCODE_INDEX );        var->type = ASN_NULL;        return var;    }        /*         * Set up any non-wildcarded values - some         *   of which may be null. That's fine.         */    if (!oval_var)        oval_var = obj->old_vars;    if (!dd_var) {        dd_var   = obj->dvars;        odd_var  = obj->old_dvars;    }    if (!cond_var)        cond_var = obj->cvars;        /*     * ... and return the appropriate value.     */    if (obj->expObjCond_len &&        (!cond_var || *cond_var->val.integer == 0)) {        /*         * expObjectConditional says no         */        snmp_set_var_typed_integer( var, ASN_INTEGER, EXPERRCODE_INDEX );        var->type = ASN_NULL;        return var;    }    if (dd_var && odd_var &&        *dd_var->val.integer != *odd_var->val.integer) {        /*         * expObjectDeltaD says no         */        snmp_set_var_typed_integer( var, ASN_INTEGER, EXPERRCODE_INDEX );        var->type = ASN_NULL;        return var;    }    /*     * XXX - May need to check sysUpTime discontinuities     *            (unless this is handled earlier....)     */    switch ( obj->expObjectSampleType ) {    case EXPSAMPLETYPE_ABSOLUTE:        snmp_clone_var( val_var, var );        break;    case EXPSAMPLETYPE_DELTA:        snmp_set_var_typed_integer( var, ASN_INTEGER /* or UNSIGNED? */,                              *val_var->val.integer - *oval_var->val.integer );        break;    case EXPSAMPLETYPE_CHANGED:        if ( val_var->val_len != oval_var->val_len )            n = 1;        else if (memcmp( val_var->val.string, oval_var->val.string,                                               val_var->val_len ) != 0 )            n = 1;        else            n = 0;        snmp_set_var_typed_integer( var, ASN_UNSIGNED, n );    }    return var;}    /*     * Utility routine to parse (and skip over) an integer constant     */int_expParse_integer( char *start, char **end ) {    int n;    char *cp;    n = atoi(start);    for (cp=start; *cp; cp++)        if (!isdigit(*cp))            break;    *end = cp;    return n;}netsnmp_variable_list *_expValue_evalOperator(netsnmp_variable_list *left,                        netsnmp_variable_list *op,                        netsnmp_variable_list *right) {    int n;    switch( *op->val.integer ) {    case EXP_OPERATOR_ADD:        n = *left->val.integer + *right->val.integer; break;    case EXP_OPERATOR_SUBTRACT:        n = *left->val.integer - *right->val.integer; break;    case EXP_OPERATOR_MULTIPLY:        n = *left->val.integer * *right->val.integer; break;    case EXP_OPERATOR_DIVIDE:        n = *left->val.integer / *right->val.integer; break;    case EXP_OPERATOR_REMAINDER:        n = *left->val.integer % *right->val.integer; break;    case EXP_OPERATOR_BITXOR:        n = *left->val.integer ^ *right->val.integer; break;    case EXP_OPERATOR_BITNEGATE:        n = 99; /* *left->val.integer ~ *right->val.integer; */ break;    case EXP_OPERATOR_BITOR:        n = *left->val.integer | *right->val.integer; break;    case EXP_OPERATOR_BITAND:        n = *left->val.integer & *right->val.integer; break;    case EXP_OPERATOR_NOT:        n = 99; /* *left->val.integer ! *right->val.integer; */ break;    case EXP_OPERATOR_LESS:        n = *left->val.integer < *right->val.integer; break;    case EXP_OPERATOR_GREAT:        n = *left->val.integer > *right->val.integer; break;    case EXP_OPERATOR_EQUAL:        n = *left->val.integer == *right->val.integer; break;    case EXP_OPERATOR_NOTEQ:        n = *left->val.integer != *right->val.integer; break;    case EXP_OPERATOR_LESSEQ:        n = *left->val.integer <= *right->val.integer; break;    case EXP_OPERATOR_GREATEQ:        n = *left->val.integer >= *right->val.integer; break;    case EXP_OPERATOR_OR:        n = *left->val.integer || *right->val.integer; break;    case EXP_OPERATOR_AND:        n = *left->val.integer && *right->val.integer; break;    case EXP_OPERATOR_LSHIFT:        n = *left->val.integer << *right->val.integer; break;    case EXP_OPERATOR_RSHIFT:        n = *left->val.integer >> *right->val.integer; break;        break;    default:        left->next_variable = NULL;        snmp_free_var(left);        right->next_variable = NULL;        snmp_free_var(right);        snmp_set_var_typed_integer( op, ASN_INTEGER, EXPERRCODE_OPERATOR );        op->type = ASN_NULL;        return op;    }    /* XXX */    left->next_variable = NULL;    snmp_free_var(left);    op->next_variable = NULL;    snmp_free_var(op);    snmp_set_var_typed_integer( right, ASN_INTEGER, n );    return right;}netsnmp_variable_list *_expValue_evalFunction(netsnmp_variable_list *func) {    netsnmp_variable_list *params = func->next_variable;    /* XXX */    params->next_variable = NULL;    snmp_free_var(params);    snmp_set_var_typed_integer( func, ASN_INTEGER, 99 );    return func;}netsnmp_variable_list *_expValue_evalExpr2(netsnmp_variable_list *exprAlDente);netsnmp_variable_list *_expValue_evalExpr(  netsnmp_variable_list *expIdx,                     char *exprRaw, char **exprEnd,                     oid *suffix, size_t suffix_len ){    netsnmp_variable_list *exprAlDente = NULL;    netsnmp_variable_list *vtail = NULL;    char *cp1, *cp2, *cp3;    netsnmp_variable_list *var = NULL;    int   i, n, level;    int   neg = 0;    oid   oid_buf[MAX_OID_LEN];    DEBUGMSGTL(("disman:expr:eval1", "Evaluating '%s'\n", exprRaw));    if (!expIdx || !exprRaw)        return NULL;    /*     * The expression is evaluated in two stages.     * First, we simplify ("parboil") the raw expression,     *   tokenizing it into a sequence of varbind values, inserting     *   object parameters, and (recursively) evaluating any     *   parenthesised sub-expressions or function arguments.     */    for (cp1=exprRaw; cp1 && *cp1; ) {        switch (*cp1) {        case '$':            /*             * Locate the appropriate instance of the specified             * parameter, and insert the corresponding value.             */            n   = _expParse_integer( cp1+1, &cp1 );            var = _expValue_evalParam( expIdx, n, suffix, suffix_len );            if ( var && var->type == ASN_NULL ) {                DEBUGMSGTL(("disman:expr:eval", "Invalid parameter '%d'\n", n));                /* Note position of failure in expression */                var->data = (void *)(cp1 - exprRaw);                snmp_free_var(exprAlDente);                return var;            } else {                if (vtail)                   vtail->next_variable = var;                else                   exprAlDente = var;                vtail = var;                var   = NULL;            }            break;        case '(':            /*             * Recursively evaluate the sub-expression             */            var = _expValue_evalExpr( expIdx, cp1+1, &cp2,                                      suffix, suffix_len );            if ( var && var->type == ASN_NULL ) {                /* Adjust position of failure */                var->data = (void *)(cp1 - exprRaw + (int)var->data);                return var;            } else if (*cp2 != ')') {                snmp_free_var(exprAlDente);                DEBUGMSGTL(("disman:expr:eval", "Unbalanced parenthesis\n"));                snmp_set_var_typed_integer( var, ASN_INTEGER,                                            EXPERRCODE_PARENTHESIS );                var->type = ASN_NULL;                var->data = (void *)(cp2 - exprRaw);                return var;            } else {                if (vtail)                   vtail->next_variable = var;                else                   exprAlDente = var;                vtail = var;                var   = NULL;                cp1   = cp2+1;   /* Skip to end of sub-expression */            }            break;        case ')':        case ',':            /*             * End of current (sub-)expression             * Note the end-position, and evaluate             *  the parboiled list of tokens.             */            *exprEnd = cp1;            var = _expValue_evalExpr2( exprAlDente );            snmp_free_var(exprAlDente);            return var;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -