diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 1e558d5a6393ce092976881ec1035fda31c0d7d4..c37cb259df2fe8584711d334e38e2c7e50338ce5 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.387 2004/05/14 17:04:44 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.388 2004/05/17 14:35:29 momjian Exp $
  *
  * NOTES
  *
@@ -697,6 +697,8 @@ PostmasterMain(int argc, char *argv[])
 		ereport(FATAL,
 				(errmsg("%s: could not locate my own executable path",
 						progname)));
+	if (strlen(pkglib_path) == 0)
+		get_pkglib_path(my_exec_path, pkglib_path);
 
 #ifdef EXEC_BACKEND
 	if (find_other_exec(argv[0], "postgres", PG_VERSIONSTR, postgres_exec_path) < 0)
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 72750bfa623ac3f181e2870fea3caa2fd7c25c74..f06340a54e4fc28b34b785c0a5f5e5f3f03a8a37 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.406 2004/05/14 17:04:45 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.407 2004/05/17 14:35:31 momjian Exp $
  *
  * NOTES
  *	  this is the "main" module of the postgres backend and
@@ -2652,6 +2652,9 @@ PostgresMain(int argc, char *argv[], const char *username)
 			ereport(FATAL,
 					(errmsg("%s: could not locate postgres executable",
 							argv[0])));
+		if (strlen(pkglib_path) == 0)
+			get_pkglib_path(my_exec_path, pkglib_path);
+			
 		/*
 		 * Validate we have been given a reasonable-looking DataDir (if
 		 * under postmaster, assume postmaster did this already).
diff --git a/src/backend/utils/fmgr/Makefile b/src/backend/utils/fmgr/Makefile
index 000b17a21d5f507c210ef03298627c935726dc30..37b6d03e23f543bac655041b38e837ca0d5bf820 100644
--- a/src/backend/utils/fmgr/Makefile
+++ b/src/backend/utils/fmgr/Makefile
@@ -4,7 +4,7 @@
 #    Makefile for utils/fmgr
 #
 # IDENTIFICATION
-#    $PostgreSQL: pgsql/src/backend/utils/fmgr/Makefile,v 1.15 2003/12/23 21:56:20 tgl Exp $
+#    $PostgreSQL: pgsql/src/backend/utils/fmgr/Makefile,v 1.16 2004/05/17 14:35:31 momjian Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -14,7 +14,7 @@ include $(top_builddir)/src/Makefile.global
 
 OBJS = dfmgr.o fmgr.o funcapi.o
 
-override CPPFLAGS += -DPKGLIBDIR=\"$(pkglibdir)\" -DDLSUFFIX=\"$(DLSUFFIX)\"
+override CPPFLAGS += -DDLSUFFIX=\"$(DLSUFFIX)\"
 
 
 all: SUBSYS.o
diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c
index 60d982b9458a692199810f1da04513a413f4bab7..3aeadfa20e2d25d25f48ba46e2d4171d8d16669c 100644
--- a/src/backend/utils/fmgr/dfmgr.c
+++ b/src/backend/utils/fmgr/dfmgr.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.71 2004/03/09 05:06:45 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.72 2004/05/17 14:35:31 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -270,12 +270,6 @@ file_exists(const char *name)
 #error "DLSUFFIX must be defined to compile this file."
 #endif
 
-/* Example format: "/usr/local/pgsql/lib" */
-#ifndef PKGLIBDIR
-#error "PKGLIBDIR needs to be defined to compile this file."
-#endif
-
-
 /*
  * If name contains a slash, check if the file exists, if so return
  * the name.  Else (no slash) try to expand using search path (see
@@ -341,62 +335,29 @@ expand_dynamic_library_name(const char *name)
 static char *
 substitute_libpath_macro(const char *name)
 {
-	size_t		macroname_len;
-	char	   *replacement = NULL;
-#ifdef WIN32
-	char		basename[MAXPGPATH];
-#endif
-
+	const char *sep_ptr;
+	char	   *ret;
+	
 	AssertArg(name != NULL);
 
 	if (name[0] != '$')
 		return pstrdup(name);
 
-#ifndef WIN32
-	macroname_len = strcspn(name + 1, "/") + 1;
-#else
-	macroname_len = strcspn(name + 1, "/\\") + 1;
-#endif
-
-	if (strncmp(name, "$libdir", macroname_len) == 0)
-#ifndef WIN32
-		replacement = PKGLIBDIR;
-#else
-	{
-		char *p;
-		if (GetModuleFileName(NULL,basename,MAXPGPATH) == 0)
-			ereport(FATAL,
-					(errmsg("GetModuleFileName failed (%i)",(int)GetLastError())));
-
-		canonicalize_path(basename);
-		if ((p = last_path_separator(basename)) == NULL)
-			ereport(FATAL,
-					(errmsg("unexpected failure in determining PKGLIBDIR (%s)",basename)));
-		else
-			*p = '\0';
-
-		strcat(basename,"/../lib");
-		replacement = basename;
-	}
-#endif
-	else
+	if ((sep_ptr = first_path_separator(name)) == NULL)
+		sep_ptr = name + strlen(name);
+		
+	if (strlen("$libdir") != sep_ptr - name ||
+		strncmp(name, "$libdir", strlen("$libdir")) != 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_NAME),
 				 errmsg("invalid macro name in dynamic library path")));
 
-	if (name[macroname_len] == '\0')
-		return pstrdup(replacement);
-	else
-	{
-		char	   *new;
+	ret = palloc(strlen(pkglib_path) + strlen(sep_ptr) + 1);
 
-		new = palloc(strlen(replacement) + (strlen(name) - macroname_len) + 1);
+	strcpy(ret, pkglib_path);
+	strcat(ret, sep_ptr);
 
-		strcpy(new, replacement);
-		strcat(new, name + macroname_len);
-
-		return new;
-	}
+	return ret;
 }
 
 
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
index 356d45e62e4dc26419122e67766decb70b4b120a..d94130a1b0aad6ca1e70ec8b6164f9a127d83648 100644
--- a/src/backend/utils/init/globals.c
+++ b/src/backend/utils/init/globals.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.85 2004/05/13 22:45:03 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.86 2004/05/17 14:35:32 momjian Exp $
  *
  * NOTES
  *	  Globals used all over the place should be declared here and not
@@ -46,6 +46,7 @@ char	   *DataDir = NULL;
 char		OutputFileName[MAXPGPATH];
 
 char		my_exec_path[MAXPGPATH];	/* full path to postgres executable */
