Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 80219 | Differences between
and this patch

Collapse All | Expand All

(-)distcc-2.18.3.orig/Makefile.in (-3 / +5 lines)
Lines 21-31 Link Here
21
# These autoconf variables may contain recursive Make expansions, and
21
# These autoconf variables may contain recursive Make expansions, and
22
# so they have to be done here rather than written into config.h.
22
# so they have to be done here rather than written into config.h.
23
23
24
CFLAGS = @CFLAGS@
24
CFLAGS = @CFLAGS@ -I/usr/include/howl
25
LDFLAGS = @LDFLAGS@
25
LDFLAGS = @LDFLAGS@
26
CC = @CC@
26
CC = @CC@
27
CPP = @CPP@
27
CPP = @CPP@
28
CPPFLAGS = @CPPFLAGS@ ${DIR_DEFS} -Isrc -I$(srcdir)/lzo
28
CPPFLAGS = @CPPFLAGS@ ${DIR_DEFS} -Isrc -I$(srcdir)/lzo -DHAVE_HOWL
29
29
30
srcdir = @srcdir@
30
srcdir = @srcdir@
31
top_srcdir = @top_srcdir@
31
top_srcdir = @top_srcdir@
Lines 56-62 Link Here
56
GNOME_CFLAGS = @GNOME_CFLAGS@
56
GNOME_CFLAGS = @GNOME_CFLAGS@
57
GNOME_LIBS = @GNOME_LIBS@
57
GNOME_LIBS = @GNOME_LIBS@
58
58
59
LIBS = @LIBS@
59
LIBS = @LIBS@ -lhowl -lpthread
60
60
61
DESTDIR =
61
DESTDIR =
62
62
Lines 180-185 Link Here
180
	src/ssh.o src/state.o src/strip.o				\
180
	src/ssh.o src/state.o src/strip.o				\
181
	src/timefile.o src/traceenv.o					\
181
	src/timefile.o src/traceenv.o					\
182
	src/where.o							\
182
	src/where.o							\
183
	src/zeroconf.o							\
183
	$(common_obj)
184
	$(common_obj)
184
185
185
distccd_obj = src/access.o						\
186
distccd_obj = src/access.o						\
Lines 187-192 Link Here
187
	src/ncpus.o							\
188
	src/ncpus.o							\
188
	src/prefork.o							\
189
	src/prefork.o							\
189
	src/serve.o src/setuid.o src/srvnet.o src/srvrpc.o src/state.o	\
190
	src/serve.o src/setuid.o src/srvnet.o src/srvrpc.o src/state.o	\
191
	src/zeroconf-reg.o                                              \
190
	$(common_obj) @BUILD_POPT@
192
	$(common_obj) @BUILD_POPT@
191
193
192
# Objects that need to be linked in to build monitors
194
# Objects that need to be linked in to build monitors
(-)distcc-2.18.3.orig/aclocal.m4 (+57 lines)
Line 0 Link Here
1
2
dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not)
3
dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page
4
dnl also defines GSTUFF_PKG_ERRORS on error
5
AC_DEFUN(PKG_CHECK_MODULES, [
6
  succeeded=no
7
8
  if test -z "$PKG_CONFIG"; then
9
    AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
10
  fi
11
12
  if test "$PKG_CONFIG" = "no" ; then
13
     echo "*** The pkg-config script could not be found. Make sure it is"
14
     echo "*** in your path, or set the PKG_CONFIG environment variable"
15
     echo "*** to the full path to pkg-config."
16
     echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config."
17
  else
18
     PKG_CONFIG_MIN_VERSION=0.9.0
19
     if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then
20
        AC_MSG_CHECKING(for $2)
21
22
        if $PKG_CONFIG --exists "$2" ; then
23
            AC_MSG_RESULT(yes)
24
            succeeded=yes
25
26
            AC_MSG_CHECKING($1_CFLAGS)
27
            $1_CFLAGS=`$PKG_CONFIG --cflags "$2"`
28
            AC_MSG_RESULT($$1_CFLAGS)
29
30
            AC_MSG_CHECKING($1_LIBS)
31
            $1_LIBS=`$PKG_CONFIG --libs "$2"`
32
            AC_MSG_RESULT($$1_LIBS)
33
        else
34
            $1_CFLAGS=""
35
            $1_LIBS=""
36
            ## If we have a custom action on failure, don't print errors, but 
37
            ## do set a variable so people can do so.
38
            $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
39
            ifelse([$4], ,echo $$1_PKG_ERRORS,)
40
        fi
41
42
        AC_SUBST($1_CFLAGS)
43
        AC_SUBST($1_LIBS)
44
     else
45
        echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer."
46
        echo "*** See http://www.freedesktop.org/software/pkgconfig"
47
     fi
48
  fi
49
50
  if test $succeeded = yes; then
51
     ifelse([$3], , :, [$3])
52
  else
53
     ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4])
54
  fi
55
])
56
57
(-)distcc-2.18.3.orig/configure.ac (+14 lines)
Lines 386-391 Link Here
386
    AC_DEFINE(HAVE_SOCKADDR_STORAGE, 1, [define if you have struct sockaddr_storage]),,
386
    AC_DEFINE(HAVE_SOCKADDR_STORAGE, 1, [define if you have struct sockaddr_storage]),,
