Exemple #1
0
/** Associates a unicast IP address with an open SLP handle.
 *
 * Associates an IP address @p unicast_ip with a particular SLPHandle 
 * @p hSLP. @p unicast_ip is the IP address of the SA/DA from which service
 * is requested.
 *
 * @param[in] hSLP - The SLPHandle with which the @p unicast_ip address is 
 *    to be associated.
 *
 * @param[in] unicast_ip - IP address of the SA/DA from which service 
 *    is requested.
 *
 * @return An SLPError code.
 */
SLPEXP SLPError SLPAPI SLPAssociateIP(
      SLPHandle hSLP, 
      const char * unicast_ip)
{
#ifndef UNICAST_NOT_SUPPORTED
   SLPHandleInfo * handle;
   int result;

   SLP_ASSERT(hSLP != 0);
   SLP_ASSERT(*(unsigned int *)hSLP == SLP_HANDLE_SIG);
   SLP_ASSERT(unicast_ip != 0);
   SLP_ASSERT(*unicast_ip != 0);

   /* check for invalid parameters */
   if (!hSLP || *(unsigned int*)hSLP != SLP_HANDLE_SIG
         || !unicast_ip || !*unicast_ip)
      return SLP_PARAMETER_BAD;

   handle = (SLPHandleInfo *)hSLP;
   handle->dounicast = SLP_TRUE;

   /** @todo Verify error conditions in associate ip address. */

   result = SLPNetResolveHostToAddr(unicast_ip, &handle->ucaddr);
   if (SLPNetSetPort(&handle->ucaddr, (uint16_t)SLPPropertyAsInteger("net.slp.port")) != 0)
      return SLP_PARAMETER_BAD;

   return SLP_OK;
#else
   (void)hSLP;
   (void)unicast_ip;
   return SLP_NOT_IMPLEMENTED;
#endif   /* ! UNICAST_NOT_SUPPORTED */
}
Exemple #2
0
/** Gets the SNDBUF and RCVBUF sizes.
 *
 * @param[in] sndBufSize - A poniter to the integer to which global SNDBUF
 *                          value is assigned
 * @param[in] sndBufSize - A poniter to the integer to which global RCVBUF
 *                          value is assigned
 */
void SLPPropertyInternalGetSndRcvBufSize(int *sndBufSize, int *rcvBufSize)
{
   SLP_ASSERT(sndBufSize);
   SLP_ASSERT(rcvBufSize);
   *sndBufSize = s_GlobalPropertyInternalSndBufSize;
   *rcvBufSize = s_GlobalPropertyInternalRcvBufSize;
}
Exemple #3
0
/** Associates an interface list with an SLP handle.
 *
 * Associates a list of interfaces @p McastIFList on which multicast needs
 * to be done with a particular SLPHandle @p hSLP. @p McastIFList is a comma 
 * separated list of host interface IP addresses.
 *
 * @param[in] hSLP - The SLPHandle with which the interface list is to be 
 *    associated with.
 *
 * @param[in] McastIFList - A comma separated list of host interface IP 
 *    addresses on which multicast needs to be done.
 *
 * @return An SLPError code.
 */
SLPEXP SLPError SLPAPI SLPAssociateIFList(
      SLPHandle hSLP, 
      const char * McastIFList)
{
#ifndef MI_NOT_SUPPORTED
   SLPHandleInfo * handle;

   SLP_ASSERT(hSLP != 0);
   SLP_ASSERT(*(unsigned int *)hSLP == SLP_HANDLE_SIG);
   SLP_ASSERT(McastIFList != 0);
   SLP_ASSERT(*McastIFList != 0);

   /* check for invalid parameters */
   if (!hSLP || *(unsigned int*)hSLP != SLP_HANDLE_SIG 
         || !McastIFList || !*McastIFList)
      return SLP_PARAMETER_BAD;

   handle = (SLPHandleInfo *)hSLP;

   /** @todo Copy the interface list, rather than just assign it. */

   handle->McastIFList = McastIFList;

   return SLP_OK;
#else
   (void)hSLP;
   (void)McastIFList;
   return SLP_NOT_IMPLEMENTED;
#endif   /* ! MI_NOT_SUPPORTED */
}
Exemple #4
0
/** Returns local hostname.
 *
 * @param[out] hostfdn - A pointer to char pointer that is set to buffer 
 *    contining this machine's FDN.
 * @param[in] hostfdnLen - The length of @p hostfdn. 
 * @param[in] numeric_only - A flag that forces the return of numeric 
 *    addresss.
 * @param[in] family - A hint: The family to get info for - can be 
 *    AF_INET, AF_INET6, or AF_UNSPEC for both.
 *
 * @remarks Caller must free returns @p hostfdn string with xfree.
 */
