vfs_fruit: Time Machine/FULLSYNC: add mDNS/DNS-SD advertisement

Omri Mor omri50 at gmail.com
Mon Jul 24 23:11:09 UTC 2017


Alright, so here’s the latest version, incorporating the previous suggestions.
It includes some modernizations to the existing code:
	DEBUG(10, …)	=>	DBG_DEBUG(…)
	if (… < 0)			=>	ret = …; if (ret < 0)
That can be easily split into a different patch.

If we want to include the UUID (adVU), we’ll need to figure out where to store it.
gencache isn’t appropriate, from what I can tell—storing there requires a timeout (as it’s a *cache*), which doesn’t make sense for a persistent UUID.
Perhaps secrets.tdb? The documentation says it stores “internal settings”, which the UUID would qualify for.
However, it’s not as if it’s ‘secret’ information, so I’m not sure if it’s a good fit.
Is there a database for generic, persistent data?

Omri

diff --git a/source3/smbd/avahi_register.c b/source3/smbd/avahi_register.c
index 368168d..5379705 100644
--- a/source3/smbd/avahi_register.c
+++ b/source3/smbd/avahi_register.c
@@ -18,12 +18,23 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+/*
+ * Avahi aborts on allocation failure (OOM),
+ * unless a custom allocator which doesn't do so has been set.
+ *
+ * This is particularly important for the avahi_string_list_*() functions,
+ * which return NULL on allocation failure.
+ * Since it should abort on allocation failure (before returning NULL),
+ * we don't check the result.
+ */
+
 #include "includes.h"
 #include "smbd/smbd.h"
 
 #include <avahi-client/client.h>
 #include <avahi-client/publish.h>
 #include <avahi-common/error.h>
