From 6301972e69e06a3988123563757701047e521309 Mon Sep 17 00:00:00 2001 From: quamrulmina Date: Thu, 31 Dec 2015 17:06:32 -0600 Subject: [PATCH] Add multiple ../../.. support in sftp-server for changing directories or get/put Before one could provide only one .. ; now it can be any numbers. cd ../../.. or get ../backup/myfile.c --- all these formations now work. --- openbsd-compat/realpath.c | 128 ++++++++++++++------------------------ 1 file changed, 46 insertions(+), 82 deletions(-) diff --git a/openbsd-compat/realpath.c b/openbsd-compat/realpath.c index 2e88230..434e67a 100644 --- a/openbsd-compat/realpath.c +++ b/openbsd-compat/realpath.c @@ -203,101 +203,65 @@ realpath(const char *path, char resolved[PATH_MAX]) #else -char *realpathWin32(const char *path, char resolved[PATH_MAX]) +void backslashconvert(char *str) { - size_t path_len; - unsigned int lastSlash; - char realpath[PATH_MAX]; - char * pch; + while (*str) { + if (*str == '/') + *str = '\\'; // convert forward slash to back slash + str++; + } - path_len = strlcpy(realpath, path+1, sizeof(realpath)); - - char * pchMac; - pchMac = strstr (realpath, "._"); - if (pchMac != NULL) - { - pchMac[0] = '\0'; - pchMac++; - pchMac++; - strcat(realpath, pchMac); - } - - pch = strrchr(realpath, '/'); - lastSlash = pch - realpath + 1; - if(path_len == lastSlash) - { - realpath[lastSlash-1] = '\0'; - } - - pch = strrchr(realpath,'.'); - if(pch != NULL) - { - if (realpath[pch-realpath - 1] == '.') - { - realpath[pch - realpath - 2] = '\0'; - pch = strrchr(realpath, '/'); - if(pch != NULL) - realpath[pch - realpath] = '\0'; - } - } - - /* - * Store terminating slash in 'X:/' on Windows. - */ - - if (realpath[1] == ':' && realpath[2] == 0) - { - realpath[2] = '/'; - realpath[3] = 0; - } - - resolved[0] = *path; // will be our first slash in /x:/users/test1 format - strncpy (resolved+1, realpath, sizeof(realpath)); - return resolved; } +// convert back slash to forward slash +void slashconvert(char *str) +{ + while (*str) { + if (*str == '\\') + *str = '/'; // convert back slash to forward slash + str++; + } +} + +char *realpathWin32(const char *path, char resolved[PATH_MAX]) +{ + char realpath[PATH_MAX]; + + strlcpy(resolved, path + 1, sizeof(realpath)); + backslashconvert(resolved); + PathCanonicalizeA(realpath, resolved); + slashconvert(realpath); + + /* + * Store terminating slash in 'X:/' on Windows. + */ + + if (realpath[1] == ':' && realpath[2] == 0) + { + realpath[2] = '/'; + realpath[3] = 0; + } + + resolved[0] = *path; // will be our first slash in /x:/users/test1 format + strncpy(resolved + 1, realpath, sizeof(realpath)); + return resolved; +} + +// like realpathWin32() but takes out the first slash so that windows systems can work on the actual file or directory char *realpathWin32i(const char *path, char resolved[PATH_MAX]) { - size_t path_len; - unsigned int lastSlash; char realpath[PATH_MAX]; - char * pch; if (path[0] != '/') { // absolute form x:/abc/def given, no first slash to take out - path_len = strlcpy(realpath, path, sizeof(realpath)); + strlcpy(resolved, path, sizeof(realpath)); } else - path_len = strlcpy(realpath, path + 1, sizeof(realpath)); + strlcpy(resolved, path + 1, sizeof(realpath)); - char * pchMac; - pchMac = strstr(realpath, "._"); - if (pchMac != NULL) - { - pchMac[0] = '\0'; - pchMac++; - pchMac++; - strcat(realpath, pchMac); - } - - pch = strrchr(realpath, '/'); - lastSlash = pch - realpath + 1; - if (path_len == lastSlash) - { - realpath[lastSlash - 1] = '\0'; - } - - pch = strrchr(realpath, '.'); - if (pch != NULL) - { - if (realpath[pch - realpath - 1] == '.') - { - realpath[pch - realpath - 2] = '\0'; - pch = strrchr(realpath, '/'); - if (pch != NULL) - realpath[pch - realpath] = '\0'; - } - } + backslashconvert(resolved); + PathCanonicalizeA(realpath, resolved); + slashconvert(realpath); /* * Store terminating slash in 'X:/' on Windows.