/***************************************************************************/ /* */ /* Project: OpenSLP - OpenSource implementation of Service Location */ /* Protocol Version 2 */ /* */ /* File: slpd_database.c */ /* */ /* Abstract: Implements database abstraction. Currently a simple */ /* double linked list (common/slp_database.c) is used for the */ /* underlying storage. */ /* */ /*-------------------------------------------------------------------------*/ /* */ /* Please submit patches to http://www.openslp.org */ /* */ /*-------------------------------------------------------------------------*/ /* */ /* Copyright (C) 2000 Caldera Systems, Inc */ /* All rights reserved. */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions are */ /* met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Caldera Systems nor the names of its */ /* contributors may be used to endorse or promote products derived */ /* from this software without specific prior written permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CALDERA */ /* SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /***************************************************************************/ /*=========================================================================*/ /* slpd includes */ /*=========================================================================*/ #include "slpd_database.h" #include "slpd_regfile.h" #include "slpd_property.h" #include "slpd_log.h" #include "slpd_knownda.h" #ifdef ENABLE_PREDICATES #include "slpd_predicate.h" #endif /*=========================================================================*/ /* common code includes */ /*=========================================================================*/ #include "slp_compare.h" #include "slp_xmalloc.h" #include "slp_pid.h" /*=========================================================================*/ SLPDDatabase G_SlpdDatabase; /* slpd database global */ /*=========================================================================*/ /*=========================================================================*/ void SLPDDatabaseAge(int seconds, int ageall) /* Ages the database entries and clears new and deleted entry lists */ /* */ /* seconds (IN) the number of seconds to age each entry by */ /* */ /* ageall (IN) age even entries with SLP_LIFETIME_MAXIMUM */ /* */ /* Returns - None */ /*=========================================================================*/ { SLPDatabaseHandle dh; SLPDatabaseEntry* entry; SLPSrvReg* srvreg; dh = SLPDatabaseOpen(&G_SlpdDatabase.database); if ( dh ) { while ( 1 ) { entry = SLPDatabaseEnum(dh); if ( entry == NULL ) break; /* srvreg is the SrvReg message from the database */ srvreg = &(entry->msg->body.srvreg); if ( srvreg->urlentry.lifetime == SLP_LIFETIME_MAXIMUM ) { if ( srvreg->source == SLP_REG_SOURCE_LOCAL || srvreg->source == SLP_REG_SOURCE_STATIC ) { /* entries that were made from local registrations */ /* and entries made from static registration file */ /* that have a lifetime of SLP_LIFETIME_MAXIMUM must */ /* NEVER be aged */ continue; } if ( ageall == 0 ) { /* Don't age any services that have a lifetime of */ /* SLP_LIFETIME_MAXIMUM unless explicitly told to */ continue; } } /* Age entry */ srvreg->urlentry.lifetime -= seconds; /* Remove entries that have timed out */ if ( srvreg->urlentry.lifetime <= 0 ) { SLPDLogRegistration("Timeout",entry); SLPDatabaseRemove(dh,entry); } } SLPDatabaseClose(dh); } } /*=========================================================================*/ int SLPDDatabaseReg(SLPMessage msg, SLPBuffer buf) /* Add a service registration to the database */ /* */ /* msg (IN) SLPMessage of a SrvReg message as returned by */ /* SLPMessageParse() */ /* */ /* buf (IN) Otherwise unreferenced buffer interpreted by the msg */ /* structure */ /* */ /* Returns - Zero on success. Nonzero on error */ /* */ /* NOTE: All registrations are treated as fresh */ /*=========================================================================*/ { SLPDatabaseHandle dh; SLPDatabaseEntry* entry; SLPSrvReg* entryreg; SLPSrvReg* reg; int result; /* reg is the SrvReg message being registered */ reg = &(msg->body.srvreg); /* check service-url syntax */ if ( SLPCheckServiceUrlSyntax(reg->urlentry.url, reg->urlentry.urllen) ) { return SLP_ERROR_INVALID_REGISTRATION; } /* check attr-list syntax */ if ( reg->attrlistlen && SLPCheckAttributeListSyntax(reg->attrlist,reg->attrlistlen) ) { return SLP_ERROR_INVALID_REGISTRATION; } dh = SLPDatabaseOpen(&G_SlpdDatabase.database); if ( dh ) { /*-----------------------------------------------------*/ /* Check to see if there is already an identical entry */ /*-----------------------------------------------------*/ while ( 1 ) { entry = SLPDatabaseEnum(dh); if ( entry == NULL ) break; /* entry reg is the SrvReg message from the database */ entryreg = &(entry->msg->body.srvreg); if ( SLPCompareString(entryreg->urlentry.urllen, entryreg->urlentry.url, reg->urlentry.urllen, reg->urlentry.url) == 0 ) { if ( SLPIntersectStringList(entryreg->scopelistlen, entryreg->scopelist, reg->scopelistlen, reg->scopelist) > 0 ) { /* Check to ensure the source addr is the same */ /* as the original */ if ( G_SlpdProperty.checkSourceAddr && memcmp(&(entry->msg->peer.sin_addr), &(msg->peer.sin_addr), sizeof(struct in_addr)) ) { SLPDatabaseClose(dh); return SLP_ERROR_AUTHENTICATION_FAILED; } #ifdef ENABLE_SLPv2_SECURITY if ( entryreg->urlentry.authcount && entryreg->urlentry.authcount != reg->urlentry.authcount ) { SLPDatabaseClose(dh); return SLP_ERROR_AUTHENTICATION_FAILED; } #endif /* Remove the identical entry */ SLPDatabaseRemove(dh,entry); break; } } } /*------------------------------------*/ /* Add the new srvreg to the database */ /*------------------------------------*/ entry = SLPDatabaseEntryCreate(msg,buf); if ( entry ) { /* set the source (allows for quicker aging ) */ if ( msg->body.srvreg.source == SLP_REG_SOURCE_UNKNOWN ) { if ( ISLOCAL(msg->peer.sin_addr) ) { msg->body.srvreg.source = SLP_REG_SOURCE_LOCAL; } else { msg->body.srvreg.source = SLP_REG_SOURCE_REMOTE; } } /* add to database */ SLPDatabaseAdd(dh, entry); SLPDLogRegistration("Registration",entry); /* SUCCESS! */ result = 0; } else { result = SLP_ERROR_INTERNAL_ERROR; } SLPDatabaseClose(dh); } else { result = SLP_ERROR_INTERNAL_ERROR; } return result; } /*=========================================================================*/ int SLPDDatabaseDeReg(SLPMessage msg) /* Remove a service registration from the database */ /* */ /* msg - (IN) message interpreting an SrvDereg message */ /* */ /* Returns - Zero on success. Non-zero on failure */ /*=========================================================================*/ { SLPDatabaseHandle dh; SLPDatabaseEntry* entry; SLPSrvReg* entryreg; SLPSrvDeReg* dereg; dh = SLPDatabaseOpen(&G_SlpdDatabase.database); if ( dh ) { /* dereg is the SrvDereg being deregistered */ dereg = &(msg->body.srvdereg); /*---------------------------------------------*/ /* Check to see if there is an identical entry */ /*---------------------------------------------*/ while ( 1 ) { entry = SLPDatabaseEnum(dh); if ( entry == NULL ) break; /* entry reg is the SrvReg message from the database */ entryreg = &(entry->msg->body.srvreg); if ( SLPCompareString(entryreg->urlentry.urllen, entryreg->urlentry.url, dereg->urlentry.urllen, dereg->urlentry.url) == 0 ) { if ( SLPIntersectStringList(entryreg->scopelistlen, entryreg->scopelist, dereg->scopelistlen, dereg->scopelist) > 0 ) { /* Check to ensure the source addr is the same as */ /* the original */ if ( G_SlpdProperty.checkSourceAddr && memcmp(&(entry->msg->peer.sin_addr), &(msg->peer.sin_addr), sizeof(struct in_addr)) ) { SLPDatabaseClose(dh); return SLP_ERROR_AUTHENTICATION_FAILED; } #ifdef ENABLE_SLPv2_SECURITY if ( entryreg->urlentry.authcount && entryreg->urlentry.authcount != dereg->urlentry.authcount ) { SLPDatabaseClose(dh); return SLP_ERROR_AUTHENTICATION_FAILED; } #endif /* remove the registration from the database */ SLPDLogRegistration("Deregistration",entry); SLPDatabaseRemove(dh,entry); break; } } } SLPDatabaseClose(dh); if ( entry==NULL ) { return SLP_ERROR_INVALID_REGISTRATION; } } 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; } /*=========================================================================*/ void SLPDDatabaseSrvRqstEnd(SLPDDatabaseSrvRqstResult* result) /* Find services in the database */ /* */ /* result (IN) pointer result structure previously passed to */ /* SLPDDatabaseSrvRqstStart */ /* */ /* Returns - None */ /*=========================================================================*/ { if ( result ) { SLPDatabaseClose((SLPDatabaseHandle)result->reserved); xfree(result); } } /*=========================================================================*/ int SLPDDatabaseSrvTypeRqstStart(SLPMessage msg, SLPDDatabaseSrvTypeRqstResult** result) /* Find service types in the database */ /* */ /* msg (IN) the SrvTypRqst to find. */ /* */ /* result (OUT) pointer result structure */ /* */ /* Returns - Zero on success. Non-zero on failure */ /* */ /* Note: Caller must pass *result to SLPDDatabaseSrvtypeRqstEnd() to */ /* free */ /*=========================================================================*/ { SLPDatabaseHandle dh; SLPDatabaseEntry* entry; SLPSrvReg* entryreg; SLPSrvTypeRqst* srvtyperqst; dh = SLPDatabaseOpen(&G_SlpdDatabase.database); if ( dh ) { /* srvtyperqst is the SrvTypeRqst being made */ srvtyperqst = &(msg->body.srvtyperqst); while ( 1 ) { /*-----------------------------------------------------------------*/ /* Allocate result with generous srvtypelist of url entry pointers */ /*-----------------------------------------------------------------*/ *result = (SLPDDatabaseSrvTypeRqstResult*) xrealloc(*result, sizeof(SLPDDatabaseSrvTypeRqstResult) + G_SlpdDatabase.srvtypelistlen); if ( *result == NULL ) { /* out of memory */ SLPDatabaseClose(dh); return SLP_ERROR_INTERNAL_ERROR; } (*result)->srvtypelist = (char*)((*result) + 1); (*result)->srvtypelistlen = 0; (*result)->reserved = dh; /*-------------------------------------------------*/ /* Rewind enumeration in case we had to reallocate */ /*-------------------------------------------------*/ SLPDatabaseRewind(dh); 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); if ( SLPCompareNamingAuth(entryreg->srvtypelen, entryreg->srvtype, srvtyperqst->namingauthlen, srvtyperqst->namingauth) == 0 && SLPIntersectStringList(srvtyperqst->scopelistlen, srvtyperqst->scopelist, entryreg->scopelistlen, entryreg->scopelist) && SLPContainsStringList((*result)->srvtypelistlen, (*result)->srvtypelist, entryreg->srvtypelen, entryreg->srvtype) == 0 ) { /* Check to see if we allocated a big enough srvtypelist */ if ( (*result)->srvtypelistlen + entryreg->srvtypelen > G_SlpdDatabase.srvtypelistlen ) { /* Oops we did not allocate a big enough result */ G_SlpdDatabase.srvtypelistlen *= 2; break; } /* Append a comma if needed */ if ( (*result)->srvtypelistlen ) { (*result)->srvtypelist[(*result)->srvtypelistlen] = ','; (*result)->srvtypelistlen += 1; } /* Append the service type */ memcpy(((*result)->srvtypelist) + (*result)->srvtypelistlen, entryreg->srvtype, entryreg->srvtypelen); (*result)->srvtypelistlen += entryreg->srvtypelen; } } } SLPDatabaseClose(dh); } return 0; } /*=========================================================================*/ void SLPDDatabaseSrvTypeRqstEnd(SLPDDatabaseSrvTypeRqstResult* result) /* Release resources used to find service types in the database */ /* */ /* result (IN) pointer result structure previously passed to */ /* SLPDDatabaseSrvTypeRqstStart */ /* */ /* Returns - None */ /*=========================================================================*/ { if ( result ) { SLPDatabaseClose((SLPDatabaseHandle)result->reserved); xfree(result); } } /*=========================================================================*/ 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; } /*=========================================================================*/ void SLPDDatabaseAttrRqstEnd(SLPDDatabaseAttrRqstResult* result) /* Release resources used to find attributes in the database */ /* */ /* result (IN) pointer result structure previously passed to */ /* SLPDDatabaseSrvTypeRqstStart */ /* */ /* Returns - None */ /*=========================================================================*/ { if ( result ) { SLPDatabaseClose((SLPDatabaseHandle)result->reserved); if ( result->ispartial && result->attrlist ) free(result->attrlist); xfree(result); } } /*=========================================================================*/ void* SLPDDatabaseEnumStart() /* Start an enumeration of the entire database */ /* */ /* Returns: An enumeration handle that is passed to subsequent calls to */ /* SLPDDatabaseEnum(). Returns NULL on failure. Returned */ /* enumeration handle (if not NULL) must be passed to */ /* SLPDDatabaseEnumEnd() when you are done with it. */ /*=========================================================================*/ { return SLPDatabaseOpen(&G_SlpdDatabase.database); } /*=========================================================================*/ SLPMessage SLPDDatabaseEnum(void* eh, SLPMessage* msg, SLPBuffer* buf) /* Enumerate through all entries of the database */ /* */ /* eh (IN) pointer to opaque data that is used to maintain */ /* enumerate entries. Pass in a pointer to NULL to start */ /* enumeration. */ /* */ /* msg (OUT) pointer to the SrvReg message that discribes buf */ /* */ /* buf (OUT) pointer to the SrvReg message buffer */ /* */ /* returns: Pointer to enumerated entry or NULL if end of enumeration */ /*=========================================================================*/ { SLPDatabaseEntry* entry; entry = SLPDatabaseEnum((SLPDatabaseHandle) eh); if ( entry ) { *msg = entry->msg; *buf = entry->buf; } else { *msg = 0; *buf = 0; } return *msg; } /*=========================================================================*/ void SLPDDatabaseEnumEnd(void* eh) /* End an enumeration started by SLPDDatabaseEnumStart() */ /* */ /* Parameters: eh (IN) The enumeration handle returned by */ /* SLPDDatabaseEnumStart() */ /*=========================================================================*/ { if ( eh ) { SLPDatabaseClose((SLPDatabaseHandle)eh); } } /*=========================================================================*/ int SLPDDatabaseIsEmpty() /* Returns an boolean value indicating whether the database is empty */ /*=========================================================================*/ { int result = 1; SLPDatabaseHandle dh; dh = SLPDatabaseOpen(&G_SlpdDatabase.database); { result = SLPDatabaseCount(dh) == 0; SLPDatabaseClose(dh); } return result; } /*=========================================================================*/ int SLPDDatabaseInit(const char* regfile) /* Initialize the database with registrations from a regfile. */ /* */ /* regfile (IN) the regfile to register. Pass in NULL for no regfile */ /* */ /* Returns - zero on success or non-zero on error. */ /*=========================================================================*/ { /* Set initial values */ memset(&G_SlpdDatabase,0,sizeof(G_SlpdDatabase)); G_SlpdDatabase.urlcount = SLPDDATABASE_INITIAL_URLCOUNT; G_SlpdDatabase.srvtypelistlen = SLPDDATABASE_INITIAL_SRVTYPELISTLEN; SLPDatabaseInit(&G_SlpdDatabase.database); /* Call the reinit function */ return SLPDDatabaseReInit(regfile); } /*=========================================================================*/ int SLPDDatabaseReInit(const char* regfile) /* Re-initialize the database with changed registrations from a regfile. */ /* */ /* regfile (IN) the regfile to register. */ /* */ /* Returns - zero on success or non-zero on error. */ /*=========================================================================*/ { SLPDatabaseHandle dh; SLPDatabaseEntry* entry; SLPMessage msg; SLPBuffer buf; FILE* fd; /*------------------------------------------------------------------*/ /* open the database handle and remove all the static registrations */ /* (the registrations from the /etc/slp.reg) file. */ /*------------------------------------------------------------------*/ dh = SLPDatabaseOpen(&G_SlpdDatabase.database); if ( dh ) { while ( 1 ) { entry = SLPDatabaseEnum(dh); if ( entry == NULL ) break; if ( entry->msg->body.srvreg.source == SLP_REG_SOURCE_STATIC ) { SLPDatabaseRemove(dh,entry); } } SLPDatabaseClose(dh); } /*--------------------------------------*/ /* Read static registration file if any */ /*--------------------------------------*/ if ( regfile ) { fd = fopen(regfile,"rb"); if ( fd ) { while ( SLPDRegFileReadSrvReg(fd, &msg, &buf) == 0 ) { SLPDDatabaseReg(msg, buf); } fclose(fd); } } return 0; } #ifdef DEBUG /*=========================================================================*/ void SLPDDatabaseDeinit(void) /* Cleans up all resources used by the database */ /*=========================================================================*/ { SLPDatabaseDeinit(&G_SlpdDatabase.database); } /*=========================================================================*/ void SLPDDatabaseDump(void) /* Dumps currently valid service registrations present with slpd */ /*=========================================================================*/ { SLPMessage msg; SLPBuffer buf; void* eh; eh = SLPDDatabaseEnumStart(); if ( eh ) { SLPDLog("\n========================================================================\n"); SLPDLog("Dumping Registrations\n"); SLPDLog("========================================================================\n"); while ( SLPDDatabaseEnum(eh, &msg, &buf) ) { SLPDLogMessageInternals(msg); SLPDLog("\n"); } SLPDDatabaseEnumEnd(eh); } } #endif