diff -ruN distcc.orig/Makefile.in distcc/Makefile.in
--- distcc.orig/Makefile.in	2002-11-11 00:26:38.000000000 +0100
+++ distcc/Makefile.in	2002-11-10 22:41:32.000000000 +0100
@@ -116,7 +116,7 @@
 
 common_obj = src/trace.o src/util.o src/io.o src/exec.o src/arg.o	\
 src/rpc.o src/tempfile.o src/bulk.o src/help.o src/filename.o		\
-src/lock.o src/where.o src/hosts.o
+src/lock.o src/where.o src/hosts.o src/postproc.o
 
 distcc_obj = src/distcc.o src/clinet.o src/strip.o src/implicit.o $(common_obj)
 
@@ -135,12 +135,12 @@
 src/h_exten.c src/h_hosts.c src/h_issource.c src/h_scanargs.c		\
 src/help.c src/hosts.c src/io.c src/rpc.c src/serve.c src/srvnet.c	\
 src/tempfile.c src/trace.c src/util.c src/where.c src/zip.c src/strip.c \
-src/h_strip.c src/implicit.c src/lock.c
+src/h_strip.c src/implicit.c src/lock.c src/postproc.c
 
 HEADERS = src/clinet.h src/distcc.h src/exitcode.h src/hosts.h		\
 	src/io.h src/tempfile.h	src/strip.h src/implicit.h		\
 	src/opt.h src/rpc.h src/trace.h src/util.h src/bulk.h 		\
-	src/exec.h src/lock.h src/where.h
+	src/exec.h src/lock.h src/where.h src/postproc.h
 
 MEN = man/distcc.1 man/distccd.1
 
diff -ruN distcc.orig/src/distcc.c distcc/src/distcc.c
--- distcc.orig/src/distcc.c	2002-11-11 00:26:38.000000000 +0100
+++ distcc/src/distcc.c	2002-11-10 23:14:02.000000000 +0100
@@ -60,6 +60,7 @@
 #include "exec.h"
 #include "where.h"
 #include "lock.h"
+#include "postproc.h"
 
 
 /* for trace.c */