+char		pkglib_path[MAXPGPATH];	/* full path to lib directory */
 
 BackendId	MyBackendId;
 
diff --git a/src/bin/initdb/Makefile b/src/bin/initdb/Makefile
index d709f6076678cb990b5ab019a501cce8750637c6..3fcdccfa4a32550a456b382701cf1bc87cf37bca 100644
--- a/src/bin/initdb/Makefile
+++ b/src/bin/initdb/Makefile
@@ -5,7 +5,7 @@
 # Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
 # Portions Copyright (c) 1994, Regents of the University of California
 #
-# $PostgreSQL: pgsql/src/bin/initdb/Makefile,v 1.37 2004/05/11 21:57:14 momjian Exp $
+# $PostgreSQL: pgsql/src/bin/initdb/Makefile,v 1.38 2004/05/17 14:35:33 momjian Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -13,7 +13,7 @@ subdir = src/bin/initdb
 top_builddir = ../../..
 include $(top_builddir)/src/Makefile.global
 
-override CPPFLAGS := -DPGDATADIR=\"$(datadir)\" -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS)
+override CPPFLAGS := -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS)
 
 OBJS=	initdb.o \
 	$(filter exec.o, $(LIBOBJS))
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 7b9e2d5b3b848a1684d787183035108d979aa007..5aae743f0f584e0eeb1ff50c80300d35191b3d43 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -39,7 +39,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  * Portions taken from FreeBSD.
  *
- * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.30 2004/05/17 13:17:29 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.31 2004/05/17 14:35:33 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -69,11 +69,8 @@ int			optreset;
 
 /*
  * these values are passed in by makefile defines
- *
- * Note that "datadir" is not the directory we're going to initialize,
- * it's merely how Autoconf names PREFIX/share.
  */
-char	   *datadir = PGDATADIR;
+char		*share_path = NULL;
 
 /* values to be obtained from arguments */
 char	   *pg_data = "";
@@ -129,7 +126,7 @@ static const char *backend_options = "-F -O -c search_path=pg_catalog -c exit_on
 
 
 /* path to 'initdb' binary directory */
-char	   bindir[MAXPGPATH];
+char	   bin_path[MAXPGPATH];
 char	   backend_exec[MAXPGPATH];
 
 static void *xmalloc(size_t size);
@@ -730,8 +727,8 @@ mkdatadir(char *subdir)
 static void
 set_input(char **dest, char *filename)
 {
-	*dest = xmalloc(strlen(datadir) + strlen(filename) + 2);
-	sprintf(*dest, "%s/%s", datadir, filename);
+	*dest = xmalloc(strlen(share_path) + strlen(filename) + 2);
+	sprintf(*dest, "%s/%s", share_path, filename);
 }
 
 /*
@@ -1849,7 +1846,7 @@ main(int argc, char *argv[])
 				printf(_("Running in noclean mode.  Mistakes will not be cleaned up.\n"));
 				break;
 			case 'L':
-				datadir = xstrdup(optarg);
+				share_path = xstrdup(optarg);
 				break;
 			case 1:
 				locale = xstrdup(optarg);
@@ -1951,9 +1948,15 @@ main(int argc, char *argv[])
 	}
 
 	/* store binary directory */