static int SLPNetGetThisHostname(char * hostfdn, size_t hostfdnLen,
      int numeric_only, int family)
{
   char host[MAX_HOST_NAME];
   struct addrinfo * ifaddr;
   struct addrinfo hints;
   int sts = 0;

   *hostfdn = 0;

   memset(&hints, 0, sizeof(hints));
   hints.ai_socktype = SOCK_STREAM;
   hints.ai_family = family;
   if (gethostname(host, MAX_HOST_NAME) == 0)
   {
      sts = getaddrinfo(host, 0, &hints, &ifaddr);
      if (sts == 0)
      {
         /* If the hostname has a '.' then it is probably a qualified 
          * domain name. If it is not then we better use the IP address.
          */ 
         if (!numeric_only && strchr(host, '.'))
            strncpy(hostfdn, host, hostfdnLen);
         else
            sts = SLPNetAddrInfoToString(ifaddr, hostfdn, hostfdnLen);
         freeaddrinfo(ifaddr);
      }
      else
         SLP_ASSERT(1);  /* TODO: what? assert(1) does nothing by definition! */
   }
   return(sts);
}
Exemple #5
0
/** Convert an array of sockaddr_storage buffers to a comma-delimited list.
 * 
 * Converts an array of sockaddr_storage buffers to a comma-delimited list of
 * addresses in presentation (string) format.
 *
 * @param[in] addrs - A pointer to array of sockaddr_storages to convert.
 * @param[in] addrcount - The number of elements in @p addrs.
 * @param[out] addrstr - The address in which to return a pointer to an
 *    allocated comma-delimited list of addresses.
 *
 * @return Zero on success, non-zero (with errno set) on error.
 *
 * @remarks The caller must free @p addrstr when no longer needed.
 */
int SLPIfaceSockaddrsToString(struct sockaddr_storage const * addrs,
      int addrcount, char ** addrstr)
{
   int i;

   SLP_ASSERT(addrs && addrcount && addrstr);
   if (!addrs || !addrcount || !addrstr)
      return (errno = EINVAL), -1;

   /* 40 is the maximum size of a string representation of
    * an IPv6 address (including the comma for the list) 
    */
   if ((*addrstr = xmalloc(addrcount * 40)) == 0)
      return (errno = ENOMEM), -1;

   **addrstr = 0;

   for (i = 0; i < addrcount; i++)
   {
      char buf[1024] = "";

      SLPNetSockAddrStorageToString(&addrs[i], buf, sizeof(buf));

      strcat(*addrstr, buf);
      if (i != addrcount - 1)
         strcat(*addrstr, ",");
   }
   return 0;
}  
Exemple #6
0
/** Return a property by name.
 * 
 * This is the internal property access routine. If the @p buffer and @p bufszp
 * parameters are used, then this routine will return a copy of the internal
 * value string. Otherwise it returns a pointer to the internal value string.
 *
 * @param[in] name - The name of the property to return.
 * @param[out] buffer - The address of storage for the requested property 
 *    value. This parameter is optional, and may be specified as NULL.
 * @param[in/out] bufszp - On entry, contains the size of @p buffer. On exit,
 *    returns the number of bytes used or required. If @p buffer is too small
 *    then this parameter returns the number of bytes required to return all
 *    of the value. If too large, then this parameter returns the number of 
 *    bytes used in @p buffer.
 * 
 * @return A pointer to the value of the property named by @p name. If the
 *    @p buffer and @p bufszp parameters are specified, returns a pointer to
 *    @p buffer, otherwise a pointer to the internal value buffer is returned.
 * 
 * @remarks If an internal value string pointer is returned, then OpenSLP 
 * is absolved of all responsibility regarding concurrent access to the 
 * internal property database.
 * 
 * @remarks The correct way to call this routine with a @p buffer parameter
 * is to size the buffer as appropriate, or size it to zero. This routine will
 * return the required size in *bufszp. Then call it again with a @p buffer
 * parameter of the returned size. If @p bufszp is returned containing any
 * value less than or equal to the originally specified size, then the caller
 * knows that the entire value was returned in @p buffer.
 */