387
    [#include <sys/socket.h>])
387
    [#include <sys/socket.h>])
388
388
389
dnl check for howl
390
PKG_CHECK_MODULES(HOWL, [howl],
391
[AC_DEFINE(HAVE_HOWL, 1, [defined if howl is available])
392
CFLAGS="$CFLAGS $HOWL_CFLAGS"
393
LIBS="$LIBS $HOWL_LIBS"
394
ZEROCONF_DISTCC_OBJS="src/zeroconf.o"
395
ZEROCONF_DISTCCD_OBJS="src/zeroconf-reg.o"],
396
[ZEROCONF_DISTCC_OBJS=""
397
ZEROCONF_DISTCCD_OBJS=""])
398
AC_SUBST(ZEROCONF_DISTCC_OBJS)
399
AC_SUBST(ZEROCONF_DISTCCD_OBJS)
400
401
AC_DEFINE(HAVE_HOWL, 1, [defined because I do])
402
389
dnl ##### Output
403
dnl ##### Output
390
AC_SUBST(docdir)
404
AC_SUBST(docdir)
391
AC_SUBST(CFLAGS)
405
AC_SUBST(CFLAGS)
(-)distcc-2.18.3.orig/src/distcc.c (+56 lines)
Lines 83-88 Link Here
83
"   COMPILER                   defaults to \"cc\"\n"
83
"   COMPILER                   defaults to \"cc\"\n"
84
"   --help                     explain usage and exit\n"
84
"   --help                     explain usage and exit\n"
85
"   --version                  show version and exit\n"
85
"   --version                  show version and exit\n"
86
"   --show-hosts               show host list and exit\n"
87
"   -j                         calculate the concurrency level from\n"
88
"                              the host list.\n"
86
"\n"
89
"\n"
87
"Environment variables:\n"
90
"Environment variables:\n"
88
"   See the manual page for a complete list.\n"
91
"   See the manual page for a complete list.\n"
Lines 135-140 Link Here
135
    signal(SIGHUP, &dcc_client_signalled);
138
    signal(SIGHUP, &dcc_client_signalled);
136
}
139
}
137
140
141
static void dcc_free_hostlist(struct dcc_hostdef *list) {
142
    while (list) {
143
        struct dcc_hostdef *l = list;
144
        list = list->next;
145
        dcc_free_hostdef(l);
146
    }
147
}
148
149
static void dcc_show_hosts(void) {
150
    struct dcc_hostdef *list, *l;
151
    int nhosts;
152
    
153
    if (dcc_get_hostlist(&list, &nhosts) != 0) {
154
        rs_log_crit("Failed to get host list");
155
        return;
156
    }
157
158
    for (l = list; l; l = l->next)
159
        printf("%s\n", l->hostdef_string);
160
161
    dcc_free_hostlist(list);
162
}
163
164
static void dcc_concurrency_level(void) {
165
    struct dcc_hostdef *list, *l;
166
    int nhosts;
167
    int nslots = 0;
168
    
169
    if (dcc_get_hostlist(&list, &nhosts) != 0) {
170
        rs_log_crit("Failed to get host list");
171
        return;
172
    }
173
174
   for (l = list; l; l = l->next)
175
        nslots += l->n_slots;
176
177
    dcc_free_hostlist(list);
178
179
    printf("%i\n", nslots);
180
}
181
138
#define MAXNEWFLAGS 32
182
#define MAXNEWFLAGS 32
139
#define MAXFLAGLEN  127
183
#define MAXFLAGLEN  127
140
184
Lines 282-287 Link Here
282
            ret = 0;
326
            ret = 0;
283
            goto out;
327
            goto out;
284
        }
328
        }
329
330
        if (!strcmp(argv[1], "--show-hosts")) {
331
            dcc_show_hosts();
332
            ret = 0;
333
            goto out;
334
        }
335
336
        if (!strcmp(argv[1], "-j")) {
337
            dcc_concurrency_level();
338
            ret = 0;
339
            goto out;
340
        }
285
        
341
        
286
        if(!(newargv = getNewArgvFromEnv(argv))) {
342
        if(!(newargv = getNewArgvFromEnv(argv))) {
287
            ret = EXIT_OUT_OF_MEMORY;
343
            ret = EXIT_OUT_OF_MEMORY;
(-)distcc-2.18.3.orig/src/distcc.h (-1 / +2 lines)
Lines 112-118 Link Here
112
                        int *ret_nhosts);
112
                        int *ret_nhosts);
113
int dcc_parse_hosts(const char *where, const char *source_name,
113
int dcc_parse_hosts(const char *where, const char *source_name,
114
                    struct dcc_hostdef **ret_list,
114
                    struct dcc_hostdef **ret_list,
115
                    int *ret_nhosts);
115
                    int *ret_nhosts, struct dcc_hostdef **ret_prev);
116
116
117
/* ncpu.c */
117
/* ncpu.c */
118
int dcc_ncpus(int *);
118
int dcc_ncpus(int *);
Lines 226-231 Link Here
226
int dcc_make_tmpnam(const char *, const char *suffix, char **);
226
int dcc_make_tmpnam(const char *, const char *suffix, char **);
227
227
228
int dcc_mkdir(const char *path) WARN_UNUSED;
228
int dcc_mkdir(const char *path) WARN_UNUSED;
229
int dcc_get_subdir(const char *name, char **path_ret) WARN_UNUSED;
229
int dcc_get_lock_dir(char **path_ret) WARN_UNUSED;
230
int dcc_get_lock_dir(char **path_ret) WARN_UNUSED;
230
int dcc_get_state_dir(char **path_ret) WARN_UNUSED;
231
int dcc_get_state_dir(char **path_ret) WARN_UNUSED;
231
int dcc_get_top_dir(char **path_ret) WARN_UNUSED;
232
int dcc_get_top_dir(char **path_ret) WARN_UNUSED;
(-)distcc-2.18.3.orig/src/dopt.c (+9 lines)
Lines 93-98 Link Here
93
    opt_log_level
93
    opt_log_level