@@ -173,6 +174,7 @@
                         const char *cpp_fname)
 {
     long stime_usec, utime_usec;
+    char *pp_fname;
     int ret;
 
     if ((ret = dcc_x_req_header(net_fd))
@@ -203,7 +205,10 @@
         return EXIT_IO_ERROR;
     }
 
-    if ((ret = dcc_x_file(net_fd, cpp_fname, "DOTI", NULL)))
+    if ((ret = dcc_post_process (cpp_fname, &pp_fname) != 0))
+        return ret;
+
+    if ((ret = dcc_x_file(net_fd, pp_fname, "DOTI", NULL)))
         return ret;
 
     rs_trace("client finished sending request to server");
@@ -450,6 +455,9 @@
     if ((ret = dcc_strip_local_args(argv, &argv_stripped)))
         goto fallback;
 
+    if ((ret = dcc_post_process_set_source (input_fname)))
+        goto fallback;
+    
     if ((ret = dcc_compile_remote(argv_stripped, cpp_fname, output_fname,
                                   cpp_pid, host, status)) != 0) {
         /* Returns zero if we successfully ran the compiler, even if
diff -ruN distcc.orig/src/postproc.c distcc/src/postproc.c
--- distcc.orig/src/postproc.c	1970-01-01 01:00:00.000000000 +0100
+++ distcc/src/postproc.c	2002-11-10 23:57:17.000000000 +0100
@@ -0,0 +1,360 @@
+/* -*- c-file-style: "java"; indent-tabs-mode: nil; fill-column: 78 -*-
+ * 
+ * distcc -- A simple distributed compiler system
+ * $Header: $
+ *
+ * Copyright (C) 2002 by Tim Janik <timj@gtk.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "distcc.h"
+#include "trace.h"
+#include "assert.h"
+#include "tempfile.h"
+#include "postproc.h"
+
+
+/* buffered input */
+#define BUFFER_SIZE    4000
+typedef struct {
+    int   fd;
+    char *bound;
+    char  buffer[BUFFER_SIZE + 1];
+    char *text;
+} PPInput;
+
+static inline int peek_char (PPInput *inp)
+{
+    if (inp->text < inp->bound)
+        return *inp->text;
+    else if (inp->fd >= 0) {
+        int count;
+        char *buffer = inp->buffer;
+        do
+            count = read (inp->fd, buffer, BUFFER_SIZE);
+        while (count == -1 && (errno == EINTR || errno == EAGAIN));
+        if (count < 1) {
+            inp->fd = -1;
+            return EOF;
+        } else {
+            inp->text = buffer;
+            inp->bound = buffer + count;
+            return *inp->text;
+        }
+    } else
+        return EOF;
+}
+
+static inline int get_char (PPInput *inp)
+{
+    int c = peek_char (inp);
+    if (c != EOF)
+        inp->text++;
+    return c;
+}
+
+static void unget_char (PPInput *inp,
+                        char     c)
+{
+    /* we only allow unget backs after a non-EOF get_char() */
+    assert (inp->text > inp->buffer);
+    inp->text--;
+    inp->text[0] = c;
+}
+
+
+/* buffered output */
+typedef struct {
+    int     fd;
+    char   *p;
+    char    buffer[BUFFER_SIZE + 1];
+} PPOutput;
+
+static void flush_output (PPOutput *out)
+{
+    int count, n = out->p - out->buffer;
+    errno = 0;
+    if (n) {
+        do
+            count = write (out->fd, out->buffer, n);
+        while (count == -1 && (errno == EINTR || errno == EAGAIN));
+        if (count != n)
+            rs_log_error ("failed to write %u bytes: %s", n, strerror (errno));
+    }
+    out->p = out->buffer;
+}
+
+static inline void write_char (PPOutput *out,
+                               int       ch)
+{
+    *(out->p++) = ch;
+    if (out->p - out->buffer >= BUFFER_SIZE)
+        flush_output (out);
+}
+
+
+/* source file path name */
+static char *pp_source_name = NULL;
+
+/* rarely triggered. post processed output usually doesn't
+ * contain comments (an exception would be gcc -E -C)
+ */
+static void post_process_comment_rest (PPInput  *inp,
+                                       PPOutput *out,
+                                       int       term /* must be '\n' or '/' */)
+{
+    int seenast = FALSE;
+    /* read up to \n or * followed by / */
+    while (1) {
+        int c = get_char (inp);
+        switch (c) {
+        case EOF:
+            return;       /* broken input */
+        case '*':
+            write_char (out, c);
+            seenast = TRUE;
+            break;
+        case '/':
+            write_char (out, c);
+            if (seenast && term == c)
+                return;
+            break;
+        case '\n':
+            write_char (out, c);
+            if (term == c)
+                return;
+            seenast = FALSE;
+            break;
+        default:
+            write_char (out, c);
+            seenast = FALSE;
+            break;
+        }
+    }
+}
+
+/* process the rest of a string, after the initial '\'' or '\"' has been read */
+static inline void post_process_string_rest (PPInput  *inp,
+                                             PPOutput *out,
+                                             int       term /* must be '\"' or '\'' */)
+{
+    int escape = FALSE;
+    while (1) {
+        int c = get_char (inp);
+        switch (c) {
+        case EOF:
+            return;	/* broken input */
+        case '\\':
+            write_char (out, c);
+            escape = !escape;
+            break;
+        case '\"':
+        case '\'':
+            write_char (out, c);
+            if (c == term && !escape)
+                return;
+            escape = FALSE;
+            break;
+        default:
+            write_char (out, c);
+            escape = FALSE;
+            break;
+        }
+    }
+}
+
+/* handle the case where a line starts with '#' which indicates
+ * preprocessor instructions. the ones to care about here are
+ * '# 3 "files/foo.c"', i.e. source file references. those are
+ * patched up to only contain absolute pathnames.
+ */
+static int post_process_hashcross (PPInput    *inp,
+                                   PPOutput   *out,
+                                   const char *pathprefix)
+{
+    int c;
+    /* check whether here comes a #-line directive, hash already parsed.
+     * we need to return the last char processed for our caller to update state.
+     */
+    
+    /* read up spaces */
+    c = get_char (inp);
+    while (c == ' ' || c == '\t') {
+        write_char (out, c);
+        c = get_char (inp);
+    }
+    /* read up digits */
+    while (c >= '0' && c <= '9') {
+        write_char (out, c);
+        c = get_char (inp);
+    }
+    /* read up spaces */
+    while (c == ' ' || c == '\t') {
+        write_char (out, c);
+        c = get_char (inp);
+    }
+    /* read up double quote */
+    if (c != '\"')
+        goto abort;
+    write_char (out, c);
+    c = get_char (inp);
+    /* here it comes: if c is a slash, we got an absolute
+     * pathname. otherwise we insert our prefix and handle
+     * the rest as an ordinary string.
+     */
+    if (c != '/') {
+        const char *p = pathprefix;
+        while (*p)
+            write_char (out, *p++);
+    }
+    unget_char (inp, c);
+    post_process_string_rest (inp, out, '\"');
+    return '\"';
+    
+    abort:
+    if (c != EOF)
+        write_char (out, c);
+    return c;
+}
+
+static void post_process (PPInput    *inp,
+                          PPOutput   *out,
+                          const char *pathprefix)
+{
+    int seennewline = TRUE;
+    int lastc, c = '\n';
+    while (1) {
+        lastc = c;
+        c = get_char (inp);
+        switch (c) {
+        case EOF:
+            return;
+	case '\n':
+            write_char (out, c);
+            seennewline = TRUE;
+            break;
+	case '#':
+            write_char (out, c);
+            if (seennewline) {
+                c = post_process_hashcross (inp, out, pathprefix);
+                if (c == EOF)
+                    return;
+	    }
+            seennewline = c == '\n';
+            break;
+	case ' ':
+	case '\t':
+            write_char (out, c);
+            /* preserve seennewline */
+            break;
+	case '*':
+            write_char (out, c);
+            if (lastc == '/') {
+                post_process_comment_rest (inp, out, '/');
+                c = '/';
+            }
+            seennewline = FALSE;
+            break;
+	case '\"': case '\'':
+            write_char (out, c);
+            post_process_string_rest (inp, out, c);
+            seennewline = FALSE;
+            break;
+	default:
+            write_char (out, c);
+            seennewline = FALSE;
+            break;
+	}
+    }
+}
+
+int dcc_post_process (const char *in_fname,
+                      char      **out_fname)
+{
+    char *p, *dirname;
+    PPOutput out = { -1, 0, { 0, } };
+    PPInput inp = { -1, 0, { 0, }, 0 };
+
+    *out_fname = dcc_make_tmpnam ("ppline", ".i");
+    
+    inp.fd = open (in_fname, O_RDONLY);
+    if (inp.fd < 0) {
+        rs_log_error ("opening input \"%s\" failed: %s", in_fname, strerror (errno));
+        return -1;
+    }
+
+    out.p = out.buffer;
+    out.fd = open (*out_fname, O_CREAT | O_TRUNC | O_WRONLY, 0644);
+    if (out.fd < 0) {
+        rs_log_error ("opening output \"%s\" failed: %s", *out_fname, strerror (errno));
+        close (inp.fd);
+        return -1;
+    }
+
+    if (!pp_source_name)
+        pp_source_name = strdup ("");
+    
+    /* figure slash terminated directory name */
+    if (pp_source_name[0] == '/') {
+        dirname = strdup (pp_source_name);
+    } else {
+        int dl, sl = strlen (pp_source_name);
+        char cdirbuf[8192];
+        char *cdir = getcwd (cdirbuf, sizeof (cdirbuf));
+        if (!cdir)
+            return -1;
+        dl = strlen (cdir);
+        dirname = malloc (dl + 1 + sl + 1);
+        strcpy (dirname, cdir);
+        dirname[dl++] = '/';
+        strcpy (dirname + dl, pp_source_name);
+    }
+    p = strrchr (dirname, '/');
+    if (p)
+        p[1] = 0;
+
+    post_process (&inp, &out, dirname);
+    flush_output (&out);
+    free (dirname);
+
+    close (inp.fd);
+    if (close (out.fd)) {
+        rs_log_error ("flushing output %s failed: %s\n", *out_fname, strerror (errno));
+        return -1;
+    }
+    return 0;
+}
+
+int dcc_post_process_set_source (const char *source_name)
+{
+    if (pp_source_name)
+        free (pp_source_name);
+    pp_source_name = source_name ? strdup (source_name) : NULL;
+    return 0;
+}
diff -ruN distcc.orig/src/postproc.h distcc/src/postproc.h
--- distcc.orig/src/postproc.h	1970-01-01 01:00:00.000000000 +0100
+++ distcc/src/postproc.h	2002-11-10 22:44:33.000000000 +0100
@@ -0,0 +1,28 @@
+/* -*- c-file-style: "java"; indent-tabs-mode: nil; fill-column: 78 -*-
+ * 
+ * distcc -- A simple distributed compiler system
+ * $Header: $
+ *
+ * Copyright (C) 2002 by Tim Janik <timj@gtk.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+/* postproc.c */
+int dcc_post_process_set_source (const char *source_name);
+int dcc_post_process            (const char *in_fname,
+                                 char      **out_fname);
+