-	strcpy(bindir, backend_exec);
-	*last_path_separator(bindir) = '\0';
-	
+	strcpy(bin_path, backend_exec);
+	*last_path_separator(bin_path) = '\0';
+
+	if (!share_path)
+	{
+		share_path = xmalloc(MAXPGPATH);
+		get_share_path(backend_exec, share_path);
+	}
+
 	if ((short_version = get_short_version()) == NULL)
 	{
 		fprintf(stderr, _("%s: could not determine valid short version string\n"), progname);
@@ -1983,13 +1986,13 @@ main(int argc, char *argv[])
 	{
 		fprintf(stderr,
 				"VERSION=%s\n"
-				"PGDATA=%s\ndatadir=%s\nPGPATH=%s\n"
+				"PGDATA=%s\nshare_path=%s\nPGPATH=%s\n"
 				"ENCODING=%s\nENCODINGID=%s\n"
 				"POSTGRES_SUPERUSERNAME=%s\nPOSTGRES_BKI=%s\n"
 				"POSTGRES_DESCR=%s\nPOSTGRESQL_CONF_SAMPLE=%s\n"
 				"PG_HBA_SAMPLE=%s\nPG_IDENT_SAMPLE=%s\n",
 				PG_VERSION,
-				pg_data, datadir, bindir,
+				pg_data, share_path, bin_path,
 				encoding, encodingid,
 				username, bki_file,
 				desc_file, conf_file,
@@ -2182,8 +2185,8 @@ main(int argc, char *argv[])
 		   "    %s%s%s/postmaster -D %s%s%s\n"
 		   "or\n"
 		   "    %s%s%s/pg_ctl -D %s%s%s -l logfile start\n\n"),
-		 QUOTE_PATH, bindir, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH,
-		QUOTE_PATH, bindir, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH);
+		 QUOTE_PATH, bin_path, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH,
+		QUOTE_PATH, bin_path, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH);
 
 	return 0;
 }
diff --git a/src/bin/psql/Makefile b/src/bin/psql/Makefile
index d6af0c6b1405c6b50c84e41508e3ceef50ba21be..44a66b03783e1d2abad958be495e98592f0e4267 100644
--- a/src/bin/psql/Makefile
+++ b/src/bin/psql/Makefile
@@ -5,7 +5,7 @@
 # Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
 # Portions Copyright (c) 1994, Regents of the University of California
 #
-# $PostgreSQL: pgsql/src/bin/psql/Makefile,v 1.43 2004/04/26 17:40:48 momjian Exp $
+# $PostgreSQL: pgsql/src/bin/psql/Makefile,v 1.44 2004/05/17 14:35:33 momjian Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -15,11 +15,12 @@ include $(top_builddir)/src/Makefile.global
 
 REFDOCDIR= $(top_srcdir)/doc/src/sgml/ref
 
-override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) -DFRONTEND -DSYSCONFDIR='"$(sysconfdir)"'
+override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) -DFRONTEND
 
 OBJS=	command.o common.o help.o input.o stringutils.o mainloop.o copy.o \
 	startup.o prompt.o variables.o large_obj.o print.o describe.o \
-	psqlscan.o tab-complete.o mbprint.o
+	psqlscan.o tab-complete.o mbprint.o \
+	$(filter exec.o, $(LIBOBJS))
 
 FLEXFLAGS = -Cfe
 
@@ -29,6 +30,9 @@ all: submake-libpq submake-libpgport psql
 psql: $(OBJS) $(libpq_builddir)/libpq.a
 	$(CC) $(CFLAGS) $(OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@$(X)
 
+exec.c: % : $(top_srcdir)/src/port/%
+	rm -f $@ && $(LN_S) $< .
+
 help.o: $(srcdir)/sql_help.h
 
 ifdef PERL
@@ -60,7 +64,7 @@ uninstall:
 
 # psqlscan.c is in the distribution tarball, so is not cleaned here
 clean distclean:
-	rm -f psql$(X) $(OBJS)
+	rm -f psql$(X) $(OBJS) exec.c
 
 maintainer-clean: distclean
 	rm -f $(srcdir)/sql_help.h $(srcdir)/psqlscan.c
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 4f4e059ee940ccbd139823d8d52dbae0971d8600..908b8dec8026e401ac2a5c439d7606a7aa1571f7 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2003, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/startup.c,v 1.92 2004/05/02 04:25:45 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/startup.c,v 1.93 2004/05/17 14:35:33 momjian Exp $
  */
 #include "postgres_fe.h"
 
@@ -74,7 +74,7 @@ struct adhoc_opts
 
 static void parse_psql_options(int argc, char *argv[],
 				   struct adhoc_opts * options);
-static void process_psqlrc(void);
+static void process_psqlrc(char *argv0);
 static void process_psqlrc_file(char *filename);
 static void showVersion(void);
 
@@ -239,7 +239,7 @@ main(int argc, char *argv[])
 	if (options.action == ACT_FILE && strcmp(options.action_string, "-") != 0)
 	{
 		if (!options.no_psqlrc)
-			process_psqlrc();
+			process_psqlrc(argv[0]);
 
 		successResult = process_file(options.action_string);
 	}
@@ -305,7 +305,7 @@ main(int argc, char *argv[])
 		SetVariable(pset.vars, "PROMPT3", DEFAULT_PROMPT3);
 
 		if (!options.no_psqlrc)
-			process_psqlrc();
+			process_psqlrc(argv[0]);
 		if (!pset.notty)
 			initializeInput(options.no_readline ? 0 : 1);
 		if (options.action_string)		/* -f - was used */
@@ -567,22 +567,24 @@ parse_psql_options(int argc, char *argv[], struct adhoc_opts * options)
 
 }
 
