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