+#include <avahi-common/strlst.h>
 
 struct avahi_state_struct {
 	struct AvahiPoll *poll;
@@ -42,27 +53,27 @@ static void avahi_entry_group_callback(AvahiEntryGroup *g,
 
 	switch (status) {
 	case AVAHI_ENTRY_GROUP_ESTABLISHED:
-		DEBUG(10, ("avahi_entry_group_callback: "
-			   "AVAHI_ENTRY_GROUP_ESTABLISHED\n"));
+		DBG_DEBUG("avahi_entry_group_callback: "
+			  "AVAHI_ENTRY_GROUP_ESTABLISHED\n");
 		break;
 	case AVAHI_ENTRY_GROUP_FAILURE:
 		error = avahi_client_errno(state->client);
 
-		DEBUG(10, ("avahi_entry_group_callback: "
-			   "AVAHI_ENTRY_GROUP_FAILURE: %s\n",
-			   avahi_strerror(error)));
+		DBG_DEBUG("avahi_entry_group_callback: "
+			  "AVAHI_ENTRY_GROUP_FAILURE: %s\n",
+			  avahi_strerror(error));
 		break;
 	case AVAHI_ENTRY_GROUP_COLLISION:
-		DEBUG(10, ("avahi_entry_group_callback: "
-			   "AVAHI_ENTRY_GROUP_COLLISION\n"));
+		DBG_DEBUG("avahi_entry_group_callback: "
+			  "AVAHI_ENTRY_GROUP_COLLISION\n");
 		break;
 	case AVAHI_ENTRY_GROUP_UNCOMMITED:
-		DEBUG(10, ("avahi_entry_group_callback: "
-                           "AVAHI_ENTRY_GROUP_UNCOMMITED\n"));
+		DBG_DEBUG("avahi_entry_group_callback: "
+                          "AVAHI_ENTRY_GROUP_UNCOMMITED\n");
 		break;
 	case AVAHI_ENTRY_GROUP_REGISTERING:
-		DEBUG(10, ("avahi_entry_group_callback: "
-                           "AVAHI_ENTRY_GROUP_REGISTERING\n"));
+		DBG_DEBUG("avahi_entry_group_callback: "
+                          "AVAHI_ENTRY_GROUP_REGISTERING\n");
 		break;
 	}
 }
@@ -75,42 +86,80 @@ static void avahi_client_callback(AvahiClient *c, AvahiClientState status,
 	int error;
 
 	switch (status) {
-	case AVAHI_CLIENT_S_RUNNING:
-		DEBUG(10, ("avahi_client_callback: AVAHI_CLIENT_S_RUNNING\n"));
+	case AVAHI_CLIENT_S_RUNNING: {
+		int ret;
+		int snum;
+		int num_services = lp_numservices();
+		int dk = 0;
+		AvahiStringList *adisk = NULL;
+
+		DBG_DEBUG("avahi_client_callback: AVAHI_CLIENT_S_RUNNING\n");
 
 		state->entry_group = avahi_entry_group_new(
 			c, avahi_entry_group_callback, state);
 		if (state->entry_group == NULL) {
 			error = avahi_client_errno(c);
-			DEBUG(10, ("avahi_entry_group_new failed: %s\n",
-				   avahi_strerror(error)));
+			DBG_DEBUG("avahi_entry_group_new failed: %s\n",
+				  avahi_strerror(error));
 			break;
 		}
-		if (avahi_entry_group_add_service(
+
+		ret = avahi_entry_group_add_service(
 			    state->entry_group, AVAHI_IF_UNSPEC,
 			    AVAHI_PROTO_UNSPEC, 0, lp_netbios_name(),
-			    "_smb._tcp", NULL, NULL, state->port, NULL) < 0) {
+			    "_smb._tcp", NULL, NULL, state->port, NULL);
+		if (ret < 0) {
 			error = avahi_client_errno(c);
-			DEBUG(10, ("avahi_entry_group_add_service failed: "
-				   "%s\n", avahi_strerror(error)));
+			DBG_DEBUG("avahi_entry_group_add_service failed: %s\n",
+				  avahi_strerror(error));
 			avahi_entry_group_free(state->entry_group);
 			state->entry_group = NULL;
 			break;
 		}
-		if (avahi_entry_group_commit(state->entry_group) < 0) {
+
+		for (snum = 0; snum < num_services; snum++) {
+			if (lp_snum_ok(snum) &&
+			    lp_parm_bool(snum, "fruit", "time machine", false))
+			{
+				adisk = avahi_string_list_add_printf(
+					    adisk, "dk%d=adVN=%s,adVF=0x82",
+					    dk++, lp_const_servicename(snum));
+			}
+		}
+		if (dk > 0) {
+			adisk = avahi_string_list_add(
+				    adisk, "sys=waMa=0,adVF=0x100");
+			ret = avahi_entry_group_add_service_strlst(
+				    state->entry_group, AVAHI_IF_UNSPEC,
+				    AVAHI_PROTO_UNSPEC, 0, lp_netbios_name(),
+				    "_adisk._tcp", NULL, NULL, 0, adisk);
+			avahi_string_list_free(adisk);
+			if (ret < 0) {
+				error = avahi_client_errno(c);
+				DBG_DEBUG("avahi_entry_group_add_service_strlst "
+					  "failed: %s\n", avahi_strerror(error));
+				avahi_entry_group_free(state->entry_group);
+				state->entry_group = NULL;
+				break;
+			}
+		}
+
+		ret = avahi_entry_group_commit(state->entry_group);
+		if (ret < 0) {
 			error = avahi_client_errno(c);
-			DEBUG(10, ("avahi_entry_group_commit failed: "
-				   "%s\n", avahi_strerror(error)));
+			DBG_DEBUG("avahi_entry_group_commit failed: %s\n",
+				  avahi_strerror(error));
 			avahi_entry_group_free(state->entry_group);
 			state->entry_group = NULL;
 			break;
 		}
 		break;
+	}
 	case AVAHI_CLIENT_FAILURE:
 		error = avahi_client_errno(c);
 
-		DEBUG(10, ("avahi_client_callback: AVAHI_CLIENT_FAILURE: %s\n",
-			   avahi_strerror(error)));
+		DBG_DEBUG("avahi_client_callback: AVAHI_CLIENT_FAILURE: %s\n",
+			  avahi_strerror(error));
 
 		if (error != AVAHI_ERR_DISCONNECTED) {
 			break;
@@ -120,22 +169,19 @@ static void avahi_client_callback(AvahiClient *c, AvahiClientState status,
 						 avahi_client_callback, state,
 						 &error);
 		if (state->client == NULL) {
-			DEBUG(10, ("avahi_client_new failed: %s\n",
-				   avahi_strerror(error)));
+			DBG_DEBUG("avahi_client_new failed: %s\n",
+				  avahi_strerror(error));
 			break;
 		}
 		break;
 	case AVAHI_CLIENT_S_COLLISION:
-		DEBUG(10, ("avahi_client_callback: "
-			   "AVAHI_CLIENT_S_COLLISION\n"));
+		DBG_DEBUG("avahi_client_callback: AVAHI_CLIENT_S_COLLISION\n");
 		break;
 	case AVAHI_CLIENT_S_REGISTERING:
-		DEBUG(10, ("avahi_client_callback: "
-			   "AVAHI_CLIENT_S_REGISTERING\n"));
+		DBG_DEBUG("avahi_client_callback: AVAHI_CLIENT_S_REGISTERING\n");
 		break;
 	case AVAHI_CLIENT_CONNECTING:
-		DEBUG(10, ("avahi_client_callback: "
-			   "AVAHI_CLIENT_CONNECTING\n"));
+		DBG_DEBUG("avahi_client_callback: AVAHI_CLIENT_CONNECTING\n");
 		break;
 	}
 }
@@ -159,8 +205,8 @@ void *avahi_start_register(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
 					 avahi_client_callback, state,
 					 &error);
 	if (state->client == NULL) {
-		DEBUG(10, ("avahi_client_new failed: %s\n",
-			   avahi_strerror(error)));
+		DBG_DEBUG("avahi_client_new failed: %s\n",
+			  avahi_strerror(error));
 		goto fail;
 	}
 	return state;



More information about the samba-technical mailing list