-#ifndef SYSCONFDIR
-#error "You must compile this file with SYSCONFDIR defined."
-#endif
-
 
 /*
  * Load .psqlrc file, if found.
  */
 static void
-process_psqlrc(void)
+process_psqlrc(char *argv0)
 {
-	char	   *globalFile = SYSCONFDIR "/" SYSPSQLRC;
 	char	   *home;
 	char	   *psqlrc;
+	char	   global_file[MAXPGPATH];
+	char	   my_exec_path[MAXPGPATH];
+	char	   etc_path[MAXPGPATH];
+
+	find_my_exec(argv0, my_exec_path);
+	get_etc_path(my_exec_path, etc_path);
 
-	process_psqlrc_file(globalFile);
+	snprintf(global_file, MAXPGPATH, "%s/%s", etc_path, SYSPSQLRC);
+	process_psqlrc_file(global_file);
 
 	if ((home = getenv("HOME")) != NULL)
 	{
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
index 09f2cf2aa2480422d8bc71e3166c82df23ed2830..a97caf0fac2f71d628f66eb1aee97f0e1769a3ca 100644
--- a/src/include/miscadmin.h
+++ b/src/include/miscadmin.h
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.158 2004/05/13 22:45:04 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.159 2004/05/17 14:35:33 momjian Exp $
  *
  * NOTES
  *	  some of the information in this file should be moved to
@@ -143,6 +143,7 @@ extern long MyCancelKey;
 
 extern char OutputFileName[];
 extern char my_exec_path[];
+extern char pkglib_path[];
 
 /*
  * done in storage/backendid.h for now.
diff --git a/src/include/port.h b/src/include/port.h
index ca184bd98c9577de9b1db4239899760a8846d9e3..ea64dd617900ccc219f0bb8fa36285719801246f 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/port.h,v 1.31 2004/05/14 17:04:47 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/port.h,v 1.32 2004/05/17 14:35:34 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -26,12 +26,17 @@ extern char *first_path_separator(const char *filename);
 extern char *last_path_separator(const char *filename);
 extern void canonicalize_path(char *path);
 extern const char *get_progname(const char *argv0);
+extern void get_share_path(const char *my_exec_path, char *ret_path);
+extern void get_etc_path(const char *my_exec_path, char *ret_path);
+extern void get_include_path(const char *my_exec_path, char *ret_path);
+extern void get_pkginclude_path(const char *my_exec_path, char *ret_path);
+extern void get_pkglib_path(const char *my_exec_path, char *ret_path);
+
 
 /* Portable way to find binaries */
 extern int find_my_exec(const char *argv0, char *full_path);
 extern int find_other_exec(const char *argv0, char const *target,
 						   const char *versionstr, char *retpath);
-
 #if defined(__CYGWIN__) || defined(WIN32)
 #define EXE ".exe"
 #define DEVNULL "nul"
@@ -180,13 +185,6 @@ extern int pqGethostbyname(const char *name,
 				struct hostent **result,
 				int *herrno);
 
-/* $PATH (or %PATH%) path separator */
-#ifdef WIN32
-#define PATHSEP ';'
-#else
-#define PATHSEP ':'
-#endif
-
 /* FIXME: [win32] Placeholder win32 replacements, to allow continued development */
 #ifdef WIN32
 #define fsync(a)	_commit(a)
diff --git a/src/interfaces/ecpg/preproc/Makefile b/src/interfaces/ecpg/preproc/Makefile
index d57fffb78812931a94b281cd2fb53a48a6ecc991..51f5e4c9f1fc14a8396fd7103dccc1adbc3f6f90 100644
--- a/src/interfaces/ecpg/preproc/Makefile
+++ b/src/interfaces/ecpg/preproc/Makefile
@@ -1,4 +1,4 @@
-# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.103 2004/04/30 04:14:06 momjian Exp $
+# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.104 2004/05/17 14:35:34 momjian Exp $
 
 subdir = src/interfaces/ecpg/preproc
 top_builddir = ../../../..
@@ -11,8 +11,6 @@ PATCHLEVEL=0
 override CPPFLAGS := -I$(srcdir)/../include -I$(srcdir) $(CPPFLAGS) \
 	-DMAJOR_VERSION=$(MAJOR_VERSION) \
 	-DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL) \
-	-DINCLUDEDIR=\"$(includedir)\" \
-	-DPKGINCLUDEDIR=\"$(pkgincludedir)\" \
 	-DFRONTEND
 
 ifeq ($(GCC), yes)
@@ -20,15 +18,18 @@ override CFLAGS += -Wno-error
 endif
 override CFLAGS += $(PTHREAD_CFLAGS)
 
-OBJS=preproc.o type.o ecpg.o ecpg_keywords.o output.o\
-    keywords.o c_keywords.o ../ecpglib/typename.o descriptor.o variable.o
-
+OBJS=	preproc.o type.o ecpg.o ecpg_keywords.o output.o\
+	keywords.o c_keywords.o ../ecpglib/typename.o descriptor.o variable.o \
+	$(filter exec.o, $(LIBOBJS))
 
 all: submake-libpgport ecpg
 
 ecpg: $(OBJS)
 	$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) $(PTHREAD_LIBS) -o $@$(X)
 
