Commit | Line | Data |
---|---|---|
9978080e WD |
1 | This adds Service Location Protocol support. |
2 | ||
3 | After applying this patch, run these commands for a successful build: | |
4 | ||
27e96866 | 5 | ./prepare-source |
9978080e | 6 | ./configure --enable-slp |
9978080e WD |
7 | make |
8 | ||
9a7eef96 WD |
9 | --- old/Makefile.in |
10 | +++ new/Makefile.in | |
9978080e WD |
11 | @@ -12,6 +12,8 @@ CFLAGS=@CFLAGS@ |
12 | CPPFLAGS=@CPPFLAGS@ | |
13 | EXEEXT=@EXEEXT@ | |
14 | LDFLAGS=@LDFLAGS@ | |
15 | +LIBSLP=@LIBSLP@ | |
16 | +SLPOBJ=@SLPOBJ@ | |
17 | ||
18 | INSTALLCMD=@INSTALL@ | |
19 | INSTALLMAN=@INSTALL@ | |
20 | @@ -35,7 +37,7 @@ OBJS1=rsync.o generator.o receiver.o cle | |
21 | OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o \ | |
22 | fileio.o batch.o clientname.o chmod.o | |
23 | OBJS3=progress.o pipe.o | |
24 | -DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o | |
25 | +DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o $(SLPOBJ) | |
26 | popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \ | |
27 | popt/popthelp.o popt/poptparse.o | |
28 | OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@ | |
29 | @@ -69,7 +71,7 @@ install-strip: | |
30 | $(MAKE) INSTALL_STRIP='-s' install | |
31 | ||
32 | rsync$(EXEEXT): $(OBJS) | |
33 | - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) | |
34 | + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) $(LIBSLP) | |
35 | ||
36 | $(OBJS): $(HEADERS) | |
37 | ||
9a7eef96 WD |
38 | --- old/clientserver.c |
39 | +++ new/clientserver.c | |
27e96866 | 40 | @@ -836,6 +836,13 @@ int daemon_main(void) |
9978080e WD |
41 | * address too. In fact, why not just do inet_ntop on the |
42 | * local address??? */ | |
43 | ||
44 | +#ifdef HAVE_LIBSLP | |
45 | + if (register_services()) { | |
46 | + rprintf(FINFO, | |
47 | + "Couldn't register with service discovery protocol, continuing anyway\n"); | |
48 | + } | |
49 | +#endif | |
50 | + | |
51 | if (((pid_file = lp_pid_file()) != NULL) && (*pid_file != '\0')) { | |
52 | char pidbuf[16]; | |
53 | int fd; | |
9a7eef96 WD |
54 | --- old/configure.in |
55 | +++ new/configure.in | |
afcb578c | 56 | @@ -522,6 +522,29 @@ if test $rsync_cv_chown_follows_symlink |
9978080e WD |
57 | AC_DEFINE(CHOWN_MODIFIES_SYMLINK, 1, [Define to 1 if chown modifies symlinks.]) |
58 | fi | |
59 | ||
60 | +AC_ARG_ENABLE(slp, [ --disable-slp turn off SLP support, defaults to on]) | |
61 | +AC_ARG_WITH(openslp-libs, [ --with-openslp-libs set directory for OpenSLP library], | |
62 | + LDFLAGS="-L$withval $LDFLAGS" | |
63 | + DSOFLAGS="-L$withval $DSOFLAGS",) | |
64 | +AC_ARG_WITH(openslp-includes, [ --with-openslp-includes set directory for OpenSLP includes], | |
65 | + CFLAGS="-I$withval $CFLAGS" | |
66 | + CXXFLAGS="-I$withval $CXXFLAGS" | |
67 | + CPPFLAGS="-I$withval $CPPFLAGS",) | |
68 | + | |
69 | +LIBSLP="" | |
70 | +SLPOBJ="" | |
71 | + | |
72 | +if test x$enable_slp != xno; then | |
73 | + AC_CHECK_HEADER(slp.h, | |
74 | + AC_CHECK_LIB(slp, SLPOpen, | |
75 | + AC_DEFINE(HAVE_LIBSLP, 1, [Define to 1 for SLP support]) | |
76 | + SLPOBJ="srvreg.o srvloc.o" | |
77 | + LIBSLP="-lslp")) | |
78 | +fi | |
79 | + | |
80 | +AC_SUBST(LIBSLP) | |
81 | +AC_SUBST(SLPOBJ) | |
82 | + | |
83 | AC_CACHE_CHECK([for working socketpair],rsync_cv_HAVE_SOCKETPAIR,[ | |
84 | AC_TRY_RUN([ | |
85 | #include <sys/types.h> | |
9a7eef96 WD |
86 | --- old/loadparm.c |
87 | +++ new/loadparm.c | |
9978080e WD |
88 | @@ -105,6 +105,7 @@ typedef struct |
89 | char *socket_options; | |
90 | ||
91 | int rsync_port; | |
92 | + int slp_refresh; | |
93 | int syslog_facility; | |
94 | } global; | |
95 | ||
96 | @@ -286,6 +287,7 @@ static struct parm_struct parm_table[] = | |
97 | {"motd file", P_STRING, P_GLOBAL,&Globals.motd_file, NULL,0}, | |
98 | {"pid file", P_STRING, P_GLOBAL,&Globals.pid_file, NULL,0}, | |
99 | {"port", P_INTEGER,P_GLOBAL,&Globals.rsync_port, NULL,0}, | |
100 | + {"slp refresh", P_INTEGER,P_GLOBAL,&Globals.slp_refresh, NULL,0}, | |
101 | {"socket options", P_STRING, P_GLOBAL,&Globals.socket_options, NULL,0}, | |
102 | {"syslog facility", P_ENUM, P_GLOBAL,&Globals.syslog_facility,enum_facilities,0}, | |
103 | ||
104 | @@ -379,6 +381,7 @@ FN_GLOBAL_STRING(lp_pid_file, &Globals.p | |
105 | FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options) | |
106 | ||
107 | FN_GLOBAL_INTEGER(lp_rsync_port, &Globals.rsync_port) | |
108 | +FN_GLOBAL_INTEGER(lp_slp_refresh, &Globals.slp_refresh) | |
109 | FN_GLOBAL_INTEGER(lp_syslog_facility, &Globals.syslog_facility) | |
110 | ||
111 | FN_LOCAL_STRING(lp_auth_users, auth_users) | |
9a7eef96 WD |
112 | --- old/main.c |
113 | +++ new/main.c | |
27e96866 | 114 | @@ -962,6 +962,18 @@ static int start_client(int argc, char * |
9978080e WD |
115 | if (!read_batch) { /* for read_batch, NO source is specified */ |
116 | argc--; | |
117 | shell_path = check_for_hostspec(argv[0], &shell_machine, &rsync_port); | |
118 | + | |
119 | + if (shell_machine && !shell_machine[0]) { | |
120 | +#ifdef HAVE_LIBSLP | |
121 | + /* User entered just rsync:// URI */ | |
122 | + print_service_list(); | |
123 | + exit_cleanup(0); | |
124 | +#else /* No SLP, die here */ | |
125 | + rprintf(FINFO, "No SLP support, cannot browse\n"); | |
126 | + exit_cleanup(RERR_SYNTAX); | |
127 | +#endif | |
128 | + } | |
129 | + | |
130 | if (shell_path) { /* source is remote */ | |
131 | char *dummy1; | |
132 | int dummy2; | |
9a7eef96 WD |
133 | --- old/options.c |
134 | +++ new/options.c | |
afcb578c | 135 | @@ -196,6 +196,7 @@ static void print_rsync_version(enum log |
9978080e WD |
136 | char const *hardlinks = "no "; |
137 | char const *links = "no "; | |
138 | char const *ipv6 = "no "; | |
139 | + char const *slp = "no "; | |
140 | STRUCT_STAT *dumstat; | |
141 | ||
142 | #ifdef HAVE_SOCKETPAIR | |
afcb578c | 143 | @@ -218,6 +219,10 @@ static void print_rsync_version(enum log |
9978080e WD |
144 | ipv6 = ""; |
145 | #endif | |
146 | ||
147 | +#if HAVE_LIBSLP | |
148 | + slp = ""; | |
149 | +#endif | |
150 | + | |
151 | rprintf(f, "%s version %s protocol version %d\n", | |
152 | RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION); | |
153 | rprintf(f, "Copyright (C) 1996-2006 by Andrew Tridgell, Wayne Davison, and others.\n"); | |
afcb578c | 154 | @@ -230,9 +235,9 @@ static void print_rsync_version(enum log |
9978080e WD |
155 | /* Note that this field may not have type ino_t. It depends |
156 | * on the complicated interaction between largefile feature | |
157 | * macros. */ | |
158 | - rprintf(f, " %sinplace, %sIPv6, " | |
159 | + rprintf(f, " %sinplace, %sIPv6, %sSLP, " | |
160 | "%d-bit system inums, %d-bit internal inums\n", | |
161 | - have_inplace, ipv6, | |
162 | + have_inplace, ipv6, slp, | |
163 | (int) (sizeof dumstat->st_ino * 8), | |
164 | (int) (sizeof (int64) * 8)); | |
165 | #ifdef MAINTAINER_MODE | |
9a7eef96 WD |
166 | --- old/rsync.h |
167 | +++ new/rsync.h | |
9978080e WD |
168 | @@ -154,6 +154,9 @@ |
169 | #define SIGNIFICANT_ITEM_FLAGS (~(\ | |
170 | ITEM_BASIS_TYPE_FOLLOWS | ITEM_XNAME_FOLLOWS | ITEM_LOCAL_CHANGE)) | |
171 | ||
172 | +/* this is the minimum we'll use, irrespective of config setting */ | |
173 | +/* definately don't set to less than about 30 seconds */ | |
174 | +#define SLP_MIN_TIMEOUT 120 | |
175 | ||
176 | /* Log-message categories. Only FERROR and FINFO get sent over the socket. | |
177 | * FLOG and FCLIENT are only used on the daemon side for custom logging, | |
9a7eef96 WD |
178 | --- old/rsync.yo |
179 | +++ new/rsync.yo | |
9978080e WD |
180 | @@ -137,7 +137,12 @@ particular rsync daemon by leaving off t |
181 | ||
182 | quote(tt(rsync somehost.mydomain.com::)) | |
183 | ||
184 | -See the following section for more details. | |
185 | +And, if Service Location Protocol is available, the following will list the | |
186 | +available rsync servers: | |
187 | + | |
188 | +quote(tt(rsync rsync://)) | |
189 | + | |
190 | +See the following section for even more usage details. | |
191 | ||
192 | manpagesection(ADVANCED USAGE) | |
193 | ||
9a7eef96 WD |
194 | --- old/rsyncd.conf |
195 | +++ new/rsyncd.conf | |
9978080e WD |
196 | @@ -0,0 +1,3 @@ |
197 | + | |
198 | +slp refresh = 300 | |
199 | + | |
9a7eef96 WD |
200 | --- old/rsyncd.conf.yo |
201 | +++ new/rsyncd.conf.yo | |
9978080e WD |
202 | @@ -119,6 +119,15 @@ details on some of the options you may b |
203 | special socket options are set. These settings are superseded by the | |
204 | bf(--sockopts) command-line option. | |
205 | ||
206 | +dit(bf(slp refresh)) This option is used to determine how long service | |
207 | +advertisements are valid (measured in seconds), and is only applicable if | |
208 | +you have Service Location Protocol support compiled in. If this option is | |
209 | +not set or is set to zero, then service advertisements never time out. If | |
210 | +this is set to less than 120 seconds, then 120 seconds is used. If it is | |
211 | +set to more than 65535, then 65535 is used (which is a limitation of SLP). | |
212 | +Using 3600 (one hour) is a good number if you tend to change your | |
213 | +configuration. | |
214 | + | |
215 | enddit() | |
216 | ||
217 | ||
afcb578c | 218 | @@ -544,6 +553,7 @@ use chroot = no |
9978080e WD |
219 | max connections = 4 |
220 | syslog facility = local5 | |
221 | pid file = /var/run/rsyncd.pid | |
222 | +slp refresh = 3600 | |
223 | ||
224 | [ftp] | |
225 | path = /var/ftp/pub | |
9a7eef96 WD |
226 | --- old/socket.c |
227 | +++ new/socket.c | |
9978080e WD |
228 | @@ -447,6 +447,14 @@ void start_accept_loop(int port, int (*f |
229 | { | |
230 | fd_set deffds; | |
231 | int *sp, maxfd, i; | |
232 | + time_t next_slp_refresh; | |
233 | + short slp_timeout = lp_slp_refresh(); | |
234 | + if (slp_timeout) { | |
235 | + if (slp_timeout < SLP_MIN_TIMEOUT) | |
236 | + slp_timeout = SLP_MIN_TIMEOUT; | |
237 | + /* re-register before slp times out */ | |
238 | + slp_timeout -= 15; | |
239 | + } | |
240 | ||
27e96866 | 241 | #ifdef HAVE_SIGACTION |
9978080e WD |
242 | sigact.sa_flags = SA_NOCLDSTOP; |
243 | @@ -475,14 +483,20 @@ void start_accept_loop(int port, int (*f | |
244 | maxfd = sp[i]; | |
245 | } | |
246 | ||
247 | + next_slp_refresh = time(NULL) + slp_timeout; | |
248 | + | |
249 | /* now accept incoming connections - forking a new process | |
250 | * for each incoming connection */ | |
251 | while (1) { | |
252 | fd_set fds; | |
253 | pid_t pid; | |
254 | int fd; | |
255 | + int sel_ret; | |
256 | + struct timeval slp_tv; | |
257 | struct sockaddr_storage addr; | |
258 | socklen_t addrlen = sizeof addr; | |
259 | + slp_tv.tv_sec = 10; | |
260 | + slp_tv.tv_usec = 0; | |
261 | ||
262 | /* close log file before the potentially very long select so | |
263 | * file can be trimmed by another process instead of growing | |
264 | @@ -494,8 +508,13 @@ void start_accept_loop(int port, int (*f | |
265 | #else | |
266 | fds = deffds; | |
267 | #endif | |
268 | - | |
269 | - if (select(maxfd + 1, &fds, NULL, NULL, NULL) != 1) | |
270 | + sel_ret = select(maxfd + 1, &fds, NULL, NULL, slp_timeout ? &slp_tv: NULL); | |
271 | + if (sel_ret == 0 && slp_timeout && time(NULL) > next_slp_refresh) { | |
272 | + rprintf(FINFO, "Service registration expired, refreshing it\n"); | |
273 | + register_services(); | |
274 | + next_slp_refresh = time(NULL) + slp_timeout; | |
275 | + } | |
276 | + if (sel_ret != 1) | |
277 | continue; | |
278 | ||
279 | for (i = 0, fd = -1; sp[i] >= 0; i++) { | |
9a7eef96 WD |
280 | --- old/srvloc.c |
281 | +++ new/srvloc.c | |
9978080e WD |
282 | @@ -0,0 +1,105 @@ |
283 | +/* -*- c-file-style: "linux"; -*- | |
284 | + | |
285 | + Copyright (C) 2002 by Brad Hards <bradh@frogmouth.net> | |
286 | + | |
287 | + This program is free software; you can redistribute it and/or modify | |
288 | + it under the terms of the GNU General Public License as published by | |
289 | + the Free Software Foundation; either version 2 of the License, or | |
290 | + (at your option) any later version. | |
291 | + | |
292 | + This program is distributed in the hope that it will be useful, | |
293 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
294 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
295 | + GNU General Public License for more details. | |
296 | + | |
297 | + You should have received a copy of the GNU General Public License | |
298 | + along with this program; if not, write to the Free Software | |
299 | + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
300 | +*/ | |
301 | + | |
302 | +/* This file implements the service location functionality */ | |
303 | +/* Basically, it uses normal Service Location Protocol API */ | |
304 | + | |
305 | +/* It is really a cheap hack - just to show how it might work | |
306 | + in a real application. | |
307 | +*/ | |
308 | + | |
309 | +#include "rsync.h" | |
310 | + | |
311 | +#include <slp.h> | |
312 | +#include <stdio.h> | |
313 | +#include <string.h> | |
314 | + | |
315 | +/* This one just prints out the attributes */ | |
316 | +static SLPBoolean getAttrCallback(UNUSED(SLPHandle hslp), const char *attrlist, | |
317 | + SLPError errcode, UNUSED(void *cookie)) | |
318 | +{ | |
319 | + char *cleanstr; | |
320 | + | |
321 | + if (errcode == SLP_OK) { | |
322 | + if (!strcmp(attrlist, "(comment=)")) { | |
323 | + rprintf(FINFO, "\t(No description)\n"); | |
324 | + } else { | |
325 | + cleanstr = strrchr(attrlist, ')') ; | |
326 | + *cleanstr = ' '; /* remove last ')' */ | |
327 | + rprintf(FINFO, "\t%s\n", strchr(attrlist, '=') + 1); | |
328 | + } | |
329 | + } | |
330 | + return SLP_FALSE; | |
331 | +} | |
332 | + | |
333 | +SLPBoolean getSLPSrvURLCallback(UNUSED(SLPHandle hslp), const char *srvurl, | |
334 | + UNUSED(unsigned short lifetime), SLPError errcode, | |
335 | + void *cookie) | |
336 | +{ | |
337 | + SLPError result; | |
338 | + SLPHandle attrhslp; | |
339 | + | |
340 | + if (errcode == SLP_OK) { | |
341 | + /* chop service: off the front */ | |
342 | + rprintf(FINFO, " %s ", (strchr(srvurl, ':') + 1)); | |
343 | + /* check for any attributes */ | |
344 | + if (SLPOpen("en", SLP_FALSE,&attrhslp) == SLP_OK) { | |
345 | + result = SLPFindAttrs(attrhslp, srvurl, | |
346 | + "", /* return all attributes */ | |
347 | + "", /* use configured scopes */ | |
348 | + getAttrCallback, NULL); | |
349 | + if (result != SLP_OK) { | |
350 | + rprintf(FERROR, "errorcode: %i\n",result); | |
351 | + } | |
352 | + SLPClose(attrhslp); | |
353 | + } | |
354 | + *(SLPError*)cookie = SLP_OK; | |
355 | + } else { | |
356 | + *(SLPError*)cookie = errcode; | |
357 | + } | |
358 | + | |
359 | + | |
360 | + /* Return SLP_TRUE because we want to be called again | |
361 | + * if more services were found. */ | |
362 | + | |
363 | + return SLP_TRUE; | |
364 | +} | |
365 | + | |
366 | +int print_service_list(void) | |
367 | +{ | |
368 | + SLPError err; | |
369 | + SLPError callbackerr; | |
370 | + SLPHandle hslp; | |
371 | + | |
372 | + err = SLPOpen("en",SLP_FALSE,&hslp); | |
373 | + if (err != SLP_OK) { | |
374 | + rprintf(FERROR, "Error opening slp handle %i\n", err); | |
375 | + return err; | |
376 | + } | |
377 | + | |
378 | + SLPFindSrvs(hslp, "rsync", | |
379 | + 0, /* use configured scopes */ | |
380 | + 0, /* no attr filter */ | |
381 | + getSLPSrvURLCallback, &callbackerr); | |
382 | + | |
383 | + /* Now that we're done using slp, close the slp handle */ | |
384 | + SLPClose(hslp); | |
385 | + | |
386 | + return 0; | |
387 | +} | |
9a7eef96 WD |
388 | --- old/srvreg.c |
389 | +++ new/srvreg.c | |
9978080e WD |
390 | @@ -0,0 +1,128 @@ |
391 | +/* -*- c-file-style: "linux"; -*- | |
392 | + | |
393 | + Copyright (C) 2002 by Brad Hards <bradh@frogmouth.net> | |
394 | + | |
395 | + This program is free software; you can redistribute it and/or modify | |
396 | + it under the terms of the GNU General Public License as published by | |
397 | + the Free Software Foundation; either version 2 of the License, or | |
398 | + (at your option) any later version. | |
399 | + | |
400 | + This program is distributed in the hope that it will be useful, | |
401 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
402 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
403 | + GNU General Public License for more details. | |
404 | + | |
405 | + You should have received a copy of the GNU General Public License | |
406 | + along with this program; if not, write to the Free Software | |
407 | + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
408 | +*/ | |
409 | + | |
410 | +/* This file implements the service registration functionality */ | |
411 | + | |
412 | +/* Basically, it uses normal Service Location Protocol API */ | |
413 | + | |
414 | +#include "rsync.h" | |
415 | +#include "slp.h" | |
416 | +#include "netdb.h" | |
417 | + | |
418 | +extern int rsync_port; | |
419 | + | |
420 | +static void slp_callback(UNUSED(SLPHandle hslp), SLPError errcode, void *cookie) | |
421 | +{ | |
422 | + /* return the error code in the cookie */ | |
423 | + *(SLPError*)cookie = errcode; | |
424 | + | |
425 | + /* You could do something else here like print out | |
426 | + * the errcode, etc. Remember, as a general rule, | |
427 | + * do not try to do too much in a callback because | |
428 | + * it is being executed by the same thread that is | |
429 | + * reading slp packets from the wire. */ | |
430 | +} | |
431 | + | |
432 | +int register_services(void) | |
433 | +{ | |
434 | + SLPError err, callbackerr; | |
435 | + SLPHandle hslp; | |
436 | + int n; | |
437 | + int i; | |
438 | + char srv[120]; | |
439 | + char attr[120]; | |
440 | + char localhost[256]; | |
441 | + extern char *config_file; | |
442 | + short timeout; | |
443 | + struct addrinfo aih, *ai = 0; | |
444 | + | |
445 | + if (!lp_load(config_file, 0)) { | |
446 | + exit_cleanup(RERR_SYNTAX); | |
447 | + } | |
448 | + | |
449 | + n = lp_numservices(); | |
450 | + | |
451 | + if (0 == lp_slp_refresh()) | |
452 | + timeout = SLP_LIFETIME_MAXIMUM; /* don't expire, ever */ | |
453 | + else if (SLP_MIN_TIMEOUT > lp_slp_refresh()) | |
454 | + timeout = SLP_MIN_TIMEOUT; /* use a reasonable minimum */ | |
455 | + else if (SLP_LIFETIME_MAXIMUM <= lp_slp_refresh()) | |
456 | + timeout = (SLP_LIFETIME_MAXIMUM - 1); /* as long as possible */ | |
457 | + else | |
458 | + timeout = lp_slp_refresh(); | |
459 | + | |
460 | + rprintf(FINFO, "rsyncd registering %d service%s with slpd for %d seconds:\n", n, ((n==1)? "":"s"), timeout); | |
461 | + err = SLPOpen("en",SLP_FALSE,&hslp); | |
462 | + if (err != SLP_OK) { | |
463 | + rprintf(FINFO, "Error opening slp handle %i\n",err); | |
464 | + return err; | |
465 | + } | |
466 | + if (gethostname(localhost, sizeof localhost)) { | |
467 | + rprintf(FINFO, "Could not get hostname: %s\n", strerror(errno)); | |
468 | + return err; | |
469 | + } | |
470 | + memset(&aih, 0, sizeof aih); | |
471 | + aih.ai_family = PF_UNSPEC; | |
472 | + aih.ai_flags = AI_CANONNAME; | |
473 | + if (0 != (err = getaddrinfo(localhost, 0, &aih, &ai)) || !ai) { | |
474 | + rprintf(FINFO, "Could not resolve hostname: %s\n", gai_strerror(err)); | |
475 | + return err; | |
476 | + } | |
477 | + /* Register each service with SLP */ | |
478 | + for (i = 0; i < n; i++) { | |
479 | + if (!lp_list(i)) | |
480 | + continue; | |
481 | + | |
482 | + snprintf(srv, sizeof srv, "service:rsync://%s:%d/%s", | |
483 | + ai->ai_canonname, | |
484 | + rsync_port, | |
485 | + lp_name(i)); | |
486 | + rprintf(FINFO, " %s\n", srv); | |
487 | + if (lp_comment(i)) { | |
488 | + snprintf(attr, sizeof attr, "(comment=%s)", | |
489 | + lp_comment(i)); | |
490 | + } | |
491 | + err = SLPReg(hslp, | |
492 | + srv, /* service to register */ | |
493 | + timeout, | |
494 | + 0, /* this is ignored */ | |
495 | + attr, /* attributes */ | |
496 | + SLP_TRUE, /* new registration - don't change this */ | |
497 | + slp_callback, /* callback */ | |
498 | + &callbackerr); | |
499 | + | |
500 | + /* err may contain an error code that occurred as the slp library | |
501 | + * _prepared_ to make the call. */ | |
502 | + if (err != SLP_OK || callbackerr != SLP_OK) | |
503 | + rprintf(FINFO, "Error registering service with slp %i\n", err); | |
504 | + | |
505 | + /* callbackerr may contain an error code (that was assigned through | |
506 | + * the callback cookie) that occurred as slp packets were sent on | |
507 | + * the wire. */ | |
508 | + if (callbackerr != SLP_OK) | |
509 | + rprintf(FINFO, "Error registering service with slp %i\n",callbackerr); | |
510 | + } | |
511 | + | |
512 | + /* Now that we're done using slp, close the slp handle */ | |
513 | + freeaddrinfo(ai); | |
514 | + SLPClose(hslp); | |
515 | + | |
516 | + /* refresh is done in main select loop */ | |
517 | + return 0; | |
518 | +} |