/*=========================================================================*/ 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 SLPDDatabaseReg(SLPSrvReg* srvreg, unsigned int regtype) /* Add a service registration to the database */ /* */ /* srvreg - (IN) pointer to the SLPSrvReg to be added to the database */ /* */ /* regtype - (IN) registration types or'ed together: */ /* SLPDDATABASE_REG_FRESH */ /* SLPDDATABASE_REG_LOCAL */ /* SLPDDATABASE_REG_STATIC */ /* */ /* Returns - Zero on success. > 0 if something is wrong with srvreg */ /* < 0 if out of memory */ /* */ /* NOTE: All registrations are treated as fresh regardless of the */ /* setting of the fresh parameter */ /*=========================================================================*/ { int result = -1; SLPDDatabaseEntry* entry = (SLPDDatabaseEntry*)G_DatabaseList.head; /* Check to see if there is already an identical entry */ while(entry) { if(SLPCompareString(entry->urllen, entry->url, srvreg->urlentry.urllen, srvreg->urlentry.url) == 0) { if(SLPIntersectStringList(entry->scopelistlen, entry->scopelist, srvreg->scopelistlen, srvreg->scopelist) > 0) { SLPListUnlink(&G_DatabaseList,(SLPListItem*)entry); break; } } entry = (SLPDDatabaseEntry*) entry->listitem.next; } /* if no identical entry are found, create a new one */ if(entry == 0) { entry = SLPDDatabaseEntryAlloc(); if(entry == 0) { /* Out of memory */ goto FAILURE; } } /*----------------------------------------------------------------*/ /* copy info from the message from the wire to the database entry */ /*----------------------------------------------------------------*/ /* scope */ if(entry->scopelistlen >= srvreg->scopelistlen) { memcpy(entry->scopelist,srvreg->scopelist,srvreg->scopelistlen); } else { if(entry->scopelist) free(entry->scopelist); entry->scopelist = (char*)memdup(srvreg->scopelist,srvreg->scopelistlen); if(entry->scopelist == 0) goto FAILURE; } entry->scopelistlen = srvreg->scopelistlen; /* URL */ if(entry->urllen >= srvreg->urlentry.urllen) { memcpy(entry->url,srvreg->urlentry.url,srvreg->urlentry.urllen); } else { if(entry->url) free(entry->url); entry->url = (char*)memdup(srvreg->urlentry.url,srvreg->urlentry.urllen); if(entry->url == 0) goto FAILURE; } entry->urllen = srvreg->urlentry.urllen; /* lifetime */ entry->lifetime = srvreg->urlentry.lifetime; /* is local */ entry->regtype = regtype; /* SrvType */ if(entry->srvtypelen >= srvreg->srvtypelen) { memcpy(entry->srvtype,srvreg->srvtype,srvreg->srvtypelen); } else { if(entry->srvtype) free(entry->srvtype); entry->srvtype = (char*)memdup(srvreg->srvtype,srvreg->srvtypelen); if(entry->srvtype == 0) goto FAILURE; } entry->srvtypelen = srvreg->srvtypelen; /* Attributes */ if(srvreg->attrlistlen) { #ifdef USE_PREDICATES /* Tricky: perform an in place null termination of the attrlist */ /* Remember this squishes the authblock count */ ((char*)srvreg->attrlist)[srvreg->attrlistlen] = 0; if(SLPAttrFreshen(entry->attr, srvreg->attrlist) != SLP_OK) { result = 1; goto FAILURE; } /* Serialize all attributes into entry->attrlist */ if(entry->attrlist) { free(entry->attrlist); entry->attrlist = 0; entry->attrlistlen = 0; } if(SLPAttrSerialize(entry->attr, "", &entry->attrlist, entry->attrlistlen, &entry->attrlistlen, SLP_FALSE)) { goto FAILURE; } #else if(entry->attrlistlen >= srvreg->attrlistlen) { memcpy(entry->attrlist,srvreg->attrlist,srvreg->attrlistlen); } else { if(entry->attrlist) free(entry->attrlist); entry->attrlist = memdup(srvreg->attrlist,srvreg->attrlistlen); if(entry->attrlist == 0) goto FAILURE; } entry->attrlistlen = srvreg->attrlistlen; #endif } /* link the new (or modified) entry into the list */ SLPListLinkHead(&G_DatabaseList,(SLPListItem*)entry); /* traceReg if necessary */ SLPDLogTraceReg("Registered", entry); return 0; FAILURE: if(entry) { SLPDDatabaseEntryFree(entry); } return result; }
/*=========================================================================*/ 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; }