Allow relative paths as long as the hardcoded path matches the bin path
authorBruce Momjian
Tue, 25 May 2004 20:47:41 +0000 (20:47 +0000)
committerBruce Momjian
Tue, 25 May 2004 20:47:41 +0000 (20:47 +0000)
up to the last bin directory name.

src/port/path.c

index cc01962baac17735b27ea68bce0c0592a9a68c7b..fda684c45281c40838812fc8e8020e956b04ac8f 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/port/path.c,v 1.14 2004/05/25 18:18:29 momjian Exp $
+ *   $PostgreSQL: pgsql/src/port/path.c,v 1.15 2004/05/25 20:47:41 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -26,7 +26,7 @@
 #define    ISSEP(ch)   ((ch) == '/' || (ch) == '\\')
 #endif
 
-static bool relative_path(const char *path1, const char *path2);
+const static char *relative_path(const char *bin_path, const char *other_path);
 static void trim_directory(char *path);
 static void trim_trailing_separator(char *path);
 
@@ -37,6 +37,14 @@ static void trim_trailing_separator(char *path);
        (p)++; \
 }
 
+/* Macro creates a relative path */
+#define MAKE_RELATIVE \
+do { \
+       StrNCpy(path, my_exec_path, MAXPGPATH); \
+       trim_directory(path); \
+       trim_directory(path); \
+       snprintf(ret_path, MAXPGPATH, "%s/%s", path, p); \
+} while (0)
 
 /*
  * first_path_separator
@@ -114,14 +122,10 @@ void
 get_share_path(const char *my_exec_path, char *ret_path)
 {
    char path[MAXPGPATH];
+   const char *p;
    
-   if (relative_path(PGBINDIR, PGSHAREDIR))
-   {
-       StrNCpy(path, my_exec_path, MAXPGPATH);
-       trim_directory(path);   /* trim off binary */
-       trim_directory(path);   /* trim off /bin */
-       snprintf(ret_path, MAXPGPATH, "%s/share", path);
-   }
+   if ((p = relative_path(PGBINDIR, PGSHAREDIR)))
+       MAKE_RELATIVE;
    else
        StrNCpy(ret_path, PGSHAREDIR, MAXPGPATH);
 }
@@ -135,14 +139,10 @@ void
 get_etc_path(const char *my_exec_path, char *ret_path)
 {
    char path[MAXPGPATH];
+   const char *p;
    
-   if (relative_path(PGBINDIR, SYSCONFDIR))
-   {
-       StrNCpy(path, my_exec_path, MAXPGPATH);
-       trim_directory(path);
-       trim_directory(path);
-       snprintf(ret_path, MAXPGPATH, "%s/etc", path);
-   }
+   if ((p = relative_path(PGBINDIR, SYSCONFDIR)))
+       MAKE_RELATIVE;
    else
        StrNCpy(ret_path, SYSCONFDIR, MAXPGPATH);
 }
@@ -156,14 +156,10 @@ void
 get_include_path(const char *my_exec_path, char *ret_path)
 {
    char path[MAXPGPATH];
+   const char *p;
    
-   if (relative_path(PGBINDIR, INCLUDEDIR))
-   {
-       StrNCpy(path, my_exec_path, MAXPGPATH);
-       trim_directory(path);
-       trim_directory(path);
-       snprintf(ret_path, MAXPGPATH, "%s/include", path);
-   }
+   if ((p = relative_path(PGBINDIR, INCLUDEDIR)))
+       MAKE_RELATIVE;
    else
        StrNCpy(ret_path, INCLUDEDIR, MAXPGPATH);
 }
@@ -177,14 +173,10 @@ void
 get_pkginclude_path(const char *my_exec_path, char *ret_path)
 {
    char path[MAXPGPATH];
+   const char *p;
    
-   if (relative_path(PGBINDIR, PKGINCLUDEDIR))
-   {
-       StrNCpy(path, my_exec_path, MAXPGPATH);
-       trim_directory(path);
-       trim_directory(path);
-       snprintf(ret_path, MAXPGPATH, "%s/include", path);
-   }
+   if ((p = relative_path(PGBINDIR, PKGINCLUDEDIR)))
+       MAKE_RELATIVE;
    else
        StrNCpy(ret_path, PKGINCLUDEDIR, MAXPGPATH);
 }
