diff options
Diffstat (limited to 'meta/recipes-devtools/distcc/files')
-rw-r--r-- | meta/recipes-devtools/distcc/files/distcc-avahi.patch | 1738 | ||||
-rw-r--r-- | meta/recipes-devtools/distcc/files/makefile-param-order.patch | 20 |
2 files changed, 0 insertions, 1758 deletions
diff --git a/meta/recipes-devtools/distcc/files/distcc-avahi.patch b/meta/recipes-devtools/distcc/files/distcc-avahi.patch deleted file mode 100644 index 1f15d4b82a..0000000000 --- a/meta/recipes-devtools/distcc/files/distcc-avahi.patch +++ /dev/null | |||
@@ -1,1738 +0,0 @@ | |||
1 | Upstream-Status: Pending | ||
2 | |||
3 | --- upstream/aclocal.m4 1970-01-01 01:00:00.000000000 +0100 | ||
4 | +++ lennart/aclocal.m4 2005-11-18 04:19:18.000000000 +0100 | ||
5 | @@ -0,0 +1,171 @@ | ||
6 | +# generated automatically by aclocal 1.9.6 -*- Autoconf -*- | ||
7 | + | ||
8 | +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, | ||
9 | +# 2005 Free Software Foundation, Inc. | ||
10 | +# This file is free software; the Free Software Foundation | ||
11 | +# gives unlimited permission to copy and/or distribute it, | ||
12 | +# with or without modifications, as long as this notice is preserved. | ||
13 | + | ||
14 | +# This program is distributed in the hope that it will be useful, | ||
15 | +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without | ||
16 | +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A | ||
17 | +# PARTICULAR PURPOSE. | ||
18 | + | ||
19 | +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- | ||
20 | +# | ||
21 | +# Copyright © 2004 Scott James Remnant <scott@netsplit.com>. | ||
22 | +# | ||
23 | +# This program is free software; you can redistribute it and/or modify | ||
24 | +# it under the terms of the GNU General Public License as published by | ||
25 | +# the Free Software Foundation; either version 2 of the License, or | ||
26 | +# (at your option) any later version. | ||
27 | +# | ||
28 | +# This program is distributed in the hope that it will be useful, but | ||
29 | +# WITHOUT ANY WARRANTY; without even the implied warranty of | ||
30 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
31 | +# General Public License for more details. | ||
32 | +# | ||
33 | +# You should have received a copy of the GNU General Public License | ||
34 | +# along with this program; if not, write to the Free Software | ||
35 | +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
36 | +# | ||
37 | +# As a special exception to the GNU General Public License, if you | ||
38 | +# distribute this file as part of a program that contains a | ||
39 | +# configuration script generated by Autoconf, you may include it under | ||
40 | +# the same distribution terms that you use for the rest of that program. | ||
41 | + | ||
42 | +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) | ||
43 | +# ---------------------------------- | ||
44 | +AC_DEFUN([PKG_PROG_PKG_CONFIG], | ||
45 | +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) | ||
46 | +m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) | ||
47 | +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl | ||
48 | +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then | ||
49 | + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) | ||
50 | +fi | ||
51 | +if test -n "$PKG_CONFIG"; then | ||
52 | + _pkg_min_version=m4_default([$1], [0.9.0]) | ||
53 | + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) | ||
54 | + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then | ||
55 | + AC_MSG_RESULT([yes]) | ||
56 | + else | ||
57 | + AC_MSG_RESULT([no]) | ||
58 | + PKG_CONFIG="" | ||
59 | + fi | ||
60 | + | ||
61 | +fi[]dnl | ||
62 | +])# PKG_PROG_PKG_CONFIG | ||
63 | + | ||
64 | +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) | ||
65 | +# | ||
66 | +# Check to see whether a particular set of modules exists. Similar | ||
67 | +# to PKG_CHECK_MODULES(), but does not set variables or print errors. | ||
68 | +# | ||
69 | +# | ||
70 | +# Similar to PKG_CHECK_MODULES, make sure that the first instance of | ||
71 | +# this or PKG_CHECK_MODULES is called, or make sure to call | ||
72 | +# PKG_CHECK_EXISTS manually | ||
73 | +# -------------------------------------------------------------- | ||
74 | +AC_DEFUN([PKG_CHECK_EXISTS], | ||
75 | +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl | ||
76 | +if test -n "$PKG_CONFIG" && \ | ||
77 | + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then | ||
78 | + m4_ifval([$2], [$2], [:]) | ||
79 | +m4_ifvaln([$3], [else | ||
80 | + $3])dnl | ||
81 | +fi]) | ||
82 | + | ||
83 | + | ||
84 | +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) | ||
85 | +# --------------------------------------------- | ||
86 | +m4_define([_PKG_CONFIG], | ||
87 | +[if test -n "$PKG_CONFIG"; then | ||
88 | + if test -n "$$1"; then | ||
89 | + pkg_cv_[]$1="$$1" | ||
90 | + else | ||
91 | + PKG_CHECK_EXISTS([$3], | ||
92 | + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], | ||
93 | + [pkg_failed=yes]) | ||
94 | + fi | ||
95 | +else | ||
96 | + pkg_failed=untried | ||
97 | +fi[]dnl | ||
98 | +])# _PKG_CONFIG | ||
99 | + | ||
100 | +# _PKG_SHORT_ERRORS_SUPPORTED | ||
101 | +# ----------------------------- | ||
102 | +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], | ||
103 | +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) | ||
104 | +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then | ||
105 | + _pkg_short_errors_supported=yes | ||
106 | +else | ||
107 | + _pkg_short_errors_supported=no | ||
108 | +fi[]dnl | ||
109 | +])# _PKG_SHORT_ERRORS_SUPPORTED | ||
110 | + | ||
111 | + | ||
112 | +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], | ||
113 | +# [ACTION-IF-NOT-FOUND]) | ||
114 | +# | ||
115 | +# | ||
116 | +# Note that if there is a possibility the first call to | ||
117 | +# PKG_CHECK_MODULES might not happen, you should be sure to include an | ||
118 | +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac | ||
119 | +# | ||
120 | +# | ||
121 | +# -------------------------------------------------------------- | ||
122 | +AC_DEFUN([PKG_CHECK_MODULES], | ||
123 | +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl | ||
124 | +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl | ||
125 | +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl | ||
126 | + | ||
127 | +pkg_failed=no | ||
128 | +AC_MSG_CHECKING([for $1]) | ||
129 | + | ||
130 | +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) | ||
131 | +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) | ||
132 | + | ||
133 | +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS | ||
134 | +and $1[]_LIBS to avoid the need to call pkg-config. | ||
135 | +See the pkg-config man page for more details.]) | ||
136 | + | ||
137 | +if test $pkg_failed = yes; then | ||
138 | + _PKG_SHORT_ERRORS_SUPPORTED | ||
139 | + if test $_pkg_short_errors_supported = yes; then | ||
140 | + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"` | ||
141 | + else | ||
142 | + $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` | ||
143 | + fi | ||
144 | + # Put the nasty error message in config.log where it belongs | ||
145 | + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD | ||
146 | + | ||
147 | + ifelse([$4], , [AC_MSG_ERROR(dnl | ||
148 | +[Package requirements ($2) were not met: | ||
149 | + | ||
150 | +$$1_PKG_ERRORS | ||
151 | + | ||
152 | +Consider adjusting the PKG_CONFIG_PATH environment variable if you | ||
153 | +installed software in a non-standard prefix. | ||
154 | + | ||
155 | +_PKG_TEXT | ||
156 | +])], | ||
157 | + [$4]) | ||
158 | +elif test $pkg_failed = untried; then | ||
159 | + ifelse([$4], , [AC_MSG_FAILURE(dnl | ||
160 | +[The pkg-config script could not be found or is too old. Make sure it | ||
161 | +is in your PATH or set the PKG_CONFIG environment variable to the full | ||
162 | +path to pkg-config. | ||
163 | + | ||
164 | +_PKG_TEXT | ||
165 | + | ||
166 | +To get pkg-config, see <http://www.freedesktop.org/software/pkgconfig>.])], | ||
167 | + [$4]) | ||
168 | +else | ||
169 | + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS | ||
170 | + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS | ||
171 | + AC_MSG_RESULT([yes]) | ||
172 | + ifelse([$3], , :, [$3]) | ||
173 | +fi[]dnl | ||
174 | +])# PKG_CHECK_MODULES | ||
175 | + | ||
176 | +m4_include([acinclude.m4]) | ||
177 | --- upstream/Makefile.in 2005-11-18 16:15:40.000000000 +0100 | ||
178 | +++ lennart/Makefile.in 2005-11-18 01:14:43.000000000 +0100 | ||
179 | @@ -171,6 +171,7 @@ | ||
180 | src/ssh.o src/state.o src/strip.o \ | ||
181 | src/timefile.o src/traceenv.o \ | ||
182 | src/where.o \ | ||
183 | + @ZEROCONF_DISTCC_OBJS@ \ | ||
184 | $(common_obj) | ||
185 | |||
186 | distccd_obj = src/access.o \ | ||
187 | @@ -178,6 +179,7 @@ | ||
188 | src/ncpus.o \ | ||
189 | src/prefork.o \ | ||
190 | src/serve.o src/setuid.o src/srvnet.o src/srvrpc.o src/state.o \ | ||
191 | + @ZEROCONF_DISTCCD_OBJS@ \ | ||
192 | $(common_obj) @BUILD_POPT@ | ||
193 | |||
194 | # Objects that need to be linked in to build monitors | ||
195 | --- upstream/src/distcc.c 2005-11-18 16:15:40.000000000 +0100 | ||
196 | +++ lennart/src/distcc.c 2005-11-18 01:14:43.000000000 +0100 | ||
197 | @@ -83,6 +83,9 @@ | ||
198 | " COMPILER defaults to \"cc\"\n" | ||
199 | " --help explain usage and exit\n" | ||
200 | " --version show version and exit\n" | ||
201 | +" --show-hosts show host list and exit\n" | ||
202 | +" -j calculate the concurrency level from\n" | ||
203 | +" the host list.\n" | ||
204 | "\n" | ||
205 | "Environment variables:\n" | ||
206 | " See the manual page for a complete list.\n" | ||
207 | @@ -135,7 +138,46 @@ | ||
208 | signal(SIGHUP, &dcc_client_signalled); | ||
209 | } | ||
210 | |||
211 | +static void dcc_free_hostlist(struct dcc_hostdef *list) { | ||
212 | + while (list) { | ||
213 | + struct dcc_hostdef *l = list; | ||
214 | + list = list->next; | ||
215 | + dcc_free_hostdef(l); | ||
216 | + } | ||
217 | +} | ||
218 | + | ||
219 | +static void dcc_show_hosts(void) { | ||
220 | + struct dcc_hostdef *list, *l; | ||
221 | + int nhosts; | ||
222 | + | ||
223 | + if (dcc_get_hostlist(&list, &nhosts) != 0) { | ||
224 | + rs_log_crit("Failed to get host list"); | ||
225 | + return; | ||
226 | + } | ||
227 | + | ||
228 | + for (l = list; l; l = l->next) | ||
229 | + printf("%s\n", l->hostdef_string); | ||
230 | + | ||
231 | + dcc_free_hostlist(list); | ||
232 | +} | ||
233 | + | ||
234 | +static void dcc_concurrency_level(void) { | ||
235 | + struct dcc_hostdef *list, *l; | ||
236 | + int nhosts; | ||
237 | + int nslots = 0; | ||
238 | + | ||
239 | + if (dcc_get_hostlist(&list, &nhosts) != 0) { | ||
240 | + rs_log_crit("Failed to get host list"); | ||
241 | + return; | ||
242 | + } | ||
243 | + | ||
244 | + for (l = list; l; l = l->next) | ||
245 | + nslots += l->n_slots; | ||
246 | |||
247 | + dcc_free_hostlist(list); | ||
248 | + | ||
249 | + printf("%i\n", nslots); | ||
250 | +} | ||
251 | |||
252 | /** | ||
253 | * distcc client entry point. | ||
254 | @@ -182,6 +224,18 @@ | ||
255 | ret = 0; | ||
256 | goto out; | ||
257 | } | ||
258 | + | ||
259 | + if (!strcmp(argv[1], "--show-hosts")) { | ||
260 | + dcc_show_hosts(); | ||
261 | + ret = 0; | ||
262 | + goto out; | ||
263 | + } | ||
264 | + | ||
265 | + if (!strcmp(argv[1], "-j")) { | ||
266 | + dcc_concurrency_level(); | ||
267 | + ret = 0; | ||
268 | + goto out; | ||
269 | + } | ||
270 | |||
271 | dcc_find_compiler(argv, &compiler_args); | ||
272 | /* compiler_args is now respectively either "cc -c hello.c" or | ||
273 | --- upstream/src/distcc.h 2005-11-18 16:15:40.000000000 +0100 | ||
274 | +++ lennart/src/distcc.h 2005-11-18 01:14:43.000000000 +0100 | ||
275 | @@ -112,7 +112,7 @@ | ||
276 | int *ret_nhosts); | ||
277 | int dcc_parse_hosts(const char *where, const char *source_name, | ||
278 | struct dcc_hostdef **ret_list, | ||
279 | - int *ret_nhosts); | ||
280 | + int *ret_nhosts, struct dcc_hostdef **ret_prev); | ||
281 | |||
282 | /* ncpu.c */ | ||
283 | int dcc_ncpus(int *); | ||
284 | @@ -226,6 +226,7 @@ | ||
285 | int dcc_make_tmpnam(const char *, const char *suffix, char **); | ||
286 | |||
287 | int dcc_mkdir(const char *path) WARN_UNUSED; | ||
288 | +int dcc_get_subdir(const char *name, char **path_ret) WARN_UNUSED; | ||
289 | int dcc_get_lock_dir(char **path_ret) WARN_UNUSED; | ||
290 | int dcc_get_state_dir(char **path_ret) WARN_UNUSED; | ||
291 | int dcc_get_top_dir(char **path_ret) WARN_UNUSED; | ||
292 | --- upstream/src/dopt.c 2005-11-18 16:15:40.000000000 +0100 | ||
293 | +++ lennart/src/dopt.c 2005-11-18 04:14:26.000000000 +0100 | ||
294 | @@ -93,6 +93,10 @@ | ||
295 | opt_log_level | ||
296 | }; | ||
297 | |||
298 | +#ifdef HAVE_AVAHI | ||
299 | +/* Flag for enabling/disabling Zeroconf using Avahi */ | ||
300 | +int opt_zeroconf = 0; | ||
301 | +#endif | ||
302 | |||
303 | const struct poptOption options[] = { | ||
304 | { "allow", 'a', POPT_ARG_STRING, 0, 'a', 0, 0 }, | ||
305 | @@ -115,6 +119,9 @@ | ||
306 | { "verbose", 0, POPT_ARG_NONE, 0, 'v', 0, 0 }, | ||
307 | { "version", 0, POPT_ARG_NONE, 0, 'V', 0, 0 }, | ||
308 | { "wizard", 'W', POPT_ARG_NONE, 0, 'W', 0, 0 }, | ||
309 | +#ifdef HAVE_AVAHI | ||
310 | + { "zeroconf", 0, POPT_ARG_NONE, &opt_zeroconf, 0, 0, 0 }, | ||
311 | +#endif | ||
312 | { 0, 0, 0, 0, 0, 0, 0 } | ||
313 | }; | ||
314 | |||
315 | @@ -137,6 +144,9 @@ | ||
316 | " -p, --port PORT TCP port to listen on\n" | ||
317 | " --listen ADDRESS IP address to listen on\n" | ||
318 | " -a, --allow IP[/BITS] client address access control\n" | ||
319 | +#ifdef HAVE_AVAHI | ||
320 | +" --zeroconf register via mDNS/DNS-SD\n" | ||
321 | +#endif | ||
322 | " Debug and trace:\n" | ||
323 | " --log-level=LEVEL set detail level for log file\n" | ||
324 | " levels: critical, error, warning, notice, info, debug\n" | ||
325 | --- upstream/src/dopt.h 2005-11-18 16:15:40.000000000 +0100 | ||
326 | +++ lennart/src/dopt.h 2005-11-18 02:27:45.000000000 +0100 | ||
327 | @@ -38,3 +38,7 @@ | ||
328 | extern int opt_lifetime; | ||
329 | extern char *opt_listen_addr; | ||
330 | extern int opt_niceness; | ||
331 | + | ||
332 | +#ifdef HAVE_AVAHI | ||
333 | +extern int opt_zeroconf; | ||
334 | +#endif | ||
335 | --- upstream/src/dparent.c 2005-11-18 16:15:40.000000000 +0100 | ||
336 | +++ lennart/src/dparent.c 2005-11-18 04:13:23.000000000 +0100 | ||
337 | @@ -70,6 +70,7 @@ | ||
338 | #include "types.h" | ||
339 | #include "daemon.h" | ||
340 | #include "netutil.h" | ||
341 | +#include "zeroconf.h" | ||
342 | |||
343 | static void dcc_nofork_parent(int listen_fd) NORETURN; | ||
344 | static void dcc_detach(void); | ||
345 | @@ -94,6 +95,9 @@ | ||
346 | int listen_fd; | ||
347 | int n_cpus; | ||
348 | int ret; | ||
349 | +#ifdef HAVE_AVAHI | ||
350 | + void *avahi = NULL; | ||
351 | +#endif | ||
352 | |||
353 | if ((ret = dcc_socket_listen(arg_port, &listen_fd, opt_listen_addr)) != 0) | ||
354 | return ret; | ||
355 | @@ -131,6 +135,14 @@ | ||
356 | /* Don't catch signals until we've detached or created a process group. */ | ||
357 | dcc_daemon_catch_signals(); | ||
358 | |||
359 | +#ifdef HAVE_AVAHI | ||
360 | + /* Zeroconf registration */ | ||
361 | + if (opt_zeroconf) { | ||
362 | + if (!(avahi = dcc_zeroconf_register((uint16_t) arg_port, n_cpus))) | ||
363 | + return EXIT_CONNECT_FAILED; | ||
364 | + } | ||
365 | +#endif | ||
366 | + | ||
367 | /* This is called in the master daemon, whether that is detached or | ||
368 | * not. */ | ||
369 | dcc_master_pid = getpid(); | ||
370 | @@ -138,10 +150,21 @@ | ||
371 | if (opt_no_fork) { | ||
372 | dcc_log_daemon_started("non-forking daemon"); | ||
373 | dcc_nofork_parent(listen_fd); | ||
374 | + ret = 0; | ||
375 | } else { | ||
376 | dcc_log_daemon_started("preforking daemon"); | ||
377 | - return dcc_preforking_parent(listen_fd); | ||
378 | + ret = dcc_preforking_parent(listen_fd); | ||
379 | } | ||
380 | + | ||
381 | +#ifdef HAVE_AVAHI | ||
382 | + /* Remove zeroconf registration */ | ||
383 | + if (opt_zeroconf) { | ||
384 | + if (dcc_zeroconf_unregister(avahi) != 0) | ||
385 | + return EXIT_CONNECT_FAILED; | ||
386 | + } | ||
387 | +#endif | ||
388 | + | ||
389 | + return ret; | ||
390 | } | ||
391 | |||
392 | |||
393 | --- upstream/src/help.c 2005-11-18 16:15:40.000000000 +0100 | ||
394 | +++ lennart/src/help.c 2005-11-18 02:27:45.000000000 +0100 | ||
395 | @@ -62,6 +62,9 @@ | ||
396 | "distcc comes with ABSOLUTELY NO WARRANTY. distcc is free software, and\n" | ||
397 | "you may use, modify and redistribute it under the terms of the GNU \n" | ||
398 | "General Public License version 2 or later.\n" | ||
399 | +#ifdef HAVE_AVAHI | ||
400 | +"\nBuilt with Zeroconf support.\n" | ||
401 | +#endif | ||
402 | "\n" | ||
403 | , | ||
404 | prog, PACKAGE_VERSION, GNU_HOST, DISTCC_DEFAULT_PORT, | ||
405 | --- upstream/src/hostfile.c 2005-11-18 16:15:40.000000000 +0100 | ||
406 | +++ lennart/src/hostfile.c 2005-11-18 01:14:43.000000000 +0100 | ||
407 | @@ -59,7 +59,7 @@ | ||
408 | if ((ret = dcc_load_file_string(fname, &body)) != 0) | ||
409 | return ret; | ||
410 | |||
411 | - ret = dcc_parse_hosts(body, fname, ret_list, ret_nhosts); | ||
412 | + ret = dcc_parse_hosts(body, fname, ret_list, ret_nhosts, NULL); | ||
413 | |||
414 | free(body); | ||
415 | |||
416 | --- upstream/src/hosts.c 2005-11-18 16:15:40.000000000 +0100 | ||
417 | +++ lennart/src/hosts.c 2005-11-18 02:27:45.000000000 +0100 | ||
418 | @@ -96,6 +96,10 @@ | ||
419 | #include "hosts.h" | ||
420 | #include "exitcode.h" | ||
421 | #include "snprintf.h" | ||
422 | +#ifdef HAVE_AVAHI | ||
423 | +#include "zeroconf.h" | ||
424 | +#define ZEROCONF_MAGIC "+zeroconf" | ||
425 | +#endif | ||
426 | |||
427 | const int dcc_default_port = DISTCC_DEFAULT_PORT; | ||
428 | |||
429 | @@ -134,9 +138,12 @@ | ||
430 | char *path, *top; | ||
431 | int ret; | ||
432 | |||
433 | + *ret_list = NULL; | ||
434 | + *ret_nhosts = 0; | ||
435 | + | ||
436 | if ((env = getenv("DISTCC_HOSTS")) != NULL) { | ||
437 | rs_trace("read hosts from environment"); | ||
438 | - return dcc_parse_hosts(env, "$DISTCC_HOSTS", ret_list, ret_nhosts); | ||
439 | + return dcc_parse_hosts(env, "$DISTCC_HOSTS", ret_list, ret_nhosts, NULL); | ||
440 | } | ||
441 | |||
442 | /* $DISTCC_DIR or ~/.distcc */ | ||
443 | @@ -163,7 +170,7 @@ | ||
444 | rs_trace("not reading %s: %s", path, strerror(errno)); | ||
445 | free(path); | ||
446 | } | ||
447 | - | ||
448 | + | ||
449 | /* FIXME: Clearer message? */ | ||
450 | rs_log_warning("no hostlist is set; can't distribute work"); | ||
451 | |||
452 | @@ -346,17 +353,19 @@ | ||
453 | **/ | ||
454 | int dcc_parse_hosts(const char *where, const char *source_name, | ||
455 | struct dcc_hostdef **ret_list, | ||
456 | - int *ret_nhosts) | ||
457 | + int *ret_nhosts, struct dcc_hostdef **ret_prev) | ||
458 | { | ||
459 | int ret; | ||
460 | - struct dcc_hostdef *prev, *curr; | ||
461 | + struct dcc_hostdef *curr, *_prev; | ||
462 | + | ||
463 | + if (!ret_prev) { | ||
464 | + ret_prev = &_prev; | ||
465 | + _prev = NULL; | ||
466 | + } | ||
467 | |||
468 | /* TODO: Check for '/' in places where it might cause trouble with | ||
469 | * a lock file name. */ | ||
470 | |||
471 | - prev = NULL; | ||
472 | - *ret_list = NULL; | ||
473 | - *ret_nhosts = 0; | ||
474 | /* A simple, hardcoded scanner. Some of the GNU routines might be | ||
475 | * useful here, but they won't work on less capable systems. | ||
476 | * | ||
477 | @@ -390,6 +399,15 @@ | ||
478 | token_start = where; | ||
479 | token_len = strcspn(where, " #\t\n\f\r"); | ||
480 | |||
481 | +#ifdef HAVE_AVAHI | ||
482 | + if (token_len == sizeof(ZEROCONF_MAGIC)-1 && | ||
483 | + !strncmp(token_start, ZEROCONF_MAGIC, (unsigned) token_len)) { | ||
484 | + if ((ret = dcc_zeroconf_add_hosts(ret_list, ret_nhosts, 4, ret_prev) != 0)) | ||
485 | + return ret; | ||
486 | + goto skip; | ||
487 | + } | ||
488 | +#endif | ||
489 | + | ||
490 | /* Allocate new list item */ | ||
491 | curr = calloc(1, sizeof(struct dcc_hostdef)); | ||
492 | if (!curr) { | ||
493 | @@ -404,8 +422,8 @@ | ||
494 | } | ||
495 | |||
496 | /* Link into list */ | ||
497 | - if (prev) { | ||
498 | - prev->next = curr; | ||
499 | + if (*ret_prev) { | ||
500 | + (*ret_prev)->next = curr; | ||
501 | } else { | ||
502 | *ret_list = curr; /* first */ | ||
503 | } | ||
504 | @@ -434,10 +452,15 @@ | ||
505 | return ret; | ||
506 | } | ||
507 | |||
508 | + (*ret_nhosts)++; | ||
509 | + *ret_prev = curr; | ||
510 | + | ||
511 | +#ifdef HAVE_AVAHI | ||
512 | + skip: | ||
513 | +#endif | ||
514 | + | ||
515 | /* continue to next token if any */ | ||
516 | where = token_start + token_len; | ||
517 | - prev = curr; | ||
518 | - (*ret_nhosts)++; | ||
519 | } | ||
520 | |||
521 | if (*ret_nhosts) { | ||
522 | --- upstream/src/io.c 2005-11-18 16:15:40.000000000 +0100 | ||
523 | +++ lennart/src/io.c 2005-11-18 01:14:43.000000000 +0100 | ||
524 | @@ -163,7 +163,7 @@ | ||
525 | return ret; | ||
526 | else | ||
527 | continue; | ||
528 | - } else if (r == -1 && errno == EAGAIN) { | ||
529 | + } else if (r == -1 && errno == EINTR) { | ||
530 | continue; | ||
531 | } else if (r == -1) { | ||
532 | rs_log_error("failed to read: %s", strerror(errno)); | ||
533 | @@ -205,9 +205,6 @@ | ||
534 | } else if (r == -1) { | ||
535 | rs_log_error("failed to write: %s", strerror(errno)); | ||
536 | return EXIT_IO_ERROR; | ||
537 | - } else if (r == 0) { | ||
538 | - rs_log_error("unexpected eof on fd%d", fd); | ||
539 | - return EXIT_TRUNCATED; | ||
540 | } else { | ||
541 | buf = &((char *) buf)[r]; | ||
542 | len -= r; | ||
543 | --- upstream/src/tempfile.c 2005-11-18 16:15:40.000000000 +0100 | ||
544 | +++ lennart/src/tempfile.c 2005-11-18 01:14:43.000000000 +0100 | ||
545 | @@ -161,7 +161,7 @@ | ||
546 | * Return a subdirectory of the DISTCC_DIR of the given name, making | ||
547 | * sure that the directory exists. | ||
548 | **/ | ||
549 | -static int dcc_get_subdir(const char *name, | ||
550 | +int dcc_get_subdir(const char *name, | ||
551 | char **dir_ret) | ||
552 | { | ||
553 | int ret; | ||
554 | --- upstream/configure.ac 2005-11-18 16:15:40.000000000 +0100 | ||
555 | +++ lennart/configure.ac 2005-11-18 04:18:07.000000000 +0100 | ||
556 | @@ -388,6 +388,23 @@ | ||
557 | AC_DEFINE(HAVE_SOCKADDR_STORAGE, 1, [define if you have struct sockaddr_storage]),, | ||
558 | [#include <sys/socket.h>]) | ||
559 | |||
560 | +dnl check for avahi | ||
561 | +PKG_CHECK_MODULES(AVAHI, [avahi-client >= 0.6], | ||
562 | +[AC_DEFINE(HAVE_AVAHI, 1, [defined if Avahi is available]) | ||
563 | +CFLAGS="$CFLAGS $AVAHI_CFLAGS" | ||
564 | +LIBS="$LIBS $AVAHI_LIBS" | ||
565 | +ZEROCONF_DISTCC_OBJS="src/zeroconf.o" | ||
566 | +ZEROCONF_DISTCCD_OBJS="src/zeroconf-reg.o"], | ||
567 | +[ZEROCONF_DISTCC_OBJS="" | ||
568 | +ZEROCONF_DISTCCD_OBJS=""]) | ||
569 | +AC_SUBST(ZEROCONF_DISTCC_OBJS) | ||
570 | +AC_SUBST(ZEROCONF_DISTCCD_OBJS) | ||
571 | + | ||
572 | +ACX_PTHREAD | ||
573 | +LIBS="$PTHREAD_LIBS $LIBS" | ||
574 | +CFLAGS="$CFLAGS $PTHREAD_CFLAGS" | ||
575 | +CC="$PTHREAD_CC" | ||
576 | + | ||
577 | dnl ##### Output | ||
578 | AC_SUBST(docdir) | ||
579 | AC_SUBST(CFLAGS) | ||
580 | --- upstream/acinclude.m4 1970-01-01 01:00:00.000000000 +0100 | ||
581 | +++ lennart/acinclude.m4 2005-11-18 04:17:08.000000000 +0100 | ||
582 | @@ -0,0 +1,235 @@ | ||
583 | +dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) | ||
584 | +dnl | ||
585 | +dnl This macro figures out how to build C programs using POSIX threads. | ||
586 | +dnl It sets the PTHREAD_LIBS output variable to the threads library and | ||
587 | +dnl linker flags, and the PTHREAD_CFLAGS output variable to any special | ||
588 | +dnl C compiler flags that are needed. (The user can also force certain | ||
589 | +dnl compiler flags/libs to be tested by setting these environment | ||
590 | +dnl variables.) | ||
591 | +dnl | ||
592 | +dnl Also sets PTHREAD_CC to any special C compiler that is needed for | ||
593 | +dnl multi-threaded programs (defaults to the value of CC otherwise). | ||
594 | +dnl (This is necessary on AIX to use the special cc_r compiler alias.) | ||
595 | +dnl | ||
596 | +dnl NOTE: You are assumed to not only compile your program with these | ||
597 | +dnl flags, but also link it with them as well. e.g. you should link | ||
598 | +dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS | ||
599 | +dnl $LIBS | ||
600 | +dnl | ||
601 | +dnl If you are only building threads programs, you may wish to use | ||
602 | +dnl these variables in your default LIBS, CFLAGS, and CC: | ||
603 | +dnl | ||
604 | +dnl LIBS="$PTHREAD_LIBS $LIBS" | ||
605 | +dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS" | ||
606 | +dnl CC="$PTHREAD_CC" | ||
607 | +dnl | ||
608 | +dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute | ||
609 | +dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to | ||
610 | +dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). | ||
611 | +dnl | ||
612 | +dnl ACTION-IF-FOUND is a list of shell commands to run if a threads | ||
613 | +dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to | ||
614 | +dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the | ||
615 | +dnl default action will define HAVE_PTHREAD. | ||
616 | +dnl | ||
617 | +dnl Please let the authors know if this macro fails on any platform, or | ||
618 | +dnl if you have any other suggestions or comments. This macro was based | ||
619 | +dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with | ||
620 | +dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros | ||
621 | +dnl posted by Alejandro Forero Cuervo to the autoconf macro repository. | ||
622 | +dnl We are also grateful for the helpful feedback of numerous users. | ||
623 | +dnl | ||
624 | +dnl @category InstalledPackages | ||
625 | +dnl @author Steven G. Johnson <stevenj@alum.mit.edu> | ||
626 | +dnl @version 2005-01-14 | ||
627 | +dnl @license GPLWithACException | ||
628 | + | ||
629 | +AC_DEFUN([ACX_PTHREAD], [ | ||
630 | +AC_REQUIRE([AC_CANONICAL_HOST]) | ||
631 | +AC_LANG_SAVE | ||
632 | +AC_LANG_C | ||
633 | +acx_pthread_ok=no | ||
634 | + | ||
635 | +# We used to check for pthread.h first, but this fails if pthread.h | ||
636 | +# requires special compiler flags (e.g. on True64 or Sequent). | ||
637 | +# It gets checked for in the link test anyway. | ||
638 | + | ||
639 | +# First of all, check if the user has set any of the PTHREAD_LIBS, | ||
640 | +# etcetera environment variables, and if threads linking works using | ||
641 | +# them: | ||
642 | +if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then | ||
643 | + save_CFLAGS="$CFLAGS" | ||
644 | + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" | ||
645 | + save_LIBS="$LIBS" | ||
646 | + LIBS="$PTHREAD_LIBS $LIBS" | ||
647 | + AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) | ||
648 | + AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) | ||
649 | + AC_MSG_RESULT($acx_pthread_ok) | ||
650 | + if test x"$acx_pthread_ok" = xno; then | ||
651 | + PTHREAD_LIBS="" | ||
652 | + PTHREAD_CFLAGS="" | ||
653 | + fi | ||
654 | + LIBS="$save_LIBS" | ||
655 | + CFLAGS="$save_CFLAGS" | ||
656 | +fi | ||
657 | + | ||
658 | +# We must check for the threads library under a number of different | ||
659 | +# names; the ordering is very important because some systems | ||
660 | +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the | ||
661 | +# libraries is broken (non-POSIX). | ||
662 | + | ||
663 | +# Create a list of thread flags to try. Items starting with a "-" are | ||
664 | +# C compiler flags, and other items are library names, except for "none" | ||
665 | +# which indicates that we try without any flags at all, and "pthread-config" | ||
666 | +# which is a program returning the flags for the Pth emulation library. | ||
667 | + | ||
668 | +acx_pthread_flags="pthreads pthread none -Kthread -kthread lthread -pthread -pthreads -mthreads --thread-safe -mt pthread-config" | ||
669 | + | ||
670 | +# The ordering *is* (sometimes) important. Some notes on the | ||
671 | +# individual items follow: | ||
672 | + | ||
673 | +# pthreads: AIX (must check this before -lpthread) | ||
674 | +# none: in case threads are in libc; should be tried before -Kthread and | ||
675 | +# other compiler flags to prevent continual compiler warnings | ||
676 | +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) | ||
677 | +# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) | ||
678 | +# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) | ||
679 | +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) | ||
680 | +# -pthreads: Solaris/gcc | ||
681 | +# -mthreads: Mingw32/gcc, Lynx/gcc | ||
682 | +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it | ||
683 | +# doesn't hurt to check since this sometimes defines pthreads too; | ||
684 | +# also defines -D_REENTRANT) | ||
685 | +# pthread: Linux, etcetera | ||
686 | +# --thread-safe: KAI C++ | ||
687 | +# pthread-config: use pthread-config program (for GNU Pth library) | ||
688 | + | ||
689 | +case "${host_cpu}-${host_os}" in | ||
690 | + *solaris*) | ||
691 | + | ||
692 | + # On Solaris (at least, for some versions), libc contains stubbed | ||
693 | + # (non-functional) versions of the pthreads routines, so link-based | ||
694 | + # tests will erroneously succeed. (We need to link with -pthread or | ||
695 | + # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather | ||
696 | + # a function called by this macro, so we could check for that, but | ||
697 | + # who knows whether they'll stub that too in a future libc.) So, | ||
698 | + # we'll just look for -pthreads and -lpthread first: | ||
699 | + | ||
700 | + acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags" | ||
701 | + ;; | ||
702 | +esac | ||
703 | + | ||
704 | +if test x"$acx_pthread_ok" = xno; then | ||
705 | +for flag in $acx_pthread_flags; do | ||
706 | + | ||
707 | + case $flag in | ||
708 | + none) | ||
709 | + AC_MSG_CHECKING([whether pthreads work without any flags]) | ||
710 | + ;; | ||
711 | + | ||
712 | + -*) | ||
713 | + AC_MSG_CHECKING([whether pthreads work with $flag]) | ||
714 | + PTHREAD_CFLAGS="$flag" | ||
715 | + ;; | ||
716 | + | ||
717 | + pthread-config) | ||
718 | + AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) | ||
719 | + if test x"$acx_pthread_config" = xno; then continue; fi | ||
720 | + PTHREAD_CFLAGS="`pthread-config --cflags`" | ||
721 | + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" | ||
722 | + ;; | ||
723 | + | ||
724 | + *) | ||
725 | + AC_MSG_CHECKING([for the pthreads library -l$flag]) | ||
726 | + PTHREAD_LIBS="-l$flag" | ||
727 | + ;; | ||
728 | + esac | ||
729 | + | ||
730 | + save_LIBS="$LIBS" | ||
731 | + save_CFLAGS="$CFLAGS" | ||
732 | + LIBS="$PTHREAD_LIBS $LIBS" | ||
733 | + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" | ||
734 | + | ||
735 | + # Check for various functions. We must include pthread.h, | ||
736 | + # since some functions may be macros. (On the Sequent, we | ||
737 | + # need a special flag -Kthread to make this header compile.) | ||
738 | + # We check for pthread_join because it is in -lpthread on IRIX | ||
739 | + # while pthread_create is in libc. We check for pthread_attr_init | ||
740 | + # due to DEC craziness with -lpthreads. We check for | ||
741 | + # pthread_cleanup_push because it is one of the few pthread | ||
742 | + # functions on Solaris that doesn't have a non-functional libc stub. | ||
743 | + # We try pthread_create on general principles. | ||
744 | + AC_TRY_LINK([#include <pthread.h>], | ||
745 | + [pthread_t th; pthread_join(th, 0); | ||
746 | + pthread_attr_init(0); pthread_cleanup_push(0, 0); | ||
747 | + pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], | ||
748 | + [acx_pthread_ok=yes]) | ||
749 | + | ||
750 | + LIBS="$save_LIBS" | ||
751 | + CFLAGS="$save_CFLAGS" | ||
752 | + | ||
753 | + AC_MSG_RESULT($acx_pthread_ok) | ||
754 | + if test "x$acx_pthread_ok" = xyes; then | ||
755 | + break; | ||
756 | + fi | ||
757 | + | ||
758 | + PTHREAD_LIBS="" | ||
759 | + PTHREAD_CFLAGS="" | ||
760 | +done | ||
761 | +fi | ||
762 | + | ||
763 | +# Various other checks: | ||
764 | +if test "x$acx_pthread_ok" = xyes; then | ||
765 | + save_LIBS="$LIBS" | ||
766 | + LIBS="$PTHREAD_LIBS $LIBS" | ||
767 | + save_CFLAGS="$CFLAGS" | ||
768 | + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" | ||
769 | + | ||
770 | + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. | ||
771 | + AC_MSG_CHECKING([for joinable pthread attribute]) | ||
772 | + attr_name=unknown | ||
773 | + for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do | ||
774 | + AC_TRY_LINK([#include <pthread.h>], [int attr=$attr;], | ||
775 | + [attr_name=$attr; break]) | ||
776 | + done | ||
777 | + AC_MSG_RESULT($attr_name) | ||
778 | + if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then | ||
779 | + AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, | ||
780 | + [Define to necessary symbol if this constant | ||
781 | + uses a non-standard name on your system.]) | ||
782 | + fi | ||
783 | + | ||
784 | + AC_MSG_CHECKING([if more special flags are required for pthreads]) | ||
785 | + flag=no | ||
786 | + case "${host_cpu}-${host_os}" in | ||
787 | + *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; | ||
788 | + *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; | ||
789 | + esac | ||
790 | + AC_MSG_RESULT(${flag}) | ||
791 | + if test "x$flag" != xno; then | ||
792 | + PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" | ||
793 | + fi | ||
794 | + | ||
795 | + LIBS="$save_LIBS" | ||
796 | + CFLAGS="$save_CFLAGS" | ||
797 | + | ||
798 | + # More AIX lossage: must compile with cc_r | ||
799 | + AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC}) | ||
800 | +else | ||
801 | + PTHREAD_CC="$CC" | ||
802 | +fi | ||
803 | + | ||
804 | +AC_SUBST(PTHREAD_LIBS) | ||
805 | +AC_SUBST(PTHREAD_CFLAGS) | ||
806 | +AC_SUBST(PTHREAD_CC) | ||
807 | + | ||
808 | +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: | ||
809 | +if test x"$acx_pthread_ok" = xyes; then | ||
810 | + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) | ||
811 | + : | ||
812 | +else | ||
813 | + acx_pthread_ok=no | ||
814 | + $2 | ||
815 | +fi | ||
816 | +AC_LANG_RESTORE | ||
817 | +])dnl ACX_PTHREAD | ||
818 | --- upstream/src/zeroconf.h 1970-01-01 01:00:00.000000000 +0100 | ||
819 | +++ lennart/src/zeroconf.h 2005-11-18 04:06:29.000000000 +0100 | ||
820 | @@ -0,0 +1,13 @@ | ||
821 | +#ifndef foozeroconfhfoo | ||
822 | +#define foozeroconfhfoo | ||
823 | + | ||
824 | +#include <inttypes.h> | ||
825 | + | ||
826 | +int dcc_zeroconf_add_hosts(struct dcc_hostdef **re_list, int *ret_nhosts, int slots, struct dcc_hostdef **ret_prev); | ||
827 | + | ||
828 | +void * dcc_zeroconf_register(uint16_t port, int n_cpus); | ||
829 | +int dcc_zeroconf_unregister(void*); | ||
830 | + | ||
831 | +#define DCC_DNS_SERVICE_TYPE "_distcc._tcp" | ||
832 | + | ||
833 | +#endif | ||
834 | --- upstream/src/zeroconf.c 1970-01-01 01:00:00.000000000 +0100 | ||
835 | +++ lennart/src/zeroconf.c 2005-11-18 15:51:45.000000000 +0100 | ||
836 | @@ -0,0 +1,602 @@ | ||
837 | +/* -*- c-file-style: "java"; indent-tabs-mode: nil -*- */ | ||
838 | + | ||
839 | +#include "config.h" | ||
840 | + | ||
841 | +#include <assert.h> | ||
842 | +#include <stdio.h> | ||
843 | +#include <sys/select.h> | ||
844 | +#include <signal.h> | ||
845 | +#include <sys/file.h> | ||
846 | +#include <sys/time.h> | ||
847 | +#include <time.h> | ||
848 | +#include <sys/stat.h> | ||
849 | +#include <string.h> | ||
850 | +#include <errno.h> | ||
851 | +#include <unistd.h> | ||
852 | +#include <stdlib.h> | ||
853 | +#include <limits.h> | ||
854 | + | ||
855 | +#include <avahi-common/domain.h> | ||
856 | +#include <avahi-common/error.h> | ||
857 | +#include <avahi-common/malloc.h> | ||
858 | +#include <avahi-common/address.h> | ||
859 | +#include <avahi-common/simple-watch.h> | ||
860 | +#include <avahi-client/lookup.h> | ||
861 | + | ||
862 | +#include "distcc.h" | ||
863 | +#include "hosts.h" | ||
864 | +#include "zeroconf.h" | ||
865 | +#include "trace.h" | ||
866 | +#include "exitcode.h" | ||
867 | + | ||
868 | +/* How long shall the background daemon be idle before i terminates itself? */ | ||
869 | +#define MAX_IDLE_TIME 20 | ||
870 | + | ||
871 | +/* Maxium size of host file to load */ | ||
872 | +#define MAX_FILE_SIZE (1024*100) | ||
873 | + | ||
874 | +/* General daemon data */ | ||
875 | +struct daemon_data { | ||
876 | + struct host *hosts; | ||
877 | + int fd; | ||
878 | + int n_slots; | ||
879 | + | ||
880 | + AvahiClient *client; | ||
881 | + AvahiServiceBrowser *browser; | ||
882 | + AvahiSimplePoll *simple_poll; | ||
883 | +}; | ||
884 | + | ||
885 | +/* Zeroconf service wrapper */ | ||
886 | +struct host { | ||
887 | + struct daemon_data *daemon_data; | ||
888 | + struct host *next; | ||
889 | + | ||
890 | + AvahiIfIndex interface; | ||
891 | + AvahiProtocol protocol; | ||
892 | + char *service; | ||
893 | + char *domain; | ||
894 | + | ||
895 | + AvahiAddress address; | ||
896 | + uint16_t port; | ||
897 | + int n_cpus; | ||
898 | + | ||
899 | + AvahiServiceResolver *resolver; | ||
900 | +}; | ||
901 | + | ||
902 | +/* A generic, system-independent lock routine, similar to sys_lock, | ||
903 | + * but more powerful: | ||
904 | + * rw: if non-zero: r/w lock instead of r/o lock | ||
905 | + * enable: lock or unlock | ||
906 | + * block: block when locking */ | ||
907 | +static int generic_lock(int fd, int rw, int enable, int block) { | ||
908 | +#if defined(F_SETLK) | ||
909 | + struct flock lockparam; | ||
910 | + | ||
911 | + lockparam.l_type = enable ? (rw ? F_WRLCK : F_RDLCK) : F_UNLCK; | ||
912 | + lockparam.l_whence = SEEK_SET; | ||
913 | + lockparam.l_start = 0; | ||
914 | + lockparam.l_len = 0; /* whole file */ | ||
915 | + | ||
916 | + return fcntl(fd, block ? F_SETLKW : F_SETLK, &lockparam); | ||
917 | +#elif defined(HAVE_FLOCK) | ||
918 | + return flock(fd, (enable ? (rw ? LOCK_EX : LOCK_SH) : LOCK_UN) | (block ? LOCK_NB : 0)); | ||
919 | +#elif defined(HAVE_LOCKF) | ||
920 | + return lockf(fd, (enable ? (block ? F_LOCK : F_TLOCK) : F_ULOCK)); | ||
921 | +#else | ||
922 | +# error "No supported lock method. Please port this code." | ||
923 | +#endif | ||
924 | +} | ||
925 | + | ||
926 | +/* Return the number of seconds, when the specified file was last | ||
927 | + * read. If the atime of that file is < clip_time, use clip_time | ||
928 | + * instead */ | ||
929 | +static time_t fd_last_used(int fd, time_t clip_time) { | ||
930 | + struct stat st; | ||
931 | + time_t now, ft; | ||
932 | + assert(fd >= 0); | ||
933 | + | ||
934 | + if (fstat(fd, &st) < 0) { | ||
935 | + rs_log_crit("fstat() failed: %s\n", strerror(errno)); | ||
936 | + return -1; | ||
937 | + } | ||
938 | + | ||
939 | + if ((now = time(NULL)) == (time_t) -1) { | ||
940 | + rs_log_crit("time() failed: %s\n", strerror(errno)); | ||
941 | + return -1; | ||
942 | + } | ||
943 | + | ||
944 | + ft = clip_time ? (st.st_atime < clip_time ? clip_time : st.st_atime) : st.st_atime; | ||
945 | + assert(ft <= now); | ||
946 | + | ||
947 | + return now - ft; | ||
948 | +} | ||
949 | + | ||
950 | +/* Write host data to host file */ | ||
951 | +static int write_hosts(struct daemon_data *d) { | ||
952 | + struct host *h; | ||
953 | + int r = 0; | ||
954 | + assert(d); | ||
955 | + | ||
956 | + rs_log_info("writing zeroconf data.\n"); | ||
957 | + | ||
958 | + if (generic_lock(d->fd, 1, 1, 1) < 0) { | ||
959 | + rs_log_crit("lock failed: %s\n", strerror(errno)); | ||
960 | + return -1; | ||
961 | + } | ||
962 | + | ||
963 | + if (lseek(d->fd, 0, SEEK_SET) < 0) { | ||
964 | + rs_log_crit("lseek() failed: %s\n", strerror(errno)); | ||
965 | + return -1; | ||
966 | + } | ||
967 | + | ||
968 | + if (ftruncate(d->fd, 0) < 0) { | ||
969 | + rs_log_crit("ftruncate() failed: %s\n", strerror(errno)); | ||
970 | + return -1; | ||
971 | + } | ||
972 | + | ||
973 | + for (h = d->hosts; h; h = h->next) { | ||
974 | + char t[256], a[AVAHI_ADDRESS_STR_MAX]; | ||
975 | + | ||
976 | + if (h->resolver) | ||
977 | + /* Not yet fully resolved */ | ||
978 | + continue; | ||
979 | + | ||
980 | + snprintf(t, sizeof(t), "%s:%u/%i\n", avahi_address_snprint(a, sizeof(a), &h->address), h->port, d->n_slots * h->n_cpus); | ||
981 | + | ||
982 | + if (dcc_writex(d->fd, t, strlen(t)) != 0) { | ||
983 | + rs_log_crit("write() failed: %s\n", strerror(errno)); | ||
984 | + goto finish; | ||
985 | + } | ||
986 | + } | ||
987 | + | ||
988 | + r = 0; | ||
989 | + | ||
990 | +finish: | ||
991 | + | ||
992 | + generic_lock(d->fd, 1, 0, 1); | ||
993 | + return r; | ||
994 | + | ||
995 | +}; | ||
996 | + | ||
997 | +/* Free host data */ | ||
998 | +static void free_host(struct host *h) { | ||
999 | + assert(h); | ||
1000 | + | ||
1001 | + if (h->resolver) | ||
1002 | + avahi_service_resolver_free(h->resolver); | ||
1003 | + | ||
1004 | + free(h->service); | ||
1005 | + free(h->domain); | ||
1006 | + free(h); | ||
1007 | +} | ||
1008 | + | ||
1009 | +/* Remove a service from the host list */ | ||
1010 | +static void remove_service(struct daemon_data *d, AvahiIfIndex interface, AvahiProtocol protocol, const char *name, const char *domain) { | ||
1011 | + struct host *h, *p = NULL; | ||
1012 | + assert(d); | ||
1013 | + | ||
1014 | + for (h = d->hosts; h; h = h->next) { | ||
1015 | + if (h->interface == interface && | ||
1016 | + h->protocol == protocol && | ||
1017 | + !strcmp(h->service, name) && | ||
1018 | + avahi_domain_equal(h->domain, domain)) { | ||
1019 | + | ||
1020 | + if (p) | ||
1021 | + p->next = h->next; | ||
1022 | + else | ||
1023 | + d->hosts = h->next; | ||
1024 | + | ||
1025 | + free_host(h); | ||
1026 | + | ||
1027 | + break; | ||
1028 | + } else | ||
1029 | + p = h; | ||
1030 | + } | ||
1031 | +} | ||
1032 | + | ||
1033 | +/* Called when a resolve call completes */ | ||
1034 | +static void resolve_reply(AvahiServiceResolver *UNUSED(r), | ||
1035 | + AvahiIfIndex UNUSED(interface), | ||
1036 | + AvahiProtocol UNUSED(protocol), | ||
1037 | + AvahiResolverEvent event, | ||
1038 | + const char *name, | ||
1039 | + const char *UNUSED(type), | ||
1040 | + const char *UNUSED(domain), | ||
1041 | + const char *UNUSED(host_name), | ||
1042 | + const AvahiAddress *a, | ||
1043 | + uint16_t port, | ||
1044 | + AvahiStringList *txt, | ||
1045 | + AvahiLookupResultFlags UNUSED(flags), | ||
1046 | + void *userdata) { | ||
1047 | + | ||
1048 | + struct host *h = userdata; | ||
1049 | + | ||
1050 | + switch (event) { | ||
1051 | + | ||
1052 | + case AVAHI_RESOLVER_FOUND: { | ||
1053 | + AvahiStringList *i; | ||
1054 | + | ||
1055 | + /* Look for the number of CPUs in TXT RRs */ | ||
1056 | + for (i = txt; i; i = i->next) { | ||
1057 | + char *key, *value; | ||
1058 | + | ||
1059 | + if (avahi_string_list_get_pair(i, &key, &value, NULL) < 0) | ||
1060 | + continue; | ||
1061 | + | ||
1062 | + if (!strcmp(key, "cpus")) | ||
1063 | + if ((h->n_cpus = atoi(value)) <= 0) | ||
1064 | + h->n_cpus = 1; | ||
1065 | + | ||
1066 | + avahi_free(key); | ||
1067 | + avahi_free(value); | ||
1068 | + } | ||
1069 | + | ||
1070 | + h->address = *a; | ||
1071 | + h->port = port; | ||
1072 | + | ||
1073 | + avahi_service_resolver_free(h->resolver); | ||
1074 | + h->resolver = NULL; | ||
1075 | + | ||
1076 | + /* Write modified hosts file */ | ||
1077 | + write_hosts(h->daemon_data); | ||
1078 | + | ||
1079 | + break; | ||
1080 | + } | ||
1081 | + | ||
1082 | + case AVAHI_RESOLVER_FAILURE: | ||
1083 | + | ||
1084 | + rs_log_warning("Failed to resolve service '%s': %s\n", name, | ||
1085 | + avahi_strerror(avahi_client_errno(h->daemon_data->client))); | ||
1086 | + | ||
1087 | + free_host(h); | ||
1088 | + break; | ||
1089 | + } | ||
1090 | + | ||
1091 | +} | ||
1092 | + | ||
1093 | +/* Called whenever a new service is found or removed */ | ||
1094 | +static void browse_reply(AvahiServiceBrowser *UNUSED(b), | ||
1095 | + AvahiIfIndex interface, | ||
1096 | + AvahiProtocol protocol, | ||
1097 | + AvahiBrowserEvent event, | ||
1098 | + const char *name, | ||
1099 | + const char *type, | ||
1100 | + const char *domain, | ||
1101 | + AvahiLookupResultFlags UNUSED(flags), | ||
1102 | + void *userdata) { | ||
1103 | + | ||
1104 | + struct daemon_data *d = userdata; | ||
1105 | + assert(d); | ||
1106 | + | ||
1107 | + switch (event) { | ||
1108 | + case AVAHI_BROWSER_NEW: { | ||
1109 | + struct host *h; | ||
1110 | + | ||
1111 | + h = malloc(sizeof(struct host)); | ||
1112 | + assert(h); | ||
1113 | + | ||
1114 | + rs_log_info("new service: %s\n", name); | ||
1115 | + | ||
1116 | + if (!(h->resolver = avahi_service_resolver_new(d->client, | ||
1117 | + interface, | ||
1118 | + protocol, | ||
1119 | + name, | ||
1120 | + type, | ||
1121 | + domain, | ||
1122 | + AVAHI_PROTO_UNSPEC, | ||
1123 | + 0, | ||
1124 | + resolve_reply, | ||
1125 | + h))) { | ||
1126 | + rs_log_warning("Failed to create service resolver for '%s': %s\n", name, | ||
1127 | + avahi_strerror(avahi_client_errno(d->client))); | ||
1128 | + | ||
1129 | + free(h); | ||
1130 | + | ||
1131 | + } else { | ||
1132 | + | ||
1133 | + /* Fill in missing data */ | ||
1134 | + h->service = strdup(name); | ||
1135 | + assert(h->service); | ||
1136 | + h->domain = strdup(domain); | ||
1137 | + assert(h->domain); | ||
1138 | + h->daemon_data = d; | ||
1139 | + h->interface = interface; | ||
1140 | + h->protocol = protocol; | ||
1141 | + h->next = d->hosts; | ||
1142 | + h->n_cpus = 1; | ||
1143 | + d->hosts = h; | ||
1144 | + } | ||
1145 | + | ||
1146 | + break; | ||
1147 | + } | ||
1148 | + | ||
1149 | + case AVAHI_BROWSER_REMOVE: | ||
1150 | + | ||
1151 | + rs_log_info("Removed service: %s\n", name); | ||
1152 | + | ||
1153 | + remove_service(d, interface, protocol, name, domain); | ||
1154 | + write_hosts(d); | ||
1155 | + break; | ||
1156 | + | ||
1157 | + case AVAHI_BROWSER_FAILURE: | ||
1158 | + rs_log_crit("Service Browser failure '%s': %s\n", name, | ||
1159 | + avahi_strerror(avahi_client_errno(d->client))); | ||
1160 | + | ||
1161 | + avahi_simple_poll_quit(d->simple_poll); | ||
1162 | + break; | ||
1163 | + | ||
1164 | + case AVAHI_BROWSER_CACHE_EXHAUSTED: | ||
1165 | + case AVAHI_BROWSER_ALL_FOR_NOW: | ||
1166 | + ; | ||
1167 | + | ||
1168 | + } | ||
1169 | +} | ||
1170 | + | ||
1171 | +static void client_callback(AvahiClient *client, AvahiClientState state, void *userdata) { | ||
1172 | + struct daemon_data *d = userdata; | ||
1173 | + | ||
1174 | + switch (state) { | ||
1175 | + | ||
1176 | + case AVAHI_CLIENT_FAILURE: | ||
1177 | + rs_log_crit("Client failure: %s\n", avahi_strerror(avahi_client_errno(client))); | ||
1178 | + avahi_simple_poll_quit(d->simple_poll); | ||
1179 | + break; | ||
1180 | + | ||
1181 | + case AVAHI_CLIENT_S_COLLISION: | ||
1182 | + case AVAHI_CLIENT_S_REGISTERING: | ||
1183 | + case AVAHI_CLIENT_S_RUNNING: | ||
1184 | + case AVAHI_CLIENT_CONNECTING: | ||
1185 | + ; | ||
1186 | + } | ||
1187 | +} | ||
1188 | + | ||
1189 | +/* The main function of the background daemon */ | ||
1190 | +static void daemon_proc(const char *host_file, const char *lock_file, int n_slots) { | ||
1191 | + int ret = 1; | ||
1192 | + int lock_fd = -1; | ||
1193 | + struct daemon_data d; | ||
1194 | + time_t clip_time; | ||
1195 | + int error; | ||
1196 | + | ||
1197 | + rs_add_logger(rs_logger_syslog, RS_LOG_DEBUG, NULL, 0); | ||
1198 | + | ||
1199 | + /* Prepare daemon data structure */ | ||
1200 | + d.fd = -1; | ||
1201 | + d.hosts = NULL; | ||
1202 | + d.n_slots = n_slots; | ||
1203 | + d.simple_poll = NULL; | ||
1204 | + d.browser = NULL; | ||
1205 | + d.client = NULL; | ||
1206 | + clip_time = time(NULL); | ||
1207 | + | ||
1208 | + rs_log_info("Zeroconf daemon running.\n"); | ||
1209 | + | ||
1210 | + /* Open daemon lock file and lock it */ | ||
1211 | + if ((lock_fd = open(lock_file, O_RDWR|O_CREAT, 0666)) < 0) { | ||
1212 | + rs_log_crit("open('%s') failed: %s\n", lock_file, strerror(errno)); | ||
1213 | + goto finish; | ||
1214 | + } | ||
1215 | + | ||
1216 | + if (generic_lock(lock_fd, 1, 1, 0) < 0) { | ||
1217 | + /* lock failed, there's probably already another daemon running */ | ||
1218 | + goto finish; | ||
1219 | + } | ||
1220 | + | ||
1221 | + /* Open host file */ | ||
1222 | + if ((d.fd = open(host_file, O_RDWR|O_CREAT, 0666)) < 0) { | ||
1223 | + rs_log_crit("open('%s') failed: %s\n", host_file, strerror(errno)); | ||
1224 | + goto finish; | ||
1225 | + } | ||
1226 | + | ||
1227 | + /* Clear host file */ | ||
1228 | + write_hosts(&d); | ||
1229 | + | ||
1230 | + if (!(d.simple_poll = avahi_simple_poll_new())) { | ||
1231 | + rs_log_crit("Failed to create simple poll object.\n"); | ||
1232 | + goto finish; | ||
1233 | + } | ||
1234 | + | ||
1235 | + if (!(d.client = avahi_client_new(avahi_simple_poll_get(d.simple_poll), | ||
1236 | + 0, | ||
1237 | + client_callback, | ||
1238 | + &d, | ||
1239 | + &error))) { | ||
1240 | + rs_log_crit("Failed to create Avahi client object: %s\n", avahi_strerror(error)); | ||
1241 | + goto finish; | ||
1242 | + } | ||
1243 | + | ||
1244 | + if (!(d.browser = avahi_service_browser_new(d.client, | ||
1245 | + AVAHI_IF_UNSPEC, | ||
1246 | + AVAHI_PROTO_UNSPEC, | ||
1247 | + DCC_DNS_SERVICE_TYPE, | ||
1248 | + NULL, | ||
1249 | + 0, | ||
1250 | + browse_reply, | ||
1251 | + &d))) { | ||
1252 | + rs_log_crit("Failed to create service browser object: %s\n", avahi_strerror(avahi_client_errno(d.client))); | ||
1253 | + goto finish; | ||
1254 | + } | ||
1255 | + | ||
1256 | + /* Check whether the host file has been used recently */ | ||
1257 | + while (fd_last_used(d.fd, clip_time) <= MAX_IDLE_TIME) { | ||
1258 | + | ||
1259 | + /* Iterate the main loop for 500ms */ | ||
1260 | + if (avahi_simple_poll_iterate(d.simple_poll, 500) != 0) { | ||
1261 | + rs_log_crit("Event loop exited abnormaly.\n"); | ||
1262 | + goto finish; | ||
1263 | + } | ||
1264 | + } | ||
1265 | + | ||
1266 | + /* Wer are idle */ | ||
1267 | + rs_log_info("Zeroconf daemon unused.\n"); | ||
1268 | + | ||
1269 | + ret = 0; | ||
1270 | + | ||
1271 | +finish: | ||
1272 | + | ||
1273 | + /* Cleanup */ | ||
1274 | + if (lock_fd >= 0) { | ||
1275 | + generic_lock(lock_fd, 1, 0, 0); | ||
1276 | + close(lock_fd); | ||
1277 | + } | ||
1278 | + | ||
1279 | + if (d.fd >= 0) | ||
1280 | + close(d.fd); | ||
1281 | + | ||
1282 | + while (d.hosts) { | ||
1283 | + struct host *h = d.hosts; | ||
1284 | + d.hosts = d.hosts->next; | ||
1285 | + free_host(h); | ||
1286 | + } | ||
1287 | + | ||
1288 | + if (d.client) | ||
1289 | + avahi_client_free(d.client); | ||
1290 | + | ||
1291 | + if (d.simple_poll) | ||
1292 | + avahi_simple_poll_free(d.simple_poll); | ||
1293 | + | ||
1294 | + rs_log_info("zeroconf daemon ended.\n"); | ||
1295 | + | ||
1296 | + _exit(ret); | ||
1297 | +} | ||
1298 | + | ||
1299 | +/* Return path to the zeroconf directory in ~/.distcc */ | ||
1300 | +static int get_zeroconf_dir(char **dir_ret) { | ||
1301 | + static char *cached; | ||
1302 | + int ret; | ||
1303 | + | ||
1304 | + if (cached) { | ||
1305 | + *dir_ret = cached; | ||
1306 | + return 0; | ||
1307 | + } else { | ||
1308 | + ret = dcc_get_subdir("zeroconf", dir_ret); | ||
1309 | + if (ret == 0) | ||
1310 | + cached = *dir_ret; | ||
1311 | + return ret; | ||
1312 | + } | ||
1313 | +} | ||
1314 | + | ||
1315 | +/* Get the host list from zeroconf */ | ||
1316 | +int dcc_zeroconf_add_hosts(struct dcc_hostdef **ret_list, int *ret_nhosts, int n_slots, struct dcc_hostdef **ret_prev) { | ||
1317 | + char host_file[PATH_MAX], lock_file[PATH_MAX], *s = NULL; | ||
1318 | + int lock_fd = -1, host_fd = -1; | ||
1319 | + int fork_daemon = 0; | ||
1320 | + int r = -1; | ||
1321 | + char *dir; | ||
1322 | + struct stat st; | ||
1323 | + | ||
1324 | + if (get_zeroconf_dir(&dir) != 0) { | ||
1325 | + rs_log_crit("failed to get zeroconf dir.\n"); | ||
1326 | + goto finish; | ||
1327 | + } | ||
1328 | + | ||
1329 | + snprintf(lock_file, sizeof(lock_file), "%s/lock", dir); | ||
1330 | + snprintf(host_file, sizeof(host_file), "%s/hosts", dir); | ||
1331 | + | ||
1332 | + /* Open lock file */ | ||
1333 | + if ((lock_fd = open(lock_file, O_RDWR|O_CREAT, 0666)) < 0) { | ||
1334 | + rs_log_crit("open('%s') failed: %s\n", lock_file, strerror(errno)); | ||
1335 | + goto finish; | ||
1336 | + } | ||
1337 | + | ||
1338 | + /* Try to lock the lock file */ | ||
1339 | + if (generic_lock(lock_fd, 1, 1, 0) >= 0) { | ||
1340 | + /* The lock succeeded => there's no daemon running yet! */ | ||
1341 | + fork_daemon = 1; | ||
1342 | + generic_lock(lock_fd, 1, 0, 0); | ||
1343 | + } | ||
1344 | + | ||
1345 | + close(lock_fd); | ||
1346 | + | ||
1347 | + /* Shall we fork a new daemon? */ | ||
1348 | + if (fork_daemon) { | ||
1349 | + pid_t pid; | ||
1350 | + | ||
1351 | + rs_log_info("Spawning zeroconf daemon.\n"); | ||
1352 | + | ||
1353 | + if ((pid = fork()) == -1) { | ||
1354 | + rs_log_crit("fork() failed: %s\n", strerror(errno)); | ||
1355 | + goto finish; | ||
1356 | + } else if (pid == 0) { | ||
1357 | + int fd; | ||
1358 | + /* Child */ | ||
1359 | + | ||
1360 | + /* Close file descriptors and replace them by /dev/null */ | ||
1361 | + close(0); | ||
1362 | + close(1); | ||
1363 | + close(2); | ||
1364 | + fd = open("/dev/null", O_RDWR); | ||
1365 | + assert(fd == 0); | ||
1366 | + fd = dup(0); | ||
1367 | + assert(fd == 1); | ||
1368 | + fd = dup(0); | ||
1369 | + assert(fd == 2); | ||
1370 | + | ||
1371 | +#ifdef HAVE_SETSID | ||
1372 | + setsid(); | ||
1373 | +#endif | ||
1374 | + | ||
1375 | + chdir("/"); | ||
1376 | + rs_add_logger(rs_logger_syslog, RS_LOG_DEBUG, NULL, 0); | ||
1377 | + daemon_proc(host_file, lock_file, n_slots); | ||
1378 | + } | ||
1379 | + | ||
1380 | + /* Parent */ | ||
1381 | + | ||
1382 | + /* Wait some time for initial host gathering */ | ||
1383 | + usleep(1000000); /* 1000 ms */ | ||
1384 | + | ||
1385 | + } | ||
1386 | + | ||
1387 | + /* Open host list read-only */ | ||
1388 | + if ((host_fd = open(host_file, O_RDONLY)) < 0) { | ||
1389 | + rs_log_crit("open('%s') failed: %s\n", host_file, strerror(errno)); | ||
1390 | + goto finish; | ||
1391 | + } | ||
1392 | + | ||
1393 | + /* A read lock */ | ||
1394 | + if (generic_lock(host_fd, 0, 1, 1) < 0) { | ||
1395 | + rs_log_crit("lock failed: %s\n", strerror(errno)); | ||
1396 | + goto finish; | ||
1397 | + } | ||
1398 | + | ||
1399 | + /* Get file size */ | ||
1400 | + if (fstat(host_fd, &st) < 0) { | ||
1401 | + rs_log_crit("stat() failed: %s\n", strerror(errno)); | ||
1402 | + goto finish; | ||
1403 | + } | ||
1404 | + | ||
1405 | + if (st.st_size >= MAX_FILE_SIZE) { | ||
1406 | + rs_log_crit("file too large.\n"); | ||
1407 | + goto finish; | ||
1408 | + } | ||
1409 | + | ||
1410 | + /* read file data */ | ||
1411 | + s = malloc((size_t) st.st_size+1); | ||
1412 | + assert(s); | ||
1413 | + | ||
1414 | + if (dcc_readx(host_fd, s, (size_t) st.st_size) != 0) { | ||
1415 | + rs_log_crit("failed to read from file.\n"); | ||
1416 | + goto finish; | ||
1417 | + } | ||
1418 | + s[st.st_size] = 0; | ||
1419 | + | ||
1420 | + /* Parse host data */ | ||
1421 | + if (dcc_parse_hosts(s, host_file, ret_list, ret_nhosts, ret_prev) != 0) { | ||
1422 | + rs_log_crit("failed to parse host file.\n"); | ||
1423 | + goto finish; | ||
1424 | + } | ||
1425 | + | ||
1426 | + r = 0; | ||
1427 | + | ||
1428 | +finish: | ||
1429 | + if (host_fd >= 0) { | ||
1430 | + generic_lock(host_fd, 0, 0, 1); | ||
1431 | + close(host_fd); | ||
1432 | + } | ||
1433 | + | ||
1434 | + free(s); | ||
1435 | + | ||
1436 | + return r; | ||
1437 | +} | ||
1438 | + | ||
1439 | --- upstream/src/zeroconf-reg.c 1970-01-01 01:00:00.000000000 +0100 | ||
1440 | +++ lennart/src/zeroconf-reg.c 2005-11-18 15:34:00.000000000 +0100 | ||
1441 | @@ -0,0 +1,297 @@ | ||
1442 | +/* -*- c-file-style: "java"; indent-tabs-mode: nil -*- */ | ||
1443 | + | ||
1444 | +#include "config.h" | ||
1445 | + | ||
1446 | +#include <assert.h> | ||
1447 | +#include <stdio.h> | ||
1448 | +#include <sys/select.h> | ||
1449 | +#include <signal.h> | ||
1450 | +#include <sys/file.h> | ||
1451 | +#include <sys/time.h> | ||
1452 | +#include <time.h> | ||
1453 | +#include <sys/stat.h> | ||
1454 | +#include <sys/poll.h> | ||
1455 | +#include <pthread.h> | ||
1456 | +#include <stdlib.h> | ||
1457 | +#include <unistd.h> | ||
1458 | +#include <string.h> | ||
1459 | +#include <errno.h> | ||
1460 | + | ||
1461 | +#include <avahi-common/simple-watch.h> | ||
1462 | +#include <avahi-common/error.h> | ||
1463 | +#include <avahi-common/alternative.h> | ||
1464 | +#include <avahi-common/malloc.h> | ||
1465 | +#include <avahi-client/publish.h> | ||
1466 | + | ||
1467 | +#include "distcc.h" | ||
1468 | +#include "zeroconf.h" | ||
1469 | +#include "trace.h" | ||
1470 | +#include "exitcode.h" | ||
1471 | + | ||
1472 | +struct context { | ||
1473 | + int thread_running; | ||
1474 | + pthread_t thread_id; | ||
1475 | + pthread_mutex_t mutex; | ||
1476 | + char *name; | ||
1477 | + AvahiSimplePoll *simple_poll; | ||
1478 | + AvahiClient *client; | ||
1479 | + AvahiEntryGroup *group; | ||
1480 | + uint16_t port; | ||
1481 | + int n_cpus; | ||
1482 | +}; | ||
1483 | + | ||
1484 | +static void publish_reply(AvahiEntryGroup *g, AvahiEntryGroupState state, void *userdata); | ||
1485 | + | ||
1486 | +static void register_stuff(struct context *ctx) { | ||
1487 | + | ||
1488 | + if (!ctx->group) { | ||
1489 | + | ||
1490 | + if (!(ctx->group = avahi_entry_group_new(ctx->client, publish_reply, ctx))) { | ||
1491 | + rs_log_crit("Failed to create entry group: %s\n", avahi_strerror(avahi_client_errno(ctx->client))); | ||
1492 | + goto fail; | ||
1493 | + } | ||
1494 | + | ||
1495 | + } | ||
1496 | + | ||
1497 | + if (avahi_entry_group_is_empty(ctx->group)) { | ||
1498 | + char cpus[32]; | ||
1499 | + | ||
1500 | + snprintf(cpus, sizeof(cpus), "cpus=%i", ctx->n_cpus); | ||
1501 | + | ||
1502 | + /* Register our service */ | ||
1503 | + | ||
1504 | + if (avahi_entry_group_add_service(ctx->group, | ||
1505 | + AVAHI_IF_UNSPEC, | ||
1506 | + AVAHI_PROTO_UNSPEC, | ||
1507 | + 0, | ||
1508 | + ctx->name, | ||
1509 | + DCC_DNS_SERVICE_TYPE, | ||
1510 | + NULL, | ||
1511 | + NULL, | ||
1512 | + ctx->port, | ||
1513 | + "txtvers=1", | ||
1514 | + cpus, | ||
1515 | + "distcc="PACKAGE_VERSION, | ||
1516 | + "gnuhost="GNU_HOST, | ||
1517 | + NULL) < 0) { | ||
1518 | + rs_log_crit("Failed to add service: %s\n", avahi_strerror(avahi_client_errno(ctx->client))); | ||
1519 | + goto fail; | ||
1520 | + } | ||
1521 | + | ||
1522 | + if (avahi_entry_group_commit(ctx->group) < 0) { | ||
1523 | + rs_log_crit("Failed to commit entry group: %s\n", avahi_strerror(avahi_client_errno(ctx->client))); | ||
1524 | + goto fail; | ||
1525 | + } | ||
1526 | + } | ||
1527 | + | ||
1528 | + return; | ||
1529 | + | ||
1530 | + fail: | ||
1531 | + avahi_simple_poll_quit(ctx->simple_poll); | ||
1532 | +} | ||
1533 | + | ||
1534 | +/* Called when publishing of service data completes */ | ||
1535 | +static void publish_reply(AvahiEntryGroup *UNUSED(g), AvahiEntryGroupState state, void *userdata) { | ||
1536 | + struct context *ctx = userdata; | ||
1537 | + | ||
1538 | + switch (state) { | ||
1539 | + | ||
1540 | + case AVAHI_ENTRY_GROUP_COLLISION: { | ||
1541 | + char *n; | ||
1542 | + | ||
1543 | + /* Pick a new name for our service */ | ||
1544 | + | ||
1545 | + n = avahi_alternative_service_name(ctx->name); | ||
1546 | + assert(n); | ||
1547 | + | ||
1548 | + avahi_free(ctx->name); | ||
1549 | + ctx->name = n; | ||
1550 | + | ||
1551 | + register_stuff(ctx); | ||
1552 | + break; | ||
1553 | + } | ||
1554 | + | ||
1555 | + case AVAHI_ENTRY_GROUP_FAILURE: | ||
1556 | + rs_log_crit("Failed to register service: %s\n", avahi_strerror(avahi_client_errno(ctx->client))); | ||
1557 | + avahi_simple_poll_quit(ctx->simple_poll); | ||
1558 | + break; | ||
1559 | + | ||
1560 | + case AVAHI_ENTRY_GROUP_UNCOMMITED: | ||
1561 | + case AVAHI_ENTRY_GROUP_REGISTERING: | ||
1562 | + case AVAHI_ENTRY_GROUP_ESTABLISHED: | ||
1563 | + ; | ||
1564 | + } | ||
1565 | +} | ||
1566 | + | ||
1567 | +static void client_callback(AvahiClient *client, AvahiClientState state, void *userdata) { | ||
1568 | + struct context *ctx = userdata; | ||
1569 | + | ||
1570 | + ctx->client = client; | ||
1571 | + | ||
1572 | + switch (state) { | ||
1573 | + | ||
1574 | + case AVAHI_CLIENT_S_RUNNING: | ||
1575 | + | ||
1576 | + register_stuff(ctx); | ||
1577 | + break; | ||
1578 | + | ||
1579 | + case AVAHI_CLIENT_S_COLLISION: | ||
1580 | + | ||
1581 | + if (ctx->group) | ||
1582 | + avahi_entry_group_reset(ctx->group); | ||
1583 | + break; | ||
1584 | + | ||
1585 | + case AVAHI_CLIENT_FAILURE: | ||
1586 | + | ||
1587 | + if (avahi_client_errno(client) == AVAHI_ERR_DISCONNECTED) { | ||
1588 | + int error; | ||
1589 | + | ||
1590 | + avahi_client_free(ctx->client); | ||
1591 | + ctx->client = NULL; | ||
1592 | + ctx->group = NULL; | ||
1593 | + | ||
1594 | + /* Reconnect to the server */ | ||
1595 | + | ||
1596 | + if (!(ctx->client = avahi_client_new(avahi_simple_poll_get(ctx->simple_poll), | ||
1597 | + AVAHI_CLIENT_NO_FAIL, | ||
1598 | + client_callback, | ||
1599 | + ctx, | ||
1600 | + &error))) { | ||
1601 | + | ||
1602 | + rs_log_crit("Failed to contact server: %s\n", avahi_strerror(error)); | ||
1603 | + avahi_simple_poll_quit(ctx->simple_poll); | ||
1604 | + } | ||
1605 | + | ||
1606 | + } else { | ||
1607 | + rs_log_crit("Client failure: %s\n", avahi_strerror(avahi_client_errno(client))); | ||
1608 | + avahi_simple_poll_quit(ctx->simple_poll); | ||
1609 | + } | ||
1610 | + | ||
1611 | + break; | ||
1612 | + | ||
1613 | + case AVAHI_CLIENT_S_REGISTERING: | ||
1614 | + case AVAHI_CLIENT_CONNECTING: | ||
1615 | + ; | ||
1616 | + } | ||
1617 | +} | ||
1618 | + | ||
1619 | +static void* thread(void *userdata) { | ||
1620 | + struct context *ctx = userdata; | ||
1621 | + sigset_t mask; | ||
1622 | + int r; | ||
1623 | + | ||
1624 | + /* Make sure that signals are delivered to the main thread */ | ||
1625 | + sigfillset(&mask); | ||
1626 | + pthread_sigmask(SIG_BLOCK, &mask, NULL); | ||
1627 | + | ||
1628 | + pthread_mutex_lock(&ctx->mutex); | ||
1629 | + | ||
1630 | + /* Run the main loop */ | ||
1631 | + r = avahi_simple_poll_loop(ctx->simple_poll); | ||
1632 | + | ||
1633 | + /* Cleanup some stuff */ | ||
1634 | + if (ctx->client) | ||
1635 | + avahi_client_free(ctx->client); | ||
1636 | + ctx->client = NULL; | ||
1637 | + ctx->group = NULL; | ||
1638 | + | ||
1639 | + pthread_mutex_unlock(&ctx->mutex); | ||
1640 | + | ||
1641 | + return NULL; | ||
1642 | +} | ||
1643 | + | ||
1644 | +static int poll_func(struct pollfd *ufds, unsigned int nfds, int timeout, void *userdata) { | ||
1645 | + pthread_mutex_t *mutex = userdata; | ||
1646 | + int r; | ||
1647 | + | ||
1648 | + /* Before entering poll() we unlock the mutex, so that | ||
1649 | + * avahi_simple_poll_quit() can succeed from another thread. */ | ||
1650 | + | ||
1651 | + pthread_mutex_unlock(mutex); | ||
1652 | + r = poll(ufds, nfds, timeout); | ||
1653 | + pthread_mutex_lock(mutex); | ||
1654 | + | ||
1655 | + return r; | ||
1656 | +} | ||
1657 | + | ||
1658 | +/* register a distcc service in DNS-SD/mDNS with the given port and number of CPUs */ | ||
1659 | +void* dcc_zeroconf_register(uint16_t port, int n_cpus) { | ||
1660 | + struct context *ctx = NULL; | ||
1661 | + | ||
1662 | + char service[256] = "distcc@"; | ||
1663 | + int error, ret; | ||
1664 | + | ||
1665 | + ctx = malloc(sizeof(struct context)); | ||
1666 | + assert(ctx); | ||
1667 | + ctx->client = NULL; | ||
1668 | + ctx->group = NULL; | ||
1669 | + ctx->simple_poll = NULL; | ||
1670 | + ctx->thread_running = 0; | ||
1671 | + ctx->port = port; | ||
1672 | + ctx->n_cpus = n_cpus; | ||
1673 | + pthread_mutex_init(&ctx->mutex, NULL); | ||
1674 | + | ||
1675 | + /* Prepare service name */ | ||
1676 | + gethostname(service+7, sizeof(service)-8); | ||
1677 | + service[sizeof(service)-1] = 0; | ||
1678 | + | ||
1679 | + ctx->name = strdup(service); | ||
1680 | + assert(ctx->name); | ||
1681 | + | ||
1682 | + if (!(ctx->simple_poll = avahi_simple_poll_new())) { | ||
1683 | + rs_log_crit("Failed to create event loop object.\n"); | ||
1684 | + goto fail; | ||
1685 | + } | ||
1686 | + | ||
1687 | + avahi_simple_poll_set_func(ctx->simple_poll, poll_func, &ctx->mutex); | ||
1688 | + | ||
1689 | + if (!(ctx->client = avahi_client_new(avahi_simple_poll_get(ctx->simple_poll), AVAHI_CLIENT_NO_FAIL, client_callback, ctx, &error))) { | ||
1690 | + rs_log_crit("Failed to create client object: %s\n", avahi_strerror(avahi_client_errno(ctx->client))); | ||
1691 | + goto fail; | ||
1692 | + } | ||
1693 | + | ||
1694 | + /* Create the mDNS event handler */ | ||
1695 | + if ((ret = pthread_create(&ctx->thread_id, NULL, thread, ctx)) < 0) { | ||
1696 | + rs_log_crit("Failed to create thread: %s\n", strerror(ret)); | ||
1697 | + goto fail; | ||
1698 | + } | ||
1699 | + | ||
1700 | + ctx->thread_running = 1; | ||
1701 | + | ||
1702 | + return ctx; | ||
1703 | + | ||
1704 | + fail: | ||
1705 | + | ||
1706 | + if (ctx) | ||
1707 | + dcc_zeroconf_unregister(ctx); | ||
1708 | + | ||
1709 | + return NULL; | ||
1710 | +} | ||
1711 | + | ||
1712 | +/* Unregister this server from DNS-SD/mDNS */ | ||
1713 | +int dcc_zeroconf_unregister(void *u) { | ||
1714 | + struct context *ctx = u; | ||
1715 | + | ||
1716 | + if (ctx->thread_running) { | ||
1717 | + pthread_mutex_lock(&ctx->mutex); | ||
1718 | + avahi_simple_poll_quit(ctx->simple_poll); | ||
1719 | + pthread_mutex_unlock(&ctx->mutex); | ||
1720 | + | ||
1721 | + pthread_join(ctx->thread_id, NULL); | ||
1722 | + ctx->thread_running = 0; | ||
1723 | + } | ||
1724 | + | ||
1725 | + avahi_free(ctx->name); | ||
1726 | + | ||
1727 | + if (ctx->client) | ||
1728 | + avahi_client_free(ctx->client); | ||
1729 | + | ||
1730 | + if (ctx->simple_poll) | ||
1731 | + avahi_simple_poll_free(ctx->simple_poll); | ||
1732 | + | ||
1733 | + pthread_mutex_destroy(&ctx->mutex); | ||
1734 | + | ||
1735 | + free(ctx); | ||
1736 | + | ||
1737 | + return 0; | ||
1738 | +} | ||
diff --git a/meta/recipes-devtools/distcc/files/makefile-param-order.patch b/meta/recipes-devtools/distcc/files/makefile-param-order.patch deleted file mode 100644 index fc57414f12..0000000000 --- a/meta/recipes-devtools/distcc/files/makefile-param-order.patch +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | distcc: Put the "-lLIB" parameter in the end of the gcc command. | ||
2 | |||
3 | Signed-off-by: Dongxiao Xu <dongxiao.xu@intel.com> | ||
4 | |||
5 | Upstream-Status: Pending | ||
6 | |||
7 | diff -ruN distcc-2.18.3-orig/Makefile.in distcc-2.18.3/Makefile.in | ||
8 | --- distcc-2.18.3-orig/Makefile.in 2011-07-25 16:43:21.000000000 +0800 | ||
9 | +++ distcc-2.18.3/Makefile.in 2011-07-25 16:45:39.000000000 +0800 | ||
10 | @@ -378,8 +378,8 @@ | ||
11 | |||
12 | distccmon-gnome@EXEEXT@: $(mon_obj) $(gnome_obj) | ||
13 | $(CC) -o $@ $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(LIBS) \ | ||
14 | - $(GNOME_CFLAGS) $(GNOME_LIBS) \ | ||
15 | - $(mon_obj) $(gnome_obj) | ||
16 | + $(GNOME_CFLAGS) \ | ||
17 | + $(mon_obj) $(gnome_obj) $(GNOME_LIBS) | ||
18 | |||
19 | |||
20 | ## Dist targets | ||