94
};
94
};
95
95
96
#ifdef HAVE_HOWL
97
int opt_zeroconf = 0;
98
#endif
96
99
97
const struct poptOption options[] = {
100
const struct poptOption options[] = {
98
    { "allow", 'a',      POPT_ARG_STRING, 0, 'a', 0, 0 },
101
    { "allow", 'a',      POPT_ARG_STRING, 0, 'a', 0, 0 },
Lines 115-120 Link Here
115
    { "verbose", 0,      POPT_ARG_NONE, 0, 'v', 0, 0 },
118
    { "verbose", 0,      POPT_ARG_NONE, 0, 'v', 0, 0 },
116
    { "version", 0,      POPT_ARG_NONE, 0, 'V', 0, 0 },
119
    { "version", 0,      POPT_ARG_NONE, 0, 'V', 0, 0 },
117
    { "wizard", 'W',     POPT_ARG_NONE, 0, 'W', 0, 0 },
120
    { "wizard", 'W',     POPT_ARG_NONE, 0, 'W', 0, 0 },
121
#ifdef HAVE_HOWL    
122
    { "zeroconf", 0,     POPT_ARG_NONE, &opt_zeroconf, 0, 0, 0 },
123
#endif    
118
    { 0, 0, 0, 0, 0, 0, 0 }
124
    { 0, 0, 0, 0, 0, 0, 0 }
119
};
125
};
120
126
Lines 137-142 Link Here
137
"    -p, --port PORT            TCP port to listen on\n"
143
"    -p, --port PORT            TCP port to listen on\n"
138
"    --listen ADDRESS           IP address to listen on\n"
144
"    --listen ADDRESS           IP address to listen on\n"
139
"    -a, --allow IP[/BITS]      client address access control\n"
145
"    -a, --allow IP[/BITS]      client address access control\n"
146
#ifdef HAVE_HOWL    
147
"    --zeroconf                 register via mDNS/DNS-SD\n"
148
#endif
140
"  Debug and trace:\n"
149
"  Debug and trace:\n"
141
"    --log-level=LEVEL          set detail level for log file\n"
150
"    --log-level=LEVEL          set detail level for log file\n"
142
"      levels: critical, error, warning, notice, info, debug\n"
151
"      levels: critical, error, warning, notice, info, debug\n"
(-)distcc-2.18.3.orig/src/dopt.h (+2 lines)
Lines 38-40 Link Here
38
extern int opt_lifetime;
38
extern int opt_lifetime;
39
extern char *opt_listen_addr;
39
extern char *opt_listen_addr;
40
extern int opt_niceness;
40
extern int opt_niceness;
41
42
extern int opt_zeroconf;
(-)distcc-2.18.3.orig/src/dparent.c (-1 / +24 lines)
Lines 70-75 Link Here
70
#include "types.h"
70
#include "types.h"
71
#include "daemon.h"
71
#include "daemon.h"
72
#include "netutil.h"
72
#include "netutil.h"
73
#include "zeroconf.h"
73
74
74
static void dcc_nofork_parent(int listen_fd) NORETURN;
75
static void dcc_nofork_parent(int listen_fd) NORETURN;
75
static void dcc_detach(void);
76
static void dcc_detach(void);
Lines 94-99 Link Here
94
    int listen_fd;
95
    int listen_fd;
95
    int n_cpus;
96
    int n_cpus;
96
    int ret;
97
    int ret;
98
#ifdef HAVE_HOWL
99
    sw_discovery discovery;
100
#endif
97
101
98
    if ((ret = dcc_socket_listen(arg_port, &listen_fd, opt_listen_addr)) != 0)
102
    if ((ret = dcc_socket_listen(arg_port, &listen_fd, opt_listen_addr)) != 0)
99
        return ret;
103
        return ret;
Lines 131-136 Link Here
131
    /* Don't catch signals until we've detached or created a process group. */
135
    /* Don't catch signals until we've detached or created a process group. */
132
    dcc_daemon_catch_signals();
136
    dcc_daemon_catch_signals();
133
137
138
#ifdef HAVE_HOWL        
139
    /* Zeroconf registration */
140
    if (opt_zeroconf) {
141
        if ((ret = dcc_zeroconf_register(&discovery, arg_port, n_cpus)) != 0)
142
            return EXIT_CONNECT_FAILED;
143
    }
144
#endif
145
        
134
    /* This is called in the master daemon, whether that is detached or
146
    /* This is called in the master daemon, whether that is detached or
135
     * not.  */
147
     * not.  */
136
    dcc_master_pid = getpid();
148
    dcc_master_pid = getpid();
Lines 138-147 Link Here
138
    if (opt_no_fork) {
150
    if (opt_no_fork) {
139
        dcc_log_daemon_started("non-forking daemon");   
151
        dcc_log_daemon_started("non-forking daemon");   
140
        dcc_nofork_parent(listen_fd);
152
        dcc_nofork_parent(listen_fd);
153
        ret = 0;
141
    } else {
154
    } else {
142
        dcc_log_daemon_started("preforking daemon");
155
        dcc_log_daemon_started("preforking daemon");
143
        return dcc_preforking_parent(listen_fd);
156
        ret = dcc_preforking_parent(listen_fd);
144
    }
157
    }
158
159
#ifdef HAVE_HOWL
160
    /* Remove zeroconf registration */
161
    if (opt_zeroconf) {
162
        if ((ret = dcc_zeroconf_unregister(discovery)) != 0)
163
            return EXIT_CONNECT_FAILED;
164
    }
165
#endif
166
    
167
    return ret;
145
}
168
}
146
169
147
170
(-)distcc-2.18.3.orig/src/help.c (+3 lines)
Lines 62-67 Link Here
62
"distcc comes with ABSOLUTELY NO WARRANTY.  distcc is free software, and\n"
62
"distcc comes with ABSOLUTELY NO WARRANTY.  distcc is free software, and\n"
63
"you may use, modify and redistribute it under the terms of the GNU \n"
63
"you may use, modify and redistribute it under the terms of the GNU \n"
64
"General Public License version 2 or later.\n"
64
"General Public License version 2 or later.\n"
65
#ifdef HAVE_HOWL
66
"\nBuilt with Zeroconf support.\n"
67
#endif
65
"\n"
68
"\n"
66
           ,
69
           ,
67
           prog, PACKAGE_VERSION, GNU_HOST, DISTCC_DEFAULT_PORT,
