+++ /dev/null
---- distcc-2.0.1/src/hosts.c.old Wed Oct 9 08:58:04 2002
-+++ distcc-2.0.1/src/hosts.c Wed Oct 9 09:16:14 2002
-@@ -72,6 +72,9 @@
- #include <errno.h>
- #include <time.h>
- #include <ctype.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-
- #include "distcc.h"
- #include "trace.h"
-@@ -107,9 +110,45 @@
- char *where;
-
- where = getenv("DISTCC_HOSTS");
-- if (!where) {
-- rs_log_warning("$DISTCC_HOSTS is not defined; can't distribute work");
-- return EXIT_BAD_HOSTSPEC;
-+ if (!where) {
-+ char *filename;
-+ int file;
-+ char buffer[4096];
-+ int readcount;
-+ char *listbuf=0;
-+ int listbufsize=4096;
-+ int listbuflen=0;
-+ int parseresult;
-+
-+ listbuf = malloc(4096);
-+
-+ filename = getenv("DISTCC_HOSTS_FILE");
-+ if (!filename)
-+ {
-+ rs_log_warning("$DISTCC_HOSTS or $DISTCC_HOSTS_FILE not defined;"
-+ " can't distribute work");
-+ return 1;
-+ }
-+ file = open(filename, O_RDONLY);
-+
-+ while ((readcount = read(file, buffer, 4096)) > 0)
-+ {
-+ if (readcount+listbuflen > listbufsize)
-+ {
-+ char *temp;
-+ temp = malloc(readcount+listbuflen);
-+ memcpy(temp, listbuf, listbuflen);
-+ free(listbuf);
-+ listbuf = temp;
-+ listbufsize = readcount+listbuflen;
-+ }
-+ memcpy(listbuf+listbuflen, buffer, readcount);
-+ }
-+ close(file);
-+ /* ok, I've read the file, now have it parsed */
-+ parseresult = dcc_parse_hosts(listbuf, ret_list, ret_nhosts);
-+ free(listbuf);
-+ return parseresult;
- }
-
- return dcc_parse_hosts(where, ret_list, ret_nhosts);
-@@ -296,7 +335,7 @@
- if (*ret_nhosts) {
- return 0;
- } else {
-- rs_log_warning("$DISTCC_HOSTS is empty; can't distribute work");
-+ rs_log_warning("$DISTCC_HOSTS or $DISTCC_HOSTS_FILE is empty; can't distribute work");
- return EXIT_BAD_HOSTSPEC;
- }
- }
+++ /dev/null
---- src/distcc.c.orig Mon May 5 07:25:00 2003
-+++ src/distcc.c Mon May 5 21:07:30 2003
-@@ -117,8 +117,14 @@
- "Each host can be given in any of these forms:\n"
- "\n"
- " localhost run in place\n"
--" HOST TCP connection, port %d\n"
--" HOST:PORT TCP connection, specified port\n"
-+" HOST[:PORT][,OPT...] TCP connection (default port=%d)\n"
-+"\n"
-+"OPT Values:\n"
-+" slots=N Maximum of N simultaneous jobs allowed\n"
-+" N Abbreviation of the slots=N option\n"
-+"\n"
-+"Hostname examples:\n"
-+" foo foo:4242 foo,4 bar:4100,2 bar,slots=3\n"
- " @HOST SSH connection\n"
- " USER$HOST SSH connection to specified host\n"
- "\n"
---- src/hosts.c.orig Mon May 5 06:59:53 2003
-+++ src/hosts.c Mon May 5 21:01:23 2003
-@@ -176,21 +176,43 @@
- }
-
-
--static int dcc_parse_multiplier(const char **psrc, struct dcc_hostdef *hostdef)
-+static int dcc_parse_options(const char **psrc, struct dcc_hostdef *hostdef)
- {
-- char *mul;
-- const char *token = *psrc;
-+ char *opt, *arg;
-+ const char *token;
- int ret;
-
-- if ((*psrc)[0] == '/') {
-- (*psrc)++;
-- if ((ret = dcc_dup_part(psrc, &mul, "/: \t\n\f")) != 0)
-+ while ((*psrc)[0] == ',') {
-+ token = (*psrc)++;
-+ if ((ret = dcc_dup_part(psrc, &opt, ", \t\n\f")) != 0)
- return ret;
-- if (!mul || atoi(mul) == 0) {
-- rs_log_error("bad multiplier \"%s\" in host specification", token);
-+ if (opt) {
-+ if ((arg = strchr(opt, '=')) != NULL)
-+ *arg++ = '\0';
-+ else if (isdigit(*opt)) {
-+ arg = opt;
-+ opt = NULL;
-+ }
-+ else
-+ arg = NULL;
-+ }
-+ else
-+ arg = NULL;
-+ if (!arg) {
-+ rs_log_error("malformed option in host specification: \"%s\"", token);
-+ return EXIT_BAD_HOSTSPEC;
-+ }
-+ if (!opt || strcmp(opt, "slots") == 0) {
-+ hostdef->n_slots = atoi(arg);
-+ if (hostdef->n_slots <= 0) {
-+ rs_log_error("invalid number of slots in host specification: \"%s\"", token);
-+ return EXIT_BAD_HOSTSPEC;
-+ }
-+ }
-+ else {
-+ rs_log_error("unknown option in host specification: \"%s\"", token);
- return EXIT_BAD_HOSTSPEC;
- }
-- hostdef->n_slots = atoi(mul);
- }
- return 0;
- }
-@@ -211,7 +233,7 @@
-
- token++;
-
-- if ((ret = dcc_dup_part(&token, &hostdef->hostname, "/: \t\n\f")) != 0)
-+ if ((ret = dcc_dup_part(&token, &hostdef->hostname, ",: \t\n\f")) != 0)
- return ret;
-
- if (!hostdef->hostname) {
-@@ -220,15 +242,15 @@
- return EXIT_BAD_HOSTSPEC;
- }
-
-- if ((ret = dcc_parse_multiplier(&token, hostdef)) != 0)
-- return ret;
--
- if (token[0] == ':') {
- token++;
-- if ((ret = dcc_dup_part(&token, &hostdef->ssh_command, " \t\n\f")) != 0)
-+ if ((ret = dcc_dup_part(&token, &hostdef->ssh_command, ", \t\n\f")) != 0)
- return ret;
- }
--
-+
-+ if ((ret = dcc_parse_options(&token, hostdef)) != 0)
-+ return ret;
-+
- hostdef->mode = DCC_MODE_SSH;
- return 0;
- }
-@@ -241,7 +263,7 @@
- int ret;
- const char *token = token_start;
-
-- if ((ret = dcc_dup_part(&token, &hostdef->hostname, "/: \t\n\f")) != 0)
-+ if ((ret = dcc_dup_part(&token, &hostdef->hostname, ",: \t\n\f")) != 0)
- return ret;
-
- if (!hostdef->hostname) {
-@@ -250,14 +272,11 @@
- return EXIT_BAD_HOSTSPEC;
- }
-
-- if ((ret = dcc_parse_multiplier(&token, hostdef)) != 0)
-- return ret;
--
- hostdef->port = dcc_default_port;
- if (token[0] == ':') {
- token++;
-
-- if ((ret = dcc_dup_part(&token, &port_str, " \t\n\f")) != 0)
-+ if ((ret = dcc_dup_part(&token, &port_str, ", \t\n\f")) != 0)
- return ret;
-
- if (port_str) {
-@@ -270,7 +289,10 @@
- free(port_str);
- }
- }
--
-+
-+ if ((ret = dcc_parse_options(&token, hostdef)) != 0)
-+ return ret;
-+
- hostdef->mode = DCC_MODE_TCP;
- return 0;
- }
-@@ -279,13 +301,13 @@
- static int dcc_parse_localhost(struct dcc_hostdef *hostdef,
- const char * token_start)
- {
-- const char *token = token_start + strlen("localhost");
-+ const char *token = token_start + (sizeof "localhost") - 1;
-
- hostdef->mode = DCC_MODE_LOCAL;
- hostdef->hostname = strdup("localhost");
- hostdef->n_slots = 1;
-
-- return dcc_parse_multiplier(&token, hostdef);
-+ return dcc_parse_options(&token, hostdef);
- }
-
-
-@@ -316,7 +338,7 @@
- * definition. We then duplicate the relevant subcomponents into
- * the relevant fields. */
- while (1) {
-- int token_len;
-+ unsigned int token_len;
- const char *token_start;
- int has_at;
-
-@@ -347,8 +369,10 @@
-
- has_at = (memchr(token_start, '@', token_len) != NULL);
-
-- if (!strncmp(token_start, "localhost", token_len)
-- || !strncmp(token_start, "localhost/", strlen("localhost/"))) {
-+ if (token_len >= (sizeof "localhost")-1
-+ && strncmp(token_start, "localhost", (sizeof "localhost")-1) == 0
-+ && (token_len == (sizeof "localhost")-1
-+ || token_start[(sizeof "localhost")-1] == ',')) {
- if ((ret = dcc_parse_localhost(curr, token_start)) != 0)
- return ret;
- } else if (has_at) {
---- linuxdoc/distcc.sgml.orig Fri May 16 08:43:29 2003
-+++ linuxdoc/distcc.sgml Sat May 17 21:38:13 2003
-@@ -174,7 +174,7 @@
- On the client, set the <tt>DISTCC_HOSTS</tt> environment
- variable to indicate which volunteer machines to use.
- For example:
-- <tscreen><verb>DISTCC_HOSTS='angry toey:4202 localhost'</verb></tscreen>
-+ <tscreen><verb>HOSTNAME[:PORT][,OPT...]</verb></tscreen>
-
- <item>
- Set the <tt>CC</tt> variable or edit Makefiles to prefix
-@@ -182,6 +182,13 @@
- <tscreen><verb>distcc gcc -o hello.o -c hello.c</verb></tscreen>
- </enum>
- </p>
-+
-+ <p>
-+ You can specify one or more host-specific options at the end of the
-+ host-spec by appending each one after a comma. The current option
-+ is slots=N (abbreviated as just N, if desired).
-+ The "slots" option specifies the maximum number of jobs that the
-+ associated host should be given simultaneously (e.g. "localhost,2").
- </sect>
-
-
+++ /dev/null
-Index: src/exitcode.h
---- src/exitcode.h 2 Feb 2003 12:24:29 -0000 1.13
-+++ src/exitcode.h 2 Apr 2003 02:42:27 -0000
-@@ -33,6 +33,7 @@
- * codes.
- **/
- enum dcc_exitcode {
-+ EXIT_VERSION_REQUEST = 001,
- EXIT_DISTCC_FAILED = 100, /**< General failure */
- EXIT_BAD_ARGUMENTS = 101,
- EXIT_BIND_FAILED = 102,
-Index: src/rpc.c
---- src/rpc.c 27 Mar 2003 04:45:49 -0000 1.25
-+++ src/rpc.c 2 Apr 2003 02:42:27 -0000
-@@ -160,6 +160,8 @@
- }
-
- if (memcmp(buf, expected, 4)) {
-+ if (memcmp(expected, "DIST", 4) == 0 && memcmp(buf, "QVER", 4) == 0)
-+ return EXIT_VERSION_REQUEST;
- rs_log_error("mismatch on token %s", expected);
- return EXIT_PROTOCOL_ERROR;
- }
-Index: src/serve.c
---- src/serve.c 31 Mar 2003 08:36:37 -0000 1.83
-+++ src/serve.c 2 Apr 2003 02:42:27 -0000
-@@ -87,8 +87,11 @@
- static int dcc_r_request_header(int ifd)
- {
- int vers;
-+ int ret;
-
-- if (dcc_r_token_int(ifd, "DIST", &vers) == -1) {
-+ if ((ret = dcc_r_token_int(ifd, "DIST", &vers)) != 0) {
-+ if (ret == EXIT_VERSION_REQUEST)
-+ return ret;
- rs_log_error("client did not provide distcc magic fairy dust");
- return EXIT_PROTOCOL_ERROR;
- }
-@@ -260,8 +263,13 @@
-
- if ((ret = dcc_r_request_header(netfd))
- || (ret = dcc_r_argv(netfd, &argv))
-- || (ret = dcc_scan_args(argv, &orig_input, &orig_output, &argv)))
-+ || (ret = dcc_scan_args(argv, &orig_input, &orig_output, &argv))) {
-+ if (ret == EXIT_VERSION_REQUEST) {
-+ rs_trace("send %s", PACKAGE_VERSION);
-+ return dcc_writex(netfd, PACKAGE_VERSION, strlen(PACKAGE_VERSION));
-+ }
- return ret;
-+ }
-
- /* TODO: Make sure cleanup is called in case of error.
- *