aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2008-12-15 23:04:51 +0000
committerDaniel Stenberg <daniel@haxx.se>2008-12-15 23:04:51 +0000
commit008b848dccafc18df79e0de9163b0bfab4f5392c (patch)
tree8666390aeaf91c42de94b6247b31ec00c86d8271
parent79b7575fd894c5eba4d7a24a22b9202bb58803cd (diff)
- libssh2_sftp_last_error() was wrongly used at some places in libcurl which
made libcurl sometimes not properly abort problematic SFTP transfers.
-rw-r--r--CHANGES4
-rw-r--r--RELEASE-NOTES1
-rw-r--r--lib/ssh.c44
3 files changed, 37 insertions, 12 deletions
diff --git a/CHANGES b/CHANGES
index eaee3cb54..ba21b3f46 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,10 @@
Changelog
+Daniel Stenberg (16 Dec 2008)
+- libssh2_sftp_last_error() was wrongly used at some places in libcurl which
+ made libcurl sometimes not properly abort problematic SFTP transfers.
+
Daniel Stenberg (12 Dec 2008)
- More work with Igor Novoseltsev to first fix the remaining stuff for
removing easy handles from multi handles when the easy handle is/was within
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 96a3001ab..6183d4364 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -30,6 +30,7 @@ This release includes the following bugfixes:
o dotted IPv6 addresses longer than 39 bytes failed
o curl_easy_duphandle() doesn't try to duplicate the connection cache pointer
o build failure on OS/400 when enabling IPv6
+ o better detection of SFTP failures
This release includes the following known bugs:
diff --git a/lib/ssh.c b/lib/ssh.c
index f826a4fa4..c97d0c7e8 100644
--- a/lib/ssh.c
+++ b/lib/ssh.c
@@ -778,6 +778,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
/* Return the error type */
err = libssh2_sftp_last_error(sshc->sftp_session);
result = sftp_libssh2_error_to_CURLE(err);
+ sshc->actualcode = result?result:CURLE_SSH;
DEBUGF(infof(data, "error = %d makes libcurl = %d\n", err, result));
state(conn, SSH_STOP);
break;
@@ -1238,16 +1239,22 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
flags, data->set.new_file_perms);
if(!sshc->sftp_handle) {
- if(libssh2_session_last_errno(sshc->ssh_session) ==
- LIBSSH2_ERROR_EAGAIN) {
- rc = LIBSSH2_ERROR_EAGAIN;
+ rc = libssh2_session_last_errno(sshc->ssh_session);
+
+ if(LIBSSH2_ERROR_EAGAIN == rc)
break;
- }
else {
- err = libssh2_sftp_last_error(sshc->sftp_session);
+ if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
+ /* only when there was an SFTP protocol error can we extract
+ the sftp error! */
+ err = libssh2_sftp_last_error(sshc->sftp_session);
+ else
+ err = -1; /* not an sftp error at all */
+
if(sshc->secondCreateDirs) {
state(conn, SSH_SFTP_CLOSE);
- sshc->actualcode = sftp_libssh2_error_to_CURLE(err);
+ sshc->actualcode = err>= LIBSSH2_FX_OK?
+ sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
failf(data, "Creating the dir/file failed: %s",
sftp_libssh2_strerror(err));
break;
@@ -1263,8 +1270,18 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
break;
}
state(conn, SSH_SFTP_CLOSE);
- sshc->actualcode = sftp_libssh2_error_to_CURLE(err);
- failf(data, "Upload failed: %s", sftp_libssh2_strerror(err));
+ sshc->actualcode = err>= LIBSSH2_FX_OK?
+ sftp_libssh2_error_to_CURLE(err):CURLE_SSH;
+ if(!sshc->actualcode) {
+ /* Sometimes, for some reason libssh2_sftp_last_error() returns zero
+ even though libssh2_sftp_open() failed previously! We need to
+ work around that! */
+ sshc->actualcode = CURLE_SSH;
+ err=-1;
+ }
+ failf(data, "Upload failed: %s (%d/%d)",
+ err>= LIBSSH2_FX_OK?sftp_libssh2_strerror(err):"ssh error",
+ err, rc);
break;
}
}
@@ -1378,7 +1395,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
(sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
result = sftp_libssh2_error_to_CURLE(sftp_err);
state(conn, SSH_SFTP_CLOSE);
- sshc->actualcode = result;
+ sshc->actualcode = result?result:CURLE_SSH;
break;
}
}
@@ -1403,7 +1420,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
failf(data, "Could not open directory for reading: %s",
sftp_libssh2_strerror(err));
state(conn, SSH_SFTP_CLOSE);
- sshc->actualcode = sftp_libssh2_error_to_CURLE(err);
+ result = sftp_libssh2_error_to_CURLE(err);
+ sshc->actualcode = result?result:CURLE_SSH;
break;
}
}
@@ -1512,7 +1530,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
}
else if(sshc->readdir_len <= 0) {
err = libssh2_sftp_last_error(sshc->sftp_session);
- sshc->actualcode = sftp_libssh2_error_to_CURLE(err);
+ result = sftp_libssh2_error_to_CURLE(err);
+ sshc->actualcode = result?result:CURLE_SSH;
failf(data, "Could not open remote file for reading: %s :: %d",
sftp_libssh2_strerror(err),
libssh2_session_last_errno(sshc->ssh_session));
@@ -1621,7 +1640,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
failf(data, "Could not open remote file for reading: %s",
sftp_libssh2_strerror(err));
state(conn, SSH_SFTP_CLOSE);
- sshc->actualcode = sftp_libssh2_error_to_CURLE(err);
+ result = sftp_libssh2_error_to_CURLE(err);
+ sshc->actualcode = result?result:CURLE_SSH;
break;
}
}