diff options
| author | Carlos Martín Nieto <cmn@dwim.me> | 2014-08-27 15:09:07 +0200 |
|---|---|---|
| committer | Carlos Martín Nieto <cmn@dwim.me> | 2014-08-27 15:09:07 +0200 |
| commit | 6a0d2b43ee4a32b2894d3c2b7c798c4eb4853534 (patch) | |
| tree | a7fedcd3bffe2d021e31491b4f1f020c1bea8f88 /src/transports/ssh.c | |
| parent | 8733993599d9d9a8fe1b042a1e18d6ecb9b0a0b2 (diff) | |
| parent | cb92467bc284b87c38cdf32f8803a528846d094b (diff) | |
| download | libgit2-6a0d2b43ee4a32b2894d3c2b7c798c4eb4853534.tar.gz | |
Merge remote-tracking branch 'upstream/master' into cmn/ssh-retry
Diffstat (limited to 'src/transports/ssh.c')
| -rw-r--r-- | src/transports/ssh.c | 75 |
1 files changed, 70 insertions, 5 deletions
diff --git a/src/transports/ssh.c b/src/transports/ssh.c index 6a7f67e99..fff81661a 100644 --- a/src/transports/ssh.c +++ b/src/transports/ssh.c @@ -5,6 +5,10 @@ * a Linking Exception. For full terms see the included COPYING file. */ +#ifdef GIT_SSH +#include <libssh2.h> +#endif + #include "git2.h" #include "buffer.h" #include "netops.h" @@ -13,8 +17,6 @@ #ifdef GIT_SSH -#include <libssh2.h> - #define OWNING_SUBTRANSPORT(s) ((ssh_subtransport *)(s)->parent.subtransport) static const char prefix_ssh[] = "ssh://"; @@ -35,6 +37,9 @@ typedef struct { git_smart_subtransport parent; transport_smart *owner; ssh_stream *current_stream; + git_cred *cred; + char *cmd_uploadpack; + char *cmd_receivepack; } ssh_subtransport; static int list_auth_methods(int *out, LIBSSH2_SESSION *session, const char *username); @@ -134,11 +139,22 @@ static int ssh_stream_write( size_t len) { ssh_stream *s = (ssh_stream *)stream; + size_t off = 0; + ssize_t ret = 0; if (!s->sent_command && send_command(s) < 0) return -1; - if (libssh2_channel_write(s->channel, buffer, len) < LIBSSH2_ERROR_NONE) { + do { + ret = libssh2_channel_write(s->channel, buffer + off, len - off); + if (ret < 0) + break; + + off += ret; + + } while (off < len); + + if (ret < 0) { ssh_error(s->session, "SSH could not write data"); return -1; } @@ -552,7 +568,9 @@ static int ssh_uploadpack_ls( const char *url, git_smart_subtransport_stream **stream) { - return _git_ssh_setup_conn(t, url, cmd_uploadpack, stream); + const char *cmd = t->cmd_uploadpack ? t->cmd_uploadpack : cmd_uploadpack; + + return _git_ssh_setup_conn(t, url, cmd, stream); } static int ssh_uploadpack( @@ -576,7 +594,9 @@ static int ssh_receivepack_ls( const char *url, git_smart_subtransport_stream **stream) { - if (_git_ssh_setup_conn(t, url, cmd_receivepack, stream) < 0) + const char *cmd = t->cmd_receivepack ? t->cmd_receivepack : cmd_receivepack; + + if (_git_ssh_setup_conn(t, url, cmd, stream) < 0) return -1; return 0; @@ -641,6 +661,8 @@ static void _ssh_free(git_smart_subtransport *subtransport) assert(!t->current_stream); + git__free(t->cmd_uploadpack); + git__free(t->cmd_receivepack); git__free(t); } @@ -720,3 +742,46 @@ int git_smart_subtransport_ssh( return -1; #endif } + +int git_transport_ssh_with_paths(git_transport **out, git_remote *owner, void *payload) +{ +#ifdef GIT_SSH + git_strarray *paths = (git_strarray *) payload; + git_transport *transport; + transport_smart *smart; + ssh_subtransport *t; + int error; + git_smart_subtransport_definition ssh_definition = { + git_smart_subtransport_ssh, + 0, /* no RPC */ + }; + + if (paths->count != 2) { + giterr_set(GITERR_SSH, "invalid ssh paths, must be two strings"); + return GIT_EINVALIDSPEC; + } + + if ((error = git_transport_smart(&transport, owner, &ssh_definition)) < 0) + return error; + + smart = (transport_smart *) transport; + t = (ssh_subtransport *) smart->wrapped; + + t->cmd_uploadpack = git__strdup(paths->strings[0]); + GITERR_CHECK_ALLOC(t->cmd_uploadpack); + t->cmd_receivepack = git__strdup(paths->strings[1]); + GITERR_CHECK_ALLOC(t->cmd_receivepack); + + *out = transport; + return 0; +#else + GIT_UNUSED(owner); + GIT_UNUSED(payload); + + assert(out); + *out = NULL; + + giterr_set(GITERR_INVALID, "Cannot create SSH transport. Library was built without SSH support"); + return -1; +#endif +} |
