mirror of
https://github.com/moparisthebest/curl
synced 2024-11-15 14:05:03 -05:00
Fix to work with the latest CVS version of libssh2
* As of (LIBSSH2_APINO >= 200706012030) there are not *nb() functions * As of (LIBSSH2_APINO >= 200706012030) most libssh2_*() functions can return LIBSSH2_ERROR_EAGAIN to indicate that the call would block. To make the code work as previously, blocking, all the code has been updated so that when (LIBSSH2_APINO >= 200706012030) it loops simulating blocking. This allows the existing code to function and not hold up the upcoming release.
This commit is contained in:
parent
2fd2ca9dac
commit
cd4e6fbcac
370
lib/ssh.c
370
lib/ssh.c
@ -311,12 +311,26 @@ CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
/* Set libssh2 to non-blocking, since cURL is all non-blocking */
|
||||
libssh2_session_set_blocking(ssh->ssh_session, 0);
|
||||
#endif /* LIBSSH2_APINO >= 200706012030 */
|
||||
|
||||
#ifdef CURL_LIBSSH2_DEBUG
|
||||
libssh2_trace(ssh->ssh_session, LIBSSH2_TRACE_CONN|LIBSSH2_TRACE_TRANS|LIBSSH2_TRACE_KEX|LIBSSH2_TRACE_AUTH|LIBSSH2_TRACE_SCP|LIBSSH2_TRACE_SFTP|LIBSSH2_TRACE_ERROR|LIBSSH2_TRACE_PUBLICKEY);
|
||||
libssh2_trace(ssh->ssh_session, LIBSSH2_TRACE_CONN|LIBSSH2_TRACE_TRANS|
|
||||
LIBSSH2_TRACE_KEX|LIBSSH2_TRACE_AUTH|LIBSSH2_TRACE_SCP|
|
||||
LIBSSH2_TRACE_SFTP|LIBSSH2_TRACE_ERROR|
|
||||
LIBSSH2_TRACE_PUBLICKEY);
|
||||
infof(data, "SSH socket: %d\n", sock);
|
||||
#endif /* CURL_LIBSSH2_DEBUG */
|
||||
|
||||
if (libssh2_session_startup(ssh->ssh_session, sock)) {
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while ((i = libssh2_session_startup(ssh->ssh_session, sock)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
i = libssh2_session_startup(ssh->ssh_session, sock);
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
if (i) {
|
||||
failf(data, "Failure establishing ssh session");
|
||||
libssh2_session_free(ssh->ssh_session);
|
||||
ssh->ssh_session = NULL;
|
||||
@ -353,6 +367,20 @@ CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
|
||||
* presumably with a blank username. That won't work in my experience.
|
||||
* So always specify it here.
|
||||
*/
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
do {
|
||||
authlist = libssh2_userauth_list(ssh->ssh_session, ssh->user,
|
||||
strlen(ssh->user));
|
||||
|
||||
if (!authlist && (libssh2_session_last_errno(ssh->ssh_session) !=
|
||||
LIBSSH2_ERROR_EAGAIN)) {
|
||||
libssh2_session_free(ssh->ssh_session);
|
||||
ssh->ssh_session = NULL;
|
||||
Curl_safefree(working_path);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
} while (!authlist);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
authlist = libssh2_userauth_list(ssh->ssh_session, ssh->user,
|
||||
strlen(ssh->user));
|
||||
if (!authlist) {
|
||||
@ -361,6 +389,7 @@ CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
|
||||
Curl_safefree(working_path);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
infof(data, "SSH authentication methods available: %s\n", authlist);
|
||||
|
||||
/*
|
||||
@ -402,8 +431,16 @@ CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
|
||||
if (rsa_pub[0]) {
|
||||
/* The function below checks if the files exists, no need to stat() here.
|
||||
*/
|
||||
if (libssh2_userauth_publickey_fromfile(ssh->ssh_session, ssh->user,
|
||||
rsa_pub, rsa, passphrase) == 0) {
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while ((i = libssh2_userauth_publickey_fromfile(ssh->ssh_session,
|
||||
ssh->user, rsa_pub,
|
||||
rsa, passphrase)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
i = libssh2_userauth_publickey_fromfile(ssh->ssh_session, ssh->user,
|
||||
rsa_pub, rsa, passphrase);
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
if (i == 0) {
|
||||
authed = TRUE;
|
||||
infof(conn->data, "Initialized SSH public key authentication\n");
|
||||
}
|
||||
@ -412,7 +449,14 @@ CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
|
||||
if (!authed &&
|
||||
(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
|
||||
(strstr(authlist, "password") != NULL)) {
|
||||
if (!libssh2_userauth_password(ssh->ssh_session, ssh->user, ssh->passwd)) {
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while ((i = libssh2_userauth_password(ssh->ssh_session, ssh->user,
|
||||
ssh->passwd)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
i = libssh2_userauth_password(ssh->ssh_session, ssh->user, ssh->passwd);
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
if (i == 0) {
|
||||
authed = TRUE;
|
||||
infof(conn->data, "Initialized password authentication\n");
|
||||
}
|
||||
@ -423,9 +467,18 @@ CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
|
||||
if (!authed && (data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
|
||||
&& (strstr(authlist, "keyboard-interactive") != NULL)) {
|
||||
/* Authentication failed. Continue with keyboard-interactive now. */
|
||||
if (libssh2_userauth_keyboard_interactive_ex(ssh->ssh_session, ssh->user,
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while ((i = libssh2_userauth_keyboard_interactive_ex(ssh->ssh_session,
|
||||
ssh->user,
|
||||
strlen(ssh->user),
|
||||
&kbd_callback) == 0) {
|
||||
&kbd_callback)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
i = libssh2_userauth_keyboard_interactive_ex(ssh->ssh_session, ssh->user,
|
||||
strlen(ssh->user),
|
||||
&kbd_callback);
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
if (i == 0) {
|
||||
authed = TRUE;
|
||||
infof(conn->data, "Initialized keyboard interactive authentication\n");
|
||||
}
|
||||
@ -453,6 +506,19 @@ CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
|
||||
/*
|
||||
* Start the libssh2 sftp session
|
||||
*/
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
do {
|
||||
ssh->sftp_session = libssh2_sftp_init(ssh->ssh_session);
|
||||
if (!ssh->sftp_session && (libssh2_session_last_errno(ssh->ssh_session) !=
|
||||
LIBSSH2_ERROR_EAGAIN)) {
|
||||
failf(data, "Failure initialising sftp session\n");
|
||||
libssh2_session_free(ssh->ssh_session);
|
||||
ssh->ssh_session = NULL;
|
||||
Curl_safefree(working_path);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
} while (!ssh->sftp_session);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
ssh->sftp_session = libssh2_sftp_init(ssh->ssh_session);
|
||||
if (ssh->sftp_session == NULL) {
|
||||
failf(data, "Failure initialising sftp session\n");
|
||||
@ -461,11 +527,18 @@ CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
|
||||
Curl_safefree(working_path);
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
|
||||
/*
|
||||
* Get the "home" directory
|
||||
*/
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while ((i = libssh2_sftp_realpath(ssh->sftp_session, ".",
|
||||
tempHome, PATH_MAX-1)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
i = libssh2_sftp_realpath(ssh->sftp_session, ".", tempHome, PATH_MAX-1);
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
if (i > 0) {
|
||||
/* It seems that this string is not always NULL terminated */
|
||||
tempHome[i] = '\0';
|
||||
@ -572,6 +645,21 @@ CURLcode Curl_scp_do(struct connectdata *conn, bool *done)
|
||||
* the destination file will be named the same name as the last directory
|
||||
* in the path.
|
||||
*/
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
do {
|
||||
scp->ssh_channel = libssh2_scp_send_ex(scp->ssh_session, scp->path,
|
||||
LIBSSH2_SFTP_S_IRUSR|
|
||||
LIBSSH2_SFTP_S_IWUSR|
|
||||
LIBSSH2_SFTP_S_IRGRP|
|
||||
LIBSSH2_SFTP_S_IROTH,
|
||||
conn->data->set.infilesize, 0, 0);
|
||||
if (!scp->ssh_channel &&
|
||||
(libssh2_session_last_errno(scp->ssh_session) !=
|
||||
LIBSSH2_ERROR_EAGAIN)) {
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
} while (!scp->ssh_channel);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
scp->ssh_channel = libssh2_scp_send_ex(scp->ssh_session, scp->path,
|
||||
LIBSSH2_SFTP_S_IRUSR|
|
||||
LIBSSH2_SFTP_S_IWUSR|
|
||||
@ -580,6 +668,7 @@ CURLcode Curl_scp_do(struct connectdata *conn, bool *done)
|
||||
conn->data->set.infilesize, 0, 0);
|
||||
if (!scp->ssh_channel)
|
||||
return CURLE_FAILED_INIT;
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
|
||||
/* upload data */
|
||||
res = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
|
||||
@ -591,6 +680,22 @@ CURLcode Curl_scp_do(struct connectdata *conn, bool *done)
|
||||
*/
|
||||
curl_off_t bytecount;
|
||||
memset(&sb, 0, sizeof(struct stat));
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
do {
|
||||
scp->ssh_channel = libssh2_scp_recv(scp->ssh_session, scp->path, &sb);
|
||||
if (!scp->ssh_channel &&
|
||||
(libssh2_session_last_errno(scp->ssh_session) !=
|
||||
LIBSSH2_ERROR_EAGAIN)) {
|
||||
if ((sb.st_mode == 0) && (sb.st_atime == 0) && (sb.st_mtime == 0) &&
|
||||
(sb.st_size == 0)) {
|
||||
/* Since sb is still empty, it is likely the file was not found */
|
||||
return CURLE_REMOTE_FILE_NOT_FOUND;
|
||||
}
|
||||
return libssh2_session_error_to_CURLE(
|
||||
libssh2_session_last_error(scp->ssh_session, NULL, NULL, 0));
|
||||
}
|
||||
} while (!scp->ssh_channel);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
scp->ssh_channel = libssh2_scp_recv(scp->ssh_session, scp->path, &sb);
|
||||
if (!scp->ssh_channel) {
|
||||
if ((sb.st_mode == 0) && (sb.st_atime == 0) && (sb.st_mtime == 0) &&
|
||||
@ -601,6 +706,7 @@ CURLcode Curl_scp_do(struct connectdata *conn, bool *done)
|
||||
return libssh2_session_error_to_CURLE(
|
||||
libssh2_session_last_error(scp->ssh_session, NULL, NULL, 0));
|
||||
}
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
/* download data */
|
||||
bytecount = (curl_off_t) sb.st_size;
|
||||
conn->data->reqdata.maxdownload = (curl_off_t) sb.st_size;
|
||||
@ -614,6 +720,7 @@ CURLcode Curl_scp_do(struct connectdata *conn, bool *done)
|
||||
CURLcode Curl_scp_done(struct connectdata *conn, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
int rc;
|
||||
struct SSHPROTO *scp = conn->data->reqdata.proto.ssh;
|
||||
(void)premature; /* not used */
|
||||
|
||||
@ -621,6 +728,25 @@ CURLcode Curl_scp_done(struct connectdata *conn, CURLcode status,
|
||||
scp->path = NULL;
|
||||
|
||||
if (scp->ssh_channel) {
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
if (conn->data->set.upload) {
|
||||
while ((rc = libssh2_channel_send_eof(scp->ssh_channel)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (rc) {
|
||||
infof(conn->data, "Failed to send libssh2 channel EOF\n");
|
||||
}
|
||||
while ((rc = libssh2_channel_wait_eof(scp->ssh_channel)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (rc) {
|
||||
infof(conn->data, "Failed to get channel EOF\n");
|
||||
}
|
||||
while ((rc = libssh2_channel_wait_closed(scp->ssh_channel)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (rc) {
|
||||
infof(conn->data, "Channel failed to close\n");
|
||||
}
|
||||
}
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
if (conn->data->set.upload &&
|
||||
libssh2_channel_send_eof(scp->ssh_channel) < 0) {
|
||||
infof(conn->data, "Failed to send libssh2 channel EOF\n");
|
||||
@ -628,10 +754,16 @@ CURLcode Curl_scp_done(struct connectdata *conn, CURLcode status,
|
||||
if (libssh2_channel_close(scp->ssh_channel) < 0) {
|
||||
infof(conn->data, "Failed to stop libssh2 channel subsystem\n");
|
||||
}
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
}
|
||||
|
||||
if (scp->ssh_session) {
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while (libssh2_session_disconnect(scp->ssh_session, "Shutdown") ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
libssh2_session_disconnect(scp->ssh_session, "Shutdown");
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
libssh2_session_free(scp->ssh_session);
|
||||
scp->ssh_session = NULL;
|
||||
}
|
||||
@ -656,7 +788,7 @@ ssize_t Curl_scp_send(struct connectdata *conn, int sockindex,
|
||||
* NOTE: we should not store nor rely on connection-related data to be
|
||||
* in the SessionHandle struct
|
||||
*/
|
||||
#ifdef LIBSSH2CHANNEL_EAGAIN
|
||||
#if defined(LIBSSH2CHANNEL_EAGAIN) && (LIBSSH2_APINO < 200706012030)
|
||||
nwrite = (ssize_t)
|
||||
libssh2_channel_writenb(conn->data->reqdata.proto.ssh->ssh_channel,
|
||||
mem, len);
|
||||
@ -685,7 +817,7 @@ ssize_t Curl_scp_recv(struct connectdata *conn, int sockindex,
|
||||
* in the SessionHandle struct
|
||||
*/
|
||||
|
||||
#ifdef LIBSSH2CHANNEL_EAGAIN
|
||||
#if defined(LIBSSH2CHANNEL_EAGAIN) && (LIBSSH2_APINO < 200706012030)
|
||||
/* we prefer the non-blocking API but that didn't exist previously */
|
||||
nread = (ssize_t)
|
||||
libssh2_channel_readnb(conn->data->reqdata.proto.ssh->ssh_channel,
|
||||
@ -711,6 +843,7 @@ CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
|
||||
curl_off_t bytecount = 0;
|
||||
char *buf = data->state.buffer;
|
||||
unsigned long err = 0;
|
||||
int rc;
|
||||
|
||||
*done = TRUE; /* unconditionally */
|
||||
|
||||
@ -729,6 +862,23 @@ CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
|
||||
* If this is not done the destination file will be named the
|
||||
* same name as the last directory in the path.
|
||||
*/
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
do {
|
||||
sftp->sftp_handle =
|
||||
libssh2_sftp_open(sftp->sftp_session, sftp->path,
|
||||
LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
|
||||
LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
|
||||
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
|
||||
if (!sftp->sftp_handle &&
|
||||
(libssh2_session_last_errno(sftp->ssh_session) !=
|
||||
LIBSSH2_ERROR_EAGAIN)) {
|
||||
err = libssh2_sftp_last_error(sftp->sftp_session);
|
||||
failf(conn->data, "Could not open remote file for writing: %s",
|
||||
sftp_libssh2_strerror(err));
|
||||
return sftp_libssh2_error_to_CURLE(err);
|
||||
}
|
||||
} while (!sftp->sftp_handle);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
sftp->sftp_handle =
|
||||
libssh2_sftp_open(sftp->sftp_session, sftp->path,
|
||||
LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC,
|
||||
@ -740,6 +890,7 @@ CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
|
||||
sftp_libssh2_strerror(err));
|
||||
return sftp_libssh2_error_to_CURLE(err);
|
||||
}
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
|
||||
/* upload data */
|
||||
res = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
|
||||
@ -758,6 +909,20 @@ CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
|
||||
int len, totalLen, currLen;
|
||||
char *line;
|
||||
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
do {
|
||||
sftp->sftp_handle =
|
||||
libssh2_sftp_opendir(sftp->sftp_session, sftp->path);
|
||||
if (!sftp->sftp_handle &&
|
||||
(libssh2_session_last_errno(sftp->ssh_session) !=
|
||||
LIBSSH2_ERROR_EAGAIN)) {
|
||||
err = libssh2_sftp_last_error(sftp->sftp_session);
|
||||
failf(conn->data, "Could not open directory for reading: %s",
|
||||
sftp_libssh2_strerror(err));
|
||||
return sftp_libssh2_error_to_CURLE(err);
|
||||
}
|
||||
} while (!sftp->sftp_handle);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
sftp->sftp_handle =
|
||||
libssh2_sftp_opendir(sftp->sftp_session, sftp->path);
|
||||
if (!sftp->sftp_handle) {
|
||||
@ -766,9 +931,18 @@ CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
|
||||
sftp_libssh2_strerror(err));
|
||||
return sftp_libssh2_error_to_CURLE(err);
|
||||
}
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
|
||||
do {
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while ((len = libssh2_sftp_readdir(sftp->sftp_handle, filename,
|
||||
PATH_MAX, &attrs)) > 0) {
|
||||
PATH_MAX, &attrs)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
len = libssh2_sftp_readdir(sftp->sftp_handle, filename,
|
||||
PATH_MAX, &attrs);
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
if (len > 0) {
|
||||
filename[len] = '\0';
|
||||
|
||||
if (data->set.ftp_list_only) {
|
||||
@ -856,7 +1030,8 @@ CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
|
||||
|
||||
if ((time_t)attrs.mtime > (now - (3600 * 24 * 180))) {
|
||||
currLen += snprintf(line+currLen, totalLen-currLen,
|
||||
" %s %2d %2d:%02d", months[nowParts->tm_mon],
|
||||
" %s %2d %2d:%02d",
|
||||
months[nowParts->tm_mon],
|
||||
nowParts->tm_mday, nowParts->tm_hour,
|
||||
nowParts->tm_min);
|
||||
}
|
||||
@ -866,15 +1041,16 @@ CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
|
||||
nowParts->tm_mday, 1900+nowParts->tm_year);
|
||||
}
|
||||
}
|
||||
currLen += snprintf(line+currLen, totalLen-currLen, " %s", filename);
|
||||
currLen += snprintf(line+currLen, totalLen-currLen, " %s",
|
||||
filename);
|
||||
if ((attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
|
||||
((attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
|
||||
LIBSSH2_SFTP_S_IFLNK)) {
|
||||
char linkPath[PATH_MAX + 1];
|
||||
|
||||
snprintf(linkPath, PATH_MAX, "%s%s", sftp->path, filename);
|
||||
len = libssh2_sftp_readlink(sftp->sftp_session, linkPath, filename,
|
||||
PATH_MAX);
|
||||
len = libssh2_sftp_readlink(sftp->sftp_session, linkPath,
|
||||
filename, PATH_MAX);
|
||||
line = realloc(line, totalLen + 4 + len);
|
||||
if (!line)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@ -888,7 +1064,15 @@ CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
|
||||
free(line);
|
||||
}
|
||||
}
|
||||
else if (len <= 0) {
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while (libssh2_sftp_closedir(sftp->sftp_handle) == LIBSSH2_ERROR_EAGAIN);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
libssh2_sftp_closedir(sftp->sftp_handle);
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
sftp->sftp_handle = NULL;
|
||||
|
||||
/* no data to transfer */
|
||||
@ -898,6 +1082,22 @@ CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
|
||||
/*
|
||||
* Work on getting the specified file
|
||||
*/
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
do {
|
||||
sftp->sftp_handle =
|
||||
libssh2_sftp_open(sftp->sftp_session, sftp->path, LIBSSH2_FXF_READ,
|
||||
LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
|
||||
LIBSSH2_SFTP_S_IRGRP|LIBSSH2_SFTP_S_IROTH);
|
||||
if (!sftp->sftp_handle &&
|
||||
(libssh2_session_last_errno(sftp->ssh_session) !=
|
||||
LIBSSH2_ERROR_EAGAIN)) {
|
||||
err = libssh2_sftp_last_error(sftp->sftp_session);
|
||||
failf(conn->data, "Could not open remote file for reading: %s",
|
||||
sftp_libssh2_strerror(err));
|
||||
return sftp_libssh2_error_to_CURLE(err);
|
||||
}
|
||||
} while (!sftp->sftp_handle);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
sftp->sftp_handle =
|
||||
libssh2_sftp_open(sftp->sftp_session, sftp->path, LIBSSH2_FXF_READ,
|
||||
LIBSSH2_SFTP_S_IRUSR|LIBSSH2_SFTP_S_IWUSR|
|
||||
@ -908,8 +1108,15 @@ CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
|
||||
sftp_libssh2_strerror(err));
|
||||
return sftp_libssh2_error_to_CURLE(err);
|
||||
}
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
|
||||
if (libssh2_sftp_stat(sftp->sftp_session, sftp->path, &attrs)) {
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while ((rc = libssh2_sftp_stat(sftp->sftp_session, sftp->path, &attrs))
|
||||
== LIBSSH2_ERROR_EAGAIN);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
rc = libssh2_sftp_stat(sftp->sftp_session, sftp->path, &attrs);
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
if (rc) {
|
||||
/*
|
||||
* libssh2_sftp_open() didn't return an error, so maybe the server
|
||||
* just doesn't support stat()
|
||||
@ -935,19 +1142,31 @@ CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
|
||||
bytecount, FALSE, NULL, -1, NULL);
|
||||
#endif
|
||||
while (res == CURLE_OK) {
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
ssize_t nread;
|
||||
|
||||
while ((nread = libssh2_sftp_read(data->reqdata.proto.ssh->sftp_handle,
|
||||
buf, BUFSIZE-1)) == LIBSSH2_ERROR_EAGAIN);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
size_t nread;
|
||||
/* NOTE: most *read() functions return ssize_t but this returns size_t
|
||||
which normally is unsigned! */
|
||||
nread = libssh2_sftp_read(data->reqdata.proto.ssh->sftp_handle,
|
||||
buf, BUFSIZE-1);
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
|
||||
if (nread > 0)
|
||||
buf[nread] = 0;
|
||||
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
if (nread <= 0)
|
||||
break;
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
/* this check can be changed to a <= 0 when nread is changed to a
|
||||
signed variable type */
|
||||
if ((nread == 0) || (nread == (size_t)~0))
|
||||
break;
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
|
||||
bytecount += nread;
|
||||
|
||||
@ -980,6 +1199,7 @@ CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode status,
|
||||
{
|
||||
struct SSHPROTO *sftp = conn->data->reqdata.proto.ssh;
|
||||
CURLcode rc = CURLE_OK;
|
||||
int ret;
|
||||
(void)premature; /* not used */
|
||||
|
||||
Curl_safefree(sftp->path);
|
||||
@ -989,9 +1209,17 @@ CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode status,
|
||||
sftp->homedir = NULL;
|
||||
|
||||
if (sftp->sftp_handle) {
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while ((ret = libssh2_sftp_close(sftp->sftp_handle)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (ret < 0) {
|
||||
infof(conn->data, "Failed to close libssh2 file\n");
|
||||
}
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
if (libssh2_sftp_close(sftp->sftp_handle) < 0) {
|
||||
infof(conn->data, "Failed to close libssh2 file\n");
|
||||
}
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
}
|
||||
|
||||
/* Before we shut down, see if there are any post-quote commands to send: */
|
||||
@ -1007,13 +1235,26 @@ CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode status,
|
||||
}
|
||||
|
||||
if (sftp->ssh_channel) {
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while ((ret = libssh2_channel_close(sftp->ssh_channel)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (ret < 0) {
|
||||
infof(conn->data, "Failed to stop libssh2 channel subsystem\n");
|
||||
}
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
if (libssh2_channel_close(sftp->ssh_channel) < 0) {
|
||||
infof(conn->data, "Failed to stop libssh2 channel subsystem\n");
|
||||
}
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
}
|
||||
|
||||
if (sftp->ssh_session) {
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while (libssh2_session_disconnect(sftp->ssh_session, "Shutdown") ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
libssh2_session_disconnect(sftp->ssh_session, "Shutdown");
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
libssh2_session_free(sftp->ssh_session);
|
||||
sftp->ssh_session = NULL;
|
||||
}
|
||||
@ -1034,7 +1275,7 @@ ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex,
|
||||
ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
|
||||
but is changed to ssize_t in 0.15! */
|
||||
|
||||
#ifdef LIBSSH2SFTP_EAGAIN
|
||||
#if defined(LIBSSH2SFTP_EAGAIN) && (LIBSSH2_APINO < 200706012030)
|
||||
/* we prefer the non-blocking API but that didn't exist previously */
|
||||
nwrite = (ssize_t)
|
||||
libssh2_sftp_writenb(conn->data->reqdata.proto.ssh->sftp_handle, mem, len);
|
||||
@ -1190,6 +1431,7 @@ static CURLcode sftp_sendquote(struct connectdata *conn,
|
||||
long err;
|
||||
struct SessionHandle *data = conn->data;
|
||||
LIBSSH2_SFTP *sftp_session = data->reqdata.proto.ssh->sftp_session;
|
||||
int ret;
|
||||
|
||||
while (item) {
|
||||
if (item->data) {
|
||||
@ -1244,6 +1486,29 @@ static CURLcode sftp_sendquote(struct connectdata *conn,
|
||||
sftp_libssh2_strerror(err));
|
||||
return CURLE_FTP_QUOTE_ERROR;
|
||||
}
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while ((ret = libssh2_sftp_stat(sftp_session,
|
||||
path2, &attrs)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (ret != 0) { /* get those attributes */
|
||||
err = libssh2_sftp_last_error(sftp_session);
|
||||
free(path1);
|
||||
free(path2);
|
||||
failf(data, "Attempt to get SFTP stats failed: %s",
|
||||
sftp_libssh2_strerror(err));
|
||||
return CURLE_FTP_QUOTE_ERROR;
|
||||
}
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
if (libssh2_sftp_stat(sftp_session,
|
||||
path2, &attrs) != 0) { /* get those attributes */
|
||||
err = libssh2_sftp_last_error(sftp_session);
|
||||
free(path1);
|
||||
free(path2);
|
||||
failf(data, "Attempt to get SFTP stats failed: %s",
|
||||
sftp_libssh2_strerror(err));
|
||||
return CURLE_FTP_QUOTE_ERROR;
|
||||
}
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
|
||||
/* Now set the new attributes... */
|
||||
if (curl_strnequal(item->data, "chgrp", 5)) {
|
||||
@ -1275,6 +1540,18 @@ static CURLcode sftp_sendquote(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* Now send the completed structure... */
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while ((ret = libssh2_sftp_setstat(sftp_session, path2, &attrs)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (ret != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_session);
|
||||
free(path1);
|
||||
free(path2);
|
||||
failf(data, "Attempt to set SFTP stats failed: %s",
|
||||
sftp_libssh2_strerror(err));
|
||||
return CURLE_FTP_QUOTE_ERROR;
|
||||
}
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
if (libssh2_sftp_setstat(sftp_session, path2, &attrs) != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_session);
|
||||
free(path1);
|
||||
@ -1283,6 +1560,7 @@ static CURLcode sftp_sendquote(struct connectdata *conn,
|
||||
sftp_libssh2_strerror(err));
|
||||
return CURLE_FTP_QUOTE_ERROR;
|
||||
}
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
}
|
||||
else if (curl_strnequal(item->data, "ln ", 3) ||
|
||||
curl_strnequal(item->data, "symlink ", 8)) {
|
||||
@ -1298,6 +1576,18 @@ static CURLcode sftp_sendquote(struct connectdata *conn,
|
||||
free(path1);
|
||||
return err;
|
||||
}
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while ((ret = libssh2_sftp_symlink(sftp_session, path1, path2)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (ret != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_session);
|
||||
free(path1);
|
||||
free(path2);
|
||||
failf(data, "symlink command failed: %s",
|
||||
sftp_libssh2_strerror(err));
|
||||
return CURLE_FTP_QUOTE_ERROR;
|
||||
}
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
if (libssh2_sftp_symlink(sftp_session, path1, path2) != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_session);
|
||||
free(path1);
|
||||
@ -1306,8 +1596,19 @@ static CURLcode sftp_sendquote(struct connectdata *conn,
|
||||
sftp_libssh2_strerror(err));
|
||||
return CURLE_FTP_QUOTE_ERROR;
|
||||
}
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
}
|
||||
else if (curl_strnequal(item->data, "mkdir ", 6)) { /* create dir */
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while ((ret = libssh2_sftp_mkdir(sftp_session, path1, 0744)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (ret != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_session);
|
||||
free(path1);
|
||||
failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
|
||||
return CURLE_FTP_QUOTE_ERROR;
|
||||
}
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
if (libssh2_sftp_mkdir(sftp_session, path1, 0744) != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_session);
|
||||
free(path1);
|
||||
@ -1315,6 +1616,7 @@ static CURLcode sftp_sendquote(struct connectdata *conn,
|
||||
sftp_libssh2_strerror(err));
|
||||
return CURLE_FTP_QUOTE_ERROR;
|
||||
}
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
}
|
||||
else if (curl_strnequal(item->data, "rename ", 7)) { /* rename file */
|
||||
/* first param is the source path */
|
||||
@ -1328,6 +1630,17 @@ static CURLcode sftp_sendquote(struct connectdata *conn,
|
||||
free(path1);
|
||||
return err;
|
||||
}
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while ((ret = libssh2_sftp_rename(sftp_session, path1, path2)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (ret != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_session);
|
||||
free(path1);
|
||||
free(path2);
|
||||
failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
|
||||
return CURLE_FTP_QUOTE_ERROR;
|
||||
}
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
if (libssh2_sftp_rename(sftp_session,
|
||||
path1, path2) != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_session);
|
||||
@ -1337,8 +1650,19 @@ static CURLcode sftp_sendquote(struct connectdata *conn,
|
||||
sftp_libssh2_strerror(err));
|
||||
return CURLE_FTP_QUOTE_ERROR;
|
||||
}
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
}
|
||||
else if (curl_strnequal(item->data, "rmdir ", 6)) { /* delete dir */
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while ((ret = libssh2_sftp_rmdir(sftp_session, path1)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (ret != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_session);
|
||||
free(path1);
|
||||
failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
|
||||
return CURLE_FTP_QUOTE_ERROR;
|
||||
}
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
if (libssh2_sftp_rmdir(sftp_session,
|
||||
path1) != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_session);
|
||||
@ -1347,8 +1671,19 @@ static CURLcode sftp_sendquote(struct connectdata *conn,
|
||||
sftp_libssh2_strerror(err));
|
||||
return CURLE_FTP_QUOTE_ERROR;
|
||||
}
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
}
|
||||
else if (curl_strnequal(item->data, "rm ", 3)) { /* delete file */
|
||||
#if (LIBSSH2_APINO >= 200706012030)
|
||||
while ((ret = libssh2_sftp_unlink(sftp_session, path1)) ==
|
||||
LIBSSH2_ERROR_EAGAIN);
|
||||
if (ret != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_session);
|
||||
free(path1);
|
||||
failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
|
||||
return CURLE_FTP_QUOTE_ERROR;
|
||||
}
|
||||
#else /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
if (libssh2_sftp_unlink(sftp_session, path1) != 0) {
|
||||
err = libssh2_sftp_last_error(sftp_session);
|
||||
free(path1);
|
||||
@ -1356,6 +1691,7 @@ static CURLcode sftp_sendquote(struct connectdata *conn,
|
||||
sftp_libssh2_strerror(err));
|
||||
return CURLE_FTP_QUOTE_ERROR;
|
||||
}
|
||||
#endif /* !(LIBSSH2_APINO >= 200706012030) */
|
||||
}
|
||||
|
||||
if (path1)
|
||||
@ -1381,7 +1717,7 @@ ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
|
||||
|
||||
/* libssh2_sftp_read() returns size_t !*/
|
||||
|
||||
#ifdef LIBSSH2SFTP_EAGAIN
|
||||
#if defined(LIBSSH2SFTP_EAGAIN) && (LIBSSH2_APINO < 200706012030)
|
||||
/* we prefer the non-blocking API but that didn't exist previously */
|
||||
nread = (ssize_t)
|
||||
libssh2_sftp_readnb(conn->data->reqdata.proto.ssh->sftp_handle, mem, len);
|
||||
|
Loading…
Reference in New Issue
Block a user