/*=========================================================================*/ const char* SLPGetProperty(const char* pcName) /* */ /* Returns the value of the corresponding SLP property name. The returned */ /* string is owned by the library and MUST NOT be freed. */ /* */ /* pcName Null terminated string with the property name, from */ /* Section 2.1 of RFC 2614. */ /* */ /* Returns: If no error, returns a pointer to a character buffer containing*/ /* the property value. If the property was not set, returns the */ /* default value. If an error occurs, returns NULL. The returned */ /* string MUST NOT be freed. */ /*=========================================================================*/ { char conffile[MAX_PATH]; const char* result; memset(conffile,0,MAX_PATH); #ifdef WIN32 ExpandEnvironmentStrings(LIBSLP_CONFFILE,conffile,MAX_PATH); #else strncpy(conffile,LIBSLP_CONFFILE,MAX_PATH-1); #endif if(G_PropertyInit == 0) { if(SLPPropertyReadFile(conffile) == 0) { G_PropertyInit = 1; } else { return 0; } } result = SLPPropertyGet(pcName); return result; }
/*=========================================================================*/ int SLPDPropertyInit(const char* conffile) /*=========================================================================*/ { char* myname = 0; char* myinterfaces = 0; char* myurl = 0; SLPPropertyReadFile(conffile); memset(&G_SlpdProperty,0,sizeof(G_SlpdProperty)); /*-------------------------------------------------------------*/ /* Set the properties without hard defaults */ /*-------------------------------------------------------------*/ G_SlpdProperty.isDA = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.isDA")); G_SlpdProperty.activeDADetection = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.activeDADetection")); if(G_SlpdProperty.activeDADetection) { G_SlpdProperty.DAActiveDiscoveryInterval = atoi(SLPPropertyGet("net.slp.DAActiveDiscoveryInterval")); if(G_SlpdProperty.DAActiveDiscoveryInterval > 1 && G_SlpdProperty.DAActiveDiscoveryInterval < SLPD_CONFIG_DA_FIND ) { G_SlpdProperty.DAActiveDiscoveryInterval = SLPD_CONFIG_DA_FIND; } } else { G_SlpdProperty.DAActiveDiscoveryInterval = 0; } G_SlpdProperty.passiveDADetection = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.passiveDADetection")); G_SlpdProperty.isBroadcastOnly = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.isBroadcastOnly")); G_SlpdProperty.multicastTTL = atoi(SLPPropertyGet("net.slp.multicastTTL")); G_SlpdProperty.multicastMaximumWait = atoi(SLPPropertyGet("net.slp.multicastMaximumWait")); G_SlpdProperty.unicastMaximumWait = atoi(SLPPropertyGet("net.slp.unicastMaximumWait")); G_SlpdProperty.randomWaitBound = atoi(SLPPropertyGet("net.slp.randomWaitBound")); G_SlpdProperty.maxResults = atoi(SLPPropertyGet("net.slp.maxResults")); G_SlpdProperty.traceMsg = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.traceMsg")); G_SlpdProperty.traceReg = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.traceReg")); G_SlpdProperty.traceDrop = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.traceDrop")); G_SlpdProperty.traceDATraffic = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.traceDATraffic")); G_SlpdProperty.DAAddresses = SLPPropertyGet("net.slp.DAAddresses"); G_SlpdProperty.DAAddressesLen = strlen(G_SlpdProperty.DAAddresses); /* TODO make sure that we are using scopes correctly. What about DHCP, etc*/ G_SlpdProperty.useScopes = SLPPropertyGet("net.slp.useScopes"); G_SlpdProperty.useScopesLen = strlen(G_SlpdProperty.useScopes); G_SlpdProperty.locale = SLPPropertyGet("net.slp.locale"); G_SlpdProperty.localeLen = strlen(G_SlpdProperty.locale); G_SlpdProperty.securityEnabled = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.securityEnabled")); G_SlpdProperty.checkSourceAddr = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.checkSourceAddr")); G_SlpdProperty.DAHeartBeat = SLPPropertyAsInteger(SLPPropertyGet("net.slp.DAHeartBeat")); /*-------------------------------------*/ /* Set the net.slp.interfaces property */ /*-------------------------------------*/ if(SLPIfaceGetInfo(SLPPropertyGet("net.slp.interfaces"),&G_SlpdProperty.ifaceInfo) == 0) { if(SLPPropertyGet("net.slp.interfaces")) { if(SLPIfaceSockaddrsToString(G_SlpdProperty.ifaceInfo.iface_addr, G_SlpdProperty.ifaceInfo.iface_count, &myinterfaces) == 0) { if(myinterfaces) { SLPPropertySet("net.slp.interfaces", myinterfaces); xfree(myinterfaces); } } } G_SlpdProperty.interfaces = SLPPropertyGet("net.slp.interfaces"); } G_SlpdProperty.interfacesLen = strlen(G_SlpdProperty.interfaces); /*---------------------------------------------------------*/ /* Set the value used internally as the url for this agent */ /*---------------------------------------------------------*/ /* 27 is the size of "service:directory-agent://(NULL)" */ if(SLPNetGetThisHostname(&myname,1) == 0) { myurl = (char*)xmalloc(27 + strlen(myname)); if(G_SlpdProperty.isDA) { strcpy(myurl,SLP_DA_SERVICE_TYPE); } else { strcpy(myurl,SLP_SA_SERVICE_TYPE); } strcat(myurl,"://"); strcat(myurl,myname); SLPPropertySet("net.slp.agentUrl",myurl); G_SlpdProperty.myUrl = SLPPropertyGet("net.slp.agentUrl"); G_SlpdProperty.myUrlLen = strlen(G_SlpdProperty.myUrl); xfree(myurl); xfree(myname); } /*----------------------------------*/ /* Set other values used internally */ /*----------------------------------*/ G_SlpdProperty.DATimestamp = 1; /* DATimestamp must start at 1 */ G_SlpdProperty.activeDiscoveryXmits = 3; /* ensures xmit on first 3 calls to SLPDKnownDAActiveDiscovery() */ G_SlpdProperty.nextActiveDiscovery = 0; /* ensures xmit on first call to SLPDKnownDAActiveDiscovery() */ G_SlpdProperty.nextPassiveDAAdvert = 0; /* ensures xmit on first call to SLPDKnownDAPassiveDiscovery()*/ return 0; }
/** Return a list of service matching a query specification. * * Issue the query for services on the language specific SLPHandle and * return the results through the @p callback. The parameters determine * the results. * * @param[in] hSLP - The language specific SLPHandle on which to search * for services. * @param[in] pcServiceType - The Service Type String, including authority * string if any, for the request, such as can be discovered using * SLPSrvTypes. This could be, for example "service:printer:lpr" or * "service:nfs". May not be the empty string or NULL. * @param[in] pcScopeList - A pointer to a char containing a comma-separated * list of scope names. Pass in NULL or the empty string ("") to find * services in all the scopes the local host is configured to query. * @param[in] pcSearchFilter - A query formulated of attribute pattern * matching expressions in the form of a LDAPv3 Search Filter, see * [RFC 2254]. If this filter is empty, i.e. "" or NULL, all services * of the requested type in the specified scopes are returned. * @param[in] callback - A callback function through which the results of * the operation are reported. * @param[in] pvCookie - Memory passed to the @p callback code from the * client. May be NULL. * * @return If an error occurs in starting the operation, one of the SLPError * codes is returned. */ SLPEXP SLPError SLPAPI SLPFindSrvs( SLPHandle hSLP, const char * pcServiceType, const char * pcScopeList, const char * pcSearchFilter, SLPSrvURLCallback callback, void * pvCookie) { bool inuse; SLPError serr = 0; SLPHandleInfo * handle = hSLP; /* Check for invalid parameters. */ SLP_ASSERT(handle != 0); SLP_ASSERT(handle->sig == SLP_HANDLE_SIG); SLP_ASSERT(pcServiceType != 0); SLP_ASSERT(*pcServiceType != 0); SLP_ASSERT(callback != 0); if (handle == 0 || handle->sig != SLP_HANDLE_SIG || pcServiceType == 0 || *pcServiceType == 0 || callback == 0) return SLP_PARAMETER_BAD; /* Check to see if the handle is in use. */ inuse = SLPSpinLockTryAcquire(&handle->inUse); SLP_ASSERT(!inuse); if (inuse) return SLP_HANDLE_IN_USE; /* Get a scope list if not supplied. */ if (pcScopeList == 0 || *pcScopeList == 0) pcScopeList = SLPPropertyGet("net.slp.useScopes", 0, 0); /* Ensure there's a scope list of some sort... */ if (pcScopeList == 0) pcScopeList = ""; /* Get a search filter if not supplied */ if (pcSearchFilter == 0) pcSearchFilter = ""; /* Set the handle up to reference parameters. */ handle->params.findsrvs.srvtypelen = strlen(pcServiceType); handle->params.findsrvs.srvtype = pcServiceType; handle->params.findsrvs.scopelistlen = strlen(pcScopeList); handle->params.findsrvs.scopelist = pcScopeList; handle->params.findsrvs.predicatelen = strlen(pcSearchFilter); handle->params.findsrvs.predicate = pcSearchFilter; handle->params.findsrvs.callback = callback; handle->params.findsrvs.cookie = pvCookie; /* Check to see if we should be async or sync. */ #ifdef ENABLE_ASYNC_API if (handle->isAsync) { /* Copy all of the referenced parameters before creating thread. */ handle->params.findsrvs.srvtype = xstrdup(handle->params.findsrvs.srvtype); handle->params.findsrvs.scopelist = xstrdup(handle->params.findsrvs.scopelist); handle->params.findsrvs.predicate = xstrdup(handle->params.findsrvs.predicate); /* Ensure strdups and thread create succeed. */ if (handle->params.findsrvs.srvtype == 0 || handle->params.findsrvs.scopelist == 0 || handle->params.findsrvs.predicate == 0 || (handle->th = SLPThreadCreate((SLPThreadStartProc) AsyncProcessSrvRqst, handle)) == 0) { serr = SLP_MEMORY_ALLOC_FAILED; xfree((void *)handle->params.findsrvs.srvtype); xfree((void *)handle->params.findsrvs.scopelist); xfree((void *)handle->params.findsrvs.predicate); SLPSpinLockRelease(&handle->inUse); } } else #endif { /* Leave all parameters referenced. */ serr = ProcessSrvRqst(handle); SLPSpinLockRelease(&handle->inUse); } return serr; }
/** Register a service URL through OpenSLP. * * Registers the URL in @p pcSrvURL having the lifetime usLifetime with * the attribute list in pcAttrs. The @p pcAttrs list is a comma separated * list of attribute assignments in the wire format (including escaping * of reserved characters). The @p usLifetime parameter must be nonzero * and less than or equal to SLP_LIFETIME_MAXIMUM. If the @p fresh flag * is SLP_TRUE, then the registration is new (the SLP protocol FRESH flag * is set) and the registration replaces any existing registrations. * The @p pcSrvType parameter is a service type name and can be included * for service URLs that are not in the service: scheme. If the URL is * in the service: scheme, the @p pcSrvType parameter is ignored. If the * @p fresh flag is SLP_FALSE, then an existing registration is updated. * Rules for new and updated registrations, and the format for @p pcAttrs * and @p pcScopeList can be found in [RFC 2608]. Registrations and * updates take place in the language locale of the @p hSLP handle. * * @par * The API library is required to perform the operation in all scopes * obtained through configuration. * * @param[in] hSLP - The language-specific SLPHandle on which to register * the advertisement. * @param[in] srvUrl - The URL to register. May not be the empty string. * May not be NULL. Must conform to SLP Service URL syntax. * SLP_INVALID_REGISTRATION will be returned if not. * @param[in] lifetime - An unsigned short giving the life time of the * service advertisement, in seconds. The value must be an unsigned * integer less than or equal to SLP_LIFETIME_MAXIMUM, and greater * than zero. If SLP_LIFETIME_MAXIMUM is used, the registration * will remain for the life of the calling process. Also, OpenSLP, * will not allow registrations to be made with SLP_LIFETIME_MAXIMUM * unless SLP_REG_FLAG_WATCH_PID is also used. Note that RFC 2614 * defines this parameter as const unsigned short. The 'const' is * superfluous. * @param[in] srvType - The service type. If @p pURL is a "service:" * URL, then this parameter is ignored. (ALWAYS ignored since the SLP * Service URL syntax required for the @p pcSrvURL encapsulates the * service type.) * @param[in] attrList - A comma separated list of attribute assignment * expressions for the attributes of the advertisement. Use empty * string ("") for no attributes. * @param[in] fresh - An SLPBoolean that is SLP_TRUE if the registration * is new or SLP_FALSE if a RE-registration. Use of non-fresh * registrations is deprecated (post RFC 2614). SLP_TRUE must be * passed in for this parameter or SLP_BAD_PARAMETER will be returned. * It also appears that this flag has been overloaded to accept certain * specific values of "true" for internal purposes... (jmc) * @param[in] callback - A callback to report the operation completion * status. * @param[in] cookie - Memory passed to the callback code from the * client. May be NULL. * * @return If an error occurs in starting the operation, one of the * SLPError codes is returned. */ SLPEXP SLPError SLPAPI SLPReg( SLPHandle hSLP, const char * srvUrl, unsigned short lifetime, const char * srvType, const char * attrList, SLPBoolean fresh, SLPRegReport callback, void * cookie) { bool inuse; SLPError serr; SLPSrvURL * parsedurl = 0; SLPHandleInfo * handle = hSLP; /** @todo Add code to accept non- "service:" scheme * URL's - normalize with srvType parameter info. */ (void)srvType; /* not used yet */ /* Check for invalid parameters. */ SLP_ASSERT(handle != 0); SLP_ASSERT(handle->sig == SLP_HANDLE_SIG); SLP_ASSERT(srvUrl != 0); SLP_ASSERT(*srvUrl != 0); SLP_ASSERT(lifetime != 0); SLP_ASSERT(attrList != 0); SLP_ASSERT(callback != 0); if (handle == 0 || handle->sig != SLP_HANDLE_SIG || srvUrl == 0 || *srvUrl == 0 || lifetime == 0 || attrList == 0 || callback == 0) return SLP_PARAMETER_BAD; /** @todo Handle non-fresh registrations in SLPReg. */ if (fresh == SLP_FALSE) return SLP_NOT_IMPLEMENTED; /* Check to see if the handle is in use. */ inuse = SLPSpinLockTryAcquire(&handle->inUse); SLP_ASSERT(!inuse); if (inuse) return SLP_HANDLE_IN_USE; /* Parse the srvurl - mainly for service type info. */ serr = SLPParseSrvURL(srvUrl, &parsedurl); if (serr) { SLPSpinLockRelease(&handle->inUse); return serr == SLP_PARSE_ERROR? SLP_INVALID_REGISTRATION: serr; } /* Set the handle up to reference parameters. */ handle->params.reg.fresh = fresh; handle->params.reg.lifetime = lifetime; handle->params.reg.urllen = strlen(srvUrl); handle->params.reg.url = srvUrl; handle->params.reg.srvtype = parsedurl->s_pcSrvType; handle->params.reg.srvtypelen = strlen(handle->params.reg.srvtype); handle->params.reg.scopelist = SLPPropertyGet("net.slp.useScopes", 0, 0); handle->params.reg.scopelistlen = strlen(handle->params.reg.scopelist); handle->params.reg.attrlistlen = strlen(attrList); handle->params.reg.attrlist = attrList; handle->params.reg.callback = callback; handle->params.reg.cookie = cookie; #ifdef ENABLE_ASYNC_API if (handle->isAsync) { /* Copy all of the referenced parameters before creating thread. */ handle->params.reg.url = xstrdup(handle->params.reg.url); handle->params.reg.srvtype = xstrdup(handle->params.reg.url); handle->params.reg.scopelist = xstrdup(handle->params.reg.scopelist); handle->params.reg.attrlist = xstrdup(handle->params.reg.attrlist); /* Ensure strdups and thread create succeed. */ if (handle->params.reg.url == 0 || handle->params.reg.srvtype == 0 || handle->params.reg.scopelist == 0 || handle->params.reg.attrlist == 0 || (handle->th = SLPThreadCreate((SLPThreadStartProc) AsyncProcessSrvReg, handle)) == 0) { serr = SLP_MEMORY_ALLOC_FAILED; xfree((void *)handle->params.reg.url); xfree((void *)handle->params.reg.srvtype); xfree((void *)handle->params.reg.scopelist); xfree((void *)handle->params.reg.attrlist); SLPSpinLockRelease(&handle->inUse); } } else #endif { /* Reference all the parameters. */ serr = ProcessSrvReg(handle); SLPSpinLockRelease(&handle->inUse); } SLPFree(parsedurl); return serr; }
/*=========================================================================*/ void SLPDPropertyInit(const char* conffile) /*=========================================================================*/ { struct in_addr ifaddr; struct utsname myname; struct hostent* myhostent; int i; SLPPropertyReadFile(conffile); memset(&G_SlpdProperty,0,sizeof(G_SlpdProperty)); /*-------------------------------------------------------------*/ /* Set the properties with out hard defaults */ /*-------------------------------------------------------------*/ G_SlpdProperty.isBroadcastOnly = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.isBroadcastOnly")); G_SlpdProperty.passiveDADetection = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.passiveDADetection")); G_SlpdProperty.activeDADetection = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.activeDADetection")); G_SlpdProperty.activeDiscoveryAttempts = G_SlpdProperty.activeDADetection * 3; G_SlpdProperty.multicastTTL = atoi(SLPPropertyGet("net.slp.multicastTTL")); G_SlpdProperty.multicastMaximumWait = atoi(SLPPropertyGet("net.slp.multicastMaximumWait")); G_SlpdProperty.unicastMaximumWait = atoi(SLPPropertyGet("net.slp.unicastMaximumWait")); G_SlpdProperty.randomWaitBound = atoi(SLPPropertyGet("net.slp.randomWaitBound")); G_SlpdProperty.traceMsg = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.traceMsg")); G_SlpdProperty.traceReg = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.traceReg")); G_SlpdProperty.traceDrop = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.traceDrop")); G_SlpdProperty.traceDATraffic = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.traceDATraffic")); G_SlpdProperty.DAAddresses = SLPPropertyGet("net.slp.DAAddresses"); G_SlpdProperty.DAAddressesLen = strlen(G_SlpdProperty.DAAddresses); G_SlpdProperty.useScopes = SLPPropertyGet("net.slp.useScopes"); G_SlpdProperty.useScopesLen = strlen(G_SlpdProperty.useScopes); G_SlpdProperty.isDA = SLPPropertyAsBoolean(SLPPropertyGet("net.slp.isDA")); G_SlpdProperty.locale = SLPPropertyGet("net.slp.locale"); G_SlpdProperty.localeLen = strlen(G_SlpdProperty.locale); /*-------------------------------------*/ /* Set the net.slp.interfaces property */ /*-------------------------------------*/ G_SlpdProperty.interfaces = SLPPropertyGet("net.slp.interfaces"); if(*G_SlpdProperty.interfaces == 0) { /* put in all interfaces if none specified */ if(uname(&myname) >= 0) { myhostent = gethostbyname(myname.nodename); if(myhostent != 0) { if(myhostent->h_addrtype == AF_INET) { /* count the interfaces */ for(i=0; myhostent->h_addr_list[i];i++); /* allocate memory 16 bytes per interface*/ G_SlpdProperty.interfaces = (char*)malloc((i * 16) + 1); if(G_SlpdProperty.interfaces == 0) { SLPFatal("slpd is out of memory!\n"); } *(char*)G_SlpdProperty.interfaces = 0; /* null terminate */ for(i=0; myhostent->h_addr_list[i];i++) { memcpy(&ifaddr,myhostent->h_addr_list[i],sizeof(ifaddr)); if(i) { strcat((char*)G_SlpdProperty.interfaces,","); } strcat((char*)G_SlpdProperty.interfaces,inet_ntoa(ifaddr)); } } } } } if(G_SlpdProperty.interfaces) { G_SlpdProperty.interfacesLen = strlen(G_SlpdProperty.interfaces); } /*---------------------------------------------------------*/ /* Set the value used internally as the url for this agent */ /*---------------------------------------------------------*/ G_SlpdProperty.myUrl = (const char*)malloc(25 + strlen(myname.nodename)); if(G_SlpdProperty.myUrl == 0) { SLPFatal("slpd is out of memory!\n"); } if(G_SlpdProperty.isDA) { strcpy((char*)G_SlpdProperty.myUrl,"service:directory-agent://"); } else { strcpy((char*)G_SlpdProperty.myUrl,"service:service-agent://"); } if(uname(&myname) >= 0) { /* 25 is the length of "service:directory-agent://" */ strcat((char*)G_SlpdProperty.myUrl,myname.nodename); } G_SlpdProperty.myUrlLen = strlen(G_SlpdProperty.myUrl); }
/** Open an OpenSLP session handle. * * Returns a SLPHandle handle in the phSLP parameter for the language * locale passed in as the pcLang parameter. The client indicates if * operations on the handle are to be synchronous or asynchronous * through the isAsync parameter. The handle encapsulates the language * locale for SLP requests issued through the handle, and any other * resources required by the implementation. However, SLP properties * are not encapsulated by the handle; they are global. The return * value of the function is an SLPError code indicating the status of * the operation. Upon failure, the phSLP parameter is NULL. * * @par * An SLPHandle can only be used for one SLP API operation at a time. * If the original operation was started asynchronously, any attempt * to start an additional operation on the handle while the original * operation is pending results in the return of an SLP_HANDLE_IN_USE * error from the API function. The SLPClose() API function terminates * any outstanding calls on the handle. If an implementation is unable * to support a asynchronous (resp. synchronous) operation, due to * memory constraints or lack of threading support, the * SLP_NOT_IMPLEMENTED flag may be returned when the isAsync flag * is SLP_TRUE (resp. SLP_FALSE). * * @param[in] pcLang - A pointer to an array of characters containing * the [RFC 1766] Language Tag for the natural language locale of * requests and registrations issued on the handle. (Pass NULL or * the empty string to use the default locale.) * * @param[in] isAsync - An SLPBoolean indicating whether the SLPHandle * should be opened for asynchronous operation or not. * * @param[out] phSLP - A pointer to an SLPHandle, in which the open * SLPHandle is returned. If an error occurs, the value upon return * is NULL. * * @return An SLPError code; SLP_OK(0) on success, SLP_PARAMETER_BAD, * SLP_NOT_IMPLEMENTED, SLP_MEMORY_ALLOC_FAILED, * SLP_NETWORK_INIT_FAILED, SLP_INTERNAL_SYSTEM_ERROR */ SLPEXP SLPError SLPAPI SLPOpen( const char * pcLang, SLPBoolean isAsync, SLPHandle * phSLP) { SLPError serr; SLPHandleInfo * handle; /* Check for invalid parameters. */ SLP_ASSERT(phSLP != 0); if (phSLP == 0) return SLP_PARAMETER_BAD; #ifndef ENABLE_ASYNC_API if (isAsync) return SLP_NOT_IMPLEMENTED; #endif *phSLP = 0; serr = InitUserAgentLibrary(); if (serr != SLP_OK) return serr; /* Allocate and clear an SLPHandleInfo structure. */ handle = xcalloc(1, sizeof(SLPHandleInfo)); if (handle == 0) { ExitUserAgentLibrary(); return SLP_MEMORY_ALLOC_FAILED; } handle->sig = SLP_HANDLE_SIG; handle->inUse = 0; #ifdef ENABLE_ASYNC_API handle->isAsync = isAsync; #endif handle->dasock = SLP_INVALID_SOCKET; handle->sasock = SLP_INVALID_SOCKET; #ifndef UNICAST_NOT_SUPPORTED handle->unicastsock = SLP_INVALID_SOCKET; #endif /* Set the language tag. */ if (pcLang == 0 || *pcLang == 0) pcLang = SLPPropertyGet("net.slp.locale", 0, 0); handle->langtaglen = strlen(pcLang); handle->langtag = xmemdup(pcLang, handle->langtaglen + 1); if (handle->langtag == 0) { xfree(handle); ExitUserAgentLibrary(); return SLP_MEMORY_ALLOC_FAILED; } #ifdef ENABLE_SLPv2_SECURITY handle->hspi = SLPSpiOpen(LIBSLP_SPIFILE, 0); if (!handle->hspi) { xfree(handle->langtag); xfree(handle); ExitUserAgentLibrary(); return SLP_INTERNAL_SYSTEM_ERROR; } #endif *phSLP = handle; return SLP_OK; }
/*=========================================================================*/ int KnownDAGetScopes(int* scopelistlen, char** scopelist) /* Gets a list of scopes from the known DA list */ /* */ /* scopelistlen (OUT) stringlen of the scopelist */ /* */ /* scopelist (OUT) NULL terminated list of scopes */ /* */ /* returns: zero on success, non-zero on failure */ /*=========================================================================*/ { time_t curtime; SLPDAEntry* entry; int newlen; /* Refresh the cache if necessary */ curtime = time(&curtime); if(G_KnownDALastCacheRefresh == 0 || curtime - G_KnownDALastCacheRefresh > MINIMUM_DISCOVERY_INTERVAL) { G_KnownDALastCacheRefresh = curtime; /* discover DAs */ if(KnownDADiscoverFromIPC() == 0) { KnownDADiscoverFromDHCP(); KnownDADiscoverFromProperties(); KnownDADiscoverFromMulticast(0,""); } /* TODO: */ /* enumerate through all the knownda entries and generate a */ /* scopelist */ entry = (SLPDAEntry*)G_KnownDACache.head; while(entry) { newlen = G_KnownDAScopesLen; while(SLPUnionStringList(G_KnownDAScopesLen, G_KnownDAScopes, entry->scopelistlen, entry->scopelist, &newlen, G_KnownDAScopes) < 0) { G_KnownDAScopes = realloc(G_KnownDAScopes,newlen); if(G_KnownDAScopes == 0) { G_KnownDAScopesLen = 0; break; } } G_KnownDAScopesLen = newlen; entry = (SLPDAEntry*) entry->listitem.next; } /* Explicitly add in the useScopes property */ newlen = G_KnownDAScopesLen; while(SLPUnionStringList(G_KnownDAScopesLen, G_KnownDAScopes, strlen(SLPPropertyGet("net.slp.useScopes")), SLPPropertyGet("net.slp.useScopes"), &newlen, G_KnownDAScopes) < 0) { G_KnownDAScopes = realloc(G_KnownDAScopes,newlen); if(G_KnownDAScopes == 0) { G_KnownDAScopesLen = 0; break; } } G_KnownDAScopesLen = newlen; } if(G_KnownDAScopesLen) { *scopelist = malloc(G_KnownDAScopesLen + 1); if(*scopelist == 0) { return -1; } memcpy(*scopelist,G_KnownDAScopes, G_KnownDAScopesLen); (*scopelist)[G_KnownDAScopesLen] = 0; *scopelistlen = G_KnownDAScopesLen; } else { *scopelist = strdup(""); if(*scopelist == 0) { return -1; } *scopelistlen = 0; } return 0; }
/*=========================================================================*/ int KnownDAGetScopes(int* scopelistlen, char** scopelist) /* Gets a list of scopes from the known DA list */ /* */ /* scopelistlen (OUT) stringlen of the scopelist */ /* */ /* scopelist (OUT) NULL terminated list of scopes */ /* */ /* returns: zero on success, non-zero on failure */ /*=========================================================================*/ { int newlen; time_t curtime; SLPDatabaseHandle dh; SLPDatabaseEntry* entry; /* Refresh the cache if necessary */ curtime = time(&curtime); if(G_KnownDALastCacheRefresh == 0 || curtime - G_KnownDALastCacheRefresh > MINIMUM_DISCOVERY_INTERVAL) { G_KnownDALastCacheRefresh = curtime; /* discover DAs */ if(KnownDADiscoverFromIPC() == 0) { KnownDADiscoverFromDHCP(); KnownDADiscoverFromProperties(); KnownDADiscoverFromMulticast(0,""); } } /* enumerate through all the knownda entries and generate a */ /* scopelist */ dh = SLPDatabaseOpen(&G_KnownDACache); if(dh) { /*-----------------------------------*/ /* Check to find the requested entry */ /*-----------------------------------*/ while(1) { entry = SLPDatabaseEnum(dh); if(entry == NULL) break; newlen = G_KnownDAScopesLen; while(SLPUnionStringList(G_KnownDAScopesLen, G_KnownDAScopes, entry->msg->body.daadvert.scopelistlen, entry->msg->body.daadvert.scopelist, &newlen, G_KnownDAScopes) < 0) { G_KnownDAScopes = xrealloc(G_KnownDAScopes,newlen); if(G_KnownDAScopes == 0) { G_KnownDAScopesLen = 0; break; } } G_KnownDAScopesLen = newlen; } SLPDatabaseClose(dh); } /* Explicitly add in the useScopes property */ newlen = G_KnownDAScopesLen; while(SLPUnionStringList(G_KnownDAScopesLen, G_KnownDAScopes, strlen(SLPPropertyGet("net.slp.useScopes")), SLPPropertyGet("net.slp.useScopes"), &newlen, G_KnownDAScopes) < 0) { G_KnownDAScopes = xrealloc(G_KnownDAScopes,newlen); if(G_KnownDAScopes == 0) { G_KnownDAScopesLen = 0; break; } } G_KnownDAScopesLen = newlen; if(G_KnownDAScopesLen) { *scopelist = xmalloc(G_KnownDAScopesLen + 1); if(*scopelist == 0) { return -1; } memcpy(*scopelist,G_KnownDAScopes, G_KnownDAScopesLen); (*scopelist)[G_KnownDAScopesLen] = 0; *scopelistlen = G_KnownDAScopesLen; } else { *scopelist = xstrdup(""); if(*scopelist == 0) { return -1; } *scopelistlen = 0; } return 0; }
/** Return a list of service types available on the network. * * The SLPFindSrvType function issues an SLP service type request for * service types in the scopes indicated by the @p pcScopeList. The * results are returned through the @p callback parameter. The service * types are independent of language locale, but only for services * registered in one of scopes and for the indicated naming authority. * * @par * If the naming authority is "*", then results are returned for all * naming authorities. If the naming authority is the empty string, * i.e. "", then the default naming authority, "IANA", is used. "IANA" * is not a valid naming authority name, and it is a PARAMETER_BAD error * to include it explicitly. * * @par * The service type names are returned with the naming authority intact. * If the naming authority is the default (i.e. empty string) then it * is omitted, as is the separating ".". Service type names from URLs * of the service: scheme are returned with the "service:" prefix * intact. [RFC 2608] See [RFC 2609] for more information on the * syntax of service type names. * * @param[in] hSLP - The SLPHandle on which to search for types. * @param[in] pcNamingAuthority - The naming authority to search. Use "*" * for all naming authorities and the empty string, "", for the default * naming authority. * @param[in] pcScopeList - A pointer to a char containing comma separated * list of scope names to search for service types. May not be the empty * string, "". * @param[in] callback - A callback function through which the results of * the operation are reported. * @param[in] pvCookie - Memory passed to the @p callback code from the * client. May be NULL. * * @return If an error occurs in starting the operation, one of the * SLPError codes is returned. */ SLPError SLPAPI SLPFindSrvTypes( SLPHandle hSLP, const char * pcNamingAuthority, const char * pcScopeList, SLPSrvTypeCallback callback, void * pvCookie) { bool inuse; SLPError serr = 0; SLPHandleInfo * handle = hSLP; /* Check for invalid parameters. */ SLP_ASSERT(handle != 0); SLP_ASSERT(handle->sig == SLP_HANDLE_SIG); SLP_ASSERT(pcNamingAuthority != 0); SLP_ASSERT(strcmp(pcNamingAuthority, "IANA") != 0); SLP_ASSERT(callback != 0); if (handle == 0 || handle->sig != SLP_HANDLE_SIG || pcNamingAuthority == 0 || strcmp(pcNamingAuthority, "IANA") == 0 || callback == 0) return SLP_PARAMETER_BAD; /* Check to see if the handle is in use. */ inuse = SLPSpinLockTryAcquire(&handle->inUse); SLP_ASSERT(!inuse); if (inuse) return SLP_HANDLE_IN_USE; /* Get a scope list if none was specified. */ if (pcScopeList == 0 || *pcScopeList == 0) pcScopeList = SLPPropertyGet("net.slp.useScopes", 0, 0); /* Set the handle up to reference parameters. */ handle->params.findsrvtypes.namingauthlen = strlen(pcNamingAuthority); handle->params.findsrvtypes.namingauth = pcNamingAuthority; handle->params.findsrvtypes.scopelistlen = strlen(pcScopeList); handle->params.findsrvtypes.scopelist = pcScopeList; handle->params.findsrvtypes.callback = callback; handle->params.findsrvtypes.cookie = pvCookie; /* Check to see if we should be async or sync. */ #ifdef ENABLE_ASYNC_API if (handle->isAsync) { /* Copy all the referenced parameters. */ handle->params.findsrvtypes.namingauth = xstrdup(handle->params.findsrvtypes.namingauth); handle->params.findsrvtypes.scopelist = xstrdup(handle->params.findsrvtypes.scopelist); /* Ensure strdups and thread create succeed. */ if (handle->params.findsrvtypes.namingauth == 0 || handle->params.findsrvtypes.scopelist == 0 || (handle->th = SLPThreadCreate((SLPThreadStartProc) AsyncProcessSrvTypeRqst, handle)) == 0) { serr = SLP_MEMORY_ALLOC_FAILED; xfree((void *)handle->params.findsrvtypes.namingauth); xfree((void *)handle->params.findsrvtypes.scopelist); SLPSpinLockRelease(&handle->inUse); } return serr; } #endif /* Reference all parameters. */ serr = ProcessSrvTypeRqst(handle); SLPSpinLockRelease(&handle->inUse); return serr; }
int main(int argc, char * argv[]) { int ec, nval, ival; bool bval; int ivec[10]; FILE * fp; char const * pval; /* create a global configuration file */ fp = fopen(TEST_G_CFG_FILENAME, "w+"); if (!fp) return FAIL; fputs("\n", fp); fputs(" \n", fp); fputs("# This is a comment.\n", fp); fputs(" # This is another comment.\n", fp); fputs(" \t\f# This is the last comment.\n", fp); fputs("\t\t \f\tStrange Text with no equals sign\n", fp); fputs("net.slp.isDA=true\n", fp); /* default value is false */ fputs("net.slp.DAHeartBeat = 10801\n", fp); fputs("net.slp.DAAttributes=\n", fp); fputs("net.slp.useScopes =DEFAULT\n", fp); fputs("net.slp.DAAddresses\t\t\t= \n", fp); fputs("net.slp.traceDATraffic = true\n", fp); fputs("net.slp.multicastTimeouts=1001,1251,1501,2001,4001\n", fp); fclose(fp); /* create an application configuration file */ fp = fopen(TEST_A_CFG_FILENAME, "w+"); if (!fp) return FAIL; fputs("net.slp.DAHeartBeat = 10802\n", fp); fclose(fp); /* specify app configuration file */ ec = SLPPropertySetAppConfFile(TEST_A_CFG_FILENAME); if (ec != 0) return FAIL; /* specify global configuration file - initialize */ ec = SLPPropertyInit(TEST_G_CFG_FILENAME); if (ec != 0) return FAIL; /* set a mutable value */ ec = SLPPropertySet("net.slp.traceDATraffic", "false", 0); if (ec != 0) return FAIL; /* set a user-only settable value */ ec = SLPPropertySet("net.slp.isDA", "false", SLP_PA_USERSET); if (ec != 0) return FAIL; pval = SLPPropertyGet("net.slp.traceDATraffic", 0, 0); if (pval == 0 || strcmp(pval, "false") != 0) return FAIL; ival = SLPPropertyAsInteger("net.slp.DAHeartBeat"); if (ival != 10802) return FAIL; bval = SLPPropertyAsBoolean("net.slp.isDA"); if (bval != false) return FAIL; nval = SLPPropertyAsIntegerVector("net.slp.multicastTimeouts", ivec, 10); if (nval != 5 || ivec[0] != 1001 || ivec[1] != 1251 || ivec[2] != 1501 || ivec[3] != 2001 || ivec[4] != 4001) return FAIL; ival = SLPPropertyAsInteger("net.slp.fake"); if (ival != 0) return FAIL; bval = SLPPropertyAsBoolean("net.slp.fake"); if (bval != false) return FAIL; nval = SLPPropertyAsIntegerVector("net.slp.fake", ivec, 10); if (nval != 0) return FAIL; pval = SLPPropertyGet("net.slp.OpenSLPConfigFile", 0, 0); if (pval == 0 || strcmp(pval, TEST_G_CFG_FILENAME) != 0) return FAIL; /* reset a user-only settable value - indicate non-user is setting */ ec = SLPPropertySet("net.slp.isDA", "true", 0); if (ec == 0) return FAIL; /* reset a user-only settable value - indicate user is setting */ ec = SLPPropertySet("net.slp.isDA", "true", SLP_PA_USERSET); if (ec != 0) return FAIL; SLPPropertyExit(); unlink(TEST_A_CFG_FILENAME); unlink(TEST_G_CFG_FILENAME); return PASS; }