diff -ruNp -x tags -x Makefile -x '*.o' -x '*.log' -x 'config*' distcc-2.18.3-orig/src/dopt.c distcc-2.18.3/src/dopt.c
--- distcc-2.18.3-orig/src/dopt.c	2004-10-24 07:05:48.000000000 +0200
+++ distcc-2.18.3/src/dopt.c	2007-03-10 14:41:49.000000000 +0100
@@ -44,6 +44,7 @@
 #include "exitcode.h"
 #include "daemon.h"
 #include "access.h"
+#include "subst_rcmd.h"
 
 int opt_niceness = 5;           /* default */
 
@@ -66,8 +67,12 @@ int opt_no_fifo = 0;
 /** If non-NULL, listen on only this address. **/
 char *opt_listen_addr = NULL;
 
+/** Mandatory access list. Clients not on the list would be denied service. **/
 struct dcc_allow_list *opt_allowed = NULL;
 
+/** Host-based remote command translation list **/
+struct subst_rcommand *opt_subst_rcmd = NULL;
+
 /**
  * If true, don't detach from the parent.  This is probably necessary
  * for use with daemontools or other monitoring programs, and is also
@@ -111,6 +116,7 @@ const struct poptOption options[] = {
     { "no-fork", 0,      POPT_ARG_NONE, &opt_no_fork, 0, 0, 0 },
     { "pid-file", 'P',   POPT_ARG_STRING, &arg_pid_file, 0, 0, 0 },
     { "port", 'p',       POPT_ARG_INT, &arg_port,      0, 0, 0 },
+    { "subst-rcmd", 0,   POPT_ARG_STRING, 0, 's', 0, 0 },
     { "user", 0,         POPT_ARG_STRING, &opt_user, 'u', 0, 0 },
     { "verbose", 0,      POPT_ARG_NONE, 0, 'v', 0, 0 },
     { "version", 0,      POPT_ARG_NONE, 0, 'V', 0, 0 },
@@ -137,6 +143,7 @@ static void distccd_show_usage(void)
 "    -p, --port PORT            TCP port to listen on\n"
 "    --listen ADDRESS           IP address to listen on\n"
 "    -a, --allow IP[/BITS]      client address access control\n"
+"    --subst-rcmd RCMD@IP=LCMD  remote command substitution\n"
 "  Debug and trace:\n"
 "    --log-level=LEVEL          set detail level for log file\n"
 "      levels: critical, error, warning, notice, info, debug\n"
@@ -195,7 +202,17 @@ int distccd_parse_options(int argc, cons
                 goto out_exit;
             }
             break;
-
+	case 's': {
+	    struct subst_rcommand *sc;
+	    sc = dcc_subst_rcommand_parse( poptGetOptArg(po) );
+	    if (sc) {
+	    	dcc_subst_rcommand_append( &opt_subst_rcmd, sc );
+	    } else {
+                exitcode = EXIT_BAD_ARGUMENTS;
+		goto out_exit;
+	    }
+	}
+	    break;
         case 'u':
             if (getuid() != 0 && geteuid() != 0) {
                 rs_log_warning("--user is ignored when distccd is not run by root");
diff -ruNp -x tags -x Makefile -x '*.o' -x '*.log' -x 'config*' distcc-2.18.3-orig/src/serve.c distcc-2.18.3/src/serve.c
--- distcc-2.18.3-orig/src/serve.c	2004-10-24 07:05:49.000000000 +0200
+++ distcc-2.18.3/src/serve.c	2007-03-10 14:30:26.000000000 +0100
@@ -70,6 +70,7 @@
 #endif /* HAVE_SYS_SIGNAL_H */
 #include <sys/param.h>
 #include <sys/socket.h>
+#include <netinet/in.h>
 
 #include "distcc.h"
 #include "trace.h"
@@ -83,6 +84,7 @@
 #include "srvnet.h"
 #include "hosts.h"
 #include "daemon.h"
+#include "subst_rcmd.h"
 
 
 /**
@@ -91,7 +93,7 @@
  **/
 static int dcc_compile_log_fd = -1;
 
