]>
Commit | Line | Data |
---|---|---|
74264883 AM |
1 | diff --git a/source/Makefile.in b/source/Makefile.in |
2 | index ee22703..0500d73 100644 | |
3 | --- a/source/Makefile.in | |
4 | +++ b/source/Makefile.in | |
5 | @@ -69,6 +69,7 @@ WINBIND_NSS_EXTRA_LIBS=@WINBIND_NSS_EXTRA_LIBS@ | |
6 | WINBIND_NSS_PTHREAD=@WINBIND_NSS_PTHREAD@ | |
7 | PAM_WINBIND_EXTRA_LIBS=@PAM_WINBIND_EXTRA_LIBS@ | |
8 | DNSSD_LIBS=@DNSSD_LIBS@ | |
9 | +AVAHI_LIBS=@AVAHI_LIBS@ | |
10 | POPT_LIBS=@POPTLIBS@ | |
11 | LIBTALLOC_LIBS=@LIBTALLOC_LIBS@ | |
12 | LIBTDB_LIBS=@LIBTDB_LIBS@ | |
13 | @@ -250,6 +251,8 @@ AFS_OBJ = lib/afs.o | |
14 | ||
15 | AFS_SETTOKEN_OBJ = lib/afs_settoken.o | |
16 | ||
17 | +AVAHI_OBJ = @AVAHI_OBJ@ | |
18 | + | |
19 | SERVER_MUTEX_OBJ = lib/server_mutex.o | |
20 | ||
21 | PASSCHANGE_OBJ = libsmb/passchange.o | |
22 | @@ -688,7 +691,7 @@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \ | |
23 | $(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \ | |
24 | $(LIB_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) \ | |
25 | $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \ | |
26 | - $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) \ | |
27 | + $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(AVAHI_OBJ) \ | |
28 | $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \ | |
29 | $(REG_FULL_OBJ) $(POPT_LIB_OBJ) $(BUILDOPT_OBJ) \ | |
30 | $(SMBLDAP_OBJ) $(LDB_OBJ) $(LIBNET_OBJ) @LIBWBCLIENT_STATIC@ \ | |
31 | @@ -1328,7 +1331,7 @@ bin/smbd@EXEEXT@: $(BINARY_PREREQS) $(SMBD_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARE | |
32 | @echo Linking $@ | |
33 | @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) \ | |
34 | $(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \ | |
35 | - $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) $(DNSSD_LIBS) \ | |
36 | + $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) $(DNSSD_LIBS) $(AVAHI_LIBS) \ | |
37 | $(POPT_LIBS) @SMBD_LIBS@ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \ | |
38 | $(WINBIND_LIBS) | |
39 | ||
40 | @@ -1513,7 +1516,7 @@ bin/pdbtest@EXEEXT@: $(BINARY_PREREQS) $(PDBTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SH | |
41 | ||
42 | bin/vfstest@EXEEXT@: $(BINARY_PREREQS) $(VFSTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ | |
43 | @echo Linking $@ | |
44 | - @$(CC) $(FLAGS) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) \ | |
45 | + @$(CC) $(FLAGS) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(AVAHI_LIBS) \ | |
46 | $(TERMLIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) $(DNSSD_LIBS) \ | |
47 | $(ACL_LIBS) $(LIBS) $(POPT_LIBS) $(KRB5LIBS) $(LDAP_LIBS) \ | |
48 | @SMBD_LIBS@ $(NSCD_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \ | |
49 | diff --git a/source/configure.in b/source/configure.in | |
50 | index 95dd67d..8a1f7fc 100644 | |
51 | --- a/source/configure.in | |
52 | +++ b/source/configure.in | |
53 | @@ -6168,10 +6168,10 @@ AC_SUBST(FLAGS1) | |
54 | # Check if user wants DNS service discovery support | |
55 | ||
56 | AC_ARG_ENABLE(dnssd, | |
57 | -[AS_HELP_STRING([--enable-dnssd], [Enable DNS service discovery support (default=auto)])]) | |
58 | +[AS_HELP_STRING([--enable-dnssd], [Enable DNS service discovery support (default=no)])]) | |
59 | ||
60 | AC_SUBST(DNSSD_LIBS) | |
61 | -if test x"$enable_dnssd" != x"no"; then | |
62 | +if test x"$enable_dnssd" == x"yes"; then | |
63 | have_dnssd_support=yes | |
64 | ||
65 | AC_CHECK_HEADERS(dns_sd.h) | |
66 | @@ -6200,6 +6200,42 @@ if test x"$enable_dnssd" != x"no"; then | |
67 | fi | |
68 | ||
69 | ################################################# | |
70 | +# Check if user wants avahi support | |
71 | + | |
72 | +AC_ARG_ENABLE(avahi, | |
73 | +[AS_HELP_STRING([--enable-avahi], [Enable Avahi support (default=auto)])]) | |
74 | + | |
75 | +AC_SUBST(AVAHI_LIBS) | |
76 | +if test x"$enable_avahi" != x"no"; then | |
77 | + have_avahi_support=yes | |
78 | + | |
79 | + AC_CHECK_HEADERS(avahi-common/watch.h) | |
80 | + if test x"$ac_cv_header_avahi_common_watch_h" != x"yes"; then | |
81 | + have_avahi_support=no | |
82 | + fi | |
83 | + | |
84 | + AC_CHECK_HEADERS(avahi-client/client.h) | |
85 | + if test x"$ac_cv_header_avahi_common_watch_h" != x"yes"; then | |
86 | + have_avahi_support=no | |
87 | + fi | |
88 | + | |
89 | + AC_CHECK_LIB_EXT(avahi-client, AVAHI_LIBS, avahi_client_new) | |
90 | + if test x"$ac_cv_lib_ext_avahi_client_avahi_client_new" != x"yes"; then | |
91 | + have_avahi_support=no | |
92 | + fi | |
93 | + | |
94 | + if test x"$have_avahi_support" = x"yes"; then | |
95 | + AC_DEFINE(WITH_AVAHI_SUPPORT, 1, | |
96 | + [Whether to enable avahi support]) | |
97 | + AC_SUBST(AVAHI_OBJ, "lib/avahi.o smbd/avahi_register.o") | |
98 | + else | |
99 | + if test x"$enable_avahi" = x"yes"; then | |
100 | + AC_MSG_ERROR(avahi support not available) | |
101 | + fi | |
102 | + fi | |
103 | +fi | |
104 | + | |
105 | +################################################# | |
106 | # Check to see if we should use the included iniparser | |
107 | ||
108 | AC_ARG_WITH(included-iniparser, | |
109 | diff --git a/source/include/proto.h b/source/include/proto.h | |
110 | index c2b318e..794742c 100644 | |
111 | --- a/source/include/proto.h | |
112 | +++ b/source/include/proto.h | |
113 | @@ -9751,4 +9751,14 @@ NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid); | |
114 | ||
115 | NTSTATUS nss_info_template_init( void ); | |
116 | ||
117 | +/* The following definitions come from lib/avahi.c */ | |
118 | + | |
119 | +struct AvahiPoll *tevent_avahi_poll(TALLOC_CTX *mem_ctx, | |
120 | + struct event_context *ev); | |
121 | + | |
122 | +/* The following definitions come from smbd/avahi_register.c */ | |
123 | + | |
124 | +void *avahi_start_register(TALLOC_CTX *mem_ctx, struct event_context *ev, | |
125 | + uint16_t port); | |
126 | + | |
127 | #endif /* _PROTO_H_ */ | |
128 | diff --git a/source/lib/avahi.c b/source/lib/avahi.c | |
129 | new file mode 100644 | |
130 | index 0000000..bdc58cb | |
131 | --- /dev/null | |
132 | +++ b/source/lib/avahi.c | |
133 | @@ -0,0 +1,277 @@ | |
134 | +/* | |
135 | + Unix SMB/CIFS implementation. | |
136 | + Connect avahi to lib/tevents | |
137 | + Copyright (C) Volker Lendecke 2009 | |
138 | + | |
139 | + This program is free software; you can redistribute it and/or modify | |
140 | + it under the terms of the GNU General Public License as published by | |
141 | + the Free Software Foundation; either version 3 of the License, or | |
142 | + (at your option) any later version. | |
143 | + | |
144 | + This program is distributed in the hope that it will be useful, | |
145 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
146 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
147 | + GNU General Public License for more details. | |
148 | + | |
149 | + You should have received a copy of the GNU General Public License | |
150 | + along with this program. If not, see <http://www.gnu.org/licenses/>. | |
151 | +*/ | |
152 | + | |
153 | +#include "includes.h" | |
154 | + | |
155 | +#include <avahi-common/watch.h> | |
156 | + | |
157 | +struct avahi_poll_context { | |
158 | + struct event_context *ev; | |
159 | + AvahiWatch **watches; | |
160 | + AvahiTimeout **timeouts; | |
161 | +}; | |
162 | + | |
163 | +struct AvahiWatch { | |
164 | + struct avahi_poll_context *ctx; | |
165 | + struct fd_event *fde; | |
166 | + int fd; | |
167 | + AvahiWatchEvent latest_event; | |
168 | + AvahiWatchCallback callback; | |
169 | + void *userdata; | |
170 | +}; | |
171 | + | |
172 | +struct AvahiTimeout { | |
173 | + struct avahi_poll_context *ctx; | |
174 | + struct timed_event *te; | |
175 | + AvahiTimeoutCallback callback; | |
176 | + void *userdata; | |
177 | +}; | |
178 | + | |
179 | +static uint16_t avahi_flags_map_to_tevent(AvahiWatchEvent event) | |
180 | +{ | |
181 | + return ((event & AVAHI_WATCH_IN) ? EVENT_FD_READ : 0) | |
182 | + | ((event & AVAHI_WATCH_OUT) ? EVENT_FD_WRITE : 0); | |
183 | +} | |
184 | + | |
185 | +static void avahi_fd_handler(struct event_context *ev, | |
186 | + struct fd_event *fde, uint16_t flags, | |
187 | + void *private_data); | |
188 | + | |
189 | +static AvahiWatch *avahi_watch_new(const AvahiPoll *api, int fd, | |
190 | + AvahiWatchEvent event, | |
191 | + AvahiWatchCallback callback, | |
192 | + void *userdata) | |
193 | +{ | |
194 | + struct avahi_poll_context *ctx = talloc_get_type_abort( | |
195 | + api->userdata, struct avahi_poll_context); | |
196 | + int num_watches = talloc_get_size(ctx->watches)/sizeof(*ctx->watches); | |
197 | + AvahiWatch **tmp, *watch_ctx; | |
198 | + | |
199 | + tmp = talloc_realloc(ctx, ctx->watches, AvahiWatch *, num_watches + 1); | |
200 | + if (tmp == NULL) { | |
201 | + return NULL; | |
202 | + } | |
203 | + ctx->watches = tmp; | |
204 | + | |
205 | + watch_ctx = talloc(tmp, AvahiWatch); | |
206 | + if (watch_ctx == NULL) { | |
207 | + goto fail; | |
208 | + } | |
209 | + ctx->watches[num_watches] = watch_ctx; | |
210 | + | |
211 | + watch_ctx->ctx = ctx; | |
212 | + watch_ctx->fde = event_add_fd(ctx->ev, watch_ctx, fd, | |
213 | + avahi_flags_map_to_tevent(event), | |
214 | + avahi_fd_handler, watch_ctx); | |
215 | + if (watch_ctx->fde == NULL) { | |
216 | + goto fail; | |
217 | + } | |
218 | + watch_ctx->callback = callback; | |
219 | + watch_ctx->userdata = userdata; | |
220 | + return watch_ctx; | |
221 | + | |
222 | + fail: | |
223 | + TALLOC_FREE(watch_ctx); | |
224 | + ctx->watches = talloc_realloc(ctx, ctx->watches, AvahiWatch *, | |
225 | + num_watches); | |
226 | + return NULL; | |
227 | +} | |
228 | + | |
229 | +static void avahi_fd_handler(struct event_context *ev, | |
230 | + struct fd_event *fde, uint16_t flags, | |
231 | + void *private_data) | |
232 | +{ | |
233 | + AvahiWatch *watch_ctx = talloc_get_type_abort(private_data, AvahiWatch); | |
234 | + | |
235 | + watch_ctx->latest_event = | |
236 | + ((flags & EVENT_FD_READ) ? AVAHI_WATCH_IN : 0) | |
237 | + | ((flags & EVENT_FD_WRITE) ? AVAHI_WATCH_OUT : 0); | |
238 | + | |
239 | + watch_ctx->callback(watch_ctx, watch_ctx->fd, watch_ctx->latest_event, | |
240 | + watch_ctx->userdata); | |
241 | +} | |
242 | + | |
243 | +static void avahi_watch_update(AvahiWatch *w, AvahiWatchEvent event) | |
244 | +{ | |
245 | + if (event & AVAHI_WATCH_IN) { | |
246 | + event_fd_set_readable(w->fde); | |
247 | + } else { | |
248 | + event_fd_set_not_readable(w->fde); | |
249 | + } | |
250 | + if (event & AVAHI_WATCH_OUT) { | |
251 | + event_fd_set_writeable(w->fde); | |
252 | + } else { | |
253 | + event_fd_set_not_writeable(w->fde); | |
254 | + } | |
255 | +} | |
256 | + | |
257 | +static AvahiWatchEvent avahi_watch_get_events(AvahiWatch *w) | |
258 | +{ | |
259 | + return w->latest_event; | |
260 | +} | |
261 | + | |
262 | +static void avahi_watch_free(AvahiWatch *w) | |
263 | +{ | |
264 | + int i, num_watches; | |
265 | + AvahiWatch **watches = w->ctx->watches; | |
266 | + struct avahi_poll_context *ctx; | |
267 | + | |
268 | + num_watches = talloc_get_size(watches) / sizeof(*watches); | |
269 | + | |
270 | + for (i=0; i<num_watches; i++) { | |
271 | + if (w == watches[i]) { | |
272 | + break; | |
273 | + } | |
274 | + } | |
275 | + if (i == num_watches) { | |
276 | + return; | |
277 | + } | |
278 | + ctx = w->ctx; | |
279 | + TALLOC_FREE(w); | |
280 | + memmove(&watches[i], &watches[i+1], | |
281 | + sizeof(*watches) * (num_watches - i - 1)); | |
282 | + ctx->watches = talloc_realloc(ctx, watches, AvahiWatch *, | |
283 | + num_watches - 1); | |
284 | +} | |
285 | + | |
286 | +static void avahi_timeout_handler(struct event_context *ev, | |
287 | + struct timed_event *te, | |
288 | + struct timeval current_time, | |
289 | + void *private_data); | |
290 | + | |
291 | +static AvahiTimeout *avahi_timeout_new(const AvahiPoll *api, | |
292 | + const struct timeval *tv, | |
293 | + AvahiTimeoutCallback callback, | |
294 | + void *userdata) | |
295 | +{ | |
296 | + struct avahi_poll_context *ctx = talloc_get_type_abort( | |
297 | + api->userdata, struct avahi_poll_context); | |
298 | + int num_timeouts = talloc_get_size(ctx->timeouts)/sizeof(*ctx->timeouts); | |
299 | + AvahiTimeout **tmp, *timeout_ctx; | |
300 | + | |
301 | + tmp = talloc_realloc(ctx, ctx->timeouts, AvahiTimeout *, | |
302 | + num_timeouts + 1); | |
303 | + if (tmp == NULL) { | |
304 | + return NULL; | |
305 | + } | |
306 | + ctx->timeouts = tmp; | |
307 | + | |
308 | + timeout_ctx = talloc(tmp, AvahiTimeout); | |
309 | + if (timeout_ctx == NULL) { | |
310 | + goto fail; | |
311 | + } | |
312 | + ctx->timeouts[num_timeouts] = timeout_ctx; | |
313 | + | |
314 | + timeout_ctx->ctx = ctx; | |
315 | + if (tv == NULL) { | |
316 | + timeout_ctx->te = NULL; | |
317 | + } else { | |
318 | + timeout_ctx->te = event_add_timed(ctx->ev, timeout_ctx, | |
319 | + *tv, avahi_timeout_handler, | |
320 | + timeout_ctx); | |
321 | + if (timeout_ctx->te == NULL) { | |
322 | + goto fail; | |
323 | + } | |
324 | + } | |
325 | + timeout_ctx->callback = callback; | |
326 | + timeout_ctx->userdata = userdata; | |
327 | + return timeout_ctx; | |
328 | + | |
329 | + fail: | |
330 | + TALLOC_FREE(timeout_ctx); | |
331 | + ctx->timeouts = talloc_realloc(ctx, ctx->timeouts, AvahiTimeout *, | |
332 | + num_timeouts); | |
333 | + return NULL; | |
334 | +} | |
335 | + | |
336 | +static void avahi_timeout_handler(struct event_context *ev, | |
337 | + struct timed_event *te, | |
338 | + struct timeval current_time, | |
339 | + void *private_data) | |
340 | +{ | |
341 | + AvahiTimeout *timeout_ctx = talloc_get_type_abort( | |
342 | + private_data, AvahiTimeout); | |
343 | + | |
344 | + TALLOC_FREE(timeout_ctx->te); | |
345 | + timeout_ctx->callback(timeout_ctx, timeout_ctx->userdata); | |
346 | +} | |
347 | + | |
348 | +static void avahi_timeout_update(AvahiTimeout *t, const struct timeval *tv) | |
349 | +{ | |
350 | + TALLOC_FREE(t->te); | |
351 | + | |
352 | + t->te = event_add_timed(t->ctx->ev, t, *tv, avahi_timeout_handler, t); | |
353 | + /* | |
354 | + * No failure mode defined here | |
355 | + */ | |
356 | + SMB_ASSERT(t->te != NULL); | |
357 | +} | |
358 | + | |
359 | +static void avahi_timeout_free(AvahiTimeout *t) | |
360 | +{ | |
361 | + int i, num_timeouts; | |
362 | + AvahiTimeout **timeouts = t->ctx->timeouts; | |
363 | + struct avahi_poll_context *ctx; | |
364 | + | |
365 | + num_timeouts = talloc_get_size(timeouts)/sizeof(*timeouts); | |
366 | + | |
367 | + for (i=0; i<num_timeouts; i++) { | |
368 | + if (t == timeouts[i]) { | |
369 | + break; | |
370 | + } | |
371 | + } | |
372 | + if (i == num_timeouts) { | |
373 | + return; | |
374 | + } | |
375 | + ctx = t->ctx; | |
376 | + TALLOC_FREE(t); | |
377 | + memmove(&timeouts[i], &timeouts[i+1], | |
378 | + sizeof(*timeouts) * (num_timeouts - i - 1)); | |
379 | + ctx->timeouts = talloc_realloc(ctx, timeouts, AvahiTimeout *, | |
380 | + num_timeouts - 1); | |
381 | +} | |
382 | + | |
383 | +struct AvahiPoll *tevent_avahi_poll(TALLOC_CTX *mem_ctx, | |
384 | + struct event_context *ev) | |
385 | +{ | |
386 | + struct AvahiPoll *result; | |
387 | + struct avahi_poll_context *ctx; | |
388 | + | |
389 | + result = talloc(mem_ctx, struct AvahiPoll); | |
390 | + if (result == NULL) { | |
391 | + return result; | |
392 | + } | |
393 | + ctx = talloc_zero(result, struct avahi_poll_context); | |
394 | + if (ctx == NULL) { | |
395 | + TALLOC_FREE(result); | |
396 | + return NULL; | |
397 | + } | |
398 | + ctx->ev = ev; | |
399 | + | |
400 | + result->watch_new = avahi_watch_new; | |
401 | + result->watch_update = avahi_watch_update; | |
402 | + result->watch_get_events = avahi_watch_get_events; | |
403 | + result->watch_free = avahi_watch_free; | |
404 | + result->timeout_new = avahi_timeout_new; | |
405 | + result->timeout_update = avahi_timeout_update; | |
406 | + result->timeout_free = avahi_timeout_free; | |
407 | + result->userdata = ctx; | |
408 | + | |
409 | + return result; | |
410 | +} | |
411 | diff --git a/source/smbd/avahi_register.c b/source/smbd/avahi_register.c | |
412 | new file mode 100644 | |
413 | index 0000000..95cb6d1 | |
414 | --- /dev/null | |
415 | +++ b/source/smbd/avahi_register.c | |
416 | @@ -0,0 +1,170 @@ | |
417 | +/* | |
418 | + * Unix SMB/CIFS implementation. | |
419 | + * Register _smb._tcp with avahi | |
420 | + * | |
421 | + * Copyright (C) Volker Lendecke 2009 | |
422 | + * | |
423 | + * This program is free software; you can redistribute it and/or modify | |
424 | + * it under the terms of the GNU General Public License as published by | |
425 | + * the Free Software Foundation; either version 3 of the License, or | |
426 | + * (at your option) any later version. | |
427 | + * | |
428 | + * This program is distributed in the hope that it will be useful, | |
429 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
430 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
431 | + * GNU General Public License for more details. | |
432 | + * | |
433 | + * You should have received a copy of the GNU General Public License | |
434 | + * along with this program; if not, see <http://www.gnu.org/licenses/>. | |
435 | + */ | |
436 | + | |
437 | +#include "includes.h" | |
438 | + | |
439 | +#include <avahi-client/client.h> | |
440 | +#include <avahi-client/publish.h> | |
441 | +#include <avahi-common/error.h> | |
442 | + | |
443 | +struct avahi_state_struct { | |
444 | + struct AvahiPoll *poll; | |
445 | + AvahiClient *client; | |
446 | + AvahiEntryGroup *entry_group; | |
447 | + uint16_t port; | |
448 | +}; | |
449 | + | |
450 | +static void avahi_entry_group_callback(AvahiEntryGroup *g, | |
451 | + AvahiEntryGroupState status, | |
452 | + void *userdata) | |
453 | +{ | |
454 | + struct avahi_state_struct *state = talloc_get_type_abort( | |
455 | + userdata, struct avahi_state_struct); | |
456 | + int error; | |
457 | + | |
458 | + switch (status) { | |
459 | + case AVAHI_ENTRY_GROUP_ESTABLISHED: | |
460 | + DEBUG(10, ("avahi_entry_group_callback: " | |
461 | + "AVAHI_ENTRY_GROUP_ESTABLISHED\n")); | |
462 | + break; | |
463 | + case AVAHI_ENTRY_GROUP_FAILURE: | |
464 | + error = avahi_client_errno(state->client); | |
465 | + | |
466 | + DEBUG(10, ("avahi_entry_group_callback: " | |
467 | + "AVAHI_ENTRY_GROUP_FAILURE: %s\n", | |
468 | + avahi_strerror(error))); | |
469 | + break; | |
470 | + case AVAHI_ENTRY_GROUP_COLLISION: | |
471 | + DEBUG(10, ("avahi_entry_group_callback: " | |
472 | + "AVAHI_ENTRY_GROUP_COLLISION\n")); | |
473 | + break; | |
474 | + case AVAHI_ENTRY_GROUP_UNCOMMITED: | |
475 | + DEBUG(10, ("avahi_entry_group_callback: " | |
476 | + "AVAHI_ENTRY_GROUP_UNCOMMITED\n")); | |
477 | + break; | |
478 | + case AVAHI_ENTRY_GROUP_REGISTERING: | |
479 | + DEBUG(10, ("avahi_entry_group_callback: " | |
480 | + "AVAHI_ENTRY_GROUP_REGISTERING\n")); | |
481 | + break; | |
482 | + } | |
483 | +} | |
484 | + | |
485 | +static void avahi_client_callback(AvahiClient *c, AvahiClientState status, | |
486 | + void *userdata) | |
487 | +{ | |
488 | + struct avahi_state_struct *state = talloc_get_type_abort( | |
489 | + userdata, struct avahi_state_struct); | |
490 | + int error; | |
491 | + | |
492 | + switch (status) { | |
493 | + case AVAHI_CLIENT_S_RUNNING: | |
494 | + DEBUG(10, ("avahi_client_callback: AVAHI_CLIENT_S_RUNNING\n")); | |
495 | + | |
496 | + state->entry_group = avahi_entry_group_new( | |
497 | + c, avahi_entry_group_callback, state); | |
498 | + if (state->entry_group == NULL) { | |
499 | + error = avahi_client_errno(c); | |
500 | + DEBUG(10, ("avahi_entry_group_new failed: %s\n", | |
501 | + avahi_strerror(error))); | |
502 | + break; | |
503 | + } | |
504 | + if (avahi_entry_group_add_service( | |
505 | + state->entry_group, AVAHI_IF_UNSPEC, | |
506 | + AVAHI_PROTO_UNSPEC, 0, global_myname(), | |
507 | + "_smb._tcp", NULL, NULL, state->port, NULL) < 0) { | |
508 | + error = avahi_client_errno(c); | |
509 | + DEBUG(10, ("avahi_entry_group_add_service failed: " | |
510 | + "%s\n", avahi_strerror(error))); | |
511 | + avahi_entry_group_free(state->entry_group); | |
512 | + state->entry_group = NULL; | |
513 | + break; | |
514 | + } | |
515 | + if (avahi_entry_group_commit(state->entry_group) < 0) { | |
516 | + error = avahi_client_errno(c); | |
517 | + DEBUG(10, ("avahi_entry_group_commit failed: " | |
518 | + "%s\n", avahi_strerror(error))); | |
519 | + avahi_entry_group_free(state->entry_group); | |
520 | + state->entry_group = NULL; | |
521 | + break; | |
522 | + } | |
523 | + break; | |
524 | + case AVAHI_CLIENT_FAILURE: | |
525 | + error = avahi_client_errno(c); | |
526 | + | |
527 | + DEBUG(10, ("avahi_client_callback: AVAHI_CLIENT_FAILURE: %s\n", | |
528 | + avahi_strerror(error))); | |
529 | + | |
530 | + if (error != AVAHI_ERR_DISCONNECTED) { | |
531 | + break; | |
532 | + } | |
533 | + avahi_client_free(c); | |
534 | + state->client = avahi_client_new(state->poll, AVAHI_CLIENT_NO_FAIL, | |
535 | + avahi_client_callback, state, | |
536 | + &error); | |
537 | + if (state->client == NULL) { | |
538 | + DEBUG(10, ("avahi_client_new failed: %s\n", | |
539 | + avahi_strerror(error))); | |
540 | + break; | |
541 | + } | |
542 | + break; | |
543 | + case AVAHI_CLIENT_S_COLLISION: | |
544 | + DEBUG(10, ("avahi_client_callback: " | |
545 | + "AVAHI_CLIENT_S_COLLISION\n")); | |
546 | + break; | |
547 | + case AVAHI_CLIENT_S_REGISTERING: | |
548 | + DEBUG(10, ("avahi_client_callback: " | |
549 | + "AVAHI_CLIENT_S_REGISTERING\n")); | |
550 | + break; | |
551 | + case AVAHI_CLIENT_CONNECTING: | |
552 | + DEBUG(10, ("avahi_client_callback: " | |
553 | + "AVAHI_CLIENT_CONNECTING\n")); | |
554 | + break; | |
555 | + } | |
556 | +} | |
557 | + | |
558 | +void *avahi_start_register(TALLOC_CTX *mem_ctx, struct event_context *ev, | |
559 | + uint16_t port) | |
560 | +{ | |
561 | + struct avahi_state_struct *state; | |
562 | + int error; | |
563 | + | |
564 | + state = talloc(mem_ctx, struct avahi_state_struct); | |
565 | + if (state == NULL) { | |
566 | + return state; | |
567 | + } | |
568 | + state->port = port; | |
569 | + state->poll = tevent_avahi_poll(state, ev); | |
570 | + if (state->poll == NULL) { | |
571 | + goto fail; | |
572 | + } | |
573 | + state->client = avahi_client_new(state->poll, AVAHI_CLIENT_NO_FAIL, | |
574 | + avahi_client_callback, state, | |
575 | + &error); | |
576 | + if (state->client == NULL) { | |
577 | + DEBUG(10, ("avahi_client_new failed: %s\n", | |
578 | + avahi_strerror(error))); | |
579 | + goto fail; | |
580 | + } | |
581 | + return state; | |
582 | + | |
583 | + fail: | |
584 | + TALLOC_FREE(state); | |
585 | + return NULL; | |
586 | +} | |
587 | diff --git a/source/smbd/server.c b/source/smbd/server.c | |
588 | index 00a2cd4..b05758e 100644 | |
589 | --- a/source/smbd/server.c | |
590 | +++ b/source/smbd/server.c | |
591 | @@ -588,6 +588,23 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_ | |
592 | MSG_SMB_INJECT_FAULT, msg_inject_fault); | |
593 | #endif | |
594 | ||
595 | + /* Kick off our mDNS registration. */ | |
596 | + if (dns_port != 0) { | |
597 | +#ifdef WITH_DNSSD_SUPPORT | |
598 | + dns_register_smbd(&dns_reg, dns_port, &maxfd, | |
599 | + &r_fds, &idle_timeout); | |
600 | +#endif | |
601 | +#ifdef WITH_AVAHI_SUPPORT | |
602 | + void *avahi_conn; | |
603 | + avahi_conn = avahi_start_register( | |
604 | + smbd_event_context(), smbd_event_context(), | |
605 | + dns_port); | |
606 | + if (avahi_conn == NULL) { | |
607 | + DEBUG(10, ("avahi_start_register failed\n")); | |
608 | + } | |
609 | +#endif | |
610 | + } | |
611 | + | |
612 | /* now accept incoming connections - forking a new process | |
613 | for each incoming connection */ | |
614 | DEBUG(2,("waiting for a connection\n")); | |
615 | @@ -632,12 +649,6 @@ static bool open_sockets_smbd(bool is_daemon, bool interactive, const char *smb_ | |
616 | FD_ZERO(&w_fds); | |
617 | GetTimeOfDay(&now); | |
618 | ||
619 | - /* Kick off our mDNS registration. */ | |
620 | - if (dns_port != 0) { | |
621 | - dns_register_smbd(&dns_reg, dns_port, &maxfd, | |
622 | - &r_fds, &idle_timeout); | |
623 | - } | |
624 | - | |
625 | event_add_to_select_args(smbd_event_context(), &now, | |
626 | &r_fds, &w_fds, &idle_timeout, | |
627 | &maxfd); |