70
           prog, PACKAGE_VERSION, GNU_HOST, DISTCC_DEFAULT_PORT,
(-)distcc-2.18.3.orig/src/hostfile.c (-1 / +1 lines)
Lines 59-65 Link Here
59
    if ((ret = dcc_load_file_string(fname, &body)) != 0)
59
    if ((ret = dcc_load_file_string(fname, &body)) != 0)
60
        return ret;
60
        return ret;
61
61
62
    ret = dcc_parse_hosts(body, fname, ret_list, ret_nhosts);
62
    ret = dcc_parse_hosts(body, fname, ret_list, ret_nhosts, NULL);
63
63
64
    free(body);
64
    free(body);
65
65
(-)distcc-2.18.3.orig/src/hosts.c (-11 / +34 lines)
Lines 96-101 Link Here
96
#include "hosts.h"
96
#include "hosts.h"
97
#include "exitcode.h"
97
#include "exitcode.h"
98
#include "snprintf.h"
98
#include "snprintf.h"
99
#ifdef HAVE_HOWL
100
#include "zeroconf.h"
101
#define ZEROCONF_MAGIC "+zeroconf"
102
#endif
99
103
100
const int dcc_default_port = DISTCC_DEFAULT_PORT;
104
const int dcc_default_port = DISTCC_DEFAULT_PORT;
101
105
Lines 134-142 Link Here
134
    char *path, *top;
138
    char *path, *top;
135
    int ret;
139
    int ret;
136
140
141
    *ret_list = NULL;
142
    *ret_nhosts = 0;
143
137
    if ((env = getenv("DISTCC_HOSTS")) != NULL) {
144
    if ((env = getenv("DISTCC_HOSTS")) != NULL) {
138
        rs_trace("read hosts from environment");
145
        rs_trace("read hosts from environment");
139
        return dcc_parse_hosts(env, "$DISTCC_HOSTS", ret_list, ret_nhosts);
146
        return dcc_parse_hosts(env, "$DISTCC_HOSTS", ret_list, ret_nhosts, NULL);
140
    }
147
    }
141
148
142
    /* $DISTCC_DIR or ~/.distcc */
149
    /* $DISTCC_DIR or ~/.distcc */
Lines 163-169 Link Here
163
        rs_trace("not reading %s: %s", path, strerror(errno));
170
        rs_trace("not reading %s: %s", path, strerror(errno));
164
        free(path);
171
        free(path);
165
    }
172
    }
166
    
173
167
    /* FIXME: Clearer message? */
174
    /* FIXME: Clearer message? */
168
    rs_log_warning("no hostlist is set; can't distribute work");
175
    rs_log_warning("no hostlist is set; can't distribute work");
169
176
Lines 346-362 Link Here
346
 **/
353
 **/
347
int dcc_parse_hosts(const char *where, const char *source_name,
354
int dcc_parse_hosts(const char *where, const char *source_name,
348
                    struct dcc_hostdef **ret_list,
355
                    struct dcc_hostdef **ret_list,
349
                    int *ret_nhosts)
356
                    int *ret_nhosts, struct dcc_hostdef **ret_prev)
350
{
357
{
351
    int ret;
358
    int ret;
352
    struct dcc_hostdef *prev, *curr;
359
    struct dcc_hostdef *curr, *_prev;
360
361
    if (!ret_prev) {
362
        ret_prev = &_prev;
363
        _prev = NULL;
364
    }
353
365
354
    /* TODO: Check for '/' in places where it might cause trouble with
366
    /* TODO: Check for '/' in places where it might cause trouble with
355
     * a lock file name. */
367
     * a lock file name. */
356
368
357
    prev = NULL;
358
    *ret_list = NULL;
359
    *ret_nhosts = 0;
360
    /* A simple, hardcoded scanner.  Some of the GNU routines might be
369
    /* A simple, hardcoded scanner.  Some of the GNU routines might be
361
     * useful here, but they won't work on less capable systems.
370
     * useful here, but they won't work on less capable systems.
362
     *
371
     *
Lines 390-395 Link Here
390
        token_start = where;
399
        token_start = where;
391
        token_len = strcspn(where, " #\t\n\f\r");
400
        token_len = strcspn(where, " #\t\n\f\r");
392
401
402
#ifdef HAVE_HOWL
403
        if (token_len == sizeof(ZEROCONF_MAGIC)-1 && 
404
            !strncmp(token_start, ZEROCONF_MAGIC, (unsigned) token_len)) {
405
            if ((ret = dcc_zeroconf_add_hosts(ret_list, ret_nhosts, 4, ret_prev) != 0))
406
                return ret;
407
            goto skip;
408
        }
409
#endif
410
393
        /* Allocate new list item */
411
        /* Allocate new list item */
394
        curr = calloc(1, sizeof(struct dcc_hostdef));
412
        curr = calloc(1, sizeof(struct dcc_hostdef));
395
        if (!curr) {
413
        if (!curr) {
Lines 404-411 Link Here
404
        }
422
        }
405
423
406
        /* Link into list */
424
        /* Link into list */
407
        if (prev) {
425
        if (*ret_prev) {
408
            prev->next = curr;
426
            (*ret_prev)->next = curr;
409
        } else {
427
        } else {
410
            *ret_list = curr;   /* first */
428
            *ret_list = curr;   /* first */
411
        }
429
        }
Lines 434-443 Link Here
434
                return ret;
452
                return ret;
435
        }
453
        }
436
454
455
        (*ret_nhosts)++;
456
        *ret_prev = curr;
457
458
#ifdef HAVE_HOWL
459
        skip:
460
#endif
461
        
437
        /* continue to next token if any */
462
        /* continue to next token if any */
438
        where = token_start + token_len;
463
        where = token_start + token_len;
439
        prev = curr;
440
        (*ret_nhosts)++;
441
    }
464
    }
442
    
