aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEinar Floystad Dorum <einarfd@mailthief.com>2011-08-04 20:53:57 +0200
committerAndreas Schneider <asn@cryptomilk.org>2011-08-08 15:28:08 +0200
commitedb03bd2245a27e2094a170d7a8bf9b89f1dee0f (patch)
treea428f5c7a5809d082131261c7be9e4ddd91195b3
parent1204f43ea92dbc57a06a45b9293255104d940705 (diff)
downloadlibssh-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.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/src/scp.c b/src/scp.c
index 53785843..a3483468 100644
--- a/src/scp.c
+++ b/src/scp.c
@@ -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;
}