/** Thread start procedure for asynchronous find services request. * * @param[in,out] handle - Contains the request parameters, returns the * request result. * * @return An SLPError code. * * @internal */ static SLPError AsyncProcessSrvRqst(SLPHandleInfo * handle) { SLPError serr = ProcessSrvRqst(handle); xfree((void *)handle->params.findsrvs.srvtype); xfree((void *)handle->params.findsrvs.scopelist); xfree((void *)handle->params.findsrvs.predicate); SLPSpinLockRelease(&handle->inUse); return serr; }
/** Thread start procedure for asynchronous service registration. * * @param[in] handle - Contains the request parameters. * * @return An SLPError code. * * @internal */ static SLPError AsyncProcessSrvReg(SLPHandleInfo * handle) { SLPError serr = ProcessSrvReg(handle); 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); return serr; }
/** 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; }
/** 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; }