-static int dcc_run_job(int in_fd, int out_fd);
+static int dcc_run_job(int in_fd, int out_fd, struct sockaddr *cli_addr, int cli_len);
 
 
 /**
@@ -156,7 +158,7 @@ int dcc_service_job(int in_fd,
     if ((ret = dcc_check_client(cli_addr, cli_len, opt_allowed)) != 0)
         goto out;
 
-    ret = dcc_run_job(in_fd, out_fd);
+    ret = dcc_run_job(in_fd, out_fd, cli_addr, cli_len);
 
 out:
     return ret;
@@ -245,12 +247,46 @@ static int dcc_check_compiler_masq(char 
 }
 
 
+/**
+ * Map remote command sent by client to configured local command. 
+ * Useful for cross-compiling or implicit compiler version selection.
+ **/
+static char *dcc_subst_rcommand(char *cmd, struct sockaddr *cli_addr, 
+		int cli_len)
+{
+	struct subst_rcommand *x = opt_subst_rcmd;
+	struct sockaddr_in *sain = (struct sockaddr_in *)cli_addr;
+	unsigned int ipv4_addr;
+
+	if ((size_t)cli_len < sizeof(struct sockaddr_in) || 
+			sain->sin_family != AF_INET)
+	{
+		/* debug: subst-rcmd: ipv4 only supported right now */
+		return cmd;
+	}
+	ipv4_addr = sain->sin_addr.s_addr;
+
+	for (; x; x = x->next) {
+		if (x->ipv4_addr != ipv4_addr)
+			continue;
+
+		if (0==strcmp(x->remote_command, cmd)) {
+			/* trace: subst-rcmd done: client ipaddr: rcmd -> lcmd */
+			return x->local_command;
+		}
+	}
+
+	return cmd;
+}
+
 
 /**
  * Read a request, run the compiler, and send a response.
  **/
 static int dcc_run_job(int in_fd,
-                       int out_fd)
+                       int out_fd,
+		       struct sockaddr *cli_addr,
+		       int cli_len)
 {
     char **argv;
     int status;
@@ -301,6 +337,8 @@ static int dcc_run_job(int in_fd,
         || (ret = dcc_set_output(argv, temp_o)))
         goto out_cleanup;
 
+    argv[0] = dcc_subst_rcommand(argv[0], cli_addr, cli_len);
+
     if ((ret = dcc_check_compiler_masq(argv[0])))
         goto out_cleanup;
 
diff -ruNp -x tags -x Makefile -x '*.o' -x '*.log' -x 'config*' distcc-2.18.3-orig/src/subst_rcmd.c distcc-2.18.3/src/subst_rcmd.c
--- distcc-2.18.3-orig/src/subst_rcmd.c	1970-01-01 01:00:00.000000000 +0100
+++ distcc-2.18.3/src/subst_rcmd.c	2007-03-10 14:42:19.000000000 +0100
@@ -0,0 +1,88 @@
+
+#include <stdio.h>	/* sscanf() */
+#include <sys/socket.h>	/* inet_aton() */
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>	/* strlen() */
+#include <stdlib.h>	/* malloc()/free() */
+
+#include "subst_rcmd.h"
+
+struct subst_rcommand *
+dcc_subst_rcommand_parse(const char *cmd_line_param)
+{
+	/* "gcc@192.168.1.1=ppc-gcc" */
+	char *remote_command=0, *client_ipaddr=0, *local_command=0;
+	struct subst_rcommand *scc=0, *ret=0;
+	struct in_addr ina;
+
+	size_t clp_len = strlen( cmd_line_param );
+	int i;
+
+	do {
+		remote_command = (char *)malloc( clp_len );
+		client_ipaddr = (char *)malloc( clp_len );
+		local_command = (char *)malloc( clp_len );
+		scc = (struct subst_rcommand *)malloc( sizeof(*scc) );
+
+		if (!remote_command || !client_ipaddr || !local_command || !scc) {
+			/* memory allocation error */
+			break;
+		}
+
+		i = sscanf( cmd_line_param, "%[^@]@%[^=]=%s", remote_command, 
+			client_ipaddr, local_command );
+
+		if (i != 3) {
+			/* invalid input */
+			break;
+		}
+
+		i = inet_aton( client_ipaddr, &ina );
+		if (i == 0) {
+			/* bad IPv4 address */
+			break;
+		}
+
+		/* info: parsed subst_rcmd Ok */
+
+		memset( scc, 0, sizeof(*scc) );
+		scc->ipv4_addr = ina.s_addr;
+		scc->remote_command = remote_command;
+		scc->local_command = local_command;
+
+		ret = scc;
+	} while (0);
+
+	if (ret == 0) {
+		if (scc) free(scc);
+		if (remote_command) free(remote_command);
+		if (client_ipaddr) free(client_ipaddr);
+		if (local_command) free(local_command);
+	}
+
+	return ret;
+}
+
+void
+dcc_subst_rcommand_append(struct subst_rcommand **head, 
+	struct subst_rcommand *newsc)
+{
+	struct subst_rcommand *x;	/* and x marks the spot */
+
+	/* assert(head); */
+
+	newsc->next = 0;
+	x = *head;
+
+	if (x == 0) {
+		*head = newsc;
+		return;
+	} else {
+		while (x->next) {
+			x = x->next;
+		}
+		/* assert( x->next == 0 ); */
+		x->next = newsc;
+	}
+}
diff -ruNp -x tags -x Makefile -x '*.o' -x '*.log' -x 'config*' distcc-2.18.3-orig/src/subst_rcmd.h distcc-2.18.3/src/subst_rcmd.h
--- distcc-2.18.3-orig/src/subst_rcmd.h	1970-01-01 01:00:00.000000000 +0100
+++ distcc-2.18.3/src/subst_rcmd.h	2007-03-10 14:42:12.000000000 +0100
@@ -0,0 +1,18 @@
+#ifndef SUBST_RCMD_H__
+#define SUBST_RCMD_H__
+
+struct subst_rcommand {
+	unsigned int ipv4_addr;
+	char *remote_command;
+	char *local_command;
+	struct subst_rcommand *next;
+};
+
+extern struct subst_rcommand *opt_subst_rcmd;
+
+struct subst_rcommand *dcc_subst_rcommand_parse(const char *cmd_line_param);
+
+void dcc_subst_rcommand_append(struct subst_rcommand **head,
+	struct subst_rcommand *newsc);
+
+#endif /* SUBST_RCMD_H__ */
