diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c
index 2e3cb9ed2dc21e271e04a44ece6d18f8be44d29e..f46d40c5c481764bef71cf56edfe7045133adf22 100644
--- a/src/backend/utils/fmgr/dfmgr.c
+++ b/src/backend/utils/fmgr/dfmgr.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.51 2001/09/16 16:11:11 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.52 2001/10/04 19:13:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -24,7 +24,7 @@
 
 
 /*
- * List of dynamically loaded files.
+ * List of dynamically loaded files (kept in malloc'd memory).
  */
 
 typedef struct df_files
@@ -71,25 +71,25 @@ load_external_function(char *filename, char *funcname,
 	char	   *fullname;
 
 	fullname = expand_dynamic_library_name(filename);
-	if (fullname)
-		filename = fullname;
+	if (!fullname)
+		fullname = pstrdup(filename);
+	/* at this point fullname is always freshly palloc'd */
 
 	/*
 	 * Scan the list of loaded FILES to see if the file has been loaded.
 	 */
 	for (file_scanner = file_list;
 		 file_scanner != (DynamicFileList *) NULL &&
-		 strcmp(filename, file_scanner->filename) != 0;
+		 strcmp(fullname, file_scanner->filename) != 0;
 		 file_scanner = file_scanner->next)
 		;
 	if (file_scanner == (DynamicFileList *) NULL)
 	{
-
 		/*
 		 * Check for same files - different paths (ie, symlink or link)
 		 */
-		if (stat(filename, &stat_buf) == -1)
-			elog(ERROR, "stat failed on file '%s': %m", filename);
+		if (stat(fullname, &stat_buf) == -1)
+			elog(ERROR, "stat failed on file '%s': %m", fullname);
 
 		for (file_scanner = file_list;
 			 file_scanner != (DynamicFileList *) NULL &&
@@ -100,27 +100,26 @@ load_external_function(char *filename, char *funcname,
 
 	if (file_scanner == (DynamicFileList *) NULL)
 	{
-
 		/*
 		 * File not loaded yet.
 		 */
 		file_scanner = (DynamicFileList *)
-			malloc(sizeof(DynamicFileList) + strlen(filename));
+			malloc(sizeof(DynamicFileList) + strlen(fullname));
 		if (file_scanner == NULL)
 			elog(ERROR, "Out of memory in load_external_function");
 
 		MemSet((char *) file_scanner, 0, sizeof(DynamicFileList));
-		strcpy(file_scanner->filename, filename);
+		strcpy(file_scanner->filename, fullname);
 		file_scanner->device = stat_buf.st_dev;
 		file_scanner->inode = stat_buf.st_ino;
 		file_scanner->next = (DynamicFileList *) NULL;
 
-		file_scanner->handle = pg_dlopen(filename);
+		file_scanner->handle = pg_dlopen(fullname);
 		if (file_scanner->handle == (void *) NULL)
 		{
 			load_error = (char *) pg_dlerror();
 			free((char *) file_scanner);
-			elog(ERROR, "Load of file %s failed: %s", filename, load_error);
+			elog(ERROR, "Load of file %s failed: %s", fullname, load_error);
 		}
 
 		/* OK to link it into list */
@@ -135,13 +134,17 @@ load_external_function(char *filename, char *funcname,
 	 * If funcname is NULL, we only wanted to load the file.
 	 */
 	if (funcname == (char *) NULL)
+	{
+		pfree(fullname);
 		return (PGFunction) NULL;
+	}
 
 	retval = pg_dlsym(file_scanner->handle, funcname);
 
 	if (retval == (PGFunction) NULL && signalNotFound)
-		elog(ERROR, "Can't find function %s in file %s", funcname, filename);
+		elog(ERROR, "Can't find function %s in file %s", funcname, fullname);
 
+	pfree(fullname);
 	return retval;
 }
 
@@ -159,16 +162,17 @@ load_file(char *filename)
 	char	   *fullname;
 
 	fullname = expand_dynamic_library_name(filename);
-	if (fullname)
-		filename = fullname;
+	if (!fullname)
+		fullname = pstrdup(filename);
+	/* at this point fullname is always freshly palloc'd */
 
 	/*
 	 * We need to do stat() in order to determine whether this is the same
 	 * file as a previously loaded file; it's also handy so as to give a
 	 * good error message if bogus file name given.
 	 */
-	if (stat(filename, &stat_buf) == -1)
-		elog(ERROR, "LOAD: could not open file '%s': %m", filename);
+	if (stat(fullname, &stat_buf) == -1)
+		elog(ERROR, "LOAD: could not open file '%s': %m", fullname);
 
 	if (file_list != (DynamicFileList *) NULL)
 	{
@@ -197,7 +201,9 @@ load_file(char *filename)
 		}
 	}
 
-	load_external_function(filename, (char *) NULL, false);
+	load_external_function(fullname, (char *) NULL, false);
+
+	pfree(fullname);
 }
 
 
@@ -235,6 +241,8 @@ file_exists(const char *name)
  * find_in_dynamic_libpath below); if that works, return the fully
  * expanded file name.  If the previous failed, append DLSUFFIX and
  * try again.  If all fails, return NULL.
+ *
+ * A non-NULL result will always be freshly palloc'd.
  */
 static char *
 expand_dynamic_library_name(const char *name)
@@ -258,6 +266,7 @@ expand_dynamic_library_name(const char *name)
 		full = substitute_libpath_macro(name);
 		if (file_exists(full))
 			return full;
+		pfree(full);
 	}
 
 	new = palloc(strlen(name)+ strlen(DLSUFFIX) + 1);
@@ -274,15 +283,20 @@ expand_dynamic_library_name(const char *name)
 	else
 	{
 		full = substitute_libpath_macro(new);
+		pfree(new);
 		if (file_exists(full))
 			return full;
+		pfree(full);
 	}
 		
 	return NULL;
 }
 
 