char const * SLPPropertyGet(char const * name, char * buffer, size_t * bufszp)
{
   SLPProperty * property;
   char const * retval = buffer;
   size_t bufsz = bufszp? *bufszp: 0;

   /* parameter sanity check */
   SLP_ASSERT(name && (bufsz || !buffer));
   if (!name || (buffer && !bufsz))
      return 0;

   if (bufszp) *bufszp = 0;

   SLPMutexAcquire(s_PropDbLock);

   if ((property = Find(name)) != 0)
   {
      char const * value = property->value;
      if (buffer)
      {
         size_t valsz = strlen(value);
         *bufszp = valsz;
         if (valsz > bufsz)
            valsz = bufsz;
         memcpy(buffer, value, valsz - 1);
         buffer[valsz - 1] = 0;
      }
      else
         retval = value;
   }

   SLPMutexRelease(s_PropDbLock);

   return retval;
}
Exemple #7
0
/** Close an SLP handle.
 *
 * @param[in] hSLP - The handle to be closed.
 */
SLPEXP void SLPAPI SLPClose(SLPHandle hSLP)
{
   SLPHandleInfo * handle = hSLP;

   /* Check for invalid parameters. */
   SLP_ASSERT(handle != 0);
   SLP_ASSERT(handle->sig == SLP_HANDLE_SIG);

   if (!handle || handle->sig != SLP_HANDLE_SIG)
      return;

#ifdef ENABLE_ASYNC_API
   if (handle->isAsync)
      SLPThreadWait(handle->th);
#endif

   SLP_ASSERT(handle->inUse == 0);

#ifdef ENABLE_SLPv2_SECURITY
   if (handle->hspi) 
      SLPSpiClose(handle->hspi);
#endif

   if (handle->langtag)
      xfree(handle->langtag);

#ifndef UNICAST_NOT_SUPPORTED
   xfree(handle->unicastscope);
   if (handle->unicastsock != SLP_INVALID_SOCKET)
      closesocket(handle->dasock);
#endif

   xfree(handle->sascope);
   if (handle->sasock != SLP_INVALID_SOCKET)
      closesocket(handle->sasock);

   xfree(handle->dascope);
   if (handle->dasock != SLP_INVALID_SOCKET)
      closesocket(handle->dasock);

   handle->sig = 0;
   xfree(handle);
   ExitUserAgentLibrary();
}
Exemple #8
0
/** Set a new value for a property by name.
 * 
 * If the value is NULL or empty, then simply erase the existing value and
 * return.
 *
 * @param[in] name - The name of the desired property.
 * @param[in] value - The new value to which @p name should be set or
 *    NULL if the existing value should be removed.
 * @param[in] attrs - The attributes of this property - zero means no
 *    attributes are assigned, other values include SLP_PA_USERSET and 
 *    SLP_PA_READONLY.
 *
 * @return Zero on success; -1 on error, with errno set.
 * 
 * @remarks The @p attrs parameter contains a set of bit flags indicating
 * various attributes of the property. These attributes control write 
 * permissions mostly. SLP_PA_USERSET means that an attribute may not
 * be changed by reading a configuration file, except in a complete 
 * re-initialization scenario. SLP_PA_READONLY sounds like the same thing, 
 * but it's not. The difference is that once set, properties with the 
 * SLP_PA_READONLY attribute may NEVER be reset (again, except in a complete 
 * re-initialization scenario), while properties with the SLP_PA_USERSET 
 * attribute may only be reset by passing this same flag in @p attrs, 
 * indicating that the caller is actually a user, and so has the right
 * to reset the property value.
 */