+exec.c: % : $(top_srcdir)/src/port/%
+	rm -f $@ && $(LN_S) $< .
+
 # pgc is compiled as part of preproc
 preproc.o: $(srcdir)/pgc.c
 
@@ -65,7 +66,7 @@ uninstall:
 	rm -f $(DESTDIR)$(bindir)/ecpg$(X)
 
 clean distclean:
-	rm -f *.o ecpg$(X)
+	rm -f *.o ecpg$(X) exec.c
 # garbage from partial builds
 	@rm -f y.tab.c y.tab.h
 # garbage from development
diff --git a/src/interfaces/ecpg/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c
index 40edf0ecc434534ced783ff612fcbb76c0a1e95c..fb2f14a20f077b9e64503be8f799099845bfe3a8 100644
--- a/src/interfaces/ecpg/preproc/ecpg.c
+++ b/src/interfaces/ecpg/preproc/ecpg.c
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.86 2004/05/12 13:38:48 momjian Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.87 2004/05/17 14:35:34 momjian Exp $ */
 
 /* New main for ecpg, the PostgreSQL embedded SQL precompiler. */
 /* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */
@@ -120,7 +120,9 @@ main(int argc, char *const argv[])
 				out_option = 0;
 	struct _include_path *ip;
 	const char *progname;
-
+	char	   my_exec_path[MAXPGPATH];
+	char	   include_path[MAXPGPATH];
+	
 	progname = get_progname(argv[0]);
 
 	if (argc > 1)
@@ -138,6 +140,8 @@ main(int argc, char *const argv[])
 		}
 	}
 
