/*=========================================================================*/ 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 SLPDDatabaseFindAttr(SLPAttrRqst* attrrqst, SLPDDatabaseAttr* result) /* Find attributes */ /* */ /* srvtyperqst (IN) the request to find. */ /* */ /* result (OUT) pointer to a result structure that receives */ /* results */ /* */ /* Returns - 1 on success, zero if not found, negative on error */ /*=========================================================================*/ { SLPDDatabaseEntry* entry = 0; int found = 0; found = 0; entry = (SLPDDatabaseEntry*)G_DatabaseList.head; while(entry) { if(SLPCompareString(attrrqst->urllen, attrrqst->url, entry->urllen, entry->url) == 0 || SLPCompareSrvType(attrrqst->urllen, attrrqst->url, entry->srvtypelen, entry->srvtype) == 0) { if(SLPIntersectStringList(attrrqst->scopelistlen, attrrqst->scopelist, entry->scopelistlen, entry->scopelist)) { #ifdef USE_PREDICATES if(attrrqst->taglistlen && entry->attr) { /* serialize into entry->partiallist and return partiallist */ int count; SLPError err; /* TRICKY: null terminate the taglist. This is squishes the spistrlen */ /* which is not a problem because it was already copied */ ((char*)attrrqst->taglist)[attrrqst->taglistlen] = 0; err = SLPAttrSerialize(entry->attr, attrrqst->taglist, &entry->partiallist, entry->partiallistlen, &count, SLP_FALSE); if(err == SLP_BUFFER_OVERFLOW) { /* free previously allocated memory */ free(entry->partiallist); entry->partiallist = 0; entry->partiallistlen = 0; /* SLPAttrSerialize will allocate memory for us */ err = SLPAttrSerialize(entry->attr, attrrqst->taglist, &entry->partiallist, entry->partiallistlen, &entry->partiallistlen, SLP_FALSE); entry->partiallistlen = count; } if(err == SLP_OK) { result->attrlistlen = entry->partiallistlen; result->attrlist = entry->partiallist; found = 1; break; } } else #endif { result->attrlistlen = entry->attrlistlen; result->attrlist = entry->attrlist; found = 1; break; } } } entry = (SLPDDatabaseEntry*)entry->listitem.next; } return found; }
/*=========================================================================*/ 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); }