diff -ruN distcc.orig/Makefile.in distcc/Makefile.in
--- distcc.orig/Makefile.in	2003-02-18 07:44:28.000000000 +0100
+++ distcc/Makefile.in	2003-02-20 20:07:20.000000000 +0100
@@ -149,7 +149,7 @@
 tarball_sig = $(tarball_bz2).asc
 distnews = $(PACKAGE_TARNAME)-$(VERSION).NEWS
 
-common_obj = src/trace.o src/util.o src/io.o src/exec.o src/arg.o	\
+common_obj = src/trace.o src/util.o src/io.o src/exec.o src/arg.o src/postproc.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/sendfile.o			\
 	src/timeval.o
@@ -169,7 +169,7 @@
 h_strip_obj = src/h_strip.o src/trace.o src/util.o src/arg.o src/filename.o src/strip.o
 h_parsemask_obj = src/h_parsemask.o $(common_obj) src/access.o
 
-SRC = src/arg.c src/bulk.c src/clinet.c src/cpp.c			\
+SRC = src/arg.c src/bulk.c src/clinet.c src/cpp.c	src/postproc.c		\
 	src/daemon.c src/distcc.c src/sendfile.c src/access.c		\
 	src/dopt.c src/dparent.c src/exec.c src/filename.c		\
 	src/h_argvtostr.c						\
@@ -182,7 +182,7 @@
 	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/setuid.c 
 
-HEADERS = src/access.h src/clinet.h src/cpp.h				\
+HEADERS = src/access.h src/clinet.h src/cpp.h	src/postproc.h			\
 	src/distcc.h src/exitcode.h src/hosts.h				\
 	src/io.h src/tempfile.h	 src/setuid.h				\
 	src/strip.h src/implicit.h					\
diff -ruN distcc.orig/src/distcc.c distcc/src/distcc.c
--- distcc.orig/src/distcc.c	2003-02-13 08:00:58.000000000 +0100
+++ distcc/src/distcc.c	2003-02-20 20:07:20.000000000 +0100
@@ -54,6 +54,7 @@
 #include "hosts.h"
 #include "bulk.h"
 #include "tempfile.h"
+#include "postproc.h"
 #include "strip.h"
 #include "implicit.h"
 #include "exec.h"
@@ -163,6 +164,7 @@
                         const char *cpp_fname)
 {
     long stime_usec, utime_usec;
+    char *pp_fname;
     int ret;
 
     if ((ret = dcc_x_req_header(net_fd))
@@ -193,7 +195,10 @@
         return EXIT_IO_ERROR;
     }
 
-    if ((ret = dcc_x_file_timed(net_fd, cpp_fname, "DOTI", NULL)))
+    if ((ret = dcc_post_process (cpp_fname, &pp_fname) != 0))
+        return ret;
+
+    if ((ret = dcc_x_file_timed(net_fd, pp_fname, "DOTI", NULL)))
         return ret;
 
     rs_trace("client finished sending request to server");
@@ -425,6 +430,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, xmit_lock_fd)) != 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	2003-02-20 20:07:43.000000000 +0100
@@ -0,0 +1,362 @@
+/* -*- 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"
+
+
+typedef unsigned char uchar;
+
+/* buffered input */
+#define BUFFER_SIZE    4000
+typedef struct {
+    int    fd;
+    uchar *bound;
+    uchar  buffer[BUFFER_SIZE + 1];
+    uchar *text;
+} PPInput;
+
+static inline int peek_char (PPInput *inp)
+{
+    if (inp->text < inp->bound)
+        return *inp->text;
+    else if (inp->fd >= 0) {
+        int count;
+        uchar *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,
+                        uchar    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;
+    uchar  *p;
+    uchar   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	2003-02-20 20:07:20.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);
+