[SCM] Samba Shared Repository - branch v3-2-test updated - initial-v3-2-unstable-711-gdb74b99

James Peach jpeach at samba.org
Tue Dec 18 06:09:30 GMT 2007


The branch, v3-2-test has been updated
       via  db74b99d0ef1a60894c838b4c9d0d454db6cf620 (commit)
      from  92acc0115d8d4111289c2ade1db7bb060ee908db (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-2-test


- Log -----------------------------------------------------------------
commit db74b99d0ef1a60894c838b4c9d0d454db6cf620
Author: Rishi Srivatsavai <rishisv at gmail.com>
Date:   Mon Dec 17 22:09:09 2007 -0800

    Add smbclient support for basic mDNS browsing.
    
    Patch from Rishi Srivatsavai (bugzilla #4150), with tallocification
    and minor syle changes by me.

-----------------------------------------------------------------------

Summary of changes:
 source/Makefile.in        |    8 +-
 source/client/client.c    |    7 ++
 source/client/dnsbrowse.c |  236 +++++++++++++++++++++++++++++++++++++++++++++
 source/configure.in       |    1 +
 4 files changed, 250 insertions(+), 2 deletions(-)
 create mode 100644 source/client/dnsbrowse.c


Changeset truncated at 500 lines:

diff --git a/source/Makefile.in b/source/Makefile.in
index 21fc8ce..eda3297 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -673,6 +673,7 @@ LIBBIGBALLOFMUD_OBJ = $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(SECRETS_OBJ) \
 	$(GROUPDB_OBJ) $(KRBCLIENT_OBJ) $(SMBLDAP_OBJ) $(LDB_OBJ)
 
 CLIENT_OBJ1 = client/client.o client/clitar.o rpc_client/cli_pipe.o \
+	      client/dnsbrowse.o \
 	      $(RPC_CLIENT_OBJ1) \
 	      $(RPC_PARSE_OBJ2)
 
@@ -1140,7 +1141,8 @@ bin/smbd at EXEEXT@: $(BINARY_PREREQS) $(SMBD_OBJ) @BUILD_POPT@
 	@echo Linking $@
 	@$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) \
 		$(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \
-		$(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) @POPTLIBS@ @SMBD_LIBS@
+		$(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) $(DNSSD_LIBS) \
+		@POPTLIBS@ @SMBD_LIBS@
 
 bin/nmbd at EXEEXT@: $(BINARY_PREREQS) $(NMBD_OBJ) @BUILD_POPT@
 	@echo Linking $@
@@ -1159,7 +1161,9 @@ bin/rpcclient at EXEEXT@: $(BINARY_PREREQS) $(RPCCLIENT_OBJ) @BUILD_POPT@
 
 bin/smbclient at EXEEXT@: $(BINARY_PREREQS) $(CLIENT_OBJ) @BUILD_POPT@
 	@echo Linking $@
-	@$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(DYNEXP) $(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS)
+	@$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(DYNEXP) \
+		$(TERMLDFLAGS) $(TERMLIBS) $(LIBS) @POPTLIBS@ \
+		$(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS) $(DNSSD_LIBS)
 
 bin/net at EXEEXT@: $(BINARY_PREREQS) $(NET_OBJ) @BUILD_POPT@
 	@echo Linking $@
diff --git a/source/client/client.c b/source/client/client.c
index d59af9e..97d7cf0 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -28,10 +28,13 @@
 #define REGISTER 0
 #endif
 
+extern int do_smb_browse(void); /* mDNS browsing */
+
 extern bool AllowDebugChange;
 extern bool override_logfile;
 extern char tar_type;
 extern bool in_client;
+
 static int port = 0;
 static char *service;
 static char *desthost;
@@ -4512,6 +4515,7 @@ static int do_message_op(void)
 		{ "send-buffer", 'b', POPT_ARG_INT, &io_bufsize, 'b', "Changes the transmit/send buffer", "BYTES" },
 		{ "port", 'p', POPT_ARG_INT, &port, 'p', "Port to connect to", "PORT" },
 		{ "grepable", 'g', POPT_ARG_NONE, NULL, 'g', "Produce grepable output" },
+                { "browse", 'B', POPT_ARG_NONE, NULL, 'B', "Browse SMB servers using DNS" },
 		POPT_COMMON_SAMBA
 		POPT_COMMON_CONNECTION
 		POPT_COMMON_CREDENTIALS
@@ -4654,6 +4658,9 @@ static int do_message_op(void)
 		case 'g':
 			grepable=true;
 			break;
+		case 'B':
+			return(do_smb_browse());
+
 		}
 	}
 