+	find_my_exec(argv[0], my_exec_path);
+
 	while ((c = getopt(argc, argv, "vcio:I:tD:dC:r:h")) != -1)
 	{
 		switch (c)
@@ -175,12 +179,18 @@ main(int argc, char *const argv[])
 			case 'C':
 				if (strncmp(optarg, "INFORMIX", strlen("INFORMIX")) == 0)
 				{
+					char	   pkginclude_path[MAXPGPATH];
+					char	   informix_path[MAXPGPATH];
+				
 					compat = (strcmp(optarg, "INFORMIX") == 0) ? ECPG_COMPAT_INFORMIX : ECPG_COMPAT_INFORMIX_SE;
 					/* system_includes = true; */
 					add_preprocessor_define("dec_t=decimal");
 					add_preprocessor_define("intrvl_t=interval");
 					add_preprocessor_define("dtime_t=timestamp");
-					add_include_path(PKGINCLUDEDIR "/informix/esql");
+
+					get_pkginclude_path(my_exec_path, pkginclude_path);
+					snprintf(informix_path, MAXPGPATH, "%s/informix/esql", pkginclude_path);
+					add_include_path(informix_path);
 				}
 				else
 				{
@@ -216,7 +226,8 @@ main(int argc, char *const argv[])
 
 	add_include_path(".");
 	add_include_path("/usr/local/include");
-	add_include_path(INCLUDEDIR);
+	get_include_path(my_exec_path, include_path);
+	add_include_path(include_path);
 	add_include_path("/usr/include");
 
 	if (verbose)
diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile
index 619646b405bfaf81e02d53b3412f6a1d13d5db11..3537981abca12fcfcda8d771e3a43631d3535065 100644
--- a/src/interfaces/libpq/Makefile
+++ b/src/interfaces/libpq/Makefile
@@ -4,7 +4,7 @@
 #
 # Copyright (c) 1994, Regents of the University of California
 #
-# $PostgreSQL: pgsql/src/interfaces/libpq/Makefile,v 1.105 2004/05/10 23:09:04 momjian Exp $
+# $PostgreSQL: pgsql/src/interfaces/libpq/Makefile,v 1.106 2004/05/17 14:35:34 momjian Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -19,7 +19,13 @@ SO_MAJOR_VERSION= 3
 SO_MINOR_VERSION= 2
 
 override CPPFLAGS := -I$(srcdir) $(CPPFLAGS) $(PTHREAD_CFLAGS) -DFRONTEND -DSYSCONFDIR='"$(sysconfdir)"'
-override CFLAGS += $(PTHREAD_CFLAGS)
+override CFLAGS += $(PTHREAD_CFLAGS) \
+		     -DPGBINDIR=\"$(bindir)\" \
+		     -DPGDATADIR=\"$(datadir)\" \
+		     -DSYSCONFDIR='"$(sysconfdir)"' \
+		     -DINCLUDEDIR=\"$(includedir)\" \
+		     -DPKGINCLUDEDIR=\"$(pkgincludedir)\" \
+		     -DPKGLIBDIR=\"$(pkglibdir)\"
 
 OBJS=	fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \
 	fe-protocol2.o fe-protocol3.o pqexpbuffer.o pqsignal.o fe-secure.o \
diff --git a/src/port/Makefile b/src/port/Makefile
index 356a0b45856a8db3b9e3ded83f5f13b90e95358d..fc84d57260a3eed03c456735be53d202f16449db 100644
--- a/src/port/Makefile
+++ b/src/port/Makefile
@@ -7,7 +7,7 @@
 # with broken/missing library files.
 
 # IDENTIFICATION
-#    $PostgreSQL: pgsql/src/port/Makefile,v 1.10 2004/04/23 18:15:55 momjian Exp $
+#    $PostgreSQL: pgsql/src/port/Makefile,v 1.11 2004/05/17 14:35:34 momjian Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -15,6 +15,13 @@ subdir = src/port
 top_builddir = ../..
 include $(top_builddir)/src/Makefile.global
 
+override CPPFLAGS += -DPGBINDIR=\"$(bindir)\" \
+		     -DPGDATADIR=\"$(datadir)\" \
+		     -DSYSCONFDIR='"$(sysconfdir)"' \
+		     -DINCLUDEDIR=\"$(includedir)\" \
+		     -DPKGINCLUDEDIR=\"$(pkgincludedir)\" \
+		     -DPKGLIBDIR=\"$(pkglibdir)\"
+
 ifdef LIBOBJS
 all: libpgport.a
 endif
diff --git a/src/port/exec.c b/src/port/exec.c
index 102208255198eb1250602c88d5dbe9d44b74ae04..02defe9a8ddcfa5bc066392a299e677a967e3d9d 100644
--- a/src/port/exec.c
+++ b/src/port/exec.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/port/exec.c,v 1.5 2004/05/14 17:04:48 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/port/exec.c,v 1.6 2004/05/17 14:35:34 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -25,6 +25,13 @@
 
 #include "miscadmin.h"
 
+/* $PATH (or %PATH%) path separator */
+#ifdef WIN32
+#define PATHSEP ';'
+#else
+#define PATHSEP ':'
+#endif
+
 #ifndef S_IRUSR					/* XXX [TRH] should be in a header */
 #define S_IRUSR		 S_IREAD
 #define S_IWUSR		 S_IWRITE
@@ -265,6 +272,16 @@ find_my_exec(const char *argv0, char *full_path)
 
 	log_debug("could not find a \"%s\" to execute", argv0);
 	return -1;
+
+#if 0
+	/*
+	 *	Win32 has a native way to find the executable name, but the above
+	 *	method works too.
+	 */
+	if (GetModuleFileName(NULL,basename,MAXPGPATH) == 0)
+		ereport(FATAL,
+				(errmsg("GetModuleFileName failed (%i)",(int)GetLastError())));
+#endif
 }
 
 
diff --git a/src/port/path.c b/src/port/path.c
index 5d102a90c2489fbca24e84c5b5abac7b504a85d4..f5fccca278741b8dd1e58da150ec8285d3612af5 100644
--- a/src/port/path.c
+++ b/src/port/path.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/port/path.c,v 1.7 2004/05/12 13:38:49 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/port/path.c,v 1.8 2004/05/17 14:35:34 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -16,6 +16,24 @@
 #include "c.h"
 #include <ctype.h>
 
+#ifndef WIN32
+#define	ISSEP(ch)	((ch) == '/')
+#else
+#define	ISSEP(ch)	((ch) == '/' || (ch) == '\\')
+#endif
+
+static bool relative_path(const char *path1, const char *path2);
+static void trim_directory(char *path);
+static void trim_trailing_separator(char *path);
+
+/* Move to last of consecutive separators or to null byte */
+#define MOVE_TO_SEP_END(p) \
+{ \
+	while (ISSEP((p)[0]) && (ISSEP((p)[1]) || !(p)[1])) \
+		(p)++; \
+}
+
+
 /*
  *	is_absolute_path
  */
@@ -40,22 +58,12 @@ is_absolute_path(const char *filename)
 char *
 first_path_separator(const char *filename)
 {
-#ifndef WIN32
-	return strchr(filename, '/');
-#else
-	char	   *slash,
-			   *bslash;
-
-	/* How should we handle "C:file.c"? */
-	slash = strchr(filename, '/');
-	bslash = strchr(filename, '\\');
-	if (slash == NULL)
-		return bslash;
-	else if (bslash == NULL)
-		return slash;
-	else
-		return (slash < bslash) ? slash : bslash;
-#endif
+	char	   *p;
+
+	for (p = (char *)filename; *p; p++)
+		if (ISSEP(*p))
+			return p;
+	return NULL;
 }
 
 
@@ -65,22 +73,12 @@ first_path_separator(const char *filename)
 char *
 last_path_separator(const char *filename)
 {
-#ifndef WIN32
-	return strrchr(filename, '/');
-#else
-	char	   *slash,
-			   *bslash;
-
-	/* How should we handle "C:file.c"? */
-	slash = strrchr(filename, '/');
-	bslash = strrchr(filename, '\\');
-	if (slash == NULL)
-		return bslash;
-	else if (bslash == NULL)
-		return slash;
-	else
-		return (slash > bslash) ? slash : bslash;
-#endif
+	char	   *p, *ret = NULL;
+
+	for (p = (char *)filename; *p; p++)
+		if (ISSEP(*p))
+			ret = p;
+	return ret;
 }
 
 
@@ -96,17 +94,17 @@ last_path_separator(const char *filename)
 void
 canonicalize_path(char *path)
 {
+#ifdef WIN32
 	char	   *p;
 
 	for (p = path; *p; p++)
 	{
-#ifdef WIN32
 		if (*p == '\\')
 			*p = '/';
-#endif
 	}
-	if (p > path+1 && *--p == '/')
-		*p = '\0';
+#endif
+
+	trim_trailing_separator(path);
 }
 
 
@@ -122,3 +120,209 @@ get_progname(const char *argv0)
 		return last_path_separator(argv0) + 1;
 }
 
