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

📄 slpd_predicate.c

📁 SLP协议在linux下的实现。此版本为1.2.1版。官方网站为www.openslp.org
💻 C
📖 第 1 页 / 共 4 页
字号:
/*          returned through end.                                           *//*--------------------------------------------------------------------------*/{    char *operator; /* Pointer to the operator substring. */    const char *cur; /* Current working character. */    const char *last_char; /* The last character in the working string. */    FilterResult err = FR_UNSET; /* The result of an evaluation. */    FilterResult stop_condition = FR_UNSET;    if(recursion_depth <= 0)    {        return FR_PARSE_ERROR;    }    recursion_depth--;    if(*start != BRACKET_OPEN)    {        return FR_PARSE_ERROR;    }    /***** Get the current expression. *****/    last_char = *end = find_bracket_end(start);    if(*end == 0)    {        return FR_PARSE_ERROR;    }    (*end)++; /* Move the end pointer past the closing bracket. */    /****      * Check for the three legal characters that can follow an expression,     * if the following character isn't one of those, the following character      * is trash.     ****/    if(!(**end == BRACKET_OPEN || **end == BRACKET_CLOSE || **end == '\0'))    {        return FR_PARSE_ERROR;    }    /***** check for boolean op. *****/    cur = start;    cur++;    switch(*cur)    {    case('&'): /***** And. *****/    case('|'): /***** Or. *****/        {            if(*cur == '&')            {                stop_condition = FR_EVAL_FALSE;            }            else if(*cur == '|')            {                stop_condition = FR_EVAL_TRUE;            }            cur++; /* Move past operator. */            /*** Ensure that we have at least one operator. ***/            if(*cur != BRACKET_OPEN || cur >= last_char)            {                return FR_PARSE_ERROR;            }            /*** Evaluate each operand. ***/            /* NOTE: Due to the condition on the above "if", we are guarenteed that the first iteration of the loop is valid. */            do             {                err = filter(cur, &cur, slp_attr, recursion_depth);                /*** Propagate errors. ***/                if(err != FR_EVAL_TRUE && err != FR_EVAL_FALSE)                {                    return err;                }                /*** Short circuit. ***/                if(err == stop_condition)                {                    return stop_condition;                }            } while(*cur == BRACKET_OPEN && cur < last_char);             /*** If we ever get here, it means we've evaluated every operand without short circuiting -- meaning that the operation failed. ***/            return(stop_condition == FR_EVAL_TRUE ? FR_EVAL_FALSE : FR_EVAL_TRUE);        }    case('!'): /***** Not. *****/        /**** Child. ****/        cur++;        err = filter(cur, &cur, slp_attr, recursion_depth);        /*** Return errors. ***/        if(err != FR_EVAL_TRUE && err != FR_EVAL_FALSE)        {            return err;        }        /*** Perform "not". ***/        return(err == FR_EVAL_TRUE ? FR_EVAL_FALSE : FR_EVAL_TRUE);    default: /***** Unknown operator. *****/        ;        /* We don't do anything here because this will catch the first character of every leaf predicate. */    }    /***** Check for leaf operator. *****/    if(IS_VALID_TAG_CHAR(*cur))    {        Operation op;        char *lhs, *rhs; /* The two operands. */        char *val_start; /* The character after the operator. ie, the start of the rhs. */        int lhs_len, rhs_len; /* Length of the lhs/rhs. */        SLPType type;        SLPError slp_err;        /**** Demux leaf op. ****/        /* Since all search operators contain a "=", we look for the equals          * sign, and then poke around on either side of that for the real          * value.          */        operator = (char *)memchr(cur, '=', last_char - cur);        if(operator == 0)        {            /**** No search operator. ****/            return FR_PARSE_ERROR;        }        /* The rhs always follows the operator. (This doesn't really make         sense for PRESENT ops, but ignore that). */        val_start = operator + 1;         /* Check for APPROX, GREATER, or LESS. Note that we shuffle the         operator pointer back to point at the start of the op. */        if(operator == cur)        {/* Check that we can poke back one char. */            return FR_PARSE_ERROR;        }        switch(*(operator - 1))        {        case('~'):            op = EQUAL; /* See Assumptions. */            operator--;            break;        case('>'):            op = GREATER;            operator--;            break;        case('<'):            op = LESS;            operator--;            break;        default: /* No prefix to the '='. */            /**** Check for PRESENT. ****/            if((operator == last_char - 2) && (*(operator+1) == '*'))            {                op = PRESENT;            }            /**** It's none of the above: therefore it's EQUAL. ****/            else            {                op = EQUAL;            }        }        /***** Get operands. *****/        /**** Left. ****/        lhs_len = operator - cur;        lhs = (char *)cur;        /**** Right ****/        rhs_len = last_char - val_start;        rhs = val_start;        /***** Do leaf operation. *****/        /**** Check that tag exists. ****/        slp_err = SLPAttrGetType_len(slp_attr, lhs, lhs_len, &type);        if(slp_err == SLP_TAG_ERROR)        { /* Tag  doesn't exist. */            return FR_EVAL_FALSE;        }        else if(slp_err == SLP_OK)        { /* Tag exists. */            /**** Do operation. *****/            if(op == PRESENT)            {                /*** Since the PRESENT operation is the same for all types,                 do that now. ***/                return FR_EVAL_TRUE;            }            else            {                /*** A type-specific operation. ***/                switch(type)                {                case(SLP_BOOLEAN):                    err = bool_op(slp_attr, lhs, lhs_len, rhs, rhs_len, op);                     break;                case(SLP_INTEGER):                    err = int_op(slp_attr, lhs, lhs_len, rhs, op);                     break;                case(SLP_KEYWORD):                    err = keyw_op(slp_attr, lhs, rhs, op);                     break;                case(SLP_STRING):                    err = str_op(slp_attr, lhs, lhs_len, rhs, rhs_len, op);                     break;                case(SLP_OPAQUE):                    assert(0); /* Opaque is not yet supported. */                }            }        }        else        { /* Some other tag-related error. */            err = FR_INTERNAL_SYSTEM_ERROR;        }        assert(err != FR_UNSET);        return err;    }    /***** No operator. *****/    return FR_PARSE_ERROR;}/*=========================================================================*/int SLPDPredicateTest(int version,                      int attrlistlen,                      const char* attrlist,                      int predicatelen,                      const char* predicate)/* Determine whether the specified attribute list satisfies                *//* the specified predicate                                                 *//*                                                                         *//* version    (IN) SLP version of the predicate string (should always be   *//*                 2 since we don't handle SLPv1 predicates yet)           *//*                                                                         *//* attrlistlen  (IN) length of attrlist                                    *//*                                                                         *//* attr         (IN) attribute list to test                                *//*                                                                         *//* predicatelen (IN) length of the predicate string                        *//*                                                                         *//* predicate    (IN) the predicate string                                  *//*                                                                         *//* Returns: Boolean value.  Zero of test fails.  Non-zero if test fails    *//*          or if there is a parse error in the predicate string           *//*=========================================================================*/{    SLPAttributes   attr;    const char      *end; /* Pointer to the end of the parsed attribute string. */    FilterResult    err;    char            attrnull;    char            prednull;    int             result = 0;    /* An NULL or empty string is always true. */    if(predicate == 0 || *(char *)predicate == 0)    {        return 1;    }    /* Attempt v1 too. */    if(version != 2 #if defined(ENABLE_SLPv1)               && version != 1#endif      )    {        return 1;    }    /* TRICKY: Temporarily NULL terminate the attribute list     */    /*         and the predicate string.  We can do this because */    /*         there is room in the corresponding SLPv2 SRVREG   */    /*         and SRVRQST messages.  Basically we are squashing */    /*         the authcount and the spi string length.  Don't   */    /*         worry, we fix things up later and it is MUCH      */    /*         faster than a malloc() for a new buffer 1 byte    */    /*         longer!                                           */    prednull = predicate[predicatelen];    ((char*)predicate)[predicatelen] = 0;    attrnull = attrlist[attrlistlen];    ((char*)attrlist)[attrlistlen] = 0;    /* Generate an SLPAttr from the comma delimited list */    if(SLPAttrAlloc("en", NULL, SLP_FALSE, &attr) == 0)    {        if(SLPAttrFreshen(attr, attrlist) == 0)        {            switch(version)            {#if defined(ENABLE_SLPv1)            case 1:                err=filterv1(predicate, &end, attr, SLPD_ATTR_RECURSION_DEPTH);                break;#endif            default:                err=filter(predicate, &end, attr, SLPD_ATTR_RECURSION_DEPTH);                break;            }            /* Check for trailing trash data. */            if((err == FR_EVAL_TRUE || err == FR_EVAL_FALSE) && *end != 0)            {                result = 0;            }            else if(err == FR_EVAL_TRUE)            {                result = 1;            }        }        SLPAttrFree(attr);    }    /* Un null terminate */    ((char*)predicate)[predicatelen] = prednull;    ((char*)attrlist)[attrlistlen] = attrnull;    return result;}/*=========================================================================*/int SLPDFilterAttributes(int attrlistlen,                         const char* attrlist,                         int taglistlen,                         const char* taglist,                         int* resultlen,                         char** result)/* Copies attributes from the specified attribute list to a result string  *//* according to the taglist as described by section 10.4. of RFC 2608      *//*                                                                         *//* version    (IN) SLP version of the predicate string (should always be   *//*                 2 since we don't handle SLPv1 predicates yet)           *//*                                                                         *//* attrlistlen  (IN) length of attrlist                                    *//*                                                                         *//* attr         (IN) attribute list to test                                *//*                                                                         *//* predicatelen (IN) length of the predicate string                        *//*                                                                         *//* predicate    (IN) the predicate string                                  *//*                                                                         *//* Returns: Zero on success.  Nonzero on failure                           *//*=========================================================================*/{    SLPAttributes   attr;    FilterResult    err;    char            attrnull;    char            tagnull;    *result = 0;    *resultlen = 0;    /* TRICKY: Temporarily NULL terminate the attribute list     */    /*         and the tag string.  We can do this because       */    /*         there is room in the corresponding SLPv2 SRVREG   */    /*         and ATTRRQST messages.  Basically we are squashing */    /*         the authcount and the spi string length.  Don't   */    /*         worry, we fix things up later and it is MUCH      */    /*         faster than a malloc() for a new buffer 1 byte    */    /*         longer!                                           */    tagnull = taglist[taglistlen];    ((char*)taglist)[taglistlen] = 0;    attrnull = attrlist[attrlistlen];    ((char*)attrlist)[attrlistlen] = 0;    /* Generate an SLPAttr from the comma delimited list */    err = 1;    if(SLPAttrAlloc("en", NULL, SLP_FALSE, &attr) == 0)    {        if(SLPAttrFreshen(attr, attrlist) == 0)        {            err = SLPAttrSerialize(attr,                                   taglist,                                   result,                                   *resultlen,                                   resultlen,                                   SLP_FALSE);        }        SLPAttrFree(attr);    }    /* SLPAttrSerialize counts the NULL terminator which we don't care about*/    if(*resultlen)    {        *resultlen -= 1;    }    /* Un null terminate */    ((char*)taglist)[taglistlen] = tagnull;    ((char*)attrlist)[attrlistlen] = attrnull;    return(*resultlen == 0);}

⌨️ 快捷键说明

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