diff options
author | Einar Floystad Dorum <einarfd@mailthief.com> | 2011-08-04 20:53:57 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2011-08-08 15:28:08 +0200 |
commit | edb03bd2245a27e2094a170d7a8bf9b89f1dee0f (patch) | |
tree | a428f5c7a5809d082131261c7be9e4ddd91195b3 | |
parent | 1204f43ea92dbc57a06a45b9293255104d940705 (diff) | |
download | libssh-edb03bd2245a27e2094a170d7a8bf9b89f1dee0f.tar.gz libssh-edb03bd2245a27e2094a170d7a8bf9b89f1dee0f.tar.xz libssh-edb03bd2245a27e2094a170d7a8bf9b89f1dee0f.zip |
Fixed ssh_scp_write so it works when doing recursive copy
There where two issues with ssh_scp_write:
1) It did not write a status message after the last write and OpenSSH
would then give up after the write finished.
2) OpenSSH would sometimes write a status message, after near ends write.
If scp_write didn't handle it, and subsequent status message. The remote
window would shrink to zero and ssh_channel_write would start returning 0.
Signed-off-by: Einar Floystad Dorum <einarfd@mailthief.com>
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit 01c4b713dc57d16612c3b61e1857fb982623dd12)
-rw-r--r-- | src/scp.c | 30 |
1 files changed, 19 insertions, 11 deletions
@@ -380,8 +380,8 @@ int ssh_scp_response(ssh_scp scp, char **response){ */ int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len){ int w; - //int r; - //uint8_t code; + int r; + uint8_t code; if(scp==NULL) return SSH_ERROR; if(scp->state != SSH_SCP_WRITE_WRITING){ @@ -400,19 +400,27 @@ int ssh_scp_write(ssh_scp scp, const void *buffer, size_t len){ //return=channel_get_exit_status(scp->channel); return SSH_ERROR; } - /* Check if we arrived at end of file */ - if(scp->processed == scp->filelen) { -/* r=channel_read(scp->channel,&code,1,0); - if(r==SSH_ERROR){ - scp->state=SSH_SCP_ERROR; + /* Far end sometimes send a status message, which we need to read + * and handle */ + r = ssh_channel_poll(scp->channel,0); + if(r > 0){ + r = ssh_channel_read(scp->channel, &code, 1, 0); + if(r == SSH_ERROR){ return SSH_ERROR; } - if(code != 0){ - ssh_set_error(scp->session,SSH_FATAL, "scp status code %ud not valid", code); - scp->state=SSH_SCP_ERROR; + if(code == 1 || code == 2){ + ssh_set_error(scp->session,SSH_REQUEST_DENIED, "SCP: Error: status code %i received", code); + return SSH_ERROR; + } + } + /* Check if we arrived at end of file */ + if(scp->processed == scp->filelen) { + code = 0; + w = ssh_channel_write(scp->channel, &code, 1); + if(w == SSH_ERROR){ + scp->state = SSH_SCP_ERROR; return SSH_ERROR; } -*/ scp->processed=scp->filelen=0; scp->state=SSH_SCP_WRITE_INITED; } |