← Commit list

b168fc79ff

Daniel Stenberg
Daniel Stenberg
2026-04-07
SUCCESS Duration: 242s

Subject

libssh: split myssh_statemach_act into sub functions and rename

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/vssh/libssh.c+373 -249
@@ -357,6 +357,8 @@ static int myssh_in_SFTP_READDIR_INIT(struct Curl_easy *data,
struct ssh_conn *sshc,
struct SSHPROTO *sshp)
{
+ if(!sshp)
+ return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT);
Curl_pgrsSetDownloadSize(data, -1);
if(data->req.no_body) {
myssh_to(data, sshc, SSH_STOP);
@@ -384,6 +386,8 @@ static int myssh_in_SFTP_READDIR(struct Curl_easy *data,
{
CURLcode result = CURLE_OK;
+ if(!sshp)
+ return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT);
curlx_dyn_reset(&sshc->readdir_buf);
if(sshc->readdir_attrs)
sftp_attributes_free(sshc->readdir_attrs);
@@ -959,6 +963,9 @@ static int myssh_in_UPLOAD_INIT(struct Curl_easy *data,
int flags;
int rc = 0;
+ if(!sshp)
+ return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT);
+
if(data->state.resume_from) {
sftp_attributes attrs;
@@ -1105,6 +1112,8 @@ static int myssh_in_SFTP_DOWNLOAD_INIT(struct Curl_easy *data,
struct ssh_conn *sshc,
struct SSHPROTO *sshp)
{
+ if(!sshp)
+ return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT);
/* Work on getting the specified file */
if(sshc->sftp_file)
sftp_close(sshc->sftp_file);
@@ -1222,6 +1231,8 @@ static int myssh_in_SFTP_CLOSE(struct Curl_easy *data,
struct ssh_conn *sshc,
struct SSHPROTO *sshp)
{
+ if(!sshp)
+ return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT);
if(sshc->sftp_file) {
sftp_close(sshc->sftp_file);
sshc->sftp_file = NULL;
@@ -1321,7 +1332,12 @@ static int myssh_in_SFTP_QUOTE_INIT(struct Curl_easy *data,
struct ssh_conn *sshc,
struct SSHPROTO *sshp)
{
- CURLcode result = Curl_getworkingpath(data, sshc->homedir, &sshp->path);
+ CURLcode result;
+
+ 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);
@@ -1375,6 +1391,9 @@ static int myssh_in_SFTP_QUOTE(struct Curl_easy *data,
const char *cmd = sshc->quote_item->data;
sshc->acceptfail = FALSE;
+ if(!sshp)
+ return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT);
+
/* if a command starts with an asterisk, which a legal SFTP command never
can, the command is allowed to fail without it causing any
aborts or cancels etc. It causes libcurl to act as if the command
@@ -1842,19 +1861,337 @@ static void sshc_cleanup(struct ssh_conn *sshc)
}
}
+static int myssh_in_SFTP_QUOTE_SETSTAT(struct Curl_easy *data,
+ struct ssh_conn *sshc)
+{
+ int rc = sftp_setstat(sshc->sftp_session, sshc->quote_path2,
+ sshc->quote_attrs);
+ if(rc == SSH_AGAIN)
+ return rc;
+ if(rc && !sshc->acceptfail) {
+ myssh_quote_error(data, sshc, "setstat");
+ return rc;
+ }
+ myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
+ return SSH_NO_ERROR;
+}
+
+static int myssh_in_SFTP_QUOTE_SYMLINK(struct Curl_easy *data,
+ struct ssh_conn *sshc)
+{
+ int rc = sftp_symlink(sshc->sftp_session, sshc->quote_path2,
+ sshc->quote_path1);
+ if(rc == SSH_AGAIN)
+ return rc;
+ if(rc && !sshc->acceptfail) {
+ myssh_quote_error(data, sshc, "symlink");
+ return rc;
+ }
+ myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
+ return SSH_NO_ERROR;
+}
+
+static int myssh_in_SFTP_QUOTE_MKDIR(struct Curl_easy *data,
+ struct ssh_conn *sshc)
+{
+ int rc = sftp_mkdir(sshc->sftp_session, sshc->quote_path1,
+ (mode_t)data->set.new_directory_perms);
+ if(rc == SSH_AGAIN)
+ return rc;
+ if(rc && !sshc->acceptfail) {
+ myssh_quote_error(data, sshc, "mkdir");
+ return rc;
+ }
+ myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
+ return SSH_NO_ERROR;
+}
+
+static int myssh_in_SFTP_QUOTE_RENAME(struct Curl_easy *data,
+ struct ssh_conn *sshc)
+{
+ int rc = sftp_rename(sshc->sftp_session, sshc->quote_path1,
+ sshc->quote_path2);
+ if(rc == SSH_AGAIN)
+ return rc;
+ if(rc && !sshc->acceptfail) {
+ myssh_quote_error(data, sshc, "rename");
+ return rc;
+ }
+ myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
+ return SSH_NO_ERROR;
+}
+
+static int myssh_in_SFTP_QUOTE_RMDIR(struct Curl_easy *data,
+ struct ssh_conn *sshc)
+{
+ int rc = sftp_rmdir(sshc->sftp_session, sshc->quote_path1);
+ if(rc == SSH_AGAIN)
+ return rc;
+ if(rc && !sshc->acceptfail) {
+ myssh_quote_error(data, sshc, "rmdir");
+ return rc;
+ }
+ myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
+ return SSH_NO_ERROR;
+}
+
+static int myssh_in_SFTP_QUOTE_UNLINK(struct Curl_easy *data,
+ struct ssh_conn *sshc)
+{
+ int rc = sftp_unlink(sshc->sftp_session, sshc->quote_path1);
+ if(rc == SSH_AGAIN)
+ return rc;
+ if(rc && !sshc->acceptfail) {
+ myssh_quote_error(data, sshc, "rm");
+ return rc;
+ }
+ myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
+ return SSH_NO_ERROR;
+}
+
+static int myssh_in_SFTP_GETINFO(struct Curl_easy *data,
+ struct ssh_conn *sshc)
+{
+ if(data->set.get_filetime)
+ myssh_to(data, sshc, SSH_SFTP_FILETIME);
+ else
+ myssh_to(data, sshc, SSH_SFTP_TRANS_INIT);
+ return SSH_NO_ERROR;
+}
+
+static int myssh_in_SFTP_FILETIME(struct Curl_easy *data,
+ struct ssh_conn *sshc,
+ struct SSHPROTO *sshp)
+{
+ sftp_attributes attrs;
+ if(!sshp)
+ return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT);
+
+ attrs = sftp_stat(sshc->sftp_session, sshp->path);
+ if(attrs) {
+ data->info.filetime = attrs->mtime;
+ sftp_attributes_free(attrs);
+ }
+
+ myssh_to(data, sshc, SSH_SFTP_TRANS_INIT);
+ return SSH_NO_ERROR;
+}
+
+static int myssh_in_SFTP_TRANS_INIT(struct Curl_easy *data,
+ struct ssh_conn *sshc,
+ struct SSHPROTO *sshp)
+{
+ if(!sshp)
+ return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT);
+ if(data->state.upload)
+ myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT);
+ else {
+ size_t path_len = strlen(sshp->path);
+
+ if(path_len && sshp->path[path_len - 1] == '/')
+ myssh_to(data, sshc, SSH_SFTP_READDIR_INIT);
+ else
+ myssh_to(data, sshc, SSH_SFTP_DOWNLOAD_INIT);
+ }
+
+ return SSH_NO_ERROR;
+}
+
+static int myssh_in_SFTP_CREATE_DIRS_INIT(struct Curl_easy *data,
+ struct ssh_conn *sshc,
+ struct SSHPROTO *sshp)
+{
+ if(!sshp)
+ return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT);
+
+ if(strlen(sshp->path) > 1) {
+ sshc->slash_pos = sshp->path + 1; /* ignore the leading '/' */
+ myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS);
+ }
+ else {
+ myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT);
+ }
+ return SSH_NO_ERROR;
+}
+
+static int myssh_in_SFTP_CREATE_DIRS(struct Curl_easy *data,
+ struct ssh_conn *sshc,
+ struct SSHPROTO *sshp)
+{
+ if(!sshp)
+ return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT);
+
+ sshc->slash_pos = strchr(sshc->slash_pos, '/');
+ if(sshc->slash_pos) {
+ *sshc->slash_pos = 0;
+
+ infof(data, "Creating directory '%s'", sshp->path);
+ myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS_MKDIR);
+ return SSH_NO_ERROR;
+ }
+ myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT);
+ return SSH_NO_ERROR;
+}
+
+static int myssh_in_SFTP_CREATE_DIRS_MKDIR(struct Curl_easy *data,
+ struct ssh_conn *sshc,
+ struct SSHPROTO *sshp)
+{
+ int rc;
+ int err;
+ /* 'mode' - parameter is preliminary - default to 0644 */
+ if(!sshp)
+ return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT);
+
+ rc = sftp_mkdir(sshc->sftp_session, sshp->path,
+ (mode_t)data->set.new_directory_perms);
+ if(rc == SSH_AGAIN)
+ return rc;
+ *sshc->slash_pos = '/';
+ ++sshc->slash_pos;
+ if(rc < 0) {
+ /*
+ * Abort if failure was not that the directory already
+ * exists or the permission was denied (creation might
+ * succeed further down the path) - retry on unspecific
+ * FAILURE also
+ */
+ err = sftp_get_error(sshc->sftp_session);
+ if((err != SSH_FX_FILE_ALREADY_EXISTS) &&
+ (err != SSH_FX_FAILURE) &&
+ (err != SSH_FX_PERMISSION_DENIED)) {
+ return myssh_to_SFTP_CLOSE(data, sshc);
+ }
+ rc = 0; /* clear rc and continue */
+ }
+ myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS);
+ return rc;
+}
+
+static int myssh_in_SCP_UPLOAD_INIT(struct Curl_easy *data,
+ struct ssh_conn *sshc,
+ struct SSHPROTO *sshp)
+{
+ int rc;
+ if(!sshp)
+ return myssh_to_ERROR(data, sshc, CURLE_FAILED_INIT);
+
+ rc = ssh_scp_init(sshc->scp_session);
+ if(rc != SSH_OK) {
+ const char *err_msg = ssh_get_error(sshc->ssh_session);
+ failf(data, "%s", err_msg);
+ return myssh_to_ERROR(data, sshc, CURLE_UPLOAD_FAILED);
+ }
+
+ rc = ssh_scp_push_file64(sshc->scp_session, sshp->path,
+ (uint64_t)data->state.infilesize,
+ (int)data->set.new_file_perms);
+
+ if(rc != SSH_OK) {
+ const char *err_msg = ssh_get_error(sshc->ssh_session);
+ failf(data, "%s", err_msg);
+ return myssh_to_ERROR(data, sshc, CURLE_UPLOAD_FAILED);
+ }
+
+ /* upload data */
+ Curl_xfer_setup_send(data, FIRSTSOCKET);
+
+ /* not set by Curl_xfer_setup to preserve io_flags */
+ data->conn->recv_idx = FIRSTSOCKET;
+
+ myssh_to(data, sshc, SSH_STOP);
+ return SSH_NO_ERROR;
+}
+
+static int myssh_in_SCP_DOWNLOAD_INIT(struct Curl_easy *data,
+ struct ssh_conn *sshc)
+{
+ int rc = ssh_scp_init(sshc->scp_session);
+ if(rc != SSH_OK) {
+ const char *err_msg = ssh_get_error(sshc->ssh_session);
+ failf(data, "%s", err_msg);
+ return myssh_to_ERROR(data, sshc,
+ CURLE_COULDNT_CONNECT);
+ }
+ myssh_to(data, sshc, SSH_SCP_DOWNLOAD);
+ return SSH_NO_ERROR;
+}
+
+static int myssh_in_SCP_DONE(struct Curl_easy *data,
+ struct ssh_conn *sshc)
+{
+ if(data->state.upload)
+ myssh_to(data, sshc, SSH_SCP_SEND_EOF);
+ else
+ myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE);
+ return SSH_NO_ERROR;
+}
+
+static int myssh_in_SCP_SEND_EOF(struct Curl_easy *data,
+ struct ssh_conn *sshc)
+{
+ if(sshc->scp_session) {
+ int rc = ssh_scp_close(sshc->scp_session);
+ if(rc == SSH_AGAIN) {
+ /* Currently the ssh_scp_close handles waiting for
+ * EOF in blocking way.
+ */
+ return SSH_AGAIN;
+ }
+ if(rc != SSH_OK) {
+ infof(data,
+ "Failed to close libssh scp channel: %s",
+ ssh_get_error(sshc->ssh_session));
+ }
+ }
+
+ myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE);
+ return SSH_NO_ERROR;
+}
+
+static int myssh_in_SCP_CHANNEL_FREE(struct Curl_easy *data,
+ struct ssh_conn *sshc)
+{
+ if(sshc->scp_session) {
+ ssh_scp_free(sshc->scp_session);
+ sshc->scp_session = NULL;
+ }
+ CURL_TRC_SSH(data, "SCP DONE phase complete");
+
+ ssh_set_blocking(sshc->ssh_session, 0);
+
+ myssh_to(data, sshc, SSH_SESSION_DISCONNECT);
+ return SSH_NO_ERROR;
+}
+
+static CURLcode myssh_in_SESSION_FREE(struct Curl_easy *data,
+ struct ssh_conn *sshc)
+{
+ CURLcode result;
+ sshc_cleanup(sshc);
+ /* the code we are about to return */
+ result = sshc->actualcode;
+ memset(sshc, 0, sizeof(struct ssh_conn));
+ connclose(data->conn, "SSH session free");
+ sshc->state = SSH_SESSION_FREE; /* current */
+ sshc->nextstate = SSH_NO_STATE;
+ myssh_to(data, sshc, SSH_STOP);
+ return result;
+}
+
/*
- * ssh_statemach_act() runs the SSH state machine as far as it can without
+ * myssh_statemachine() runs the SSH state machine as far as it can without
* blocking and without reaching the end. The data the pointer 'block' points
* to is set to TRUE if the libssh function returns SSH_AGAIN
* meaning it wants to be called again when the socket is ready
*/
-static CURLcode myssh_statemach_act(struct Curl_easy *data,
- struct ssh_conn *sshc,
- struct SSHPROTO *sshp,
- bool *block)
+static CURLcode myssh_statemachine(struct Curl_easy *data,
+ struct ssh_conn *sshc,
+ struct SSHPROTO *sshp,
+ bool *block)
{
CURLcode result = CURLE_OK;
- int rc = SSH_NO_ERROR, err;
+ int rc = SSH_NO_ERROR;
*block = FALSE; /* we are not blocking by default */
do {
@@ -1910,14 +2247,13 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
rc = myssh_in_SFTP_REALPATH(data, sshc);
break;
case SSH_SFTP_QUOTE_INIT:
- rc = sshp ? myssh_in_SFTP_QUOTE_INIT(data, sshc, sshp) :
- CURLE_FAILED_INIT;
+ rc = myssh_in_SFTP_QUOTE_INIT(data, sshc, sshp);
break;
case SSH_SFTP_POSTQUOTE_INIT:
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 = myssh_in_SFTP_QUOTE(data, sshc, sshp);
break;
case SSH_SFTP_NEXT_QUOTE:
rc = myssh_in_SFTP_NEXT_QUOTE(data, sshc);
@@ -1926,188 +2262,52 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
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) {
- myssh_quote_error(data, sshc, "setstat");
- break;
- }
- myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
+ rc = myssh_in_SFTP_QUOTE_SETSTAT(data, sshc);
break;
-
case SSH_SFTP_QUOTE_SYMLINK:
- rc = sftp_symlink(sshc->sftp_session, sshc->quote_path2,
- sshc->quote_path1);
- if(rc == SSH_AGAIN)
- break;
- if(rc && !sshc->acceptfail) {
- myssh_quote_error(data, sshc, "symlink");
- break;
- }
- myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
+ rc = myssh_in_SFTP_QUOTE_SYMLINK(data, sshc);
break;
-
case SSH_SFTP_QUOTE_MKDIR:
- rc = sftp_mkdir(sshc->sftp_session, sshc->quote_path1,
- (mode_t)data->set.new_directory_perms);
- if(rc == SSH_AGAIN)
- break;
- if(rc && !sshc->acceptfail) {
- myssh_quote_error(data, sshc, "mkdir");
- break;
- }
- myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
+ rc = myssh_in_SFTP_QUOTE_MKDIR(data, sshc);
break;
-
case SSH_SFTP_QUOTE_RENAME:
- rc = sftp_rename(sshc->sftp_session, sshc->quote_path1,
- sshc->quote_path2);
- if(rc == SSH_AGAIN)
- break;
- if(rc && !sshc->acceptfail) {
- myssh_quote_error(data, sshc, "rename");
- break;
- }
- myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
+ rc = myssh_in_SFTP_QUOTE_RENAME(data, sshc);
break;
-
case SSH_SFTP_QUOTE_RMDIR:
- rc = sftp_rmdir(sshc->sftp_session, sshc->quote_path1);
- if(rc == SSH_AGAIN)
- break;
- if(rc && !sshc->acceptfail) {
- myssh_quote_error(data, sshc, "rmdir");
- break;
- }
- myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
+ rc = myssh_in_SFTP_QUOTE_RMDIR(data, sshc);
break;
-
case SSH_SFTP_QUOTE_UNLINK:
- rc = sftp_unlink(sshc->sftp_session, sshc->quote_path1);
- if(rc == SSH_AGAIN)
- break;
- if(rc && !sshc->acceptfail) {
- myssh_quote_error(data, sshc, "rm");
- break;
- }
- myssh_to(data, sshc, SSH_SFTP_NEXT_QUOTE);
+ rc = myssh_in_SFTP_QUOTE_UNLINK(data, sshc);
break;
-
case SSH_SFTP_QUOTE_STATVFS:
rc = myssh_in_SFTP_QUOTE_STATVFS(data, sshc);
break;
-
case SSH_SFTP_GETINFO:
- if(data->set.get_filetime) {
- myssh_to(data, sshc, SSH_SFTP_FILETIME);
- }
- else {
- myssh_to(data, sshc, SSH_SFTP_TRANS_INIT);
- }
+ rc = myssh_in_SFTP_GETINFO(data, sshc);
break;
-
- case SSH_SFTP_FILETIME: {
- sftp_attributes attrs;
- if(!sshp) {
- result = CURLE_FAILED_INIT;
- break;
- }
- attrs = sftp_stat(sshc->sftp_session, sshp->path);
- if(attrs) {
- data->info.filetime = attrs->mtime;
- sftp_attributes_free(attrs);
- }
-
- myssh_to(data, sshc, SSH_SFTP_TRANS_INIT);
+ case SSH_SFTP_FILETIME:
+ rc = myssh_in_SFTP_FILETIME(data, sshc, sshp);
break;
- }
-
case SSH_SFTP_TRANS_INIT:
- if(data->state.upload)
- myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT);
- else if(sshp) {
- size_t path_len = strlen(sshp->path);
-
- if(path_len && sshp->path[path_len - 1] == '/')
- myssh_to(data, sshc, SSH_SFTP_READDIR_INIT);
- else
- myssh_to(data, sshc, SSH_SFTP_DOWNLOAD_INIT);
- }
- else
- result = CURLE_FAILED_INIT;
+ rc = myssh_in_SFTP_TRANS_INIT(data, sshc, sshp);
break;
-
case SSH_SFTP_UPLOAD_INIT:
- rc = sshp ? myssh_in_UPLOAD_INIT(data, sshc, sshp) :
- CURLE_FAILED_INIT;
+ rc = myssh_in_UPLOAD_INIT(data, sshc, sshp);
break;
-
case SSH_SFTP_CREATE_DIRS_INIT:
- if(!sshp) {
- result = CURLE_FAILED_INIT;
- break;
- }
- else if(strlen(sshp->path) > 1) {
- sshc->slash_pos = sshp->path + 1; /* ignore the leading '/' */
- myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS);
- }
- else {
- myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT);
- }
+ rc = myssh_in_SFTP_CREATE_DIRS_INIT(data, sshc, sshp);
break;
-
case SSH_SFTP_CREATE_DIRS:
- sshc->slash_pos = strchr(sshc->slash_pos, '/');
- if(!sshp) {
- result = CURLE_FAILED_INIT;
- break;
- }
- else if(sshc->slash_pos) {
- *sshc->slash_pos = 0;
-
- infof(data, "Creating directory '%s'", sshp->path);
- myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS_MKDIR);
- break;
- }
- myssh_to(data, sshc, SSH_SFTP_UPLOAD_INIT);
+ rc = myssh_in_SFTP_CREATE_DIRS(data, sshc, sshp);
break;
-
case SSH_SFTP_CREATE_DIRS_MKDIR:
- /* 'mode' - parameter is preliminary - default to 0644 */
- if(!sshp) {
- result = CURLE_FAILED_INIT;
- break;
- }
- rc = sftp_mkdir(sshc->sftp_session, sshp->path,
- (mode_t)data->set.new_directory_perms);
- *sshc->slash_pos = '/';
- ++sshc->slash_pos;
- if(rc < 0) {
- /*
- * Abort if failure was not that the directory already exists or
- * the permission was denied (creation might succeed further down
- * the path) - retry on unspecific FAILURE also
- */
- err = sftp_get_error(sshc->sftp_session);
- if((err != SSH_FX_FILE_ALREADY_EXISTS) &&
- (err != SSH_FX_FAILURE) &&
- (err != SSH_FX_PERMISSION_DENIED)) {
- rc = myssh_to_SFTP_CLOSE(data, sshc);
- break;
- }
- rc = 0; /* clear rc and continue */
- }
- myssh_to(data, sshc, SSH_SFTP_CREATE_DIRS);
+ rc = myssh_in_SFTP_CREATE_DIRS_MKDIR(data, sshc, sshp);
break;
-
case SSH_SFTP_READDIR_INIT:
- rc = sshp ? myssh_in_SFTP_READDIR_INIT(data, sshc, sshp) :
- CURLE_FAILED_INIT;
+ rc = myssh_in_SFTP_READDIR_INIT(data, sshc, sshp);
break;
case SSH_SFTP_READDIR:
- rc = sshp ? myssh_in_SFTP_READDIR(data, sshc, sshp) : CURLE_FAILED_INIT;
+ rc = myssh_in_SFTP_READDIR(data, sshc, sshp);
break;
case SSH_SFTP_READDIR_LINK:
rc = myssh_in_SFTP_READDIR_LINK(data, sshc);
@@ -2119,14 +2319,13 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
rc = myssh_in_SFTP_READDIR_DONE(data, sshc);
break;
case SSH_SFTP_DOWNLOAD_INIT:
- rc = sshp ? myssh_in_SFTP_DOWNLOAD_INIT(data, sshc, sshp) :
- CURLE_FAILED_INIT;
+ rc = myssh_in_SFTP_DOWNLOAD_INIT(data, sshc, sshp);
break;
case SSH_SFTP_DOWNLOAD_STAT:
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 = myssh_in_SFTP_CLOSE(data, sshc, sshp);
break;
case SSH_SFTP_SHUTDOWN:
rc = myssh_in_SFTP_SHUTDOWN(data, sshc);
@@ -2134,107 +2333,32 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
case SSH_SCP_TRANS_INIT:
rc = myssh_in_TRANS_INIT(data, sshc, sshp);
break;
-
case SSH_SCP_UPLOAD_INIT:
- if(!sshp) {
- result = CURLE_FAILED_INIT;
- break;
- }
- rc = ssh_scp_init(sshc->scp_session);
- if(rc != SSH_OK) {
- 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;
- }
-
- rc = ssh_scp_push_file64(sshc->scp_session, sshp->path,
- (uint64_t)data->state.infilesize,
- (int)data->set.new_file_perms);
-
- if(rc != SSH_OK) {
- 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;
- }
-
- /* upload data */
- Curl_xfer_setup_send(data, FIRSTSOCKET);
-
- /* not set by Curl_xfer_setup to preserve io_flags */
- data->conn->recv_idx = FIRSTSOCKET;
-
- myssh_to(data, sshc, SSH_STOP);
-
+ rc = myssh_in_SCP_UPLOAD_INIT(data, sshc, sshp);
break;
-
case SSH_SCP_DOWNLOAD_INIT:
- rc = ssh_scp_init(sshc->scp_session);
- if(rc != SSH_OK) {
- const char *err_msg = ssh_get_error(sshc->ssh_session);
- failf(data, "%s", err_msg);
- rc = myssh_to_ERROR(data, sshc, CURLE_COULDNT_CONNECT);
+ rc = myssh_in_SCP_DOWNLOAD_INIT(data, sshc);
+ if(rc)
break;
- }
- myssh_to(data, sshc, SSH_SCP_DOWNLOAD);
FALLTHROUGH();
-
case SSH_SCP_DOWNLOAD:
rc = myssh_SSH_SCP_DOWNLOAD(data, sshc);
break;
-
case SSH_SCP_DONE:
- if(data->state.upload)
- myssh_to(data, sshc, SSH_SCP_SEND_EOF);
- else
- myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE);
+ rc = myssh_in_SCP_DONE(data, sshc);
break;
-
case SSH_SCP_SEND_EOF:
- if(sshc->scp_session) {
- rc = ssh_scp_close(sshc->scp_session);
- if(rc == SSH_AGAIN) {
- /* Currently the ssh_scp_close handles waiting for EOF in
- * blocking way.
- */
- break;
- }
- if(rc != SSH_OK) {
- infof(data, "Failed to close libssh scp channel: %s",
- ssh_get_error(sshc->ssh_session));
- }
- }
-
- myssh_to(data, sshc, SSH_SCP_CHANNEL_FREE);
+ rc = myssh_in_SCP_SEND_EOF(data, sshc);
break;
-
case SSH_SCP_CHANNEL_FREE:
- if(sshc->scp_session) {
- ssh_scp_free(sshc->scp_session);
- sshc->scp_session = NULL;
- }
- CURL_TRC_SSH(data, "SCP DONE phase complete");
-
- ssh_set_blocking(sshc->ssh_session, 0);
-
- myssh_to(data, sshc, SSH_SESSION_DISCONNECT);
+ myssh_in_SCP_CHANNEL_FREE(data, sshc);
FALLTHROUGH();
-
case SSH_SESSION_DISCONNECT:
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(data->conn, "SSH session free");
- sshc->state = SSH_SESSION_FREE; /* current */
- sshc->nextstate = SSH_NO_STATE;
- myssh_to(data, sshc, SSH_STOP);
+ result = myssh_in_SESSION_FREE(data, sshc);
break;
-
case SSH_QUIT:
default:
/* internal error */
@@ -2301,7 +2425,7 @@ static CURLcode myssh_multi_statemach(struct Curl_easy *data,
if(!sshc || !sshp)
return CURLE_FAILED_INIT;
- result = myssh_statemach_act(data, sshc, sshp, &block);
+ result = myssh_statemachine(data, sshc, sshp, &block);
*done = (sshc->state == SSH_STOP);
myssh_block2waitfor(conn, sshc, block);
@@ -2320,7 +2444,7 @@ static CURLcode myssh_block_statemach(struct Curl_easy *data,
bool block;
timediff_t left_ms = 1000;
- result = myssh_statemach_act(data, sshc, sshp, &block);
+ result = myssh_statemachine(data, sshc, sshp, &block);
if(result)
break;