From 578e943afcd9c818f969502a94375b1a70548bf9 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sat, 23 Mar 2019 08:38:21 +0000 Subject: win32: share code to find root prefix of path Move unc_root_len() from ash to mingw32.c and use it in the new function root_len(), which can be used in make_directory(). This reduces changes to upstream code and saves a few bytes. --- include/mingw.h | 3 +++ libbb/make_directory.c | 25 ++----------------------- shell/ash.c | 30 ++---------------------------- win32/mingw.c | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 42 insertions(+), 51 deletions(-) diff --git a/include/mingw.h b/include/mingw.h index 36c2f6805..7c9423cad 100644 --- a/include/mingw.h +++ b/include/mingw.h @@ -522,3 +522,6 @@ ULONGLONG CompatGetTickCount64(void); ssize_t get_random_bytes(void *buf, ssize_t count); int enumerate_links(const char *file, char *name); void hide_console(void); + +int unc_root_len(const char *dir); +int root_len(const char *path); diff --git a/libbb/make_directory.c b/libbb/make_directory.c index 9af5552d5..e0fd486d8 100644 --- a/libbb/make_directory.c +++ b/libbb/make_directory.c @@ -59,29 +59,8 @@ int FAST_FUNC bb_make_directory(char *path, long mode, int flags) if (flags & FILEUTILS_RECUR) { /* Get the parent */ #if ENABLE_PLATFORM_MINGW32 - if (s == path && *s && s[1] == ':') { - /* skip drive letter */ - s += 2; - } - else if (s == path && s[0] == '/' && s[1] == '/' ) { - /* skip UNC server and share */ - int count = 0; - s += 2; - while (*s) { - if (*s == '/') { - do { - ++s; - } while (*s == '/'); - if (++count == 2) { - --s; - break; - } - } - else { - ++s; - } - } - } + if (s == path) + s += root_len(path); #endif /* Bypass leading non-'/'s and then subsequent '/'s */ while (*s) { diff --git a/shell/ash.c b/shell/ash.c index cd6196640..34ddc14f1 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -2860,34 +2860,6 @@ cdopt(void) return flags; } -#if ENABLE_PLATFORM_MINGW32 -#define is_path_sep(x) ((x) == '/' || (x) == '\\') -#define is_unc_path(x) (is_path_sep(x[0]) && is_path_sep(x[1])) -#define is_root(x) (is_path_sep(x[0]) && x[1] == '\0') - -/* Return the length of the root of a UNC path, i.e. the '//host/share' - * component, or 0 if the path doesn't look like that. */ -static int -unc_root_len(const char *dir) -{ - const char *s = dir + 2; - int len; - - if (!is_unc_path(dir)) - return 0; - len = strcspn(s, "/\\"); - if (len == 0) - return 0; - s += len + 1; - len = strcspn(s, "/\\"); - if (len == 0) - return 0; - s += len; - - return s - dir; -} -#endif - /* * Update curdir (the name of the current directory) in response to a * cd command. @@ -2896,6 +2868,8 @@ static const char * updatepwd(const char *dir) { #if ENABLE_PLATFORM_MINGW32 +# define is_path_sep(x) ((x) == '/' || (x) == '\\') +# define is_root(x) (is_path_sep(x[0]) && x[1] == '\0') /* * Due to Windows drive notion, getting pwd is a completely * different thing. Handle it in a separate routine diff --git a/win32/mingw.c b/win32/mingw.c index 0206f6dca..3ee1a2496 100644 --- a/win32/mingw.c +++ b/win32/mingw.c @@ -1609,3 +1609,38 @@ void hide_console(void) } } #endif + +#define is_path_sep(x) ((x) == '/' || (x) == '\\') +#define is_unc_path(x) (is_path_sep(x[0]) && is_path_sep(x[1])) + +/* Return the length of the root of a UNC path, i.e. the '//host/share' + * component, or 0 if the path doesn't look like that. */ +int unc_root_len(const char *dir) +{ + const char *s = dir + 2; + int len; + + if (!is_unc_path(dir)) + return 0; + len = strcspn(s, "/\\"); + if (len == 0) + return 0; + s += len + 1; + len = strcspn(s, "/\\"); + if (len == 0) + return 0; + s += len; + + return s - dir; +} + +/* Return the length of the root of a path, i.e. either the drive or + * UNC '//host/share', or 0 if the path doesn't look like that. */ +int root_len(const char *path) +{ + if (path == NULL) + return 0; + if (isalpha(*path) && path[1] == ':') + return 2; + return unc_root_len(path); +} -- cgit v1.2.3-55-g6feb