mirror of
https://github.com/curl/curl.git
synced 2026-04-11 12:01:42 +08:00
libssh: simplify myssh_statemach_act()
Reduce complexity by splitting out sub functions. Made myssh_quote_error() to reduce code duplication. Closes #20252
This commit is contained in:
parent
1b24428d62
commit
bd3b2a626a
@ -727,6 +727,19 @@ static int myssh_in_SFTP_READDIR_DONE(struct Curl_easy *data,
|
||||
return SSH_NO_ERROR;
|
||||
}
|
||||
|
||||
static void myssh_quote_error(struct Curl_easy *data, struct ssh_conn *sshc,
|
||||
const char *cmd)
|
||||
{
|
||||
if(cmd)
|
||||
failf(data, "%s command failed: %s", cmd,
|
||||
ssh_get_error(sshc->ssh_session));
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
myssh_to(data, sshc, SSH_SFTP_CLOSE);
|
||||
sshc->nextstate = SSH_NO_STATE;
|
||||
sshc->actualcode = CURLE_QUOTE_ERROR;
|
||||
}
|
||||
|
||||
static int myssh_in_SFTP_QUOTE_STATVFS(struct Curl_easy *data,
|
||||
struct ssh_conn *sshc)
|
||||
{
|
||||
@ -734,12 +747,7 @@ static int myssh_in_SFTP_QUOTE_STATVFS(struct Curl_easy *data,
|
||||
|
||||
statvfs = sftp_statvfs(sshc->sftp_session, sshc->quote_path1);
|
||||
if(!statvfs && !sshc->acceptfail) {
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
failf(data, "statvfs command failed: %s",
|
||||
ssh_get_error(sshc->ssh_session));
|
||||
myssh_to(data, sshc, SSH_SFTP_CLOSE);
|
||||
sshc->nextstate = SSH_NO_STATE;
|
||||
sshc->actualcode = CURLE_QUOTE_ERROR;
|
||||
myssh_quote_error(data, sshc, "statvfs");
|
||||
return SSH_OK;
|
||||
}
|
||||
else if(statvfs) {
|
||||
@ -1765,13 +1773,9 @@ static int myssh_in_SFTP_QUOTE_STAT(struct Curl_easy *data,
|
||||
sftp_attributes_free(sshc->quote_attrs);
|
||||
sshc->quote_attrs = sftp_stat(sshc->sftp_session, sshc->quote_path2);
|
||||
if(!sshc->quote_attrs) {
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
failf(data, "Attempt to get SFTP stats failed: %d",
|
||||
sftp_get_error(sshc->sftp_session));
|
||||
myssh_to(data, sshc, SSH_SFTP_CLOSE);
|
||||
sshc->nextstate = SSH_NO_STATE;
|
||||
sshc->actualcode = CURLE_QUOTE_ERROR;
|
||||
myssh_quote_error(data, sshc, NULL);
|
||||
return SSH_NO_ERROR;
|
||||
}
|
||||
|
||||
@ -1780,12 +1784,8 @@ static int myssh_in_SFTP_QUOTE_STAT(struct Curl_easy *data,
|
||||
const char *p = sshc->quote_path1;
|
||||
curl_off_t gid;
|
||||
if(curlx_str_number(&p, &gid, UINT_MAX)) {
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
failf(data, "Syntax error: chgrp gid not a number");
|
||||
myssh_to(data, sshc, SSH_SFTP_CLOSE);
|
||||
sshc->nextstate = SSH_NO_STATE;
|
||||
sshc->actualcode = CURLE_QUOTE_ERROR;
|
||||
myssh_quote_error(data, sshc, NULL);
|
||||
return SSH_NO_ERROR;
|
||||
}
|
||||
sshc->quote_attrs->gid = (uint32_t)gid;
|
||||
@ -1795,12 +1795,8 @@ static int myssh_in_SFTP_QUOTE_STAT(struct Curl_easy *data,
|
||||
curl_off_t perms;
|
||||
const char *p = sshc->quote_path1;
|
||||
if(curlx_str_octal(&p, &perms, 07777)) {
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
failf(data, "Syntax error: chmod permissions not a number");
|
||||
myssh_to(data, sshc, SSH_SFTP_CLOSE);
|
||||
sshc->nextstate = SSH_NO_STATE;
|
||||
sshc->actualcode = CURLE_QUOTE_ERROR;
|
||||
myssh_quote_error(data, sshc, NULL);
|
||||
return SSH_NO_ERROR;
|
||||
}
|
||||
sshc->quote_attrs->permissions = (mode_t)perms;
|
||||
@ -1810,12 +1806,8 @@ static int myssh_in_SFTP_QUOTE_STAT(struct Curl_easy *data,
|
||||
const char *p = sshc->quote_path1;
|
||||
curl_off_t uid;
|
||||
if(curlx_str_number(&p, &uid, UINT_MAX)) {
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
failf(data, "Syntax error: chown uid not a number");
|
||||
myssh_to(data, sshc, SSH_SFTP_CLOSE);
|
||||
sshc->nextstate = SSH_NO_STATE;
|
||||
sshc->actualcode = CURLE_QUOTE_ERROR;
|
||||
myssh_quote_error(data, sshc, NULL);
|
||||
return SSH_NO_ERROR;
|
||||
}
|
||||
sshc->quote_attrs->uid = (uint32_t)uid;
|
||||
@ -1836,11 +1828,7 @@ static int myssh_in_SFTP_QUOTE_STAT(struct Curl_easy *data,
|
||||
}
|
||||
#endif
|
||||
if(fail) {
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
myssh_to(data, sshc, SSH_SFTP_CLOSE);
|
||||
sshc->nextstate = SSH_NO_STATE;
|
||||
sshc->actualcode = CURLE_QUOTE_ERROR;
|
||||
myssh_quote_error(data, sshc, NULL);
|
||||
return SSH_NO_ERROR;
|
||||
}
|
||||
if(date > UINT_MAX)
|
||||
@ -1871,6 +1859,104 @@ static void conn_forget_socket(struct Curl_easy *data, int sockindex)
|
||||
}
|
||||
}
|
||||
|
||||
static void myssh_SESSION_DISCONNECT(struct Curl_easy *data,
|
||||
struct ssh_conn *sshc)
|
||||
{
|
||||
/* during weird times when we have been prematurely aborted, the channel
|
||||
is still alive when we reach this state and we MUST kill the channel
|
||||
properly first */
|
||||
if(sshc->scp_session) {
|
||||
ssh_scp_free(sshc->scp_session);
|
||||
sshc->scp_session = NULL;
|
||||
}
|
||||
|
||||
if(sshc->sftp_file) {
|
||||
sftp_close(sshc->sftp_file);
|
||||
sshc->sftp_file = NULL;
|
||||
}
|
||||
if(sshc->sftp_session) {
|
||||
sftp_free(sshc->sftp_session);
|
||||
sshc->sftp_session = NULL;
|
||||
}
|
||||
|
||||
ssh_disconnect(sshc->ssh_session);
|
||||
if(!ssh_version(SSH_VERSION_INT(0, 10, 0))) {
|
||||
/* conn->sock[FIRSTSOCKET] is closed by ssh_disconnect behind our back,
|
||||
tell the connection to forget about it. This libssh
|
||||
bug is fixed in 0.10.0. */
|
||||
conn_forget_socket(data, FIRSTSOCKET);
|
||||
}
|
||||
|
||||
SSH_STRING_FREE_CHAR(sshc->homedir);
|
||||
|
||||
myssh_to(data, sshc, SSH_SESSION_FREE);
|
||||
}
|
||||
|
||||
static int myssh_SSH_SCP_DOWNLOAD(struct Curl_easy *data,
|
||||
struct ssh_conn *sshc)
|
||||
{
|
||||
curl_off_t bytecount;
|
||||
int rc = ssh_scp_pull_request(sshc->scp_session);
|
||||
if(rc != SSH_SCP_REQUEST_NEWFILE) {
|
||||
const char *err_msg = ssh_get_error(sshc->ssh_session);
|
||||
failf(data, "%s", err_msg);
|
||||
return myssh_to_ERROR(data, sshc, CURLE_REMOTE_FILE_NOT_FOUND);
|
||||
}
|
||||
|
||||
/* download data */
|
||||
bytecount = ssh_scp_request_get_size(sshc->scp_session);
|
||||
data->req.maxdownload = (curl_off_t)bytecount;
|
||||
Curl_xfer_setup_recv(data, FIRSTSOCKET, bytecount);
|
||||
|
||||
/* not set by Curl_xfer_setup to preserve keepon bits */
|
||||
data->conn->send_idx = 0;
|
||||
|
||||
myssh_to(data, sshc, SSH_STOP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int myssh_in_TRANS_INIT(struct Curl_easy *data, struct ssh_conn *sshc,
|
||||
struct SSHPROTO *sshp)
|
||||
{
|
||||
CURLcode result;
|
||||
int rc = 0;
|
||||
if(!sshp)
|
||||
return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT);
|
||||
|
||||
result = Curl_getworkingpath(data, sshc->homedir, &sshp->path);
|
||||
if(result) {
|
||||
sshc->actualcode = result;
|
||||
myssh_to(data, sshc, SSH_STOP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */
|
||||
ssh_set_blocking(sshc->ssh_session, 1);
|
||||
|
||||
if(data->state.upload) {
|
||||
if(data->state.infilesize < 0) {
|
||||
failf(data, "SCP requires a known file size for upload");
|
||||
return myssh_to_ERROR(data, sshc, CURLE_UPLOAD_FAILED);
|
||||
}
|
||||
|
||||
sshc->scp_session =
|
||||
ssh_scp_new(sshc->ssh_session, SSH_SCP_WRITE, sshp->path);
|
||||
myssh_to(data, sshc, SSH_SCP_UPLOAD_INIT);
|
||||
}
|
||||
else {
|
||||
sshc->scp_session =
|
||||
ssh_scp_new(sshc->ssh_session, SSH_SCP_READ, sshp->path);
|
||||
myssh_to(data, sshc, SSH_SCP_DOWNLOAD_INIT);
|
||||
}
|
||||
|
||||
if(!sshc->scp_session) {
|
||||
const char *err_msg = ssh_get_error(sshc->ssh_session);
|
||||
failf(data, "%s", err_msg);
|
||||
rc = myssh_to_ERROR(data, sshc, CURLE_UPLOAD_FAILED);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* ssh_statemach_act() runs the SSH state machine as far as it can without
|
||||
* blocking and without reaching the end. The data the pointer 'block' points
|
||||
@ -1883,9 +1969,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
|
||||
bool *block)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
struct connectdata *conn = data->conn;
|
||||
int rc = SSH_NO_ERROR, err;
|
||||
const char *err_msg;
|
||||
|
||||
*block = FALSE; /* we are not blocking by default */
|
||||
do {
|
||||
@ -1948,8 +2032,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
|
||||
rc = myssh_in_SFTP_POSTQUOTE_INIT(data, sshc);
|
||||
break;
|
||||
case SSH_SFTP_QUOTE:
|
||||
rc = sshp ? myssh_in_SFTP_QUOTE(data, sshc, sshp) :
|
||||
CURLE_FAILED_INIT;
|
||||
rc = sshp ? myssh_in_SFTP_QUOTE(data, sshc, sshp) : CURLE_FAILED_INIT;
|
||||
break;
|
||||
case SSH_SFTP_NEXT_QUOTE:
|
||||
rc = myssh_in_SFTP_NEXT_QUOTE(data, sshc);
|
||||
@ -1957,23 +2040,13 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
|
||||
case SSH_SFTP_QUOTE_STAT:
|
||||
rc = myssh_in_SFTP_QUOTE_STAT(data, sshc);
|
||||
break;
|
||||
|
||||
case SSH_SFTP_QUOTE_SETSTAT:
|
||||
rc = sftp_setstat(sshc->sftp_session, sshc->quote_path2,
|
||||
sshc->quote_attrs);
|
||||
if(rc == SSH_AGAIN)
|
||||
break;
|
||||
if(rc && !sshc->acceptfail) {
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
failf(data, "Attempt to set SFTP stats failed: %s",
|
||||
ssh_get_error(sshc->ssh_session));
|
||||
myssh_to(data, sshc, SSH_SFTP_CLOSE);
|
||||
sshc->nextstate = SSH_NO_STATE;
|
||||
sshc->actualcode = CURLE_QUOTE_ERROR;
|
||||
/* sshc->actualcode = sftp_error_to_CURLE(err);
|
||||
* we do not send the actual error; we return
|
||||
* the error the libssh2 backend is returning */
|
||||
myssh_quote_error(data, sshc, "setstat");
|
||||
break;
|
||||
}
|
||||
myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
|
||||
@ -1985,13 +2058,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
|
||||
if(rc == SSH_AGAIN)
|
||||
break;
|
||||
if(rc && !sshc->acceptfail) {
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
failf(data, "symlink command failed: %s",
|
||||
ssh_get_error(sshc->ssh_session));
|
||||
myssh_to(data, sshc, SSH_SFTP_CLOSE);
|
||||
sshc->nextstate = SSH_NO_STATE;
|
||||
sshc->actualcode = CURLE_QUOTE_ERROR;
|
||||
myssh_quote_error(data, sshc, "symlink");
|
||||
break;
|
||||
}
|
||||
myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
|
||||
@ -2003,12 +2070,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
|
||||
if(rc == SSH_AGAIN)
|
||||
break;
|
||||
if(rc && !sshc->acceptfail) {
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
failf(data, "mkdir command failed: %s",
|
||||
ssh_get_error(sshc->ssh_session));
|
||||
myssh_to(data, sshc, SSH_SFTP_CLOSE);
|
||||
sshc->nextstate = SSH_NO_STATE;
|
||||
sshc->actualcode = CURLE_QUOTE_ERROR;
|
||||
myssh_quote_error(data, sshc, "mkdir");
|
||||
break;
|
||||
}
|
||||
myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
|
||||
@ -2020,13 +2082,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
|
||||
if(rc == SSH_AGAIN)
|
||||
break;
|
||||
if(rc && !sshc->acceptfail) {
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
Curl_safefree(sshc->quote_path2);
|
||||
failf(data, "rename command failed: %s",
|
||||
ssh_get_error(sshc->ssh_session));
|
||||
myssh_to(data, sshc, SSH_SFTP_CLOSE);
|
||||
sshc->nextstate = SSH_NO_STATE;
|
||||
sshc->actualcode = CURLE_QUOTE_ERROR;
|
||||
myssh_quote_error(data, sshc, "rename");
|
||||
break;
|
||||
}
|
||||
myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
|
||||
@ -2037,12 +2093,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
|
||||
if(rc == SSH_AGAIN)
|
||||
break;
|
||||
if(rc && !sshc->acceptfail) {
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
failf(data, "rmdir command failed: %s",
|
||||
ssh_get_error(sshc->ssh_session));
|
||||
myssh_to(data, sshc, SSH_SFTP_CLOSE);
|
||||
sshc->nextstate = SSH_NO_STATE;
|
||||
sshc->actualcode = CURLE_QUOTE_ERROR;
|
||||
myssh_quote_error(data, sshc, "rmdir");
|
||||
break;
|
||||
}
|
||||
myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
|
||||
@ -2053,11 +2104,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
|
||||
if(rc == SSH_AGAIN)
|
||||
break;
|
||||
if(rc && !sshc->acceptfail) {
|
||||
Curl_safefree(sshc->quote_path1);
|
||||
failf(data, "rm command failed: %s", ssh_get_error(sshc->ssh_session));
|
||||
myssh_to(data, sshc, SSH_SFTP_CLOSE);
|
||||
sshc->nextstate = SSH_NO_STATE;
|
||||
sshc->actualcode = CURLE_QUOTE_ERROR;
|
||||
myssh_quote_error(data, sshc, "rm");
|
||||
break;
|
||||
}
|
||||
myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
|
||||
@ -2173,8 +2220,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
|
||||
CURLE_FAILED_INIT;
|
||||
break;
|
||||
case SSH_SFTP_READDIR:
|
||||
rc = sshp ? myssh_in_SFTP_READDIR(data, sshc, sshp) :
|
||||
CURLE_FAILED_INIT;
|
||||
rc = sshp ? myssh_in_SFTP_READDIR(data, sshc, sshp) : CURLE_FAILED_INIT;
|
||||
break;
|
||||
case SSH_SFTP_READDIR_LINK:
|
||||
rc = myssh_in_SFTP_READDIR_LINK(data, sshc);
|
||||
@ -2193,51 +2239,13 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
|
||||
rc = myssh_in_SFTP_DOWNLOAD_STAT(data, sshc);
|
||||
break;
|
||||
case SSH_SFTP_CLOSE:
|
||||
rc = sshp ? myssh_in_SFTP_CLOSE(data, sshc, sshp) :
|
||||
CURLE_FAILED_INIT;
|
||||
rc = sshp ? myssh_in_SFTP_CLOSE(data, sshc, sshp) : CURLE_FAILED_INIT;
|
||||
break;
|
||||
case SSH_SFTP_SHUTDOWN:
|
||||
rc = myssh_in_SFTP_SHUTDOWN(data, sshc);
|
||||
break;
|
||||
|
||||
case SSH_SCP_TRANS_INIT:
|
||||
if(!sshp) {
|
||||
result = CURLE_FAILED_INIT;
|
||||
break;
|
||||
}
|
||||
result = Curl_getworkingpath(data, sshc->homedir, &sshp->path);
|
||||
if(result) {
|
||||
sshc->actualcode = result;
|
||||
myssh_to(data, sshc, SSH_STOP);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */
|
||||
ssh_set_blocking(sshc->ssh_session, 1);
|
||||
|
||||
if(data->state.upload) {
|
||||
if(data->state.infilesize < 0) {
|
||||
failf(data, "SCP requires a known file size for upload");
|
||||
sshc->actualcode = CURLE_UPLOAD_FAILED;
|
||||
rc = myssh_to_ERROR(data, sshc, CURLE_UPLOAD_FAILED);
|
||||
break;
|
||||
}
|
||||
|
||||
sshc->scp_session =
|
||||
ssh_scp_new(sshc->ssh_session, SSH_SCP_WRITE, sshp->path);
|
||||
myssh_to(data, sshc, SSH_SCP_UPLOAD_INIT);
|
||||
}
|
||||
else {
|
||||
sshc->scp_session =
|
||||
ssh_scp_new(sshc->ssh_session, SSH_SCP_READ, sshp->path);
|
||||
myssh_to(data, sshc, SSH_SCP_DOWNLOAD_INIT);
|
||||
}
|
||||
|
||||
if(!sshc->scp_session) {
|
||||
err_msg = ssh_get_error(sshc->ssh_session);
|
||||
failf(data, "%s", err_msg);
|
||||
rc = myssh_to_ERROR(data, sshc, CURLE_UPLOAD_FAILED);
|
||||
}
|
||||
rc = myssh_in_TRANS_INIT(data, sshc, sshp);
|
||||
break;
|
||||
|
||||
case SSH_SCP_UPLOAD_INIT:
|
||||
@ -2247,7 +2255,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
|
||||
}
|
||||
rc = ssh_scp_init(sshc->scp_session);
|
||||
if(rc != SSH_OK) {
|
||||
err_msg = ssh_get_error(sshc->ssh_session);
|
||||
const char *err_msg = ssh_get_error(sshc->ssh_session);
|
||||
failf(data, "%s", err_msg);
|
||||
rc = myssh_to_ERROR(data, sshc, CURLE_UPLOAD_FAILED);
|
||||
break;
|
||||
@ -2258,7 +2266,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
|
||||
(int)data->set.new_file_perms);
|
||||
|
||||
if(rc != SSH_OK) {
|
||||
err_msg = ssh_get_error(sshc->ssh_session);
|
||||
const char *err_msg = ssh_get_error(sshc->ssh_session);
|
||||
failf(data, "%s", err_msg);
|
||||
rc = myssh_to_ERROR(data, sshc, CURLE_UPLOAD_FAILED);
|
||||
break;
|
||||
@ -2275,10 +2283,9 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
|
||||
break;
|
||||
|
||||
case SSH_SCP_DOWNLOAD_INIT:
|
||||
|
||||
rc = ssh_scp_init(sshc->scp_session);
|
||||
if(rc != SSH_OK) {
|
||||
err_msg = ssh_get_error(sshc->ssh_session);
|
||||
const char *err_msg = ssh_get_error(sshc->ssh_session);
|
||||
failf(data, "%s", err_msg);
|
||||
rc = myssh_to_ERROR(data, sshc, CURLE_COULDNT_CONNECT);
|
||||
break;
|
||||
@ -2286,28 +2293,10 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
|
||||
myssh_to(data, sshc, SSH_SCP_DOWNLOAD);
|
||||
FALLTHROUGH();
|
||||
|
||||
case SSH_SCP_DOWNLOAD: {
|
||||
curl_off_t bytecount;
|
||||
|
||||
rc = ssh_scp_pull_request(sshc->scp_session);
|
||||
if(rc != SSH_SCP_REQUEST_NEWFILE) {
|
||||
err_msg = ssh_get_error(sshc->ssh_session);
|
||||
failf(data, "%s", err_msg);
|
||||
rc = myssh_to_ERROR(data, sshc, CURLE_REMOTE_FILE_NOT_FOUND);
|
||||
case SSH_SCP_DOWNLOAD:
|
||||
rc = myssh_SSH_SCP_DOWNLOAD(data, sshc);
|
||||
break;
|
||||
}
|
||||
|
||||
/* download data */
|
||||
bytecount = ssh_scp_request_get_size(sshc->scp_session);
|
||||
data->req.maxdownload = (curl_off_t)bytecount;
|
||||
Curl_xfer_setup_recv(data, FIRSTSOCKET, bytecount);
|
||||
|
||||
/* not set by Curl_xfer_setup to preserve keepon bits */
|
||||
conn->send_idx = 0;
|
||||
|
||||
myssh_to(data, sshc, SSH_STOP);
|
||||
break;
|
||||
}
|
||||
case SSH_SCP_DONE:
|
||||
if(data->state.upload)
|
||||
myssh_to(data, sshc, SSH_SCP_SEND_EOF);
|
||||
@ -2346,41 +2335,14 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
|
||||
FALLTHROUGH();
|
||||
|
||||
case SSH_SESSION_DISCONNECT:
|
||||
/* during weird times when we have been prematurely aborted, the channel
|
||||
is still alive when we reach this state and we MUST kill the channel
|
||||
properly first */
|
||||
if(sshc->scp_session) {
|
||||
ssh_scp_free(sshc->scp_session);
|
||||
sshc->scp_session = NULL;
|
||||
}
|
||||
|
||||
if(sshc->sftp_file) {
|
||||
sftp_close(sshc->sftp_file);
|
||||
sshc->sftp_file = NULL;
|
||||
}
|
||||
if(sshc->sftp_session) {
|
||||
sftp_free(sshc->sftp_session);
|
||||
sshc->sftp_session = NULL;
|
||||
}
|
||||
|
||||
ssh_disconnect(sshc->ssh_session);
|
||||
if(!ssh_version(SSH_VERSION_INT(0, 10, 0))) {
|
||||
/* conn->sock[FIRSTSOCKET] is closed by ssh_disconnect behind our back,
|
||||
tell the connection to forget about it. This libssh
|
||||
bug is fixed in 0.10.0. */
|
||||
conn_forget_socket(data, FIRSTSOCKET);
|
||||
}
|
||||
|
||||
SSH_STRING_FREE_CHAR(sshc->homedir);
|
||||
|
||||
myssh_to(data, sshc, SSH_SESSION_FREE);
|
||||
myssh_SESSION_DISCONNECT(data, sshc);
|
||||
FALLTHROUGH();
|
||||
case SSH_SESSION_FREE:
|
||||
sshc_cleanup(sshc);
|
||||
/* the code we are about to return */
|
||||
result = sshc->actualcode;
|
||||
memset(sshc, 0, sizeof(struct ssh_conn));
|
||||
connclose(conn, "SSH session free");
|
||||
connclose(data->conn, "SSH session free");
|
||||
sshc->state = SSH_SESSION_FREE; /* current */
|
||||
sshc->nextstate = SSH_NO_STATE;
|
||||
myssh_to(data, sshc, SSH_STOP);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user