465
    
443
    if (*ret_nhosts) {
466
    if (*ret_nhosts) {
(-)distcc-2.18.3.orig/src/io.c (-4 / +1 lines)
Lines 160-166 Link Here
160
                return ret;
160
                return ret;
161
            else
161
            else
162
                continue;
162
                continue;
163
        } else if (r == -1 && errno == EAGAIN) {
163
        } else if (r == -1 && errno == EINTR) {
164
            continue;
164
            continue;
165
        } else if (r == -1) {
165
        } else if (r == -1) {
166
	    rs_log_error("failed to read: %s", strerror(errno));
166
	    rs_log_error("failed to read: %s", strerror(errno));
Lines 202-210 Link Here
202
        } else if (r == -1) {
202
        } else if (r == -1) {
203
            rs_log_error("failed to write: %s", strerror(errno));
203
            rs_log_error("failed to write: %s", strerror(errno));
204
            return EXIT_IO_ERROR;
204
            return EXIT_IO_ERROR;
205
        } else if (r == 0) {
206
            rs_log_error("unexpected eof on fd%d", fd);
207
            return EXIT_TRUNCATED;
208
        } else {
205
        } else {
209
            buf = &((char *) buf)[r];
206
            buf = &((char *) buf)[r];
210
            len -= r;
207
            len -= r;
(-)distcc-2.18.3.orig/src/tempfile.c (-1 / +1 lines)
Lines 161-167 Link Here
161
 * Return a subdirectory of the DISTCC_DIR of the given name, making
161
 * Return a subdirectory of the DISTCC_DIR of the given name, making
162
 * sure that the directory exists.
162
 * sure that the directory exists.
163
 **/
163
 **/
164
static int dcc_get_subdir(const char *name,
164
int dcc_get_subdir(const char *name,
165
                          char **dir_ret)
165
                          char **dir_ret)
166
{
166
{
167
    int ret;
167
    int ret;
(-)distcc-2.18.3.orig/src/zeroconf-reg.c (+110 lines)
Line 0 Link Here
1
/* -*- c-file-style: "java"; indent-tabs-mode: nil -*- */
2
3
#include "config.h"
4
5
#include <assert.h>
6
#include <stdio.h>
7
#include <sys/select.h>
8
#include <signal.h>
9
#include <sys/file.h>
10
#include <sys/time.h>
11
#include <time.h>
12
#include <sys/stat.h>
13
14
#include "distcc.h"
15
#include "zeroconf.h"
16
#include "trace.h"
17
#include "exitcode.h"
18
19
/* Called when publishing of service data completes */
20
static sw_result publish_reply(sw_discovery discovery, sw_discovery_publish_status status, sw_discovery_oid oid, sw_opaque extra) {
21
    int *done = extra;
22
    *done = 1;
23
24
    if (status != SW_DISCOVERY_PUBLISH_STARTED && status != SW_DISCOVERY_PUBLISH_STOPPED)
25
        rs_log_crit("zeroconf publishing failed (%i)", status);
26
27
    return SW_OKAY;
28
}
29
30
/* register a distcc service in DNS-SD/mDNS with the given port and number of CPUs */
31
int dcc_zeroconf_register(sw_discovery *discovery, int port, int n_cpus) {
32
    sw_salt salt;
33
    sw_discovery_oid oid;
34
    int done = 0;
35
    char service[256], hn[256], t[16];
36
    sw_text_record txt;
37
    
38
    if (sw_discovery_init(discovery) != SW_OKAY) {
39
        rs_log_crit("sw_discovery_init() failed.\n");
40
        return EXIT_CONNECT_FAILED;
41
    }
42
43
    /* Prepare TXT RR */
44
    if (sw_text_record_init(&txt) != SW_OKAY) {
45
        rs_log_crit("sw_text_record_init() failed.\n");
46
        sw_discovery_fina(*discovery);
47
        return EXIT_CONNECT_FAILED;
48
    }
49
50
    if (sw_discovery_salt(*discovery, &salt) != SW_OKAY) {
51
        rs_log_crit("sw_discovery_salt() failed.\n");
52
        goto fail;
53
    }
54
55
    /* Prepare service name */
56
    gethostname(hn, sizeof(hn)-1);
57
    hn[sizeof(hn)-1] = 0;
58
    snprintf(service, sizeof(service), "distcc@%s", hn);
59
60
    /* Prepare TXT RR */
61
    snprintf(t, sizeof(t), "cpus=%i", n_cpus);
62
    sw_text_record_add_string(txt, t);
63
64
    /* Publish the info */
65
    if (sw_discovery_publish(
66
            *discovery,
67
            0,
68
            service,
69
            "_distcc._tcp",
70
            NULL,
71
            NULL,
72
            (sw_port) port,
73
            sw_text_record_bytes(txt),
74
            sw_text_record_len(txt),
75
            publish_reply,
76
            &done,
77
            &oid) != SW_OKAY) {
78
        
79
        rs_log_crit("sw_discovery_publish() failed.\n");
80
        goto fail;
81
    }
82
83
    /* Wait until the publishing is finished */
84
    while (!done) {
85
        if (sw_salt_step(salt, NULL) != SW_OKAY) {
86
            rs_log_crit("sw_salt() failed.\n");
87
            goto fail;
88
        }
89
    
90
    }
91
92
    rs_log_info("zeroconf publishing complete");
93
94
    sw_text_record_fina(txt); 
95
    
96
    return 0;
97
    
98
 fail:
99
    
100
    sw_discovery_fina(*discovery);
101
    sw_text_record_fina(txt);
102
    return EXIT_CONNECT_FAILED;
103
}
104
105
/* Unregister this server from DNS-SD/mDNS */
106
int dcc_zeroconf_unregister(sw_discovery discovery) {
107
108
    sw_discovery_fina(discovery);
109
    return 0;
110
}
(-)distcc-2.18.3.orig/src/zeroconf.c (+493 lines)
Line 0 Link Here
1
/* -*- c-file-style: "java"; indent-tabs-mode: nil -*- */
2
3
#include "config.h"
4
5
#include <assert.h>
6
#include <stdio.h>
7
#include <sys/select.h>
8
#include <signal.h>
9
#include <sys/file.h>
10
#include <sys/time.h>
11
#include <time.h>
12
#include <sys/stat.h>
13
14
#include "distcc.h"
15
#include "hosts.h"
16
#include "zeroconf.h"
17
#include "trace.h"
18
#include "exitcode.h"
19
20
/* How long shall the background daemon be idle before i terminates itself? */
21
#define MAX_IDLE_TIME 20
22
23
/* Maxium size of host file to load */
24
#define MAX_FILE_SIZE (1024*100)
25
26
/* Zeroconf service wrapper */
27
struct host {
28
    struct host *next;
29
    sw_ipv4_address address;
30
    sw_port port;
31
    sw_uint32 iface;
32
    char *service;
33
    char *domain;
34
    int n_cpus;
35
};
36
37
/* General daemon data */
38
struct daemon_data {
39
    struct host *hosts;
40
    int fd;
41
    int n_slots;
42
};
43
44
/* A generic, system independant lock routine, similar to sys_lock,
45
 * but more powerful:
46
 *        rw:         if non-zero: r/w lock instead of r/o lock
47
 *        enable:     lock or unlock
48
 *        block:      block when locking */
49
static int generic_lock(int fd, int rw, int enable, int block) {
50
#if defined(F_SETLK)
51
    struct flock lockparam;
52
53
    lockparam.l_type = enable ? (rw ? F_WRLCK : F_RDLCK) : F_UNLCK;
54
    lockparam.l_whence = SEEK_SET;
55
    lockparam.l_start = 0;
56
    lockparam.l_len = 0;        /* whole file */
57
    
58
    return fcntl(fd, block ? F_SETLKW : F_SETLK, &lockparam);
59
#elif defined(HAVE_FLOCK)
60
    return flock(fd, (enable ? (rw ? LOCK_EX : LOCK_SH) : LOCK_UN) | (block ? LOCK_NB : 0));
61
#elif defined(HAVE_LOCKF)
62
    return lockf(fd, (enable ? (block ? F_LOCK : F_TLOCK) : F_ULOCK));
63
#else
64
#  error "No supported lock method.  Please port this code."
65
#endif
66
}
67
68
/* Return the number of seconds, when the specified file was last
69
 * read. If the atime of that file is < clip_time, use clip_time
70
 * instead */
71
static time_t fd_last_used(int fd, time_t clip_time) {
72
    struct stat st;
73
    time_t now, ft;
74
    assert(fd >= 0);
75
76
    if (fstat(fd, &st) < 0) {
77
        rs_log_crit("fstat() failed: %s\n", strerror(errno));
78
        return -1;
79
    }
80
    
81
    if ((now = time(NULL)) == (time_t) -1) {
82
        rs_log_crit("time() failed: %s\n", strerror(errno));
83
        return -1;
84
    }
85
86
    ft = clip_time ? (st.st_atime < clip_time ? clip_time : st.st_atime) : st.st_atime;
87
    assert(ft <= now);
88
89
    return now - ft;
90
}
91
92
/* Write host data to host file */
93
static int write_hosts(struct daemon_data *d) {
94
    struct host *h;
95
    int r = 0;
96
    assert(d);
97
98
    rs_log_info("writing zeroconf data.\n");
99
100
    if (generic_lock(d->fd, 1, 1, 1) < 0) {
101
        rs_log_crit("lock failed: %s\n", strerror(errno));
102
        return -1;
103
    }
104
105
    if (lseek(d->fd, 0, SEEK_SET) < 0) {
106
        rs_log_crit("lseek() failed: %s\n", strerror(errno));
107
        return -1;
108
    }
109
110
    if (ftruncate(d->fd, 0) < 0) {
111
        rs_log_crit("ftruncate() failed: %s\n", strerror(errno));
112
        return -1;
113
    }
114
115
    for (h = d->hosts; h; h = h->next) {
116
        char t[256], a[16];
117
        snprintf(t, sizeof(t), "%s:%u/%i\n", sw_ipv4_address_name(h->address, a, sizeof(a)), h->port, d->n_slots * h->n_cpus);
118
119
        if (dcc_writex(d->fd, t, strlen(t)) != 0) {
120
            rs_log_crit("write() failed: %s\n", strerror(errno));
121
            goto finish;
122
        }
123
    }
124
125
    r = 0;
126
    
127
finish:
128
129
    generic_lock(d->fd, 1, 0, 1);
130
    return r;
131
    
132
};
133
134
/* Free host data */
135
static void free_host(struct host *h) {
136
    assert(h);
137
    free(h->service);
138
    free(h->domain);
139
    free(h);
140
}
141
142
/* Remove a service from the host list */
143
static void remove_service(struct daemon_data *d, sw_uint32 iface, const char *name, const char *domain) {
144
    struct host *h, *p = NULL;
145
    assert(d);
146
147
    for (h = d->hosts; h; h = h->next) {
148
        if (h->iface == iface && !strcmp(h->service, name) && !strcmp(h->domain, domain)) {
149
150
            if (p)
151
                p->next = h->next;
152
            else
153
                d->hosts = h->next;
154
155
            free_host(h);
156
            
157
            break;
158
        } else
159
            p = h;
160
    }
161
}
162
163
/* Called when a resolve call completes */
164
static sw_result resolve_reply(
165
    sw_discovery discovery,
166
    sw_discovery_oid oid,
167
    sw_uint32 interface_index,
168
    sw_const_string name,
169
    sw_const_string type,
170
    sw_const_string domain,
171
    sw_ipv4_address address,
172
    sw_port port,
173
    sw_octets text_record,
174
    sw_ulong text_record_len,
175
    sw_opaque extra) {
176
    
177
    struct host *h;
178
    struct daemon_data *d = extra;
179
    int n_cpus = 1;
180
    sw_text_record_iterator it;
181
182
    /* Look for the number of CPUs in TXT RRs */
183
    if (sw_text_record_iterator_init(&it, text_record, text_record_len) == SW_OKAY) {
184
        sw_char key[255];
185
        sw_octet val[256];
186
        sw_ulong val_len = sizeof(val)-1;
187
188
        memset(val, 0, sizeof(val));
189
190
        while (sw_text_record_iterator_next(it, key, val, &val_len) == SW_OKAY) {
191
            if (!strcmp(key, "cpus")) {
192
                if ((n_cpus = atoi((char*) val)) <= 0)
193
                    n_cpus = 1;
194
            }
195
        }
196
        
197
        sw_text_record_iterator_fina(it);
198
    }
199
200
    /* Add a new host */
201
    h = malloc(sizeof(struct host));
202
    assert(h);
203
    h->service = strdup(name);
204
    assert(h->service);
205
    h->domain = strdup(domain);
206
    assert(h->domain);
207
    h->address = address;
208
    h->port = port;
209
    h->iface = interface_index;
210
    h->next = d->hosts;
211
    h->n_cpus = n_cpus;
212
    d->hosts = h;
213
214
    /* Write modified hosts file */
215
    write_hosts(d);
216
217
    /* Let's cancel this resolve request, we only need a single adress for this service */
218
    sw_discovery_cancel(discovery, oid);
219
    
220
    return SW_OKAY;
221
}
222
223
/* Called whenever a new service is found or removed */
224
static sw_result browse_reply(
225
    sw_discovery discovery,
226
    sw_discovery_oid oid,
227
    sw_discovery_browse_status status,
228
    sw_uint32 interface_index,
229
    sw_const_string name,
230
    sw_const_string type,
231
    sw_const_string domain,
232
    sw_opaque extra) {
233
234
    struct daemon_data *d = extra;
235
    assert(d);
236
    
237
    switch (status) {
238
        case SW_DISCOVERY_BROWSE_ADD_SERVICE: {
239
            sw_discovery_oid noid;
240
241
            rs_log_info("new service: %s\n", name);
242
243
            sw_discovery_resolve(discovery, 0, name, type, domain, resolve_reply, extra, &noid);
244
            break;
245
        }
246
        case SW_DISCOVERY_BROWSE_REMOVE_SERVICE: {
247
248
            rs_log_info("removed service: %s\n", name);
249
250
            remove_service(d, interface_index, name, domain);
251
            write_hosts(d);
252
            break;
253
        }
254
        default:
255
            ;
256
    }
257
258
    return SW_OKAY;
259
}
260
261
/* The main function of the background daemon */
262
static void daemon_proc(const char *host_file, const char *lock_file, int n_slots) {
263
    sw_discovery_oid oid;
264
    sw_discovery discovery;
265
    int ret = 1;
266
    int lock_fd = -1;
267
    struct daemon_data d;
268
    sw_salt salt;
269
    time_t clip_time; 
270
271
    /* Prepare daemon data structure */
272
    d.fd = -1;
273
    d.hosts = NULL;
274
    d.n_slots = n_slots;
275
    clip_time = time(NULL);
276
277
    rs_log_info("zeroconf daemon running.\n");
278
279
    /* Open daemon lock file and lock it */
280
    if ((lock_fd = open(lock_file, O_RDWR|O_CREAT, 0666)) < 0) {
281
        rs_log_crit("open('%s') failed: %s\n", lock_file, strerror(errno));
282
        goto finish;
283
    }
284
285
    if (generic_lock(lock_fd, 1, 1, 0) < 0) {
286
        /* lock failed, there's probably already another daemon running */
287
        goto finish;
288
    }
289
290
    /* Open host file */
291
    if ((d.fd = open(host_file, O_RDWR|O_CREAT, 0666)) < 0) {
292
        rs_log_crit("open('%s') failed: %s\n", host_file, strerror(errno));
293
        goto finish;
294
    }
295
296
    /* Clear host file */
297
    write_hosts(&d);
298
    
299
    if (sw_discovery_init(&discovery) != SW_OKAY) {
300
        rs_log_crit("sw_discovery_init() failed.\n");
301
        goto finish;
302
    }
303
304
    /* Start discovery */
305
    if (sw_discovery_browse(discovery, 0, "_distcc._tcp", NULL, browse_reply, &d, &oid) != SW_OKAY) {
306
        rs_log_crit("sw_discovery_browse() failed.\n");
307
        goto finish;
308
    }
309
310
    /* Get "salt" object for the main loop */
311
    if (sw_discovery_salt(discovery, &salt) != SW_OKAY) {
312
        rs_log_crit("sw_discovery_salt() failed.\n");
313
        goto finish;
314
    }
315
316
    /* Check whether the host file has been used recently */
317
    while (fd_last_used(d.fd, clip_time) <= MAX_IDLE_TIME) {
318
        sw_ulong msecs = 500;
319
320
        /* Iterate the main loop for 500ms */
321
        if (sw_salt_step(salt, &msecs) != SW_OKAY) {
322
            rs_log_crit("sw_salt_step() failed.\n");
323
            goto finish;
324
        }
325
    }
326
327
    /* Wer are idle */
328
    rs_log_info("zeroconf daemon unused.\n");
329
    
330
    ret = 0;
331
    
332
finish:
333
334
    /* Cleanup */
335
    if (lock_fd >= 0) {
336
        generic_lock(lock_fd, 1, 0, 0);
337
        close(lock_fd);
338
    }
339
    
340
    if (d.fd >= 0)
341
        close(d.fd);
342
343
    while (d.hosts) {
344
        struct host *h = d.hosts;
345
        d.hosts = d.hosts->next;
346
        free_host(h);
347
    }
348
349
    rs_log_info("zeroconf daemon ended.\n");
350
    
351
    exit(ret);
352
}
353
354
/* Return path to the zeroconf directory in ~/.distcc */
355
static int get_zeroconf_dir(char **dir_ret) {
356
    static char *cached;
357
    int ret;
358
    
359
    if (cached) {
360
        *dir_ret = cached;
361
        return 0;
362
    } else {
363
        ret = dcc_get_subdir("zeroconf", dir_ret);
364
        if (ret == 0)
365
            cached = *dir_ret;
366
        return ret;
367
    }
368
}
369
370
/* Get the host list from zeroconf */
371
int dcc_zeroconf_add_hosts(struct dcc_hostdef **ret_list, int *ret_nhosts, int n_slots, struct dcc_hostdef **ret_prev) {
372
    char host_file[PATH_MAX], lock_file[PATH_MAX], *s = NULL;
373
    int lock_fd = -1, host_fd = -1;
374
    int fork_daemon = 0;
375
    int r = -1;
376
    char *dir;
377
    struct stat st;
378
379
    if (get_zeroconf_dir(&dir) != 0) {
380
        rs_log_crit("failed to get zeroconf dir.\n");
381
        goto finish;
382
    }
383
    
384
    snprintf(lock_file, sizeof(lock_file), "%s/lock", dir);
385
    snprintf(host_file, sizeof(host_file), "%s/hosts", dir);
386
387
    /* Open lock file */
388
    if ((lock_fd = open(lock_file, O_RDWR|O_CREAT, 0666)) < 0) {
389
        rs_log_crit("open('%s') failed: %s\n", lock_file, strerror(errno));
390
        goto finish;
391
    }
392
393
    /* Try to lock the lock file */
394
    if (generic_lock(lock_fd, 1, 1, 0) >= 0) {
395
        /* The lock succeeded => there's no daemon running yet! */
396
        fork_daemon = 1;
397
        generic_lock(lock_fd, 1, 0, 0);
398
    }
399
    
400
    close(lock_fd);
401
402
    /* Shall we fork a new daemon? */
403
    if (fork_daemon) {
404
        pid_t pid;
405
406
        rs_log_info("Spawning zeroconf daemon.\n");
407
408
        if ((pid = fork()) == -1) {
409
            rs_log_crit("fork() failed: %s\n", strerror(errno));
410
            goto finish;
411
        } else if (pid == 0) {
412
            int fd;
413
            /* Child */
414
415
            /* Close file descriptors and replace them by /dev/null */
416
            close(0);
417
            close(1);
418
            close(2);
419
            fd = open("/dev/null", O_RDWR);
420
            assert(fd == 0);
421
            fd = dup(0);
422
            assert(fd == 1);
423
            fd = dup(0);
424
            assert(fd == 2);
425
426
#ifdef HAVE_SETSID
427
            setsid();
428
#endif
429
            
430
            chdir("/");
431
            rs_add_logger(rs_logger_syslog, RS_LOG_DEBUG, NULL, 0);
432
            daemon_proc(host_file, lock_file, n_slots);
433
        }
434
435
        /* Parent */
436
437
        /* Wait some time for initial host gathering */
438
        usleep(1000000);         /* 100 ms */
439
440
    }
441
442
    /* Open host list read-only */
443
    if ((host_fd = open(host_file, O_RDONLY)) < 0) {
444
        rs_log_crit("open('%s') failed: %s\n", host_file, strerror(errno));
445
        goto finish;
446
    }
447
448
    /* A read lock */
449
    if (generic_lock(host_fd, 0, 1, 1) < 0) {
450
        rs_log_crit("lock failed: %s\n", strerror(errno));
451
        goto finish;
452
    }
453
454
    /* Get file size */
455
    if (fstat(host_fd, &st) < 0) {
456
        rs_log_crit("stat() failed: %s\n", strerror(errno));
457
        goto finish;
458
    }
459
460
    if (st.st_size >= MAX_FILE_SIZE) {
461
        rs_log_crit("file too large.\n");
462
        goto finish;
463
    }
464
465
    /* read file data */
466
    s = malloc((size_t) st.st_size+1);
467
    assert(s);
468
469
    if (dcc_readx(host_fd, s, (size_t) st.st_size) != 0) {
470
        rs_log_crit("failed to read from file.\n");
471
        goto finish;
472
    }
473
    s[st.st_size] = 0;
474
475
    /* Parse host data */
476
    if (dcc_parse_hosts(s, host_file, ret_list, ret_nhosts, ret_prev) != 0) {
477
        rs_log_crit("failed to parse host file.\n");
478
        goto finish;
479
    }
480
481
    r = 0;
482
483
finish:
484
    if (host_fd >= 0) {
485
        generic_lock(host_fd, 0, 0, 1);
486
        close(host_fd);
487
    }
488
489
    free(s);
490
491
    return r;
492
}
493
(-)distcc-2.18.3.orig/src/zeroconf.h (+22 lines)
Line 0 Link Here
1
#ifndef foozeroconfhfoo
2
#define foozeroconfhfoo
3
4
#include <inttypes.h>
5
6
/* HOWL 0.9.6 defines PACKAGE_NAME and friends. This is broken. As a
7
 * workaround we undfined those macros here */
8
9
#undef PACKAGE_NAME
10
#undef PACKAGE_BUGREPORT
11
#undef PACKAGE_TARNAME
12
#undef PACKAGE_VERSION
13
#undef PACKAGE_STRING
14
15
#include <howl.h>
16
17
int dcc_zeroconf_add_hosts(struct dcc_hostdef **re_list, int *ret_nhosts, int slots, struct dcc_hostdef **ret_prev);
18
19
int dcc_zeroconf_register(sw_discovery *discovery, int port, int n_cpus);
20
int dcc_zeroconf_unregister(sw_discovery discovery);
21
22
#endif

Return to bug 80219