int SLPPropertySet(char const * name, char const * value, unsigned attrs)
{
   size_t namesz, valuesz;
   SLPProperty * oldprop;
   SLPProperty * newprop = 0;    /* we may be just removing the old */
   bool update = true;           /* reset if old property exists */

   /* property names must not be null or empty */
   SLP_ASSERT(name && *name);
   if (!name || !*name)
      return -1;

   if (value)
   {
      /* allocate property entry for this new value */
      namesz = strlen(name) + 1;
      valuesz = strlen(value) + 1;
      if ((newprop = (SLPProperty*)xmalloc(
            sizeof(SLPProperty) - 1 + namesz + valuesz)) == 0)
      {
         errno = ENOMEM;
         return -1;
      }

      /* set internal pointers to trailing buffer space, copy values */
      newprop->attrs = attrs;
      memcpy(newprop->name, name, namesz);
      newprop->value = newprop->name + namesz;
      memcpy(newprop->value, value, valuesz);
   }

   SLPMutexAcquire(s_PropDbLock);

   /* locate and possibly remove old property */
   if ((oldprop = Find(name))!= 0)
   {
      /* update ONLY if old is clean, or new and old are user-settable . */
      update = !oldprop->attrs 
            || (oldprop->attrs == SLP_PA_USERSET && attrs == SLP_PA_USERSET);
      if (update)
         SLPListUnlink(&s_PropertyList, (SLPListItem *)oldprop);
   }

   /* link in new property, if specified and old property was removed */
   if (newprop && update)
      SLPListLinkHead(&s_PropertyList, (SLPListItem *)newprop);

   SLPMutexRelease(s_PropDbLock);

   /* if old property was not removed, delete the new one instead */
   xfree(update? oldprop: newprop);

   return update? 0: ((errno = EACCES), -1);
}
Exemple #9
0
/** Return an allocated copy of a property by name.
 * 
 * @param[in] name - The name of the property to return.
 * 
 * @return A pointer to an allocated buffer containing a copy of the property
 *    named by @p name.
 * 
 * @remarks The caller is responsible for releasing the memory returned by 
 * calling xfree on it.
 */
char * SLPPropertyXDup(const char * name)
{
   char * retval = 0;
   SLPProperty * property;

   /* parameter sanity check */
   SLP_ASSERT(name);
   if (!name)
      return 0;

   SLPMutexAcquire(s_PropDbLock);

   if ((property = Find(name)) != 0)
      retval = xstrdup(property->value);

   SLPMutexRelease(s_PropDbLock);

   return retval;
}
Exemple #10
0
SLPError SLPAttrSerialize(SLPAttributes attr_h,
      const char * tags /* NULL terminated */,
      char ** out_buffer /* Where to write. if *out_buffer == NULL, space is alloc'd */,
      size_t bufferlen, /* Size of buffer. */
      size_t * count, /* Bytes needed/written. */
      SLPBoolean find_delta)
{
   struct xx_TinyAttr * slp_attr = (struct xx_TinyAttr *) attr_h;

   /* Write the amount of space we need. */
   if (count != NULL)
   {
      *count = slp_attr->attr_len + 1; /* For the null. */
   }

   /* Check that we have somewhere to write to. */
   if (bufferlen < slp_attr->attr_len + 1)
   {
      /* +1 for null. */
      return SLP_BUFFER_OVERFLOW;
   }
   SLP_ASSERT(out_buffer != NULL && *out_buffer != NULL); /* Verify we have somewhere to write. */


   /* Check for empty string. */
   if (slp_attr->attr_len == 0)
   {
      **out_buffer = 0; /* Empty string. */
      return SLP_OK;
   }

   /* Copy. */
   strcpy(*out_buffer, slp_attr->attributes);

   return SLP_OK;
}
Exemple #11
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;
}
Exemple #12
0
/** 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;
}
Exemple #13
0
/** 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;
}
Exemple #14
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;
}