# HG changeset patch # User Alexander Simon # Date 1271932345 -14400 # Node ID 416ed23123ff574ca3b0496a036e29b7d6a9b2d7 # Parent 76ac8e2e7231233392e48315af6c3fd0462c8edc fixing BZ#173293 Smart Secure Copy is too slow - eliminate duplicated static functions - reduce number of getcwd diff --git a/cnd.remote/tools/rfs_controller.c b/cnd.remote/tools/rfs_controller.c --- a/cnd.remote/tools/rfs_controller.c +++ b/cnd.remote/tools/rfs_controller.c @@ -37,29 +37,16 @@ * Portions Copyrighted 2009 Sun Microsystems, Inc. */ -#include - #include #include #include -#include -#include #include -#include -#include -#include -#include #include -#include -#include -#include -#include #include #include #include -#include #include "rfs_protocol.h" #include "rfs_util.h" @@ -461,7 +448,7 @@ char file_start = *file; // save file start char *file = 0; // replace the '/' that separates file from dir by zero file++; - if (!realpath(dir, real_path)) { + if (!realpath_wrapper(dir, real_path)) { report_unresolved_path(dir); break; } @@ -474,7 +461,7 @@ *pfile_start = file_start; // restore file start char } } else { - if (!realpath(path, real_path)) { + if (!realpath_wrapper(path, real_path)) { report_unresolved_path(path); break; } diff --git a/cnd.remote/tools/rfs_filedata.c b/cnd.remote/tools/rfs_filedata.c --- a/cnd.remote/tools/rfs_filedata.c +++ b/cnd.remote/tools/rfs_filedata.c @@ -37,13 +37,6 @@ * Portions Copyrighted 2009 Sun Microsystems, Inc. */ -#include -#include -#include -#include -#include -#include -#include #include #include "rfs_filedata.h" diff --git a/cnd.remote/tools/rfs_preload.c b/cnd.remote/tools/rfs_preload.c --- a/cnd.remote/tools/rfs_preload.c +++ b/cnd.remote/tools/rfs_preload.c @@ -37,20 +37,9 @@ * Portions Copyrighted 2009 Sun Microsystems, Inc. */ -#include -#include #include -#include -#include -#include -#include -#include -#include -#include +#include -#include -#include -#include #include #include @@ -127,7 +116,7 @@ inside = 1; static __thread char real_path[PATH_MAX + 1]; - if ( realpath(path, real_path)) { + if ( realpath_wrapper(path, real_path)) { path = real_path; } else { trace_unresolved_path(path, "post_open"); @@ -186,7 +175,7 @@ inside = 1; static __thread char real_path[PATH_MAX + 1]; - if ( !realpath(path, real_path)) { + if ( !realpath_wrapper(path, real_path)) { trace_unresolved_path(path, "pre_open"); inside = 0; // We usually get here if file does not exist. diff --git a/cnd.remote/tools/rfs_preload_socks.c b/cnd.remote/tools/rfs_preload_socks.c --- a/cnd.remote/tools/rfs_preload_socks.c +++ b/cnd.remote/tools/rfs_preload_socks.c @@ -39,14 +39,6 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include #include #include diff --git a/cnd.remote/tools/rfs_protocol.c b/cnd.remote/tools/rfs_protocol.c --- a/cnd.remote/tools/rfs_protocol.c +++ b/cnd.remote/tools/rfs_protocol.c @@ -37,9 +37,6 @@ * Portions Copyrighted 2009 Sun Microsystems, Inc. */ -#include -#include -#include #include #include "rfs_util.h" @@ -49,6 +46,18 @@ // char kind; // char[2] 2-bytes size representation (high byte first) // char[] data 0-32K bytes null-terminated string + +__attribute__ ((visibility ("hidden"))) +const char* pkg_kind_to_string(enum kind kind) { + switch (kind) { + case pkg_null: return "pkg_null"; + case pkg_handshake: return "pkg_handshake"; + case pkg_request: return "pkg_request"; + case pkg_reply: return "pkg_reply"; + case pkg_written: return "pkg_written"; + default: return "pkg_unknown"; + } +} static int do_send(int sd, const unsigned char* buffer, int size) { int sent = 0; diff --git a/cnd.remote/tools/rfs_protocol.h b/cnd.remote/tools/rfs_protocol.h --- a/cnd.remote/tools/rfs_protocol.h +++ b/cnd.remote/tools/rfs_protocol.h @@ -55,16 +55,7 @@ pkg_reply = 'r' }; -static const char* pkg_kind_to_string(enum kind kind) { - switch (kind) { - case pkg_null: return "pkg_null"; - case pkg_handshake: return "pkg_handshake"; - case pkg_request: return "pkg_request"; - case pkg_reply: return "pkg_reply"; - case pkg_written: return "pkg_written"; - default: return "pkg_unknown"; - } -} +const char* pkg_kind_to_string(enum kind kind); /** * The below is the representation of a package in program. diff --git a/cnd.remote/tools/rfs_util.c b/cnd.remote/tools/rfs_util.c --- a/cnd.remote/tools/rfs_util.c +++ b/cnd.remote/tools/rfs_util.c @@ -113,3 +113,117 @@ } } } + +__attribute__ ((visibility ("hidden"))) +void init_trace_flag(const char* env_var) { + char *env = getenv(env_var); + trace_flag = env && *env == '1'; +} + +__attribute__ ((visibility ("hidden"))) +void report_unresolved_path(const char* path) { + char pwd[PATH_MAX + 1]; + getcwd(pwd, sizeof pwd); + report_error("Can not resolve path: %s cwd: %s\n", path, pwd); +} + + +__attribute__ ((visibility ("hidden"))) +void _trace_unresolved_path(const char* path, const char* action) { + if (trace_flag) { + char pwd[PATH_MAX + 1]; + getcwd(pwd, sizeof pwd); + trace("Can not resolve path on %s: %s pwd: %s\n", action, path, pwd); + } +} + +__attribute__ ((visibility ("hidden"))) +void _dbg_sleep(int time) { + if (trace_flag) { + trace("Sleeping %d sec...\n", time); + sleep(time); + trace("Awoke\n"); + } +} + +__attribute__((visibility("hidden"))) +char * realpath_wrapper(const char *file_name, char *resolved_name) { +#if 0 + return realpath(file_name, resolved_name); +#else + static char cwd[PATH_MAX]; + static int inited_cwd = 0; + int len; + + if (file_name == NULL || resolved_name == NULL) { + errno = EINVAL; + return (NULL); + } + + /* + * Call resolvepath() to resolve all the symlinks in file_name, + * eliminate embedded "." components, and collapse embedded ".." + * components. We may be left with leading ".." components. + */ + if ((len = resolvepath(file_name, resolved_name, PATH_MAX)) < 0) { + (void) strlcpy(resolved_name, file_name, PATH_MAX); + return (NULL); /* errno set by resolvepath() */ + } + + if (len >= PATH_MAX) /* "can't happen" */ + len = PATH_MAX - 1; + resolved_name[len] = '\0'; + + if (*resolved_name == '/') /* nothing more to do */ + return (resolved_name); + + /* + * Prepend the current working directory to the relative path. + * If the relative path is not empty (or "."), collapse all of the + * resulting embedded ".." components with trailing cwd components. + * We know that getcwd() returns a path name free of symlinks. + */ + if (!inited_cwd) { + if (getcwd(cwd, sizeof (cwd)) == NULL) { + (void) strlcpy(resolved_name, file_name, PATH_MAX); + return (NULL); /* errno set by getcwd() */ + } + inited_cwd = 1; + } + + if (len != 0 && strcmp(resolved_name, ".") != 0) { + char *relpath = resolved_name; + char *endcwd = cwd + strlen(cwd); + + /* + * Eliminate ".." components from the relative path + * left-to-right, components from cwd right-to-left. + */ + relpath[len++] = '/'; + while (len >= 3 && strncmp(relpath, "../", 3) == 0) { + relpath += 3; + len -= 3; + while (*--endcwd != '/') + continue; + } + if (len == 0) { + /* the relative path was all ".." components */ + *endcwd = '\0'; + } else { + /* there are non-null components on both sides */ + relpath[--len] = '\0'; + *endcwd++ = '/'; + if (endcwd + len >= cwd + PATH_MAX) { + (void) strlcpy(resolved_name, + file_name, PATH_MAX); + errno = ENAMETOOLONG; + return (NULL); + } + (void) strcpy(endcwd, relpath); + } + } + + (void) strcpy(resolved_name, cwd); + return (resolved_name); +#endif +} diff --git a/cnd.remote/tools/rfs_util.h b/cnd.remote/tools/rfs_util.h --- a/cnd.remote/tools/rfs_util.h +++ b/cnd.remote/tools/rfs_util.h @@ -53,19 +53,11 @@ extern bool trace_flag; -static void init_trace_flag(const char* env_var) { - char *env = getenv(env_var); - trace_flag = env && *env == '1'; -} +void init_trace_flag(const char* env_var); void report_error(const char *format, ...); -static void report_unresolved_path(const char* path) { - char pwd[PATH_MAX + 1]; - getcwd(pwd, sizeof pwd); - report_error("Can not resolve path: %s cwd: %s\n", path, pwd); -} - +void report_unresolved_path(const char* path); #define trace(...) if (trace_flag) { _trace(__VA_ARGS__); } void _trace(const char *format, ...); @@ -77,80 +69,10 @@ void _trace_shutdown(); #define trace_unresolved_path(path, action) if (trace_flag) { _trace_unresolved_path(path, action); } -static void _trace_unresolved_path(const char* path, const char* action) { - if (trace_flag) { - char pwd[PATH_MAX + 1]; - getcwd(pwd, sizeof pwd); - trace("Can not resolve path on %s: %s pwd: %s\n", action, path, pwd); - } -} +void _trace_unresolved_path(const char* path, const char* action); #define dbg_sleep(time) if (trace_flag) { _dbg_sleep(time); } -static void _dbg_sleep(int time) { - if (trace_flag) { - trace("Sleeping %d sec...\n", time); - sleep(time); - trace("Awoke\n"); - } -} +void _dbg_sleep(int time); -/* -static char *normalize_path(const char *path, char *buffer, int max_size) { - if (path == NULL || buffer == NULL) { - errno = EINVAL; - return NULL; - } - const char *src = path; // points to the current char in the source path - char *dst = buffer; // points to the next char in the destination path - char* limit = buffer + max_size; - if (*path != '/') { - if (getcwd(buffer, max_size)) { - int len = strlen(buffer); - dst = buffer + len; - if (dst + 1 >= limit) { - errno = ENAMETOOLONG; - return NULL; - } - *(dst++) = '/'; - } else { - return NULL; - } - } - while (*src) { - if (*src == '.' && (src == path || *(src-1) == '/')) { - if (*(src+1) == '.' && *(src+2) == '/') { - // it's "/../" - src += 3; - dst--; // point the last added one - if (*dst == '/' && dst > buffer) { - dst--; - } - while (dst > buffer && *dst != '/') { - dst--; - } - dst++; - continue; - } else if (*(src+1) == '/') { - // it's "/./" - skip '.' and '/' - src += 2; - continue; - } - } - if (dst + 1 >= limit) { - errno = ENAMETOOLONG; - return NULL; - } - *(dst++) = *(src++); - } - if (*dst == '/') { - dst--; - } - if (dst + 1 >= limit) { - errno = ENAMETOOLONG; - return NULL; - } - *dst = 0; - trace("normalize: %s -> %s\n", path, buffer); - return dst; -} -*/ +char * realpath_wrapper(const char *file_name, char *resolved_name); +