-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

G'day

The attached patch adds "first draft" support for service location protocol, 
using OpenSLP  (http://www.openslp.org). This allows you to automagically 
discover all the rsync servers on your network (which is defined in terms of 
your SLP configuration - typically equal to multicast scope, but you can 
change it around with Directory agents).
Here is an example:
bradh@squirt rsync-2.5.5 $ slptool findsrvs service:rsync
service:rsync://192.168.0.22:873:/,65535
service:rsync://192.168.0.22:873:,65535
service:rsync://squirt.cuneata.net.(none):873:,65535
service:rsync://squirt.cuneata.net:873:,65535

[OK, so these are really all the same server, but there is no reason why a 
real network wouldn't have a selection]

It has at least one major problem - Doesn't report name and comment 
attributes. I don't think I understand when the config file is being read. 
AFAICT, lp_numservices should be set up when I'm running the SLP routines in 
clientserver.c (see patch, with // style comment lines), but it isn't. If 
anyone can find a better spot to do the service registration, please hack 
away, or let me know.

Other known problems:
* shouldn't hardwire the portnum, instead should read from rsync_port. 
* needs to have a standard set of attributes defined. I'll chase this up with 
Erik Guttman.
* Needs to do smarter things if hostname or domainname are broken.
* Probably needs to do smarter things for multi-homed hosts.

If anyone was in doubt after all that: DON"T APPLY THIS TO A PRODUCTION BOX.

Any comments - let me know.

Brad

- -- 
http://conf.linux.org.au. 22-25Jan2003. Perth, Australia. Birds in Black.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE9jdXbW6pHgIdAuOMRAkNGAJ9JcyAK2JNyNqVOOWY30mwwjaW+rgCgr5kh
ax9uEHJ+BssRWUW0mglWe8I=
=C0Bl
-----END PGP SIGNATURE-----
diff -Naur -xconfigure -xrsync.h clean/rsync-2.5.5/Makefile.in rsync-2.5.5/Makefile.in
--- clean/rsync-2.5.5/Makefile.in	Mon Mar 25 15:36:56 2002
+++ rsync-2.5.5/Makefile.in	Sun Sep 22 21:46:37 2002
@@ -10,6 +10,7 @@
 CC=@CC@
 CFLAGS=@CFLAGS@
 LDFLAGS=@LDFLAGS@
+LIBSLP=@LIBSLP@
 
 INSTALLCMD=@INSTALL@
 INSTALLMAN=@INSTALL@
@@ -35,7 +36,7 @@
 DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
 popt_OBJS=popt/findme.o  popt/popt.o  popt/poptconfig.o \
 	popt/popthelp.o popt/poptparse.o
-OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
+OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) $(LIBSLP) @BUILD_POPT@
 
 TLS_OBJ = tls.o syscall.o lib/permstring.o 
 
diff -Naur -xconfigure -xrsync.h clean/rsync-2.5.5/clientserver.c rsync-2.5.5/clientserver.c
--- clean/rsync-2.5.5/clientserver.c	Wed Mar 27 12:03:13 2002
+++ rsync-2.5.5/clientserver.c	Mon Sep 23 00:12:09 2002
@@ -21,6 +21,9 @@
 /* the socket based protocol for setting up a connection with rsyncd */
 
 #include "rsync.h"
+#ifdef HAVE_LIBSLP
+#include "slp.h"
+#endif
 
 extern int module_id;
 extern int read_only;
@@ -521,6 +524,20 @@
 	return rsync_module(fd, i);
 }
 
+#ifdef HAVE_LIBSLP
+void slp_callback(SLPHandle hslp, SLPError errcode, void* cookie) 
+{ 
+	/* return the error code in the cookie */ 
+	*(SLPError*)cookie = errcode; 
+
+
+	/* You could do something else here like print out  */ 
+	/* the errcode, etc.  Remember, as a general rule,  */ 
+	/* do not try to do too much in a callback because  */ 
+	/* it is being executed by the same thread that is  */ 
+	/* reading slp packets from the wire.               */ 
+}
+#endif
 
 int daemon_main(void)
 {
@@ -528,6 +545,16 @@
 	extern int orig_umask;
 	char *pid_file;
 	extern int no_detach;
+#ifdef HAVE_LIBSLP
+	SLPError err, callbackerr;
+	SLPHandle hslp;
+	int n;
+	int i;
+	char srv[120];
+	char attr[120];
+	char localhost[40];
+	char localdomain[40];
+#endif
 
 	if (is_a_socket(STDIN_FILENO)) {
 		int i;
@@ -559,6 +586,56 @@
          * address too.  In fact, why not just do inet_ntop on the
          * local address??? */
 
+#if HAVE_LIBSLP
+	rprintf(FINFO, "rsyncd registering services with slpd:\n");
+	err = SLPOpen("en",SLP_FALSE,&hslp); 
+	if(err != SLP_OK) 
+	{ 
+		printf("Error opening slp handle %i\n",err); 
+		return err; 
+	}
+	/* FIXME: check return values */
+	gethostname(localhost, sizeof(localhost));
+	getdomainname(localdomain, sizeof(localdomain));
+		   
+	/* Register each service with SLP */ 
+//	n = lp_numservices();
+//	printf("%i services!\n", n);
+		
+//	for (i=0;i<n;i++)
+//		if (lp_list(i)) {
+			snprintf(srv, sizeof(srv), "service:rsync://%s.%s:873:",localhost,localdomain);
+			rprintf(FINFO, "    %s\n", srv);
+			if (lp_comment(i)) 
+				snprintf(attr, sizeof(attr), "(name=%s),(comment=%s)",
+					 lp_name(i),
+					 lp_comment(i));
+			err = SLPReg( hslp, 
+				      srv, /* service to register */
+				      SLP_LIFETIME_MAXIMUM, /* lifetime of rsyncd */
+				      0,  /* this is ignored */
+				      attr, /* attributes */
+				      SLP_TRUE, /* new registration - don't change this */
+				      slp_callback, /* callback */
+				      &callbackerr );
+
+			/* err may contain an error code that occurred as the slp library    */ 
+			/* _prepared_ to make the call.                                     */ 
+			if(( err != SLP_OK) || (callbackerr != SLP_OK)) 
+				rprintf(FINFO, "Error registering service with slp %i\n",err); 
+
+			/* callbackerr may contain an error code (that was assigned through */ 
+			/* the callback cookie) that occurred as slp packets were sent on    */ 
+			/* the wire */ 
+			if( callbackerr != SLP_OK) 
+				rprintf(FINFO, "Error registering service with slp %i\n",callbackerr); 
+//		} 
+
+	/* Now that we're done using slp, close the slp handle */ 
+	SLPClose(hslp);
+#endif
+	
+
 	if (((pid_file = lp_pid_file()) != NULL) && (*pid_file != '\0')) {
 		char pidbuf[16];
 		int fd;
diff -Naur -xconfigure -xrsync.h clean/rsync-2.5.5/config.h.in rsync-2.5.5/config.h.in
--- clean/rsync-2.5.5/config.h.in	Tue Apr  2 11:50:49 2002
+++ rsync-2.5.5/config.h.in	Sun Sep 22 21:34:55 2002
@@ -116,6 +116,9 @@
 /* Define if you have the `socket' library (-lsocket). */
 #undef HAVE_LIBSOCKET
 
+/* Define if you have the Service Location Protocol libraries (-lslp). */
+#undef HAVE_LIBSLP
+
 /* Define if you have the `link' function. */
 #undef HAVE_LINK
 
diff -Naur -xconfigure -xrsync.h clean/rsync-2.5.5/configure.in rsync-2.5.5/configure.in
--- clean/rsync-2.5.5/configure.in	Tue Apr  2 11:41:59 2002
+++ rsync-2.5.5/configure.in	Sun Sep 22 21:31:54 2002
@@ -364,6 +364,26 @@
 AC_CHECK_FUNCS(memmove lchown vsnprintf snprintf asprintf setsid glob strpbrk)
 AC_CHECK_FUNCS(strlcat strlcpy mtrace mallinfo setgroups)
 
+AC_ARG_ENABLE(slp, [  --enable-slp            turn on SLP support, default=yes])
+AC_ARG_WITH(openslp-libs, [  --with-openslp-libs     set directory for OpenSLP library],
+    LDFLAGS="-L$withval $LDFLAGS"
+    DSOFLAGS="-L$withval $DSOFLAGS",)
+AC_ARG_WITH(openslp-includes, [  --with-openslp-includes set directory for OpenSLP includes],
+    CFLAGS="-I$withval $CFLAGS"
+    CXXFLAGS="-I$withval $CXXFLAGS"
+    CPPFLAGS="-I$withval $CPPFLAGS",)
+
+LIBSLP=""
+
+if test x$enable_slp != xno; then
+    AC_CHECK_HEADER(slp.h,
+        AC_CHECK_LIB(slp, SLPOpen,
+            AC_DEFINE(HAVE_LIBSLP)
+            LIBSLP="-lslp"))
+fi
+
+AC_SUBST(LIBSLP)
+
 AC_CACHE_CHECK([for working socketpair],rsync_cv_HAVE_SOCKETPAIR,[
 AC_TRY_RUN([
 #include <sys/types.h>

Reply via email to