* Portions Copyright (c) 1994, Regents of the University of California
  * Portions taken from FreeBSD.
  *
- * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.46 2004/08/01 06:19:23 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.47 2004/08/09 20:20:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
    /* store binary directory */
    strcpy(bin_path, backend_exec);
    *last_dir_separator(bin_path) = '\0';
+   canonicalize_path(bin_path);
 
    if (!share_path)
    {
 
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/port/exec.c,v 1.20 2004/08/09 03:12:38 momjian Exp $
+ *   $PostgreSQL: pgsql/src/port/exec.c,v 1.21 2004/08/09 20:20:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
    /* Trim off program name and keep just directory */ 
    *last_dir_separator(retpath) = '\0';
+   canonicalize_path(retpath);
+
+   /* Now append the other program's name */
    snprintf(retpath + strlen(retpath), MAXPGPATH - strlen(retpath),
             "/%s%s", target, EXE);
 
 
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/port/path.c,v 1.26 2004/08/01 06:56:39 momjian Exp $
+ *   $PostgreSQL: pgsql/src/port/path.c,v 1.27 2004/08/09 20:20:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #endif
 
    /*
-    *  Removing the trailing slash on a path means we never get
-    *  ugly double slashes.  Don't remove a leading slash, though.
-    *  Also, Win32 can't stat() a directory with a trailing slash.
+    * Removing the trailing slash on a path means we never get ugly double
+    * slashes.  Also, Win32 can't stat() a directory with a trailing slash.
+    * Don't remove a leading slash, though.
     */
    trim_trailing_separator(path);
+
+   /*
+    * Remove any trailing uses of "." or "..", too.
+    */
+   for (;;)
+   {
+       int     len = strlen(path);
+
+       if (len >= 2 && strcmp(path + len - 2, "/.") == 0)
+       {
+           trim_directory(path);
+           trim_trailing_separator(path);
+       }
+       else if (len >= 3 && strcmp(path + len - 3, "/..") == 0)
+       {
+           trim_directory(path);
+           trim_directory(path);
+           trim_trailing_separator(path);
+       }
+       else
+           break;
+   }
 }
 
 
 #ifdef WIN32
    /*
     *  Skip over network and drive specifiers for win32.
-    *  Set 'path' to point to the last character to keep.
+    *  Set 'path' to point to the last character we must keep.
     */
     if (strlen(path) >= 2)
     {