diff options
author | Etienne Samson <samson.etienne@gmail.com> | 2016-05-13 02:20:36 +0200 |
---|---|---|
committer | Carlos MartÃn Nieto <cmn@dwim.me> | 2017-03-12 15:16:29 +0100 |
commit | 559f8d57ac0e28991987dff5128cd6c72c8e5d58 (patch) | |
tree | 5c881ee89e7c6155957f948632c2f61e8a462d8b | |
parent | 53454be87f9b14f5df79a5917ce3986590438748 (diff) | |
download | libgit2-559f8d57ac0e28991987dff5128cd6c72c8e5d58.tar.gz |
Weak-link against libssh2 and load it at runtime
-rw-r--r-- | CMakeLists.txt | 7 | ||||
-rw-r--r-- | src/transports/ssh.c | 43 |
2 files changed, 49 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index d5bf21f54..98c3c8c24 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -362,7 +362,12 @@ IF (LIBSSH2_FOUND) LINK_DIRECTORIES(${LIBSSH2_LIBRARY_DIRS}) LIST(APPEND LIBGIT2_PC_LIBS ${LIBSSH2_LDFLAGS}) #SET(LIBGIT2_PC_LIBS "${LIBGIT2_PC_LIBS} ${LIBSSH2_LDFLAGS}") - SET(SSH_LIBRARIES ${LIBSSH2_LIBRARIES}) + IF (WIN32) + SET(WEAK_LINK "TODO") + ELSE() + SET(WEAK_LINK -Wl,-weak-l) + ENDIF() + SET(SSH_LIBRARIES ${WEAK_LINK} ${LIBSSH2_LIBRARIES}) CHECK_LIBRARY_EXISTS("${LIBSSH2_LIBRARIES}" libssh2_userauth_publickey_frommemory "${LIBSSH2_LIBRARY_DIRS}" HAVE_LIBSSH2_MEMORY_CREDENTIALS) IF (HAVE_LIBSSH2_MEMORY_CREDENTIALS) diff --git a/src/transports/ssh.c b/src/transports/ssh.c index 44d02e522..bdf7dc798 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -8,6 +8,7 @@ #ifdef GIT_SSH #include <libssh2.h> #endif +#include <dlfcn.h> #include "git2.h" #include "buffer.h" @@ -15,6 +16,7 @@ #include "smart.h" #include "cred.h" #include "socket_stream.h" +#include "global.h" #include "ssh.h" #ifdef GIT_SSH @@ -817,6 +819,8 @@ static int list_auth_methods(int *out, LIBSSH2_SESSION *session, const char *use } #endif +static void *libssh2_handle = NULL; + int git_smart_subtransport_ssh( git_smart_subtransport **out, git_transport *owner, void *param) { @@ -827,6 +831,13 @@ int git_smart_subtransport_ssh( GIT_UNUSED(param); + if (libssh2_handle == NULL) { + *out = NULL; + + giterr_set(GITERR_INVALID, "Cannot create SSH transport. SSH support unavailable"); + return -1; + } + t = git__calloc(sizeof(ssh_subtransport), 1); GITERR_CHECK_ALLOC(t); @@ -863,6 +874,15 @@ int git_transport_ssh_with_paths(git_transport **out, git_remote *owner, void *p NULL, }; + assert(out); + + if (libssh2_handle == NULL) { + *out = NULL; + + giterr_set(GITERR_INVALID, "Cannot create SSH transport. SSH support unavailable"); + return -1; + } + if (paths->count != 2) { giterr_set(GITERR_SSH, "invalid ssh paths, must be two strings"); return GIT_EINVALIDSPEC; @@ -893,9 +913,24 @@ int git_transport_ssh_with_paths(git_transport **out, git_remote *owner, void *p #endif } +void git_transport_ssh_global_shutdown(void); + int git_transport_ssh_global_init(void) { #ifdef GIT_SSH +#ifdef GIT_WIN32 + const char *(*libssh2_version)(int) = NULL; +#else + libssh2_handle = dlopen("libssh2.dylib", RTLD_LAZY); + const char *(*libssh2_version)(int) = dlsym(libssh2_handle, "libssh2_version"); +#endif + + // Check that libssh2's version is sufficient for us + if (!libssh2_version || !libssh2_version(LIBSSH2_VERSION_NUM)) { + return 0; + } + + git__on_shutdown(git_transport_ssh_global_shutdown); libssh2_init(0); return 0; @@ -904,6 +939,14 @@ int git_transport_ssh_global_init(void) /* Nothing to initialize */ return 0; +#endif +} +void git_transport_ssh_global_shutdown(void) +{ +#ifdef WIN + +#else + dlclose(libssh2_handle); #endif } |