-----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>