@@ -200,14 +192,10 @@ void
 get_pkglib_path(const char *my_exec_path, char *ret_path)
 {
    char path[MAXPGPATH];
+   const char *p;
    
-   if (relative_path(PGBINDIR, PKGLIBDIR))
-   {
-       StrNCpy(path, my_exec_path, MAXPGPATH);
-       trim_directory(path);
-       trim_directory(path);
-       snprintf(ret_path, MAXPGPATH, "%s/lib", path);
-   }
+   if ((p = relative_path(PGBINDIR, PKGLIBDIR)))
+       MAKE_RELATIVE;
    else
        StrNCpy(ret_path, PKGLIBDIR, MAXPGPATH);
 }
@@ -223,14 +211,10 @@ void
 get_locale_path(const char *my_exec_path, char *ret_path)
 {
    char path[MAXPGPATH];
+   const char *p;
    
-   if (relative_path(PGBINDIR, LOCALEDIR))
-   {
-       StrNCpy(path, my_exec_path, MAXPGPATH);
-       trim_directory(path);
-       trim_directory(path);
-       snprintf(ret_path, MAXPGPATH, "%s/share/locale", path);
-   }
+   if ((p = relative_path(PGBINDIR, LOCALEDIR)))
+       MAKE_RELATIVE;
    else
        StrNCpy(ret_path, LOCALEDIR, MAXPGPATH);
 }
@@ -271,68 +255,71 @@ set_pglocale(const char *argv0, const char *app)
  *
  * Do the supplied paths differ only in their last component?
  */
-static bool
-relative_path(const char *path1, const char *path2)
+static const char *
+relative_path(const char *bin_path, const char *other_path)
 {
-
+   const char *other_sep = other_path;
+   
 #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 (isalpha(*bin_path) && bin_path[1] == ':' &&
+       (!isalpha(*other_path) || !other_path[1] == ':'))
+       return NULL;
+   if ((!isalpha(*bin_path) || !bin_path[1] == ':') &&
+       (isalpha(*other_path) && other_path[1] == ':'))
+       return NULL;
+   if (isalpha(*bin_path) && bin_path[1] == ':' &&
+       isalpha(*other_path) && other_path[1] == ':')
    {
-       if (toupper(*path1) != toupper(*path2))
-           return false;
-       path1 += 2;
-       path2 += 2;
+       if (toupper(*bin_path) != toupper(*other_path))
+           return NULL;
+       bin_path += 2;
+       other_path += 2;
+       other_sep = other_path + 1;     /* past separator */
    }
 #endif
 
    while (1)
    {
        /* Move past adjacent slashes like //, and trailing ones */
-       MOVE_TO_SEP_END(path1);
-       MOVE_TO_SEP_END(path2);
+       MOVE_TO_SEP_END(bin_path);
+       MOVE_TO_SEP_END(other_path);
 
        /* One of the paths is done? */
-       if (!*path1 || !*path2)
+       if (!*bin_path || !*other_path)
            break;
 
        /* Win32 filesystem is case insensitive */
+       if ((!ISSEP(*bin_path) || !ISSEP(*other_path)) &&
 #ifndef WIN32
-       if (*path1 != *path2)
+           *bin_path != *other_path)
 #else
-       if (toupper((unsigned char) *path1) != toupper((unsigned char)*path2))
+           toupper((unsigned char) *bin_path) != toupper((unsigned char)*other_path))
 #endif
-           break;
+               break;
 
-       path1++;
-       path2++;
+       if (ISSEP(*other_path))
+           other_sep = other_path + 1;     /* past separator */
+           
+       bin_path++;
+       other_path++;
    }
 
-   /* both done, identical? */
-   if (!*path1 && !*path2)
-       return false;
+   /* identical? */
+   if (!*bin_path && !*other_path)
+       return NULL;
 
    /* advance past directory name */   
-   while (!ISSEP(*path1) && *path1)
-       path1++;
-   while (!ISSEP(*path2) && *path2)
-       path2++;
+   while (!ISSEP(*bin_path) && *bin_path)
+       bin_path++;
 
-   MOVE_TO_SEP_END(path1);
-   MOVE_TO_SEP_END(path2);
+   MOVE_TO_SEP_END(bin_path);
 
-   /* Are both strings done? */
-   if (!*path1 && !*path2)
-       return true;
+   /* Is bin done? */
+   if (!*bin_path)
+       return other_path;
    else
-       return false;
+       return NULL;
 }
 
 
@@ -372,4 +359,3 @@ trim_trailing_separator(char *path)
        for (p--; p >= path && ISSEP(*p); p--)
            *p = '\0';
 }
-