+
+/*
+ *	get_share_path
+ */
+void
+get_share_path(const char *my_exec_path, char *ret_path)
+{
+	if (relative_path(PGBINDIR, PGDATADIR))
+	{
+		/* Autoconf calls our /share 'datadir' */
+		StrNCpy(ret_path, my_exec_path, MAXPGPATH);
+		trim_directory(ret_path);	/* trim off binary */
+		trim_directory(ret_path);	/* trim off /bin */
+		strcat(ret_path, "/share");	/* add /share */
+	}
+	else
+		StrNCpy(ret_path, PGDATADIR, MAXPGPATH);
+}
+
+
+
+/*
+ *	get_etc_path
+ */
+void
+get_etc_path(const char *my_exec_path, char *ret_path)
+{
+	if (relative_path(PGBINDIR, SYSCONFDIR))
+	{
+		StrNCpy(ret_path, my_exec_path, MAXPGPATH);
+		trim_directory(ret_path);
+		trim_directory(ret_path);
+		strcat(ret_path, "/etc");
+	}
+	else
+		StrNCpy(ret_path, SYSCONFDIR, MAXPGPATH);
+}
+
+
+
+/*
+ *	get_include_path
+ */
+void
+get_include_path(const char *my_exec_path, char *ret_path)
+{
+	if (relative_path(PGBINDIR, INCLUDEDIR))
+	{
+		StrNCpy(ret_path, my_exec_path, MAXPGPATH);
+		trim_directory(ret_path);
+		trim_directory(ret_path);
+		strcat(ret_path, "/include");
+	}
+	else
+		StrNCpy(ret_path, INCLUDEDIR, MAXPGPATH);
+}
+
+
+
+/*
+ *	get_pkginclude_path
+ */
+void
+get_pkginclude_path(const char *my_exec_path, char *ret_path)
+{
+	if (relative_path(PGBINDIR, PKGINCLUDEDIR))
+	{
+		StrNCpy(ret_path, my_exec_path, MAXPGPATH);
+		trim_directory(ret_path);
+		trim_directory(ret_path);
+		strcat(ret_path, "/include");
+	}
+	else
+		StrNCpy(ret_path, PKGINCLUDEDIR, MAXPGPATH);
+}
+
+
+
+/*
+ *	get_pkglib_path
+ *
+ *	Return library path, either relative to /bin or hardcoded
+ */
+void
+get_pkglib_path(const char *my_exec_path, char *ret_path)
+{
+	if (relative_path(PGBINDIR, PKGLIBDIR))
+	{
+		StrNCpy(ret_path, my_exec_path, MAXPGPATH);
+		trim_directory(ret_path);
+		trim_directory(ret_path);
+		strcat(ret_path, "/lib");
+	}
+	else
+		StrNCpy(ret_path, PKGLIBDIR, MAXPGPATH);
+}
+
+
+
+/*
+ *	relative_path
+ *
+ *	Do the supplied paths differ only in their last component?
+ */
+static bool
+relative_path(const char *path1, const char *path2)
+{
+
+#ifdef WIN32
+	/* Driver letters match? */
+	if (isalpha(*path1) && path1[1] == ':' &&
+		(!isalpha(*path2) || !path2[1] == ':'))
+		return false;
+	if ((!isalpha(*path1) || !path1[1] == ':') &&
+		(isalpha(*path2) && path2[1] == ':')
+		return false;
+	if (isalpha(*path1) && path1[1] == ':' &&
+		isalpha(*path2) && path2[1] == ':')
+	{
+		if (toupper(*path1) != toupper(*path2))
+			return false;
+		path1 += 2;
+		path2 += 2;
+	}
+#endif
+
+	while (1)
+	{
+		/* Move past adjacent slashes like //, and trailing ones */
+		MOVE_TO_SEP_END(path1);
+		MOVE_TO_SEP_END(path2);
+
+		/* One of the paths is done? */
+		if (!*path1 || !*path2)
+			break;
+
+		/* Win32 filesystem is case insensitive */
+#ifndef WIN32
+		if (*path1 != *path2)
+#else
+		if (toupper((unsigned char) *path1) != toupper((unsigned char)*path2))
+#endif
+			break;
+
+		path1++;
+		path2++;
+	}
+
+	/* both done, identical? */
+	if (!*path1 && !*path2)
+		return false;
+
+	/* advance past directory name */	
+	while (!ISSEP(*path1) && *path1)
+		path1++;
+	while (!ISSEP(*path2) && *path2)
+		path2++;
+
+	MOVE_TO_SEP_END(path1);
+	MOVE_TO_SEP_END(path2);
+
+	/* Are both strings done? */
+	if (!*path1 && !*path2)
+		return true;
+	else
+		return false;
+}
+
+
+/*
+ *	trim_directory
+ *
+ *	Trim trailing directory from path
+ */
+static void
+trim_directory(char *path)
+{
+	char *p;
+	
+	if (path[0] == '\0')
+		return;
+
+	for (p = path + strlen(path) - 1; ISSEP(*p) && p > path; p--)
+		;
+	for (; !ISSEP(*p) && p > path; p--)
+		;
+	*p = '\0';
+	return;
+}
+
+
+
+/*
+ *	trim_trailing_separator
+ */
+static void
+trim_trailing_separator(char *path)
+{
+	char *p = path + strlen(path);
+	
+	/* trim off trailing slashes */
+	if (p > path)
+		for (p--; p >= path && ISSEP(*p); p--)
+			*p = '\0';
+}
+
diff --git a/src/timezone/Makefile b/src/timezone/Makefile
index ee3e15a120407b942c2c4aeeaeaf442c30c26834..bb3d8725439da9fa0f1b17832e28e38b0d153720 100644
--- a/src/timezone/Makefile
+++ b/src/timezone/Makefile
@@ -4,7 +4,7 @@
 #    Makefile for the timezone library
 
 # IDENTIFICATION
-#    $PostgreSQL: pgsql/src/timezone/Makefile,v 1.7 2004/04/30 20:23:28 momjian Exp $
+#    $PostgreSQL: pgsql/src/timezone/Makefile,v 1.8 2004/05/17 14:35:34 momjian Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -12,8 +12,6 @@ subdir = src/timezone
 top_builddir = ../..
 include $(top_builddir)/src/Makefile.global
 
-override CPPFLAGS += -DPGDATADIR=\"$(datadir)\"
-
 OBJS= asctime.o difftime.o localtime.o pgtz.o
 ZICOBJS= zic.o ialloc.o scheck.o localtime.o asctime.o pgtz.o
 
diff --git a/src/timezone/pgtz.c b/src/timezone/pgtz.c
index 5cea4535cc47d382d2bf361baa72d94a8b804412..3cb3849434d42b8c4743112b2565c138bf5ca9d2 100644
--- a/src/timezone/pgtz.c
+++ b/src/timezone/pgtz.c
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.7 2004/05/02 03:12:12 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/timezone/pgtz.c,v 1.8 2004/05/17 14:35:34 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -25,22 +25,7 @@ pg_TZDIR(void)
 	if (done_tzdir)
 		return tzdir;
 
-#ifndef WIN32
-	StrNCpy(tzdir, PGDATADIR, MAXPGPATH);
-#else
-	if (GetModuleFileName(NULL, tzdir, MAXPGPATH) == 0)
-		return NULL;
-#endif
-
-	canonicalize_path(tzdir);
-#ifdef WIN32
-	/* trim off binary name, then go up a directory */
-	if ((p = last_path_separator(tzdir)) == NULL)
-		return NULL;
-	else
-		*p = '\0';
-	strcat(tzdir, "/../share");
-#endif
+	get_share_dir(my_exec_path, tzdir);
 	strcat(tzdir, "/timezone");
 
 	done_tzdir = 1;