/* Finds out a relative path from first to second, i.e. goes as many .. * as needed up in first and then goes down using second */ char *diff_two_paths (const char *first, const char *second) { char *p, *q, *r, *s, *buf = 0; int i, j, prevlen = -1, currlen; char *my_first = NULL, *my_second = NULL; my_first = resolve_symlinks (first); if (my_first == NULL) return NULL; for (j = 0; j < 2; j++) { p = my_first; if (j) { my_second = resolve_symlinks (second); if (my_second == NULL) { g_free (my_first); return buf; } } q = my_second; for (;;) { r = strchr (p, PATH_SEP); s = strchr (q, PATH_SEP); if (!r || !s) break; *r = 0; *s = 0; if (strcmp (p, q)) { *r = PATH_SEP; *s = PATH_SEP; break; } else { *r = PATH_SEP; *s = PATH_SEP; } p = r + 1; q = s + 1; } p--; for (i = 0; (p = strchr (p + 1, PATH_SEP)) != NULL; i++); currlen = (i + 1) * 3 + strlen (q) + 1; if (j) { if (currlen < prevlen) g_free (buf); else { g_free (my_first); g_free (my_second); return buf; } } p = buf = g_malloc (currlen); prevlen = currlen; for (; i >= 0; i--, p += 3) strcpy (p, "../"); strcpy (p, q); } g_free (my_first); g_free (my_second); return buf; }
/* * find_my_exec -- find an absolute path to a valid executable * * argv0 is the name passed on the command line * retpath is the output area (must be of size MAXPGPATH) * Returns 0 if OK, -1 if error. * * The reason we have to work so hard to find an absolute path is that * on some platforms we can't do dynamic loading unless we know the * executable's location. Also, we need a full path not a relative * path because we will later change working directory. Finally, we want * a true path not a symlink location, so that we can locate other files * that are part of our installation relative to the executable. * * This function is not thread-safe because it calls validate_exec(), * which calls getgrgid(). This function should be used only in * non-threaded binaries, not in library routines. */ int find_my_exec(const char *argv0, char *retpath) { char cwd[MAXPGPATH], test_path[MAXPGPATH]; char *path; if (!getcwd(cwd, MAXPGPATH)) { log_error(_("could not identify current directory: %s"), strerror(errno)); return -1; } /* * If argv0 contains a separator, then PATH wasn't used. */ if (first_dir_separator(argv0) != NULL) { if (is_absolute_path(argv0)) StrNCpy(retpath, argv0, MAXPGPATH); else join_path_components(retpath, cwd, argv0); canonicalize_path(retpath); if (validate_exec(retpath) == 0) return resolve_symlinks(retpath); log_error(_("invalid binary \"%s\""), retpath); return -1; } #ifdef WIN32 /* Win32 checks the current directory first for names without slashes */ join_path_components(retpath, cwd, argv0); if (validate_exec(retpath) == 0) return resolve_symlinks(retpath); #endif /* * Since no explicit path was supplied, the user must have been relying on * PATH. We'll search the same PATH. */ if ((path = getenv("PATH")) && *path) { char *startp = NULL, *endp = NULL; do { if (!startp) startp = path; else startp = endp + 1; endp = first_path_separator(startp); if (!endp) endp = startp + strlen(startp); /* point to end */ StrNCpy(test_path, startp, Min(endp - startp + 1, MAXPGPATH)); if (is_absolute_path(test_path)) join_path_components(retpath, test_path, argv0); else { join_path_components(retpath, cwd, test_path); join_path_components(retpath, retpath, argv0); } canonicalize_path(retpath); switch (validate_exec(retpath)) { case 0: /* found ok */ return resolve_symlinks(retpath); case -1: /* wasn't even a candidate, keep looking */ break; case -2: /* found but disqualified */ log_error(_("could not read binary \"%s\""), retpath); break; } } while (*endp); } log_error(_("could not find a \"%s\" to execute"), argv0); return -1; }
char * diff_two_paths (const vfs_path_t * vpath1, const vfs_path_t * vpath2) { char *p, *q, *r, *s, *buf = NULL; int i, j, prevlen = -1, currlen; char *my_first = NULL, *my_second = NULL; my_first = resolve_symlinks (vpath1); if (my_first == NULL) goto ret; my_second = resolve_symlinks (vpath2); if (my_second == NULL) goto ret; for (j = 0; j < 2; j++) { p = my_first; q = my_second; while (TRUE) { r = strchr (p, PATH_SEP); s = strchr (q, PATH_SEP); if (r == NULL || s == NULL) break; *r = '\0'; *s = '\0'; if (strcmp (p, q) != 0) { *r = PATH_SEP; *s = PATH_SEP; break; } *r = PATH_SEP; *s = PATH_SEP; p = r + 1; q = s + 1; } p--; for (i = 0; (p = strchr (p + 1, PATH_SEP)) != NULL; i++) ; currlen = (i + 1) * 3 + strlen (q) + 1; if (j != 0) { if (currlen < prevlen) g_free (buf); else goto ret; } p = buf = g_malloc (currlen); prevlen = currlen; for (; i >= 0; i--, p += 3) strcpy (p, "../"); strcpy (p, q); } ret: g_free (my_first); g_free (my_second); return buf; }