Add some compatibility defines to dnssd.c.
[deb_shairplay.git] / src / lib / dnssd.c
index 3f6d9cf283c748e77bcca4a0105a2a15ba8be31f..4859e3239c7aa569109a7d27933d4c67508fbb29 100644 (file)
  *  Lesser General Public License for more details.
  */
 
+/* These defines allow us to compile on iOS */
+#ifndef __has_feature
+# define __has_feature(x) 0
+#endif
+#ifndef __has_extension
+# define __has_extension __has_feature
+#endif
+
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <assert.h>
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "dnssd.h"
 #include "dnssdint.h"
 #include "global.h"
 #define MAX_DEVICEID 18
 #define MAX_SERVNAME 256
 
-#ifndef WIN32
-# include <dns_sd.h>
-# define DNSSD_STDCALL
-#else
-# include <stdint.h>
-# if !defined(EFI32) && !defined(EFI64)
-#  define DNSSD_STDCALL __stdcall
+#define USE_LIBDL (defined(HAVE_LIBDL) && !defined(__APPLE__))
+
+#if defined(WIN32) || USE_LIBDL
+# ifdef WIN32
+#  include <stdint.h>
+#  if !defined(EFI32) && !defined(EFI64)
+#   define DNSSD_STDCALL __stdcall
+#  else
+#   define DNSSD_STDCALL
+#  endif
 # else
+#  include <dlfcn.h>
 #  define DNSSD_STDCALL
 # endif
 
@@ -53,6 +69,10 @@ typedef void (DNSSD_STDCALL *DNSServiceRegisterReply)
     const char                          *domain,
     void                                *context
     );
+
+#else
+# include <dns_sd.h>
+# define DNSSD_STDCALL
 #endif
 
 typedef DNSServiceErrorType (DNSSD_STDCALL *DNSServiceRegister_t)
@@ -92,6 +112,8 @@ typedef const void * (DNSSD_STDCALL *TXTRecordGetBytesPtr_t)(const TXTRecordRef
 struct dnssd_s {
 #ifdef WIN32
        HMODULE module;
+#elif USE_LIBDL
+       void *module;
 #endif
 
        DNSServiceRegister_t       DNSServiceRegister;
@@ -144,6 +166,29 @@ dnssd_init(int *error)
                free(dnssd);
                return NULL;
        }
+#elif USE_LIBDL
+       dnssd->module = dlopen("libdns_sd.so", RTLD_LAZY);
+       if (!dnssd->module) {
+               if (error) *error = DNSSD_ERROR_LIBNOTFOUND;
+               free(dnssd);
+               return NULL;
+       }
+       dnssd->DNSServiceRegister = (DNSServiceRegister_t)dlsym(dnssd->module, "DNSServiceRegister");
+       dnssd->DNSServiceRefDeallocate = (DNSServiceRefDeallocate_t)dlsym(dnssd->module, "DNSServiceRefDeallocate");
+       dnssd->TXTRecordCreate = (TXTRecordCreate_t)dlsym(dnssd->module, "TXTRecordCreate");
+       dnssd->TXTRecordSetValue = (TXTRecordSetValue_t)dlsym(dnssd->module, "TXTRecordSetValue");
+       dnssd->TXTRecordGetLength = (TXTRecordGetLength_t)dlsym(dnssd->module, "TXTRecordGetLength");
+       dnssd->TXTRecordGetBytesPtr = (TXTRecordGetBytesPtr_t)dlsym(dnssd->module, "TXTRecordGetBytesPtr");
+       dnssd->TXTRecordDeallocate = (TXTRecordDeallocate_t)dlsym(dnssd->module, "TXTRecordDeallocate");
+
+       if (!dnssd->DNSServiceRegister || !dnssd->DNSServiceRefDeallocate || !dnssd->TXTRecordCreate ||
+           !dnssd->TXTRecordSetValue || !dnssd->TXTRecordGetLength || !dnssd->TXTRecordGetBytesPtr ||
+           !dnssd->TXTRecordDeallocate) {
+               if (error) *error = DNSSD_ERROR_PROCNOTFOUND;
+               dlclose(dnssd->module);
+               free(dnssd);
+               return NULL;
+       }
 #else
        dnssd->DNSServiceRegister = &DNSServiceRegister;
        dnssd->DNSServiceRefDeallocate = &DNSServiceRefDeallocate;
@@ -163,13 +208,15 @@ dnssd_destroy(dnssd_t *dnssd)
        if (dnssd) {
 #ifdef WIN32
                FreeLibrary(dnssd->module);
+#elif USE_LIBDL
+               dlclose(dnssd->module);
 #endif
                free(dnssd);
        }
 }
 
 int
-dnssd_register_raop(dnssd_t *dnssd, const char *name, unsigned short port, const char *hwaddr, int hwaddrlen)
+dnssd_register_raop(dnssd_t *dnssd, const char *name, unsigned short port, const char *hwaddr, int hwaddrlen, int password)
 {
        TXTRecordRef txtRecord;
        char servname[MAX_SERVNAME];
@@ -188,13 +235,17 @@ dnssd_register_raop(dnssd_t *dnssd, const char *name, unsigned short port, const
        dnssd->TXTRecordSetValue(&txtRecord, "da", strlen(RAOP_DA), RAOP_DA);
        dnssd->TXTRecordSetValue(&txtRecord, "sr", strlen(RAOP_SR), RAOP_SR);
        dnssd->TXTRecordSetValue(&txtRecord, "ss", strlen(RAOP_SS), RAOP_SS);
-       dnssd->TXTRecordSetValue(&txtRecord, "pw", strlen(RAOP_PW), RAOP_PW);
+       if (password) {
+               dnssd->TXTRecordSetValue(&txtRecord, "pw", strlen("true"), "true");
+       } else {
+               dnssd->TXTRecordSetValue(&txtRecord, "pw", strlen("false"), "false");
+       }
        dnssd->TXTRecordSetValue(&txtRecord, "vn", strlen(RAOP_VN), RAOP_VN);
        dnssd->TXTRecordSetValue(&txtRecord, "tp", strlen(RAOP_TP), RAOP_TP);
        dnssd->TXTRecordSetValue(&txtRecord, "md", strlen(RAOP_MD), RAOP_MD);
        dnssd->TXTRecordSetValue(&txtRecord, "vs", strlen(GLOBAL_VERSION), GLOBAL_VERSION);
-       dnssd->TXTRecordSetValue(&txtRecord, "am", strlen(RAOP_AM), RAOP_AM);
-       dnssd->TXTRecordSetValue(&txtRecord, "sf", strlen(RAOP_SF), RAOP_SF);
+       dnssd->TXTRecordSetValue(&txtRecord, "sm", strlen(RAOP_SM), RAOP_SM);
+       dnssd->TXTRecordSetValue(&txtRecord, "ek", strlen(RAOP_EK), RAOP_EK);
 
        /* Convert hardware address to string */
        ret = utils_hwaddr_raop(servname, sizeof(servname), hwaddr, hwaddrlen);