diff -r 6ba4c0f3c9d1 -r 850be6a6885c librazor/util.c --- a/librazor/util.c Tue Jul 05 09:40:01 2016 +0100 +++ b/librazor/util.c Fri Jun 08 18:02:49 2018 +0100 @@ -364,3 +364,68 @@ } #endif /* MSWIN_API */ + +/* + * Returns an absolute path (ie., not relative to the current directory on the + * default, or any other, disk). Note that the absolute path may still have + * "." or ".." path segments present (ie., this is not equivalent to realpath). + */ +char *razor_abspath(const char *path) +{ +#ifdef MSWIN_API + + int n; + wchar_t *wpath, *wabspath; + char *abspath; + + wpath = razor_utf8_to_utf16(path, -1); + + n = GetFullPathNameW(wpath, 0, NULL, NULL); + if (!n) { + free(wpath); + return NULL; + } + + wabspath = malloc(n * sizeof(sizeof(wchar_t))); + if (!GetFullPathNameW(wpath, n, wabspath, NULL)) { + free(wabspath); + free(wpath); + return NULL; + } + free(wpath); + + abspath = razor_utf16_to_utf8(wabspath, n - 1); + free(wabspath); + + return abspath; + +#else /* MSWIN_API */ + + int pathlen, len; + char *cwd, *abspath; + + if (*path == '/') + abspath = strdup(path); + else { + pathlen = strlen(path); + for (len = 32;; len *= 2) { + abspath = malloc(pathlen + 1 + len); + if (getcwd(abspath, len)) + break; + if (errno != ERANGE) { + free(abspath); + return NULL; + } + free(abspath); + } + len = strlen(abspath); + if (abspath[len - 1] != '/') + abspath[len++] = '/'; + memcpy(abspath + len, path, pathlen + 1); + abspath = realloc(abspath, len + pathlen + 1); + } + + return abspath; + +#endif +}