/* Allocates a new thingy from a string. */ SLPError SLPAttrAllocStr( const char *lang, const FILE *template_h, const SLPBoolean strict, SLPAttributes *slp_attr_h, const char *str ) { SLPError err; char *mangle; /* A copy of the passed in string, since attr_destringify tends to chew data. */ err = SLPAttrAlloc(lang, template_h, strict, slp_attr_h); if (err != SLP_OK) { return err; } mangle = strdup(str); if (str == NULL) { SLPAttrFree(*slp_attr_h); return SLP_MEMORY_ALLOC_FAILED; } err = attr_destringify((struct xx_SLPAttributes*)*slp_attr_h, mangle, SLP_ADD); free(mangle); if (err != SLP_OK) { SLPAttrFree(*slp_attr_h); } return err; }
SLPBoolean attr_callback ( SLPHandle hslp, const char* attrlist, SLPError errcode, void* cookie ) { struct hop_attr *hop = (struct hop_attr *)cookie; SLPAttributes attr; SLPBoolean result; assert(errcode == SLP_OK || errcode == SLP_LAST_CALL); if (errcode == SLP_OK) { if (SLPAttrAlloc("en", NULL, SLP_FALSE, &attr) != SLP_OK) { /* FIXME Ummm, should prolly tell application about the internal * error. */ return SLP_FALSE; } destringify(attr, attrlist); result = hop->cb(hslp, attr, errcode, hop->cookie); assert(result == SLP_TRUE || result == SLP_FALSE); SLPAttrFree(attr); } else if (errcode == SLP_LAST_CALL) { result = hop->cb(hslp, NULL, errcode, hop->cookie); } else { result = hop->cb(hslp, NULL, errcode, hop->cookie); } return result; }
/*=========================================================================*/ void SLPDDatabaseEntryFree(SLPDDatabaseEntry* entry) /* Free all resource related to the specified entry */ /*=========================================================================*/ { if(entry) { if(entry->scopelist) free(entry->scopelist); if(entry->srvtype) free(entry->srvtype); if(entry->url) free(entry->url); if(entry->attrlist) free(entry->attrlist); if(entry->partiallist) free(entry->partiallist); #ifdef USE_PREDICATES if(entry->attr) SLPAttrFree(entry->attr); #endif free(entry); } }
void test_predicate() { char *str; int ierr; SLPAttributes slp_attr; SLPError err; /******************** Test int stuff. *********************/ err = SLPAttrAlloc("en", NULL, SLP_FALSE, &slp_attr); assert(err == SLP_OK); SLPAttrSet_int(slp_attr, "int", (int)23, SLP_ADD); SLPAttrSet_int(slp_attr, "int", (int)25, SLP_ADD); SLPAttrSet_int(slp_attr, "int", (int)27, SLP_ADD); /* Test equals. */ str = "(&(&(int=23)(int=25))(int=26))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* False. */ str = "(&(&(int=24)(int=25))(int=26))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* False. */ str = "(&(&(int=24)(int=28))(int=26))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* False. */ str = "(&(&(int=23)(int=25))(int=27))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* True. */ /* Test greater. */ str = "(int>=29)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f. */ str = "(int>=26)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* T. */ str = "(int>=24)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t. */ str = "(int>=22)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t. */ /* Test lesser. */ str = "(int<=22)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(int<=23)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ SLPAttrFree(slp_attr); /* Simple equality. */ err = SLPAttrAllocStr("en", NULL, SLP_FALSE, &slp_attr, "(a=1)"); assert(err == SLP_OK); str = "(a=1)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ SLPAttrFree(slp_attr); /******************** Test opaque stuff. *********************/ err = SLPAttrAlloc("en", NULL, SLP_FALSE, &slp_attr); assert(err == SLP_OK); err = SLPAttrSet_str(slp_attr, "op", "\\00\\12\\24\\36", SLP_REPLACE); assert(err == SLP_OK); /* Test less (single-valued). */ str = "(op<=\\00\\12\\10\\43)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(op<=\\00\\12\\24\\36)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(op<=\\00\\12\\24\\36\\12)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(op>=\\00\\12\\24\\36)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ SLPAttrFree(slp_attr); /******************** Test string stuff. *********************/ err = SLPAttrAlloc("en", NULL, SLP_FALSE, &slp_attr); assert(err == SLP_OK); err = SLPAttrSet_str(slp_attr, "str", "string", SLP_REPLACE); assert(err == SLP_OK); /* Test less (single-valued). */ str = "(str<=a)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(str<=string)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str<=strinx)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ /* Test greater (single-valued). */ str = "(str>=a)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str>=string)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str>=strinx)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ /* Test equal (single valued). */ str = "(str=a)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(str=*ing)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=stri*)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=*tri*)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=\\73*)"; /* s* */ ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=\\73\\74\\72\\69*)"; /* stri* */ ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=*\\73\\74\\72\\69*)"; /* *stri* */ ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=s*t*r*i*n*g)"; /* s*t*r*i* */ ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=s*t*r*i*ng)"; /* s*t*r*i* */ ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=\\73\\74\\72\\69ng)"; /* s*t*r*i* */ ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=s*tring)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(str=\\73*\\74ring)"; /* s*t*r*i* */ ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ /* TODO Test escaped '*'s. */ /* TODO Test multivalued. */ SLPAttrFree(slp_attr); /******************** Test boolean stuff. *********************/ err = SLPAttrAlloc("en", NULL, SLP_FALSE, &slp_attr); assert(err == SLP_OK); err = SLPAttrSet_bool(slp_attr, "bool", SLP_TRUE); assert(err == SLP_OK); /* Test equal. */ str = "(bool=true)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(bool=false)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ /* Test bad strings. */ str = "(bool=falsew)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(bool=*false)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(bool=truee)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(bool= true)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ SLPAttrFree(slp_attr); /******************** Test keyword stuff. *********************/ err = SLPAttrAlloc("en", NULL, SLP_FALSE, &slp_attr); assert(err == SLP_OK); err = SLPAttrSet_keyw(slp_attr, "keyw"); assert(err == SLP_OK); /* Test present. */ str = "(keyw=*)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(keyw=sd)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(keyw<=adf)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ SLPAttrFree(slp_attr); /********************* Test boolean operators. *********************/ err = SLPAttrAlloc("en", NULL, SLP_FALSE, &slp_attr); assert(err == SLP_OK); err = SLPAttrSet_keyw(slp_attr, "keyw"); assert(err == SLP_OK); str = "(keyw=*)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ /* Test not. */ str = "(!(keyw=*))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(!(!(keyw=*)))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(!(!(!(keyw=*))))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(!(!(!(!(keyw=*)))))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ /* Build up to testing binary ops. */ err = SLPAttrSet_bool(slp_attr, "bool", SLP_TRUE); assert(err == SLP_OK); /* Test and. */ str = "(&(keyw=*)(bool=true))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(&(keyw=*)(bool=false))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(&(keyw=*)(!(bool=false)))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(&(keywx=*)(bool=true))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(&(!(keywx=*))(bool=true))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(&(lkeyw=*)(bool=false))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(&(!(lkeyw=*))(!(bool=false)))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(&(&(keyw=*)(bool=true))(&(keyw=*)(bool=true)))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ str = "(&(&(!(keyw=*))(bool=true))(&(keyw=*)(bool=true)))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(!(&(&(!(keyw=*))(bool=true))(&(keyw=*)(bool=true))))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr == 0); /* t */ /* Test sytax errors. */ /* No preceeding bracket. */ str = "asdf=log"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* No trailing bracket. */ str = "(asdf=log"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Unbalanced brackets. */ str = "(asdf=log))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); str = "((asdf=log)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Missing operators. */ str = "(asdflog)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Check that the leaf operator isn't causing the problem. */ str = "(asdflog=q)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* Missing logical unary. */ str = "((asdflog=q))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Missing logical binary. */ str = "((asdflog=q)(asdflog=q))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Missing operands and operator. */ str = "()"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Missing unary operands. */ str = "(!)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Missing binary operands. */ str = "(&)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Missing binary operands. */ str = "(=)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); /* Missing binary operands. I _guess_ this is legal... */ str = "(thingy=)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > -1); /* Trailing trash. */ str = "(&(a=b)(c=d))"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > -1); /* Check that the following test will not be short circuited. */ str = "(a=b)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr > 0); /* f */ str = "(|(a=b)(c=d)w)"; ierr = SLPDPredicateTest( str, slp_attr); assert(ierr < 0); SLPAttrFree(slp_attr); /* Check multiple (more than two) subexpressions. */ err = SLPAttrAlloc("en", NULL, SLP_FALSE, &slp_attr); assert(err == SLP_OK); err = SLPAttrSet_int(slp_attr, "x", 1, SLP_ADD); assert(err == SLP_OK); str = "(&(x=1)(!(x=1)))"; ierr = SLPDPredicateTest((SLPDPredicate)str, slp_attr); assert(ierr > 0); /* f */ str = "(&(x=1))"; ierr = SLPDPredicateTest((SLPDPredicate)str, slp_attr); assert(ierr == 0); /* t */ str = "(&(x=1)(x=1)(x=1))"; ierr = SLPDPredicateTest((SLPDPredicate)str, slp_attr); assert(ierr == 0); /* t */ SLPAttrFree(slp_attr); }
/*=========================================================================*/ 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*/ *resultlen -=1; /* Un null terminate */ ((char*)taglist)[taglistlen] = tagnull; ((char*)attrlist)[attrlistlen] = attrnull; return (*resultlen == 0); }
/*=========================================================================*/ 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; } /* We don't handle SLPv1 predicates yet. We'll say they all match */ if(version != 2) { 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) { err = filter(predicate, &end, attr, SLPD_ATTR_RECURSION_DEPTH); /* 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; }