From 5c5ca116dbe1c62b447eaeb22d4e59db44b9a1f5 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Thu, 24 Sep 2015 17:47:10 +0100 Subject: [PATCH] Centralise stripslashes() and make it OS-sensitive. I noticed that Unix PSCP was unwantedly renaming downloaded files which had a backslash in their names, because pscp.c's stripslashes() treated \ as a path component separator, since it hadn't been modified since PSCP ran on Windows only. It also turns out that pscp.c, psftp.c and winsftp.c all had a stripslashes(), and they didn't all have quite the same prototype. So now there's one in winsftp.c and one in uxsftp.c, with appropriate OS-dependent behaviour, and the ones in pscp.c and psftp.c are gone. --- pscp.c | 29 ----------------------------- psftp.c | 29 ----------------------------- psftp.h | 17 +++++++++++++++++ unix/uxsftp.c | 14 ++++++++++++++ windows/winsftp.c | 12 ++++++------ 5 files changed, 37 insertions(+), 64 deletions(-) diff --git a/pscp.c b/pscp.c index 1d4967e7..0b37def1 100644 --- a/pscp.c +++ b/pscp.c @@ -605,35 +605,6 @@ static char *colon(char *str) return (NULL); } -/* - * Return a pointer to the portion of str that comes after the last - * slash (or backslash or colon, if `local' is TRUE). - * - * This function has the annoying strstr() property of taking a const - * char * and returning a char *. You should treat it as if it was a - * pair of overloaded functions, one mapping mutable->mutable and the - * other const->const :-( - */ -static char *stripslashes(const char *str, int local) -{ - char *p; - - if (local) { - p = strchr(str, ':'); - if (p) str = p+1; - } - - p = strrchr(str, '/'); - if (p) str = p+1; - - if (local) { - p = strrchr(str, '\\'); - if (p) str = p+1; - } - - return (char *)str; -} - /* * Determine whether a string is entirely composed of dots. */ diff --git a/psftp.c b/psftp.c index 79362619..93a96a4e 100644 --- a/psftp.c +++ b/psftp.c @@ -169,35 +169,6 @@ char *canonify(const char *name) } } -/* - * Return a pointer to the portion of str that comes after the last - * slash (or backslash or colon, if `local' is TRUE). - * - * This function has the annoying strstr() property of taking a const - * char * and returning a char *. You should treat it as if it was a - * pair of overloaded functions, one mapping mutable->mutable and the - * other const->const :-( - */ -static char *stripslashes(const char *str, int local) -{ - char *p; - - if (local) { - p = strchr(str, ':'); - if (p) str = p+1; - } - - p = strrchr(str, '/'); - if (p) str = p+1; - - if (local) { - p = strrchr(str, '\\'); - if (p) str = p+1; - } - - return (char *)str; -} - /* * qsort comparison routine for fxp_name structures. Sorts by real * file name. diff --git a/psftp.h b/psftp.h index b3022d56..57a821ab 100644 --- a/psftp.h +++ b/psftp.h @@ -177,4 +177,21 @@ int create_directory(const char *name); */ char *dir_file_cat(const char *dir, const char *file); +/* + * Return a pointer to the portion of str that comes after the last + * path component separator. + * + * If 'local' is false, path component separators are taken to just be + * '/', on the assumption that we're discussing the path syntax on the + * server. But if 'local' is true, the separators are whatever the + * local OS will treat that way - so that includes '\' and ':' on + * Windows. + * + * This function has the annoying strstr() property of taking a const + * char * and returning a char *. You should treat it as if it was a + * pair of overloaded functions, one mapping mutable->mutable and the + * other const->const :-( + */ +char *stripslashes(const char *str, int local); + #endif /* PUTTY_PSFTP_H */ diff --git a/unix/uxsftp.c b/unix/uxsftp.c index 7039b69b..3ac1d2c3 100644 --- a/unix/uxsftp.c +++ b/unix/uxsftp.c @@ -413,6 +413,20 @@ void finish_wildcard_matching(WildcardMatcher *dir) { sfree(dir); } +char *stripslashes(const char *str, int local) +{ + char *p; + + /* + * On Unix, we do the same thing regardless of the 'local' + * parameter. + */ + p = strrchr(str, '/'); + if (p) str = p+1; + + return (char *)str; +} + int vet_filename(const char *name) { if (strchr(name, '/')) diff --git a/windows/winsftp.c b/windows/winsftp.c index fa052eeb..0776cba9 100644 --- a/windows/winsftp.c +++ b/windows/winsftp.c @@ -340,14 +340,14 @@ struct WildcardMatcher { char *srcpath; }; -/* - * Return a pointer to the portion of str that comes after the last - * slash (or backslash or colon, if `local' is TRUE). - */ -static char *stripslashes(char *str, int local) +char *stripslashes(const char *str, int local) { char *p; + /* + * On Windows, \ / : are all path component separators. + */ + if (local) { p = strchr(str, ':'); if (p) str = p+1; @@ -361,7 +361,7 @@ static char *stripslashes(char *str, int local) if (p) str = p+1; } - return str; + return (char *)str; } WildcardMatcher *begin_wildcard_matching(const char *name) -- 2.45.2