diff --git a/source/client/dnsbrowse.c b/source/client/dnsbrowse.c
new file mode 100644
index 0000000..c4819ce
--- /dev/null
+++ b/source/client/dnsbrowse.c
@@ -0,0 +1,236 @@
+/*
+   Unix SMB/CIFS implementation.
+   DNS-SD browse client
+   Copyright (C) Rishi Srivatsavai 2007
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+
+#ifdef WITH_DNSSD_SUPPORT
+
+#include <dns_sd.h>
+
+/* Holds service instances found during DNS browse */
+struct mdns_smbsrv_result
+{
+	char *serviceName;
+	char *regType;
+	char *domain;
+	uint32_t ifIndex;
+	struct mdns_smbsrv_result *nextResult;
+};
+
+/* Maintains state during DNS browse */
+struct mdns_browse_state
+{
+	struct mdns_smbsrv_result *listhead; /* Browse result list head */
+	int browseDone;
+
+};
+
+
+static void
+do_smb_resolve_reply (DNSServiceRef sdRef, DNSServiceFlags flags,
+		uint32_t interfaceIndex, DNSServiceErrorType errorCode,
+		const char *fullname, const char *hosttarget, uint16_t port,
+		uint16_t txtLen, const unsigned char *txtRecord, void *context)
+{
+	printf("SMB service available on %s port %u\n",
+		hosttarget, ntohs(port));
+}
+
+
+static void do_smb_resolve(struct mdns_smbsrv_result *browsesrv)
+{
+	DNSServiceRef mdns_conn_sdref = NULL;
+	int mdnsfd;
+	int fdsetsz;
+	int ret;
+	fd_set *fdset = NULL;
+	struct timeval tv;
+	DNSServiceErrorType err;
+
+	TALLOC_CTX * ctx = talloc_tos();
+
+	err = DNSServiceResolve(&mdns_conn_sdref, 0 /* flags */,
+		browsesrv->ifIndex,
+		browsesrv->serviceName, browsesrv->regType, browsesrv->domain,
+		do_smb_resolve_reply, NULL);
+
+	if (err != kDNSServiceErr_NoError) {
+		return;
+	}
+
+	mdnsfd = DNSServiceRefSockFD(mdns_conn_sdref);
+	for (;;)  {
+		if (fdset != NULL) {
+			TALLOC_FREE(fdset);
+		}
+
+		fdsetsz = howmany(mdnsfd + 1, NFDBITS) * sizeof(fd_mask);
+		fdset = TALLOC_ZERO(ctx, fdsetsz);
+		FD_SET(mdnsfd, fdset);
+
+		tv.tv_sec = 1;
+		tv.tv_usec = 0;
+
+		/* Wait until response received from mDNS daemon */
+		ret = sys_select(mdnsfd + 1, fdset, NULL, NULL, &tv);
+		if (ret <= 0 && errno != EINTR) {
+			break;
+		}
+
+		if (FD_ISSET(mdnsfd, fdset)) {
+			/* Invoke callback function */
+			DNSServiceProcessResult(mdns_conn_sdref);
+			break;
+		}
+	}
+
+	TALLOC_FREE(fdset);
+	DNSServiceRefDeallocate(mdns_conn_sdref);
+}
+
+
+static void
+do_smb_browse_reply(DNSServiceRef sdRef, DNSServiceFlags flags,
+        uint32_t interfaceIndex, DNSServiceErrorType errorCode,
+        const char  *serviceName, const char *regtype,
+        const char  *replyDomain, void  *context)
+{
+	struct mdns_browse_state *bstatep = (struct mdns_browse_state *)context;
+	struct mdns_smbsrv_result *bresult;
+
+	if (bstatep == NULL) {
+		return;
+	}
+
+	if (errorCode != kDNSServiceErr_NoError) {
+		bstatep->browseDone = 1;
+		return;
+	}
+
+	if (flags & kDNSServiceFlagsMoreComing) {
+		bstatep->browseDone = 0;
+	} else {
+		bstatep->browseDone = 1;
+	}
+
+	if (!(flags & kDNSServiceFlagsAdd)) {
+		return;
+	}
+
+	bresult = TALLOC_ARRAY(talloc_tos(), struct mdns_smbsrv_result, 1);
+	if (bresult == NULL) {
+		return;
+	}
+
+	if (bstatep->listhead != NULL) {
+		bresult->nextResult = bstatep->listhead;
+	}
+
+	bresult->serviceName = talloc_strdup(talloc_tos(), serviceName);
+	bresult->regType = talloc_strdup(talloc_tos(), regtype);
+	bresult->domain = talloc_strdup(talloc_tos(), replyDomain);
+	bresult->ifIndex = interfaceIndex;
+	bstatep->listhead = bresult;
+}
+
+int do_smb_browse(void)
+{
+	int mdnsfd;
+	int fdsetsz;
+	int ret;
+	fd_set *fdset = NULL;
+	struct mdns_browse_state bstate;
+	struct mdns_smbsrv_result *resptr;
+	struct timeval tv;
+	DNSServiceRef mdns_conn_sdref = NULL;
+	DNSServiceErrorType err;
+
+	TALLOC_CTX * ctx = talloc_stackframe();
+
+	ZERO_STRUCT(bstate);
+
+	err = DNSServiceBrowse(&mdns_conn_sdref, 0, 0, "_smb._tcp", "",
+			do_smb_browse_reply, &bstate);
+
+	if (err != kDNSServiceErr_NoError) {
+		d_printf("Error connecting to the Multicast DNS daemon\n");
+		TALLOC_FREE(ctx);
+		return 1;
+	}
+
+	mdnsfd = DNSServiceRefSockFD(mdns_conn_sdref);
+	for (;;)  {
+		if (fdset != NULL) {
+			TALLOC_FREE(fdset);
+		}
+
+		fdsetsz = howmany(mdnsfd + 1, NFDBITS) * sizeof(fd_mask);
+		fdset = TALLOC_ZERO(ctx, fdsetsz);
+		FD_SET(mdnsfd, fdset);
+
+		tv.tv_sec = 1;
+		tv.tv_usec = 0;
+
+		/* Wait until response received from mDNS daemon */
+		ret = sys_select(mdnsfd + 1, fdset, NULL, NULL, &tv);
+		if (ret <= 0 && errno != EINTR) {
+			break;
+		}
+
+		if (FD_ISSET(mdnsfd, fdset)) {
+			/* Invoke callback function */
+			if (DNSServiceProcessResult(mdns_conn_sdref)) {
+				break;
+			}
+			if (bstate.browseDone) {
+				break;
+			}
+		}
+	}
+
+	DNSServiceRefDeallocate(mdns_conn_sdref);
+
+	if (bstate.listhead != NULL) {
+		resptr = bstate.listhead;
+		while (resptr != NULL) {
+			struct mdns_smbsrv_result *oldresptr;
+			oldresptr = resptr;
+
+			/* Resolve smb service instance */
+			do_smb_resolve(resptr);
+
+			resptr = resptr->nextResult;
+		}
+	}
+
+	TALLOC_FREE(ctx);
+	return 0;
+}
+
+#else /* WITH_DNSSD_SUPPORT */
+
+int do_smb_browse(void)
+{
+    d_printf("DNS-SD browsing is not supported on this platform\n");
+    return 1;
+}
+
+#endif /* WITH_DNSSD_SUPPORT */
+
+
diff --git a/source/configure.in b/source/configure.in
index ac60b6f..6015837 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -6191,6 +6191,7 @@ AC_SUBST(FLAGS1)
 AC_ARG_ENABLE(dnssd,
 [  --enable-dnssd          Enable DNS service discovery support (default=auto)])
 
+AC_SUBST(DNSSD_LIBS)
 if test x"$enable_dnssd" != x"no"; then
     have_dnssd_support=yes
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list