]> arthur.barton.de Git - netatalk.git/blobdiff - etc/afpd/afp_mdns.c
Set Tracker environment variabel TRACKER_USE_LOG_FILES in order to force logging...
[netatalk.git] / etc / afpd / afp_mdns.c
index 6b2ba5bacbe5574ab42c605c447a8499258c65dc..3158ce7b7fee9ef3058563309151defdc211b53b 100644 (file)
 #include <atalk/util.h>
 #include <atalk/dsi.h>
 #include <atalk/unicode.h>
+#include <atalk/netatalk_conf.h>
 
 #include "afp_zeroconf.h"
 #include "afp_mdns.h"
-#include "afp_config.h"
-#include "volume.h"
 
 /*
  * We'll store all the DNSServiceRef's here so that we can
@@ -51,15 +50,16 @@ static pthread_t       poller;
         free(str); free(key);                           \
     }
 
+static struct pollfd *fds;
 
 /*
  * This is the thread that polls the filehandles
  */
-void *polling_thread(void *arg) {
+static void *polling_thread(void *arg) {
     // First we loop through getting the filehandles and adding them to our poll, we
     // need to allocate our pollfd's
     DNSServiceErrorType error;
-    struct pollfd           *fds = calloc(svc_ref_count, sizeof(struct pollfd));
+    fds = calloc(svc_ref_count, sizeof(struct pollfd));
     assert(fds);
 
     for(int i=0; i < svc_ref_count; i++) {
@@ -79,28 +79,32 @@ void *polling_thread(void *arg) {
     return(NULL);
 }
 
-
 /*
  * This is the callback for the service register function ... actually there isn't a lot
  * we can do if we get problems, so we don't really need to do anything other than report
  * the issue.
  */
-void RegisterReply(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode,
-                   const char *name, const char *regtype, const char *domain, void *context) {
-
-    if(errorCode != kDNSServiceErr_NoError) {
+static void RegisterReply(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode,
+                          const char *name, const char *regtype, const char *domain, void *context)
+{
+    if (errorCode != kDNSServiceErr_NoError) {
         LOG(log_error, logtype_afpd, "Failed to register mDNS service: %s%s%s: code=%d",
             name, regtype, domain, errorCode);
     }
 }
 
-
 /*
  * This function unregisters anything we have already
  * registered and frees associated memory
  */
 static void unregister_stuff() {
-    pthread_kill(poller, SIGKILL);
+    pthread_cancel(poller);    
+
+    for (int i = 0; i < svc_ref_count; i++)
+        close(fds[i].fd);
+    free(fds);
+    fds = NULL;
+
     if(svc_refs) {
         for(int i=0; i < svc_ref_count; i++) {
             DNSServiceRefDeallocate(svc_refs[i]);
@@ -115,9 +119,8 @@ static void unregister_stuff() {
  * This function tries to register the AFP DNS
  * SRV service type.
  */
-static void register_stuff(const AFPConfig *configs) {
+static void register_stuff(const AFPObj *obj) {
     uint                                        port;
-    const AFPConfig                 *config;
     const struct vol                *volume;
     DSI                                         *dsi;
     char                                        name[MAXINSTANCENAMELEN+1];
@@ -159,10 +162,10 @@ static void register_stuff(const AFPConfig *configs) {
 
     // Now we can count the configs so we know how many service
     // records to allocate
-    for (config = configs; config; config = config->next) {
+    for (dsi = obj->dsi; dsi; dsi = dsi->next) {
         svc_ref_count++;                    // AFP_DNS_SERVICE_TYPE
-        if(i) svc_ref_count++;      // ADISK_SERVICE_TYPE
-        if (config->obj.options.mimicmodel) svc_ref_count++;        // DEV_INFO_SERVICE_TYPE
+        if (i) svc_ref_count++;      // ADISK_SERVICE_TYPE
+        if (obj->options.mimicmodel) svc_ref_count++;        // DEV_INFO_SERVICE_TYPE
     }
 
     // Allocate the memory to store our service refs
@@ -171,16 +174,13 @@ static void register_stuff(const AFPConfig *configs) {
     svc_ref_count = 0;
 
     /* AFP server */
-    for (config = configs; config; config = config->next) {
+    for (dsi = obj->dsi; dsi; dsi = dsi->next) {
 
-        dsi = (DSI *)config->obj.handle;
         port = getip_port((struct sockaddr *)&dsi->server);
 
-        if (convert_string(config->obj.options.unixcharset,
+        if (convert_string(obj->options.unixcharset,
                            CH_UTF8,
-                           config->obj.options.server ?
-                           config->obj.options.server :
-                           config->obj.options.hostname,
+                           obj->options.hostname,
                            -1,
                            name,
                            MAXINSTANCENAMELEN) <= 0) {
@@ -233,9 +233,11 @@ static void register_stuff(const AFPConfig *configs) {
             }
         }
 
-        if (config->obj.options.mimicmodel) {
+        if (obj->options.mimicmodel) {
+            LOG(log_info, logtype_afpd, "Registering server '%s' with model '%s'",
+                dsi->bonjourname, obj->options.mimicmodel);
             TXTRecordCreate(&txt_devinfo, 0, NULL);
-            TXTRecordPrintf(&txt_devinfo, "model", config->obj.options.mimicmodel);
+            TXTRecordPrintf(&txt_devinfo, "model", obj->options.mimicmodel);
             error = DNSServiceRegister(&svc_refs[svc_ref_count++],
                                        0,               // no flags
                                        0,               // all network interfaces
@@ -243,7 +245,14 @@ static void register_stuff(const AFPConfig *configs) {
                                        DEV_INFO_SERVICE_TYPE,
                                        "",            // default domains
                                        NULL,            // default host name
-                                       htons(port),
+                                       /*
+                                        * We would probably use port 0 zero, but we can't, from man DNSServiceRegister:
+                                        *   "A value of 0 for a port is passed to register placeholder services.
+                                        *    Place holder services are not found  when browsing, but other
+                                        *    clients cannot register with the same name as the placeholder service."
+                                        * We therefor use port 9 which is used by the adisk service type.
+                                        */
+                                       htons(9),
                                        TXTRecordGetLength(&txt_devinfo),
                                        TXTRecordGetBytesPtr(&txt_devinfo),
                                        RegisterReply,           // callback
@@ -279,10 +288,10 @@ fail:
  * Tries to setup the Zeroconf thread and any
  * neccessary config setting.
  */
-void md_zeroconf_register(const AFPConfig *configs) {
+void md_zeroconf_register(const AFPObj *obj) {
     int error;
 
-    register_stuff(configs);
+    register_stuff(obj);
     return;
 }