summaryrefslogtreecommitdiff
path: root/source3/smbd/avahi_register.c
diff options
context:
space:
mode:
authorOmri Mor <omri50@gmail.com>2017-10-01 21:39:47 -0500
committerRalph Boehme <slow@samba.org>2017-10-04 10:06:15 +0200
commit127b18eb96cb5defa025e27ff38526cdc2ea30a6 (patch)
tree18fcdb6d8182683956f3848b51f264b9459ce447 /source3/smbd/avahi_register.c
parent4d6544593b9dc789cc6b34cd24e557e0379a8e73 (diff)
downloadsamba-127b18eb96cb5defa025e27ff38526cdc2ea30a6.tar.gz
s3/smbd: register Time Machine shares with Avahi
Adds support for automatically registering the required _adisk._tcp mDNS record based on the setting of "fruit:time machine". Signed-off-by: Omri Mor <omri50@gmail.com> Reviewed-by: Ralph Boehme <slow@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3/smbd/avahi_register.c')
-rw-r--r--source3/smbd/avahi_register.c97
1 files changed, 96 insertions, 1 deletions
diff --git a/source3/smbd/avahi_register.c b/source3/smbd/avahi_register.c
index c118e61ccc2..91e8a439b84 100644
--- a/source3/smbd/avahi_register.c
+++ b/source3/smbd/avahi_register.c
@@ -24,6 +24,8 @@
#include <avahi-client/client.h>
#include <avahi-client/publish.h>
#include <avahi-common/error.h>
+#include <avahi-common/malloc.h>
+#include <avahi-common/strlst.h>
struct avahi_state_struct {
struct AvahiPoll *poll;
@@ -32,6 +34,39 @@ struct avahi_state_struct {
uint16_t port;
};
+static void *avahi_allocator_ctx = NULL;
+
+static void * avahi_allocator_malloc(size_t size)
+{
+ return talloc_size(avahi_allocator_ctx, size);
+}
+
+static void avahi_allocator_free(void *p)
+{
+ TALLOC_FREE(p);
+}
+
+static void * avahi_allocator_realloc(void *p, size_t size)
+{
+ return talloc_realloc_size(avahi_allocator_ctx, p, size);
+}
+
+static void * avahi_allocator_calloc(size_t count, size_t size)
+{
+ void *p = talloc_array_size(avahi_allocator_ctx, size, count);
+ if (p) {
+ memset(p, 0, size * count);
+ }
+ return p;
+}
+
+static const struct AvahiAllocator avahi_talloc_allocator = {
+ &avahi_allocator_malloc,
+ &avahi_allocator_free,
+ &avahi_allocator_realloc,
+ &avahi_allocator_calloc
+};
+
static void avahi_entry_group_callback(AvahiEntryGroup *g,
AvahiEntryGroupState status,
void *userdata)
@@ -70,7 +105,13 @@ static void avahi_client_callback(AvahiClient *c, AvahiClientState status,
int error;
switch (status) {
- case AVAHI_CLIENT_S_RUNNING:
+ case AVAHI_CLIENT_S_RUNNING: {
+ int snum;
+ int num_services = lp_numservices();
+ int dk = 0;
+ AvahiStringList *adisk = NULL;
+ AvahiStringList *adisk2 = NULL;
+
DBG_DEBUG("AVAHI_CLIENT_S_RUNNING\n");
state->entry_group = avahi_entry_group_new(
@@ -94,6 +135,53 @@ static void avahi_client_callback(AvahiClient *c, AvahiClientState status,
break;
}
+ for (snum = 0; snum < num_services; snum++) {
+ if (lp_snum_ok(snum) &&
+ lp_parm_bool(snum, "fruit", "time machine", false))
+ {
+ adisk2 = avahi_string_list_add_printf(
+ adisk, "dk%d=adVN=%s,adVF=0x82",
+ dk++, lp_const_servicename(snum));
+ if (adisk2 == NULL) {
+ DBG_DEBUG("avahi_string_list_add_printf"
+ "failed: returned NULL\n");
+ avahi_string_list_free(adisk);
+ avahi_entry_group_free(state->entry_group);
+ state->entry_group = NULL;
+ break;
+ }
+ adisk = adisk2;
+ adisk2 = NULL;
+ }
+ }
+ if (dk > 0) {
+ adisk2 = avahi_string_list_add(adisk, "sys=adVF=0x100");
+ if (adisk2 == NULL) {
+ DBG_DEBUG("avahi_string_list_add failed: "
+ "returned NULL\n");
+ avahi_string_list_free(adisk);
+ avahi_entry_group_free(state->entry_group);
+ state->entry_group = NULL;
+ break;
+ }
+ adisk = adisk2;
+ adisk2 = NULL;
+
+ error = 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);
+ adisk = NULL;
+ if (error != AVAHI_OK) {
+ 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;
+ }
+ }
+
error = avahi_entry_group_commit(state->entry_group);
if (error != AVAHI_OK) {
DBG_DEBUG("avahi_entry_group_commit failed: %s\n",
@@ -103,6 +191,7 @@ static void avahi_client_callback(AvahiClient *c, AvahiClientState status,
break;
}
break;
+ }
case AVAHI_CLIENT_FAILURE:
error = avahi_client_errno(c);
@@ -139,6 +228,12 @@ void *avahi_start_register(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
struct avahi_state_struct *state;
int error;
+ avahi_allocator_ctx = talloc_new(mem_ctx);
+ if (avahi_allocator_ctx == NULL) {
+ return NULL;
+ }
+ avahi_set_allocator(&avahi_talloc_allocator);
+
state = talloc(mem_ctx, struct avahi_state_struct);
if (state == NULL) {
return state;