-
+/*
+ * Substitute for any macros appearing in the given string.
+ * Result is always freshly palloc'd.
+ */
 static char *
 substitute_libpath_macro(const char * name)
 {
@@ -302,7 +316,7 @@ substitute_libpath_macro(const char * name)
 		elog(ERROR, "invalid macro name in dynamic library path");
 
 	if (name[macroname_len] == '\0')
-		return replacement;
+		return pstrdup(replacement);
 	else
 	{
 		char * new;
@@ -319,15 +333,14 @@ substitute_libpath_macro(const char * name)
 
 /*
  * Search for a file called 'basename' in the colon-separated search
- * path 'path'.  If the file is found, the full file name is returned
- * in palloced memory.  The the file is not found, return NULL.
+ * path Dynamic_library_path.  If the file is found, the full file name
+ * is returned in freshly palloc'd memory.  If the file is not found,
+ * return NULL.
  */
 static char *
 find_in_dynamic_libpath(const char * basename)
 {
 	const char *p;
-	char *full;
-	size_t len;
 	size_t baselen;
 
 	AssertArg(basename != NULL);
@@ -340,9 +353,12 @@ find_in_dynamic_libpath(const char * basename)
 
 	baselen = strlen(basename);
 
-	do {
+	for (;;)
+	{
+		size_t len;
 		char * piece;
-		const char * mangled;
+		char * mangled;
+		char *full;
 
 		len = strcspn(p, ":");
 
@@ -354,6 +370,7 @@ find_in_dynamic_libpath(const char * basename)
 		piece[len] = '\0';
 
 		mangled = substitute_libpath_macro(piece);
+		pfree(piece);
 
 		/* only absolute paths */
 		if (mangled[0] != '/')
@@ -361,6 +378,7 @@ find_in_dynamic_libpath(const char * basename)
 
 		full = palloc(strlen(mangled) + 1 + baselen + 1);
 		sprintf(full, "%s/%s", mangled, basename);
+		pfree(mangled);
 
 		if (DebugLvl > 1)
 			elog(DEBUG, "find_in_dynamic_libpath: trying %s", full);
@@ -368,13 +386,13 @@ find_in_dynamic_libpath(const char * basename)
 		if (file_exists(full))
 			return full;
 
-		pfree(piece);
 		pfree(full);
+
 		if (p[len] == '\0')
 			break;
 		else
 			p += len + 1;
-	} while(1);
+	}
 
 	return NULL;
 }