/*=========================================================================*/ int SLPDDatabaseFindAttr(SLPAttrRqst* attrrqst, SLPDDatabaseAttr* result, int count) /* Find attributes */ /* */ /* srvtyperqst (IN) the request to find. */ /* */ /* result (OUT) pointer to a result structure that receives */ /* results */ /* */ /* count (IN) number of elements in the result array */ /* */ /* Returns - >0 on success. 0 if the url of the attrrqst could not be */ /* cound and <0 on error. */ /*=========================================================================*/ { SLPDDatabaseEntry* entry = 0; int found = 0; /* TODO: Do we ever want to handle passing back all of the attributes */ /* for service types? */ 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)) { result[found].attrlen = entry->attrlistlen; result[found].attr = entry->attrlist; found++; break; } } entry = (SLPDDatabaseEntry*)entry->listitem.next; } return found; }
/*=========================================================================*/ 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 SLPDDatabaseFindSrv(SLPSrvRqst* srvrqst, SLPDDatabaseSrvUrl* result, int count) /* Find services in the database */ /* */ /* srvrqst (IN) the request to find. */ /* */ /* result (OUT) pointer to an array of result structures that receives */ /* results */ /* */ /* count (IN) number of elements in the result array */ /* */ /* Returns - The number of services found or < 0 on error. If the number */ /* of services found is exactly equal to the number of elements */ /* in the array, the call may be repeated with a larger array. */ /*=========================================================================*/ { SLPDDatabaseEntry* entry; int found; #ifdef USE_PREDICATES /* Tricky: perform an in place null termination of the predicate string */ /* Remember this squishes the high byte of spilistlen which is */ /* not a problem because it was already copied */ if(srvrqst->predicate) { ((char*)srvrqst->predicate)[srvrqst->predicatelen] = 0; } #endif /*---------------*/ /* Test services */ /*---------------*/ found = 0; entry = (SLPDDatabaseEntry*)G_DatabaseList.head; while(entry) { if(SLPCompareSrvType(srvrqst->srvtypelen, srvrqst->srvtype, entry->srvtypelen, entry->srvtype) == 0) { if(SLPIntersectStringList(srvrqst->scopelistlen, srvrqst->scopelist, entry->scopelistlen, entry->scopelist)) { #ifdef USE_PREDICATES if(srvrqst->predicate && entry->attr && SLPDPredicateTest(srvrqst->predicatever, srvrqst->predicate, entry->attr) == 0) #endif { result[found].lifetime = entry->lifetime; result[found].urllen = entry->urllen; result[found].url = entry->url; found ++; if(found >= count) { break; } } } } entry = (SLPDDatabaseEntry*)entry->listitem.next; } return found; }
/*=========================================================================*/ int SLPDDatabaseAttrRqstStart(SLPMessage msg, SLPDDatabaseAttrRqstResult** result) /* Find attributes in the database */ /* */ /* msg (IN) the AttrRqst to find. */ /* */ /* result (OUT) pointer result structure */ /* */ /* Returns - Zero on success. Non-zero on failure */ /* */ /* Note: Caller must pass *result to SLPDDatabaseAttrRqstEnd() to */ /* free */ /*=========================================================================*/ { SLPDatabaseHandle dh; SLPDatabaseEntry* entry; SLPSrvReg* entryreg; SLPAttrRqst* attrrqst; #ifdef ENABLE_SLPv2_SECURITY int i; #endif *result = xmalloc(sizeof(SLPDDatabaseAttrRqstResult)); if ( *result == NULL ) { return SLP_ERROR_INTERNAL_ERROR; } memset(*result,0,sizeof(SLPDDatabaseAttrRqstResult)); dh = SLPDatabaseOpen(&G_SlpdDatabase.database); if ( dh ) { (*result)->reserved = dh; /* attrrqst is the AttrRqst being made */ attrrqst = &(msg->body.attrrqst); while ( 1 ) { entry = SLPDatabaseEnum(dh); if ( entry == NULL ) { return 0; } /* entry reg is the SrvReg message from the database */ entryreg = &(entry->msg->body.srvreg); if ( SLPCompareString(attrrqst->urllen, attrrqst->url, entryreg->urlentry.urllen, entryreg->urlentry.url) == 0 || SLPCompareSrvType(attrrqst->urllen, attrrqst->url, entryreg->srvtypelen, entryreg->srvtype) == 0 ) { if ( SLPIntersectStringList(attrrqst->scopelistlen, attrrqst->scopelist, entryreg->scopelistlen, entryreg->scopelist) ) { if ( attrrqst->taglistlen == 0 ) { #ifdef ENABLE_SLPv2_SECURITY if ( attrrqst->spistrlen ) { for ( i=0; i< entryreg->authcount;i++ ) { if ( SLPCompareString(attrrqst->spistrlen, attrrqst->spistr, entryreg->autharray[i].spistrlen, entryreg->autharray[i].spistr) == 0 ) { break; } } if ( i == entryreg->authcount ) { continue; } } #endif /* Send back what was registered */ (*result)->attrlistlen = entryreg->attrlistlen; (*result)->attrlist = (char*)entryreg->attrlist; (*result)->authcount = entryreg->authcount; (*result)->autharray = entryreg->autharray; } #ifdef ENABLE_PREDICATES else { /* Send back a partial list as specified by taglist */ if ( SLPDFilterAttributes(entryreg->attrlistlen, entryreg->attrlist, attrrqst->taglistlen, attrrqst->taglist, &(*result)->attrlistlen, &(*result)->attrlist) == 0 ) { (*result)->ispartial = 1; break; } } #endif } } } } return 0; }
/*=========================================================================*/ int SLPDDatabaseSrvRqstStart(SLPMessage msg, SLPDDatabaseSrvRqstResult** result) /* Find services in the database */ /* */ /* msg (IN) the SrvRqst to find. */ /* */ /* result (OUT) pointer result structure */ /* */ /* Returns - Zero on success. Non-zero on failure */ /* */ /* Note: Caller must pass *result to SLPDDatabaseSrvRqstEnd() to free */ /*=========================================================================*/ { SLPDatabaseHandle dh; SLPDatabaseEntry* entry; SLPSrvReg* entryreg; SLPSrvRqst* srvrqst; #ifdef ENABLE_SLPv2_SECURITY int i; #endif /* start with the result set to NULL just to be safe */ *result = NULL; dh = SLPDatabaseOpen(&G_SlpdDatabase.database); if ( dh ) { /* srvrqst is the SrvRqst being made */ srvrqst = &(msg->body.srvrqst); while ( 1 ) { /*-----------------------------------------------------------*/ /* Allocate result with generous array of url entry pointers */ /*-----------------------------------------------------------*/ *result = (SLPDDatabaseSrvRqstResult*) xrealloc(*result, sizeof(SLPDDatabaseSrvRqstResult) + (sizeof(SLPUrlEntry*) * G_SlpdDatabase.urlcount)); if ( *result == NULL ) { /* out of memory */ SLPDatabaseClose(dh); return SLP_ERROR_INTERNAL_ERROR; } (*result)->urlarray = (SLPUrlEntry**)((*result) + 1); (*result)->urlcount = 0; (*result)->reserved = dh; /*-------------------------------------------------*/ /* Rewind enumeration in case we had to reallocate */ /*-------------------------------------------------*/ SLPDatabaseRewind(dh); /*-----------------------------------------*/ /* Check to see if there is matching entry */ /*-----------------------------------------*/ while ( 1 ) { entry = SLPDatabaseEnum(dh); if ( entry == NULL ) { /* This is the only successful way out */ return 0; } /* entry reg is the SrvReg message from the database */ entryreg = &(entry->msg->body.srvreg); /* check the service type */ if ( SLPCompareSrvType(srvrqst->srvtypelen, srvrqst->srvtype, entryreg->srvtypelen, entryreg->srvtype) == 0 && SLPIntersectStringList(entryreg->scopelistlen, entryreg->scopelist, srvrqst->scopelistlen, srvrqst->scopelist) > 0 ) { #ifdef ENABLE_PREDICATES if ( SLPDPredicateTest(msg->header.version, entryreg->attrlistlen, entryreg->attrlist, srvrqst->predicatelen, srvrqst->predicate) ) #endif { #ifdef ENABLE_SLPv2_SECURITY if ( srvrqst->spistrlen ) { for ( i=0; i< entryreg->urlentry.authcount;i++ ) { if ( SLPCompareString(srvrqst->spistrlen, srvrqst->spistr, entryreg->urlentry.autharray[i].spistrlen, entryreg->urlentry.autharray[i].spistr) == 0 ) { break; } } if ( i == entryreg->urlentry.authcount ) { continue; } } #endif if ( (*result)->urlcount + 1 > G_SlpdDatabase.urlcount ) { /* Oops we did not allocate a big enough result */ G_SlpdDatabase.urlcount *= 2; break; } (*result)->urlarray[(*result)->urlcount] = &(entryreg->urlentry); (*result)->urlcount ++; } } } } } return 0; }