diff options
author | dartraiden <wowemuh@gmail.com> | 2021-02-07 18:49:47 +0300 |
---|---|---|
committer | dartraiden <wowemuh@gmail.com> | 2021-02-07 18:49:47 +0300 |
commit | 2f0eaffffe7e5d3ac074797f880480494dbcc6f3 (patch) | |
tree | 161fa6a6df8387d618530a684de9f61f58640596 /libs/libcurl/src/vssh/libssh2.c | |
parent | 061f5621d3f64835c376a7781af86a5e5ee1145c (diff) |
libcurl: update to 7.75.0
Diffstat (limited to 'libs/libcurl/src/vssh/libssh2.c')
-rw-r--r-- | libs/libcurl/src/vssh/libssh2.c | 833 |
1 files changed, 419 insertions, 414 deletions
diff --git a/libs/libcurl/src/vssh/libssh2.c b/libs/libcurl/src/vssh/libssh2.c index a69bcda995..3130dcc74d 100644 --- a/libs/libcurl/src/vssh/libssh2.c +++ b/libs/libcurl/src/vssh/libssh2.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -103,30 +103,24 @@ static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc); static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc); static LIBSSH2_FREE_FUNC(my_libssh2_free); -static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn); -static CURLcode ssh_connect(struct connectdata *conn, bool *done); -static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done); -static CURLcode ssh_do(struct connectdata *conn, bool *done); - -static CURLcode scp_done(struct connectdata *conn, - CURLcode, bool premature); -static CURLcode scp_doing(struct connectdata *conn, - bool *dophase_done); -static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection); - -static CURLcode sftp_done(struct connectdata *conn, - CURLcode, bool premature); -static CURLcode sftp_doing(struct connectdata *conn, - bool *dophase_done); -static CURLcode sftp_disconnect(struct connectdata *conn, bool dead); -static -CURLcode sftp_perform(struct connectdata *conn, - bool *connected, - bool *dophase_done); -static int ssh_getsock(struct connectdata *conn, curl_socket_t *sock); -static int ssh_perform_getsock(const struct connectdata *conn, - curl_socket_t *sock); -static CURLcode ssh_setup_connection(struct connectdata *conn); +static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data); +static CURLcode ssh_connect(struct Curl_easy *data, bool *done); +static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done); +static CURLcode ssh_do(struct Curl_easy *data, bool *done); +static CURLcode scp_done(struct Curl_easy *data, CURLcode c, bool premature); +static CURLcode scp_doing(struct Curl_easy *data, bool *dophase_done); +static CURLcode scp_disconnect(struct Curl_easy *data, + struct connectdata *conn, bool dead_connection); +static CURLcode sftp_done(struct Curl_easy *data, CURLcode, bool premature); +static CURLcode sftp_doing(struct Curl_easy *data, bool *dophase_done); +static CURLcode sftp_disconnect(struct Curl_easy *data, + struct connectdata *conn, bool dead); +static CURLcode sftp_perform(struct Curl_easy *data, bool *connected, + bool *dophase_done); +static int ssh_getsock(struct Curl_easy *data, struct connectdata *conn, + curl_socket_t *sock); +static CURLcode ssh_setup_connection(struct Curl_easy *data, + struct connectdata *conn); /* * SCP protocol handler. @@ -144,7 +138,7 @@ const struct Curl_handler Curl_handler_scp = { ssh_getsock, /* proto_getsock */ ssh_getsock, /* doing_getsock */ ZERO_NULL, /* domore_getsock */ - ssh_perform_getsock, /* perform_getsock */ + ssh_getsock, /* perform_getsock */ scp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ @@ -172,7 +166,7 @@ const struct Curl_handler Curl_handler_sftp = { ssh_getsock, /* proto_getsock */ ssh_getsock, /* doing_getsock */ ZERO_NULL, /* domore_getsock */ - ssh_perform_getsock, /* perform_getsock */ + ssh_getsock, /* perform_getsock */ sftp_disconnect, /* disconnect */ ZERO_NULL, /* readwrite */ ZERO_NULL, /* connection_check */ @@ -308,8 +302,9 @@ static LIBSSH2_FREE_FUNC(my_libssh2_free) * SSH State machine related code */ /* This is the ONLY way to change SSH state! */ -static void state(struct connectdata *conn, sshstate nowstate) +static void state(struct Curl_easy *data, sshstate nowstate) { + struct connectdata *conn = data->conn; struct ssh_conn *sshc = &conn->proto.sshc; #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) /* for debug purposes */ @@ -380,7 +375,7 @@ static void state(struct connectdata *conn, sshstate nowstate) DEBUGASSERT(sizeof(names)/sizeof(names[0]) == SSH_LAST); if(sshc->state != nowstate) { - infof(conn->data, "SFTP %p state change from %s to %s\n", + infof(data, "SFTP %p state change from %s to %s\n", (void *)sshc, names[sshc->state], names[nowstate]); } #endif @@ -434,15 +429,14 @@ static int sshkeycallback(struct Curl_easy *easy, #define libssh2_session_startup(x,y) libssh2_session_handshake(x,y) #endif -static CURLcode ssh_knownhost(struct connectdata *conn) +static CURLcode ssh_knownhost(struct Curl_easy *data) { CURLcode result = CURLE_OK; #ifdef HAVE_LIBSSH2_KNOWNHOST_API - struct Curl_easy *data = conn->data; - if(data->set.str[STRING_SSH_KNOWNHOSTS]) { /* we're asked to verify the host against a file */ + struct connectdata *conn = data->conn; struct ssh_conn *sshc = &conn->proto.sshc; struct libssh2_knownhost *host = NULL; int rc; @@ -564,7 +558,7 @@ static CURLcode ssh_knownhost(struct connectdata *conn) default: /* unknown return codes will equal reject */ /* FALLTHROUGH */ case CURLKHSTAT_REJECT: - state(conn, SSH_SESSION_FREE); + state(data, SSH_SESSION_FREE); /* FALLTHROUGH */ case CURLKHSTAT_DEFER: /* DEFER means bail out but keep the SSH_HOSTKEY state */ @@ -609,15 +603,15 @@ static CURLcode ssh_knownhost(struct connectdata *conn) } } #else /* HAVE_LIBSSH2_KNOWNHOST_API */ - (void)conn; + (void)data; #endif return result; } -static CURLcode ssh_check_fingerprint(struct connectdata *conn) +static CURLcode ssh_check_fingerprint(struct Curl_easy *data) { + struct connectdata *conn = data->conn; struct ssh_conn *sshc = &conn->proto.sshc; - struct Curl_easy *data = conn->data; const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]; char md5buffer[33]; @@ -644,7 +638,7 @@ static CURLcode ssh_check_fingerprint(struct connectdata *conn) else failf(data, "Denied establishing ssh session: md5 fingerprint not available"); - state(conn, SSH_SESSION_FREE); + state(data, SSH_SESSION_FREE); sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION; return sshc->actualcode; } @@ -652,14 +646,14 @@ static CURLcode ssh_check_fingerprint(struct connectdata *conn) /* as we already matched, we skip the check for known hosts */ return CURLE_OK; } - return ssh_knownhost(conn); + return ssh_knownhost(data); } /* * ssh_force_knownhost_key_type() will check the known hosts file and try to * force a specific public key type from the server if an entry is found. */ -static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn) +static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data) { CURLcode result = CURLE_OK; @@ -687,8 +681,8 @@ static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn) = "ssh-dss"; const char *hostkey_method = NULL; + struct connectdata *conn = data->conn; struct ssh_conn *sshc = &conn->proto.sshc; - struct Curl_easy *data = conn->data; struct libssh2_knownhost* store = NULL; const char *kh_name_end = NULL; size_t kh_name_size = 0; @@ -763,18 +757,18 @@ static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn) hostkey_method = hostkey_method_ssh_dss; break; case LIBSSH2_KNOWNHOST_KEY_RSA1: - failf(data, "Found host key type RSA1 which is not supported\n"); + failf(data, "Found host key type RSA1 which is not supported"); return CURLE_SSH; default: - failf(data, "Unknown host key type: %i\n", + failf(data, "Unknown host key type: %i", (store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK)); return CURLE_SSH; } infof(data, "Set \"%s\" as SSH hostkey type\n", hostkey_method); result = libssh2_session_error_to_CURLE( - libssh2_session_method_pref( - sshc->ssh_session, LIBSSH2_METHOD_HOSTKEY, hostkey_method)); + libssh2_session_method_pref( + sshc->ssh_session, LIBSSH2_METHOD_HOSTKEY, hostkey_method)); } else { infof(data, "Did not find host %s in %s\n", @@ -794,11 +788,11 @@ static CURLcode ssh_force_knownhost_key_type(struct connectdata *conn) * meaning it wants to be called again when the socket is ready */ -static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) +static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) { CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; - struct SSHPROTO *sftp_scp = data->req.p.ssh; + struct connectdata *conn = data->conn; + struct SSHPROTO *sshp = data->req.p.ssh; struct ssh_conn *sshc = &conn->proto.sshc; curl_socket_t sock = conn->sock[FIRSTSOCKET]; int rc = LIBSSH2_ERROR_NONE; @@ -809,7 +803,6 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) *block = 0; /* we're not blocking by default */ do { - switch(sshc->state) { case SSH_INIT: sshc->secondCreateDirs = 0; @@ -820,14 +813,14 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) non-blocking */ libssh2_session_set_blocking(sshc->ssh_session, 0); - result = ssh_force_knownhost_key_type(conn); + result = ssh_force_knownhost_key_type(data); if(result) { - state(conn, SSH_SESSION_FREE); + state(data, SSH_SESSION_FREE); sshc->actualcode = result; break; } - state(conn, SSH_S_STARTUP); + state(data, SSH_S_STARTUP); /* FALLTHROUGH */ case SSH_S_STARTUP: @@ -840,12 +833,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); failf(data, "Failure establishing ssh session: %d, %s", rc, err_msg); - state(conn, SSH_SESSION_FREE); + state(data, SSH_SESSION_FREE); sshc->actualcode = CURLE_FAILED_INIT; break; } - state(conn, SSH_HOSTKEY); + state(data, SSH_HOSTKEY); /* FALLTHROUGH */ case SSH_HOSTKEY: @@ -854,9 +847,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) * against our known hosts. How that is handled (reading from file, * whatever) is up to us. */ - result = ssh_check_fingerprint(conn); + result = ssh_check_fingerprint(data); if(!result) - state(conn, SSH_AUTHLIST); + state(data, SSH_AUTHLIST); /* ssh_check_fingerprint sets state appropriately on error */ break; @@ -879,14 +872,14 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(libssh2_userauth_authenticated(sshc->ssh_session)) { sshc->authed = TRUE; infof(data, "SSH user accepted with no authentication\n"); - state(conn, SSH_AUTH_DONE); + state(data, SSH_AUTH_DONE); break; } ssherr = libssh2_session_last_errno(sshc->ssh_session); if(ssherr == LIBSSH2_ERROR_EAGAIN) rc = LIBSSH2_ERROR_EAGAIN; else { - state(conn, SSH_SESSION_FREE); + state(data, SSH_SESSION_FREE); sshc->actualcode = libssh2_session_error_to_CURLE(ssherr); } break; @@ -894,7 +887,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) infof(data, "SSH authentication methods available: %s\n", sshc->authlist); - state(conn, SSH_AUTH_PKEY_INIT); + state(data, SSH_AUTH_PKEY_INIT); break; case SSH_AUTH_PKEY_INIT: @@ -966,7 +959,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(out_of_memory || sshc->rsa == NULL) { Curl_safefree(sshc->rsa); Curl_safefree(sshc->rsa_pub); - state(conn, SSH_SESSION_FREE); + state(data, SSH_SESSION_FREE); sshc->actualcode = CURLE_OUT_OF_MEMORY; break; } @@ -979,10 +972,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) infof(data, "Using SSH public key file '%s'\n", sshc->rsa_pub); infof(data, "Using SSH private key file '%s'\n", sshc->rsa); - state(conn, SSH_AUTH_PKEY); + state(data, SSH_AUTH_PKEY); } else { - state(conn, SSH_AUTH_PASS_INIT); + state(data, SSH_AUTH_PASS_INIT); } break; @@ -1005,14 +998,14 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(rc == 0) { sshc->authed = TRUE; infof(data, "Initialized SSH public key authentication\n"); - state(conn, SSH_AUTH_DONE); + state(data, SSH_AUTH_DONE); } else { char *err_msg = NULL; (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); infof(data, "SSH public key authentication failed: %s\n", err_msg); - state(conn, SSH_AUTH_PASS_INIT); + state(data, SSH_AUTH_PASS_INIT); rc = 0; /* clear rc and continue */ } break; @@ -1020,10 +1013,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) case SSH_AUTH_PASS_INIT: if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) && (strstr(sshc->authlist, "password") != NULL)) { - state(conn, SSH_AUTH_PASS); + state(data, SSH_AUTH_PASS); } else { - state(conn, SSH_AUTH_HOST_INIT); + state(data, SSH_AUTH_HOST_INIT); rc = 0; /* clear rc and continue */ } break; @@ -1040,10 +1033,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(rc == 0) { sshc->authed = TRUE; infof(data, "Initialized password authentication\n"); - state(conn, SSH_AUTH_DONE); + state(data, SSH_AUTH_DONE); } else { - state(conn, SSH_AUTH_HOST_INIT); + state(data, SSH_AUTH_HOST_INIT); rc = 0; /* clear rc and continue */ } break; @@ -1051,15 +1044,15 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) case SSH_AUTH_HOST_INIT: if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) && (strstr(sshc->authlist, "hostbased") != NULL)) { - state(conn, SSH_AUTH_HOST); + state(data, SSH_AUTH_HOST); } else { - state(conn, SSH_AUTH_AGENT_INIT); + state(data, SSH_AUTH_AGENT_INIT); } break; case SSH_AUTH_HOST: - state(conn, SSH_AUTH_AGENT_INIT); + state(data, SSH_AUTH_AGENT_INIT); break; case SSH_AUTH_AGENT_INIT: @@ -1075,7 +1068,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(!sshc->ssh_agent) { infof(data, "Could not create agent object\n"); - state(conn, SSH_AUTH_KEY_INIT); + state(data, SSH_AUTH_KEY_INIT); break; } } @@ -1085,16 +1078,16 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; if(rc < 0) { infof(data, "Failure connecting to agent\n"); - state(conn, SSH_AUTH_KEY_INIT); + state(data, SSH_AUTH_KEY_INIT); rc = 0; /* clear rc and continue */ } else { - state(conn, SSH_AUTH_AGENT_LIST); + state(data, SSH_AUTH_AGENT_LIST); } } else #endif /* HAVE_LIBSSH2_AGENT_API */ - state(conn, SSH_AUTH_KEY_INIT); + state(data, SSH_AUTH_KEY_INIT); break; case SSH_AUTH_AGENT_LIST: @@ -1105,11 +1098,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; if(rc < 0) { infof(data, "Failure requesting identities to agent\n"); - state(conn, SSH_AUTH_KEY_INIT); + state(data, SSH_AUTH_KEY_INIT); rc = 0; /* clear rc and continue */ } else { - state(conn, SSH_AUTH_AGENT); + state(data, SSH_AUTH_AGENT); sshc->sshagent_prev_identity = NULL; } #endif @@ -1147,10 +1140,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(rc == LIBSSH2_ERROR_NONE) { sshc->authed = TRUE; infof(data, "Agent based authentication successful\n"); - state(conn, SSH_AUTH_DONE); + state(data, SSH_AUTH_DONE); } else { - state(conn, SSH_AUTH_KEY_INIT); + state(data, SSH_AUTH_KEY_INIT); rc = 0; /* clear rc and continue */ } #endif @@ -1159,10 +1152,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) case SSH_AUTH_KEY_INIT: if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD) && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) { - state(conn, SSH_AUTH_KEY); + state(data, SSH_AUTH_KEY); } else { - state(conn, SSH_AUTH_DONE); + state(data, SSH_AUTH_DONE); } break; @@ -1180,13 +1173,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) sshc->authed = TRUE; infof(data, "Initialized keyboard interactive authentication\n"); } - state(conn, SSH_AUTH_DONE); + state(data, SSH_AUTH_DONE); break; case SSH_AUTH_DONE: if(!sshc->authed) { failf(data, "Authentication failure"); - state(conn, SSH_SESSION_FREE); + state(data, SSH_SESSION_FREE); sshc->actualcode = CURLE_LOGIN_DENIED; break; } @@ -1196,17 +1189,17 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) */ infof(data, "Authentication complete\n"); - Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */ + Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSH is connected */ conn->sockfd = sock; conn->writesockfd = CURL_SOCKET_BAD; if(conn->handler->protocol == CURLPROTO_SFTP) { - state(conn, SSH_SFTP_INIT); + state(data, SSH_SFTP_INIT); break; } infof(data, "SSH CONNECT phase done\n"); - state(conn, SSH_STOP); + state(data, SSH_STOP); break; case SSH_SFTP_INIT: @@ -1225,11 +1218,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0); failf(data, "Failure initializing sftp session: %s", err_msg); - state(conn, SSH_SESSION_FREE); + state(data, SSH_SESSION_FREE); sshc->actualcode = CURLE_FAILED_INIT; break; } - state(conn, SSH_SFTP_REALPATH); + state(data, SSH_SFTP_REALPATH); break; case SSH_SFTP_REALPATH: @@ -1249,11 +1242,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) tempHome[rc] = '\0'; sshc->homedir = strdup(tempHome); if(!sshc->homedir) { - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->actualcode = CURLE_OUT_OF_MEMORY; break; } - conn->data->state.most_recent_ftp_entrypath = sshc->homedir; + data->state.most_recent_ftp_entrypath = sshc->homedir; } else { /* Return the error type */ @@ -1267,7 +1260,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) sshc->actualcode = result; DEBUGF(infof(data, "error = %lu makes libcurl = %d\n", sftperr, (int)result)); - state(conn, SSH_STOP); + state(data, SSH_STOP); break; } } @@ -1276,25 +1269,25 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) since the homedir will remain the same between request but the working path will not. */ DEBUGF(infof(data, "SSH CONNECT phase done\n")); - state(conn, SSH_STOP); + state(data, SSH_STOP); break; case SSH_SFTP_QUOTE_INIT: - result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path); + result = Curl_getworkingpath(data, sshc->homedir, &sshp->path); if(result) { sshc->actualcode = result; - state(conn, SSH_STOP); + state(data, SSH_STOP); break; } if(data->set.quote) { infof(data, "Sending quote commands\n"); sshc->quote_item = data->set.quote; - state(conn, SSH_SFTP_QUOTE); + state(data, SSH_SFTP_QUOTE); } else { - state(conn, SSH_SFTP_GETINFO); + state(data, SSH_SFTP_GETINFO); } break; @@ -1302,10 +1295,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(data->set.postquote) { infof(data, "Sending quote commands\n"); sshc->quote_item = data->set.postquote; - state(conn, SSH_SFTP_QUOTE); + state(data, SSH_SFTP_QUOTE); } else { - state(conn, SSH_STOP); + state(data, SSH_STOP); } break; @@ -1336,10 +1329,10 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(strcasecompare("pwd", cmd)) { /* output debug output if that is requested */ char *tmp = aprintf("257 \"%s\" is current directory.\n", - sftp_scp->path); + sshp->path); if(!tmp) { result = CURLE_OUT_OF_MEMORY; - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; break; } @@ -1349,15 +1342,15 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) /* this sends an FTP-like "header" to the header callback so that the current directory can be read very similar to how it is read when using ordinary FTP. */ - result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); + result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp)); free(tmp); if(result) { - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = result; } else - state(conn, SSH_SFTP_NEXT_QUOTE); + state(data, SSH_SFTP_NEXT_QUOTE); break; } { @@ -1369,7 +1362,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(cp == NULL) { failf(data, "Syntax error command '%s'. Missing parameter!", cmd); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; @@ -1385,7 +1378,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) failf(data, "Out of memory"); else failf(data, "Syntax error: Bad first parameter to '%s'", cmd); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = result; break; @@ -1413,13 +1406,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) else failf(data, "Syntax error in %s: Bad second parameter", cmd); Curl_safefree(sshc->quote_path1); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = result; break; } - memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); - state(conn, SSH_SFTP_QUOTE_STAT); + memset(&sshp->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES)); + state(data, SSH_SFTP_QUOTE_STAT); break; } if(strncasecompare(cmd, "ln ", 3) || @@ -1435,17 +1428,17 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) failf(data, "Syntax error in ln/symlink: Bad second parameter"); Curl_safefree(sshc->quote_path1); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = result; break; } - state(conn, SSH_SFTP_QUOTE_SYMLINK); + state(data, SSH_SFTP_QUOTE_SYMLINK); break; } else if(strncasecompare(cmd, "mkdir ", 6)) { /* create dir */ - state(conn, SSH_SFTP_QUOTE_MKDIR); + state(data, SSH_SFTP_QUOTE_MKDIR); break; } else if(strncasecompare(cmd, "rename ", 7)) { @@ -1459,26 +1452,26 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) else failf(data, "Syntax error in rename: Bad second parameter"); Curl_safefree(sshc->quote_path1); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = result; break; } - state(conn, SSH_SFTP_QUOTE_RENAME); + state(data, SSH_SFTP_QUOTE_RENAME); break; } else if(strncasecompare(cmd, "rmdir ", 6)) { /* delete dir */ - state(conn, SSH_SFTP_QUOTE_RMDIR); + state(data, SSH_SFTP_QUOTE_RMDIR); break; } else if(strncasecompare(cmd, "rm ", 3)) { - state(conn, SSH_SFTP_QUOTE_UNLINK); + state(data, SSH_SFTP_QUOTE_UNLINK); break; } #ifdef HAS_STATVFS_SUPPORT else if(strncasecompare(cmd, "statvfs ", 8)) { - state(conn, SSH_SFTP_QUOTE_STATVFS); + state(data, SSH_SFTP_QUOTE_STATVFS); break; } #endif @@ -1486,7 +1479,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) failf(data, "Unknown SFTP command"); Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; @@ -1501,15 +1494,15 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) sshc->quote_item = sshc->quote_item->next; if(sshc->quote_item) { - state(conn, SSH_SFTP_QUOTE); + state(data, SSH_SFTP_QUOTE); } else { if(sshc->nextstate != SSH_NO_STATE) { - state(conn, sshc->nextstate); + state(data, sshc->nextstate); sshc->nextstate = SSH_NO_STATE; } else { - state(conn, SSH_SFTP_GETINFO); + state(data, SSH_SFTP_GETINFO); } } break; @@ -1537,7 +1530,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2, curlx_uztoui(strlen(sshc->quote_path2)), LIBSSH2_SFTP_STAT, - &sshc->quote_attrs); + &sshp->quote_attrs); if(rc == LIBSSH2_ERROR_EAGAIN) { break; } @@ -1547,7 +1540,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) Curl_safefree(sshc->quote_path2); failf(data, "Attempt to get SFTP stats failed: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; @@ -1556,43 +1549,43 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) /* Now set the new attributes... */ if(strncasecompare(cmd, "chgrp", 5)) { - sshc->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10); - sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID; - if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) && + sshp->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10); + sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID; + if(sshp->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) && !sshc->acceptfail) { Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); failf(data, "Syntax error: chgrp gid not a number"); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; } } else if(strncasecompare(cmd, "chmod", 5)) { - sshc->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8); - sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS; + sshp->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8); + sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS; /* permissions are octal */ - if(sshc->quote_attrs.permissions == 0 && + if(sshp->quote_attrs.permissions == 0 && !ISDIGIT(sshc->quote_path1[0])) { Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); failf(data, "Syntax error: chmod permissions not a number"); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; } } else if(strncasecompare(cmd, "chown", 5)) { - sshc->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10); - sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID; - if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) && + sshp->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10); + sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID; + if(sshp->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) && !sshc->acceptfail) { Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); failf(data, "Syntax error: chown uid not a number"); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; @@ -1604,13 +1597,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); failf(data, "Syntax error: incorrect access date format"); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; } - sshc->quote_attrs.atime = (unsigned long)date; - sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME; + sshp->quote_attrs.atime = (unsigned long)date; + sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME; } else if(strncasecompare(cmd, "mtime", 5)) { time_t date = Curl_getdate_capped(sshc->quote_path1); @@ -1618,17 +1611,17 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) Curl_safefree(sshc->quote_path1); Curl_safefree(sshc->quote_path2); failf(data, "Syntax error: incorrect modification date format"); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; } - sshc->quote_attrs.mtime = (unsigned long)date; - sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME; + sshp->quote_attrs.mtime = (unsigned long)date; + sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME; } /* Now send the completed structure... */ - state(conn, SSH_SFTP_QUOTE_SETSTAT); + state(data, SSH_SFTP_QUOTE_SETSTAT); break; } @@ -1636,7 +1629,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2, curlx_uztoui(strlen(sshc->quote_path2)), LIBSSH2_SFTP_SETSTAT, - &sshc->quote_attrs); + &sshp->quote_attrs); if(rc == LIBSSH2_ERROR_EAGAIN) { break; } @@ -1646,12 +1639,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) Curl_safefree(sshc->quote_path2); failf(data, "Attempt to set SFTP stats failed: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; } - state(conn, SSH_SFTP_NEXT_QUOTE); + state(data, SSH_SFTP_NEXT_QUOTE); break; case SSH_SFTP_QUOTE_SYMLINK: @@ -1669,12 +1662,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) Curl_safefree(sshc->quote_path2); failf(data, "symlink command failed: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; } - state(conn, SSH_SFTP_NEXT_QUOTE); + state(data, SSH_SFTP_NEXT_QUOTE); break; case SSH_SFTP_QUOTE_MKDIR: @@ -1689,12 +1682,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) Curl_safefree(sshc->quote_path1); failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; } - state(conn, SSH_SFTP_NEXT_QUOTE); + state(data, SSH_SFTP_NEXT_QUOTE); break; case SSH_SFTP_QUOTE_RENAME: @@ -1715,12 +1708,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) Curl_safefree(sshc->quote_path2); failf(data, "rename command failed: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; } - state(conn, SSH_SFTP_NEXT_QUOTE); + state(data, SSH_SFTP_NEXT_QUOTE); break; case SSH_SFTP_QUOTE_RMDIR: @@ -1734,12 +1727,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) Curl_safefree(sshc->quote_path1); failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; } - state(conn, SSH_SFTP_NEXT_QUOTE); + state(data, SSH_SFTP_NEXT_QUOTE); break; case SSH_SFTP_QUOTE_UNLINK: @@ -1752,12 +1745,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) sftperr = libssh2_sftp_last_error(sshc->sftp_session); Curl_safefree(sshc->quote_path1); failf(data, "rm command failed: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; } - state(conn, SSH_SFTP_NEXT_QUOTE); + state(data, SSH_SFTP_NEXT_QUOTE); break; #ifdef HAS_STATVFS_SUPPORT @@ -1776,7 +1769,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) Curl_safefree(sshc->quote_path1); failf(data, "statvfs command failed: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = CURLE_QUOTE_ERROR; break; @@ -1797,30 +1790,30 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) statvfs.f_namemax); if(!tmp) { result = CURLE_OUT_OF_MEMORY; - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; break; } - result = Curl_client_write(conn, CLIENTWRITE_HEADER, tmp, strlen(tmp)); + result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp)); free(tmp); if(result) { - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->nextstate = SSH_NO_STATE; sshc->actualcode = result; } } - state(conn, SSH_SFTP_NEXT_QUOTE); + state(data, SSH_SFTP_NEXT_QUOTE); break; } #endif case SSH_SFTP_GETINFO: { if(data->set.get_filetime) { - state(conn, SSH_SFTP_FILETIME); + state(data, SSH_SFTP_FILETIME); } else { - state(conn, SSH_SFTP_TRANS_INIT); + state(data, SSH_SFTP_TRANS_INIT); } break; } @@ -1829,8 +1822,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) { LIBSSH2_SFTP_ATTRIBUTES attrs; - rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), + rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path, + curlx_uztoui(strlen(sshp->path)), LIBSSH2_SFTP_STAT, &attrs); if(rc == LIBSSH2_ERROR_EAGAIN) { break; @@ -1839,18 +1832,18 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) data->info.filetime = attrs.mtime; } - state(conn, SSH_SFTP_TRANS_INIT); + state(data, SSH_SFTP_TRANS_INIT); break; } case SSH_SFTP_TRANS_INIT: if(data->set.upload) - state(conn, SSH_SFTP_UPLOAD_INIT); + state(data, SSH_SFTP_UPLOAD_INIT); else { - if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/') - state(conn, SSH_SFTP_READDIR_INIT); + if(sshp->path[strlen(sshp->path)-1] == '/') + state(data, SSH_SFTP_READDIR_INIT); else - state(conn, SSH_SFTP_DOWNLOAD_INIT); + state(data, SSH_SFTP_DOWNLOAD_INIT); } break; @@ -1867,8 +1860,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(data->state.resume_from != 0) { LIBSSH2_SFTP_ATTRIBUTES attrs; if(data->state.resume_from < 0) { - rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), + rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path, + curlx_uztoui(strlen(sshp->path)), LIBSSH2_SFTP_STAT, &attrs); if(rc == LIBSSH2_ERROR_EAGAIN) { break; @@ -1894,12 +1887,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) /* If we have restart position then open for append */ flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND; else - /* Clear file before writing (normal behaviour) */ + /* Clear file before writing (normal behavior) */ flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC; sshc->sftp_handle = - libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), + libssh2_sftp_open_ex(sshc->sftp_session, sshp->path, + curlx_uztoui(strlen(sshp->path)), flags, data->set.new_file_perms, LIBSSH2_SFTP_OPENFILE); @@ -1917,7 +1910,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) sftperr = LIBSSH2_FX_OK; /* not an sftp error at all */ if(sshc->secondCreateDirs) { - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->actualcode = sftperr != LIBSSH2_FX_OK ? sftp_libssh2_error_to_CURLE(sftperr):CURLE_SSH; failf(data, "Creating the dir/file failed: %s", @@ -1928,14 +1921,14 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) (sftperr == LIBSSH2_FX_FAILURE) || (sftperr == LIBSSH2_FX_NO_SUCH_PATH)) && (data->set.ftp_create_missing_dirs && - (strlen(sftp_scp->path) > 1))) { + (strlen(sshp->path) > 1))) { /* try to create the path remotely */ rc = 0; /* clear rc and continue */ sshc->secondCreateDirs = 1; - state(conn, SSH_SFTP_CREATE_DIRS_INIT); + state(data, SSH_SFTP_CREATE_DIRS_INIT); break; } - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->actualcode = sftperr != LIBSSH2_FX_OK ? sftp_libssh2_error_to_CURLE(sftperr):CURLE_SSH; if(!sshc->actualcode) { @@ -2014,7 +2007,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) conn->sockfd = conn->writesockfd; if(result) { - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->actualcode = result; } else { @@ -2032,18 +2025,18 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) timeout here */ Curl_expire(data, 0, EXPIRE_RUN_NOW); - state(conn, SSH_STOP); + state(data, SSH_STOP); } break; } case SSH_SFTP_CREATE_DIRS_INIT: - if(strlen(sftp_scp->path) > 1) { - sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */ - state(conn, SSH_SFTP_CREATE_DIRS); + if(strlen(sshp->path) > 1) { + sshc->slash_pos = sshp->path + 1; /* ignore the leading '/' */ + state(data, SSH_SFTP_CREATE_DIRS); } else { - state(conn, SSH_SFTP_UPLOAD_INIT); + state(data, SSH_SFTP_UPLOAD_INIT); } break; @@ -2052,17 +2045,17 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(sshc->slash_pos) { *sshc->slash_pos = 0; - infof(data, "Creating directory '%s'\n", sftp_scp->path); - state(conn, SSH_SFTP_CREATE_DIRS_MKDIR); + infof(data, "Creating directory '%s'\n", sshp->path); + state(data, SSH_SFTP_CREATE_DIRS_MKDIR); break; } - state(conn, SSH_SFTP_UPLOAD_INIT); + state(data, SSH_SFTP_UPLOAD_INIT); break; case SSH_SFTP_CREATE_DIRS_MKDIR: /* 'mode' - parameter is preliminary - default to 0644 */ - rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), + rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshp->path, + curlx_uztoui(strlen(sshp->path)), data->set.new_directory_perms); if(rc == LIBSSH2_ERROR_EAGAIN) { break; @@ -2080,19 +2073,19 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) (sftperr != LIBSSH2_FX_FAILURE) && (sftperr != LIBSSH2_FX_PERMISSION_DENIED)) { result = sftp_libssh2_error_to_CURLE(sftperr); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->actualcode = result?result:CURLE_SSH; break; } rc = 0; /* clear rc and continue */ } - state(conn, SSH_SFTP_CREATE_DIRS); + state(data, SSH_SFTP_CREATE_DIRS); break; case SSH_SFTP_READDIR_INIT: Curl_pgrsSetDownloadSize(data, -1); if(data->set.opt_no_body) { - state(conn, SSH_STOP); + state(data, SSH_STOP); break; } @@ -2101,9 +2094,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) * listing */ sshc->sftp_handle = libssh2_sftp_open_ex(sshc->sftp_session, - sftp_scp->path, + sshp->path, curlx_uztoui( - strlen(sftp_scp->path)), + strlen(sshp->path)), 0, 0, LIBSSH2_SFTP_OPENDIR); if(!sshc->sftp_handle) { if(libssh2_session_last_errno(sshc->ssh_session) == @@ -2114,51 +2107,51 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) sftperr = libssh2_sftp_last_error(sshc->sftp_session); failf(data, "Could not open directory for reading: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); result = sftp_libssh2_error_to_CURLE(sftperr); sshc->actualcode = result?result:CURLE_SSH; break; } - sshc->readdir_filename = malloc(PATH_MAX + 1); - if(!sshc->readdir_filename) { - state(conn, SSH_SFTP_CLOSE); + sshp->readdir_filename = malloc(PATH_MAX + 1); + if(!sshp->readdir_filename) { + state(data, SSH_SFTP_CLOSE); sshc->actualcode = CURLE_OUT_OF_MEMORY; break; } - sshc->readdir_longentry = malloc(PATH_MAX + 1); - if(!sshc->readdir_longentry) { - Curl_safefree(sshc->readdir_filename); - state(conn, SSH_SFTP_CLOSE); + sshp->readdir_longentry = malloc(PATH_MAX + 1); + if(!sshp->readdir_longentry) { + Curl_safefree(sshp->readdir_filename); + state(data, SSH_SFTP_CLOSE); sshc->actualcode = CURLE_OUT_OF_MEMORY; break; } - Curl_dyn_init(&sshc->readdir, PATH_MAX * 2); - state(conn, SSH_SFTP_READDIR); + Curl_dyn_init(&sshp->readdir, PATH_MAX * 2); + state(data, SSH_SFTP_READDIR); break; case SSH_SFTP_READDIR: rc = libssh2_sftp_readdir_ex(sshc->sftp_handle, - sshc->readdir_filename, + sshp->readdir_filename, PATH_MAX, - sshc->readdir_longentry, + sshp->readdir_longentry, PATH_MAX, - &sshc->readdir_attrs); + &sshp->readdir_attrs); if(rc == LIBSSH2_ERROR_EAGAIN) { break; } if(rc > 0) { readdir_len = (size_t) rc; - sshc->readdir_filename[readdir_len] = '\0'; + sshp->readdir_filename[readdir_len] = '\0'; if(data->set.ftp_list_only) { - result = Curl_client_write(conn, CLIENTWRITE_BODY, - sshc->readdir_filename, + result = Curl_client_write(data, CLIENTWRITE_BODY, + sshp->readdir_filename, readdir_len); if(!result) - result = Curl_client_write(conn, CLIENTWRITE_BODY, + result = Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1); if(result) { - state(conn, SSH_STOP); + state(data, SSH_STOP); break; } /* since this counts what we send to the client, we include the @@ -2166,37 +2159,37 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) data->req.bytecount += readdir_len + 1; /* output debug output if that is requested */ - Curl_debug(data, CURLINFO_DATA_IN, sshc->readdir_filename, + Curl_debug(data, CURLINFO_DATA_IN, sshp->readdir_filename, readdir_len); Curl_debug(data, CURLINFO_DATA_IN, (char *)"\n", 1); } else { - result = Curl_dyn_add(&sshc->readdir, sshc->readdir_longentry); + result = Curl_dyn_add(&sshp->readdir, sshp->readdir_longentry); if(!result) { - if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) && - ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) == + if((sshp->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) && + ((sshp->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFLNK)) { - Curl_dyn_init(&sshc->readdir_link, PATH_MAX); - result = Curl_dyn_add(&sshc->readdir_link, sftp_scp->path); - state(conn, SSH_SFTP_READDIR_LINK); + Curl_dyn_init(&sshp->readdir_link, PATH_MAX); + result = Curl_dyn_add(&sshp->readdir_link, sshp->path); + state(data, SSH_SFTP_READDIR_LINK); if(!result) break; } else { - state(conn, SSH_SFTP_READDIR_BOTTOM); + state(data, SSH_SFTP_READDIR_BOTTOM); break; } } sshc->actualcode = result; - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); break; } } else if(rc == 0) { - Curl_safefree(sshc->readdir_filename); - Curl_safefree(sshc->readdir_longentry); - state(conn, SSH_SFTP_READDIR_DONE); + Curl_safefree(sshp->readdir_filename); + Curl_safefree(sshp->readdir_longentry); + state(data, SSH_SFTP_READDIR_DONE); break; } else if(rc < 0) { @@ -2206,9 +2199,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) failf(data, "Could not open remote file for reading: %s :: %d", sftp_libssh2_strerror(sftperr), libssh2_session_last_errno(sshc->ssh_session)); - Curl_safefree(sshc->readdir_filename); - Curl_safefree(sshc->readdir_longentry); - state(conn, SSH_SFTP_CLOSE); + Curl_safefree(sshp->readdir_filename); + Curl_safefree(sshp->readdir_longentry); + state(data, SSH_SFTP_CLOSE); break; } break; @@ -2216,52 +2209,51 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) case SSH_SFTP_READDIR_LINK: rc = libssh2_sftp_symlink_ex(sshc->sftp_session, - Curl_dyn_ptr(&sshc->readdir_link), - (int)Curl_dyn_len(&sshc->readdir_link), - sshc->readdir_filename, + Curl_dyn_ptr(&sshp->readdir_link), + (int)Curl_dyn_len(&sshp->readdir_link), + sshp->readdir_filename, PATH_MAX, LIBSSH2_SFTP_READLINK); if(rc == LIBSSH2_ERROR_EAGAIN) { break; } - readdir_len = (size_t) rc; - Curl_dyn_free(&sshc->readdir_link); + Curl_dyn_free(&sshp->readdir_link); /* append filename and extra output */ - result = Curl_dyn_addf(&sshc->readdir, " -> %s", sshc->readdir_filename); + result = Curl_dyn_addf(&sshp->readdir, " -> %s", sshp->readdir_filename); if(result) { sshc->readdir_line = NULL; - Curl_safefree(sshc->readdir_filename); - Curl_safefree(sshc->readdir_longentry); - state(conn, SSH_SFTP_CLOSE); + Curl_safefree(sshp->readdir_filename); + Curl_safefree(sshp->readdir_longentry); + state(data, SSH_SFTP_CLOSE); sshc->actualcode = result; break; } - state(conn, SSH_SFTP_READDIR_BOTTOM); + state(data, SSH_SFTP_READDIR_BOTTOM); break; case SSH_SFTP_READDIR_BOTTOM: - result = Curl_dyn_addn(&sshc->readdir, "\n", 1); + result = Curl_dyn_addn(&sshp->readdir, "\n", 1); if(!result) - result = Curl_client_write(conn, CLIENTWRITE_BODY, - Curl_dyn_ptr(&sshc->readdir), - Curl_dyn_len(&sshc->readdir)); + result = Curl_client_write(data, CLIENTWRITE_BODY, + Curl_dyn_ptr(&sshp->readdir), + Curl_dyn_len(&sshp->readdir)); if(!result) { /* output debug output if that is requested */ Curl_debug(data, CURLINFO_DATA_IN, - Curl_dyn_ptr(&sshc->readdir), - Curl_dyn_len(&sshc->readdir)); - data->req.bytecount += Curl_dyn_len(&sshc->readdir); + Curl_dyn_ptr(&sshp->readdir), + Curl_dyn_len(&sshp->readdir)); + data->req.bytecount += Curl_dyn_len(&sshp->readdir); } if(result) { - Curl_dyn_free(&sshc->readdir); - state(conn, SSH_STOP); + Curl_dyn_free(&sshp->readdir); + state(data, SSH_STOP); } else { - Curl_dyn_reset(&sshc->readdir); - state(conn, SSH_SFTP_READDIR); + Curl_dyn_reset(&sshp->readdir); + state(data, SSH_SFTP_READDIR); } break; @@ -2272,12 +2264,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) break; } sshc->sftp_handle = NULL; - Curl_safefree(sshc->readdir_filename); - Curl_safefree(sshc->readdir_longentry); + Curl_safefree(sshp->readdir_filename); + Curl_safefree(sshp->readdir_longentry); /* no data to transfer */ Curl_setup_transfer(data, -1, -1, FALSE, -1); - state(conn, SSH_STOP); + state(data, SSH_STOP); break; case SSH_SFTP_DOWNLOAD_INIT: @@ -2285,8 +2277,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) * Work on getting the specified file */ sshc->sftp_handle = - libssh2_sftp_open_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), + libssh2_sftp_open_ex(sshc->sftp_session, sshp->path, + curlx_uztoui(strlen(sshp->path)), LIBSSH2_FXF_READ, data->set.new_file_perms, LIBSSH2_SFTP_OPENFILE); if(!sshc->sftp_handle) { @@ -2298,20 +2290,20 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) sftperr = libssh2_sftp_last_error(sshc->sftp_session); failf(data, "Could not open remote file for reading: %s", sftp_libssh2_strerror(sftperr)); - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); result = sftp_libssh2_error_to_CURLE(sftperr); sshc->actualcode = result?result:CURLE_SSH; break; } - state(conn, SSH_SFTP_DOWNLOAD_STAT); + state(data, SSH_SFTP_DOWNLOAD_STAT); break; case SSH_SFTP_DOWNLOAD_STAT: { LIBSSH2_SFTP_ATTRIBUTES attrs; - rc = libssh2_sftp_stat_ex(sshc->sftp_session, sftp_scp->path, - curlx_uztoui(strlen(sftp_scp->path)), + rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path, + curlx_uztoui(strlen(sshp->path)), LIBSSH2_SFTP_STAT, &attrs); if(rc == LIBSSH2_ERROR_EAGAIN) { break; @@ -2336,14 +2328,14 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) failf(data, "Bad file size (%" CURL_FORMAT_CURL_OFF_T ")", size); return CURLE_BAD_DOWNLOAD_RESUME; } - if(conn->data->state.use_range) { + if(data->state.use_range) { curl_off_t from, to; char *ptr; char *ptr2; CURLofft to_t; CURLofft from_t; - from_t = curlx_strtoofft(conn->data->state.range, &ptr, 0, &from); + from_t = curlx_strtoofft(data->state.range, &ptr, 0, &from); if(from_t == CURL_OFFT_FLOW) return CURLE_RANGE_ERROR; while(*ptr && (ISSPACE(*ptr) || (*ptr == '-'))) @@ -2374,7 +2366,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) size = to - from + 1; } - SFTP_SEEK(conn->proto.sshc.sftp_handle, from); + SFTP_SEEK(sshc->sftp_handle, from); } data->req.size = size; data->req.maxdownload = size; @@ -2417,7 +2409,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) /* no data to transfer */ Curl_setup_transfer(data, -1, -1, FALSE, -1); infof(data, "File already completely downloaded\n"); - state(conn, SSH_STOP); + state(data, SSH_STOP); break; } Curl_setup_transfer(data, FIRSTSOCKET, data->req.size, FALSE, -1); @@ -2433,11 +2425,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(result) { /* this should never occur; the close state should be entered at the time the error occurs */ - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); sshc->actualcode = result; } else { - state(conn, SSH_STOP); + state(data, SSH_STOP); } break; @@ -2456,7 +2448,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) sshc->sftp_handle = NULL; } - Curl_safefree(sftp_scp->path); + Curl_safefree(sshp->path); DEBUGF(infof(data, "SFTP DONE done\n")); @@ -2465,11 +2457,11 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) SSH_SFTP_CLOSE to pass the correct result back */ if(sshc->nextstate != SSH_NO_STATE && sshc->nextstate != SSH_SFTP_CLOSE) { - state(conn, sshc->nextstate); + state(data, sshc->nextstate); sshc->nextstate = SSH_SFTP_CLOSE; } else { - state(conn, SSH_STOP); + state(data, SSH_STOP); result = sshc->actualcode; } break; @@ -2504,16 +2496,16 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) } Curl_safefree(sshc->homedir); - conn->data->state.most_recent_ftp_entrypath = NULL; + data->state.most_recent_ftp_entrypath = NULL; - state(conn, SSH_SESSION_DISCONNECT); + state(data, SSH_SESSION_DISCONNECT); break; case SSH_SCP_TRANS_INIT: - result = Curl_getworkingpath(conn, sshc->homedir, &sftp_scp->path); + result = Curl_getworkingpath(data, sshc->homedir, &sshp->path); if(result) { sshc->actualcode = result; - state(conn, SSH_STOP); + state(data, SSH_STOP); break; } @@ -2521,13 +2513,13 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) if(data->state.infilesize < 0) { failf(data, "SCP requires a known file size for upload"); sshc->actualcode = CURLE_UPLOAD_FAILED; - state(conn, SSH_SCP_CHANNEL_FREE); + state(data, SSH_SCP_CHANNEL_FREE); break; } - state(conn, SSH_SCP_UPLOAD_INIT); + state(data, SSH_SCP_UPLOAD_INIT); } else { - state(conn, SSH_SCP_DOWNLOAD_INIT); + state(data, SSH_SCP_DOWNLOAD_INIT); } break; @@ -2539,7 +2531,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) * directory in the path. */ sshc->ssh_channel = - SCP_SEND(sshc->ssh_session, sftp_scp->path, data->set.new_file_perms, + SCP_SEND(sshc->ssh_session, sshp->path, data->set.new_file_perms, data->state.infilesize); if(!sshc->ssh_channel) { int ssh_err; @@ -2553,8 +2545,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0)); - failf(conn->data, "%s", err_msg); - state(conn, SSH_SCP_CHANNEL_FREE); + failf(data, "%s", err_msg); + state(data, SSH_SCP_CHANNEL_FREE); sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err); /* Map generic errors to upload failed */ if(sshc->actualcode == CURLE_SSH || @@ -2572,7 +2564,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) conn->sockfd = conn->writesockfd; if(result) { - state(conn, SSH_SCP_CHANNEL_FREE); + state(data, SSH_SCP_CHANNEL_FREE); sshc->actualcode = result; } else { @@ -2585,7 +2577,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) with both accordingly */ conn->cselect_bits = CURL_CSELECT_OUT; - state(conn, SSH_STOP); + state(data, SSH_STOP); } break; @@ -2607,12 +2599,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) struct stat sb; memset(&sb, 0, sizeof(struct stat)); sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session, - sftp_scp->path, &sb); + sshp->path, &sb); #else libssh2_struct_stat sb; memset(&sb, 0, sizeof(libssh2_struct_stat)); sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session, - sftp_scp->path, &sb); + sshp->path, &sb); #endif if(!sshc->ssh_channel) { @@ -2628,8 +2620,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0)); - failf(conn->data, "%s", err_msg); - state(conn, SSH_SCP_CHANNEL_FREE); + failf(data, "%s", err_msg); + state(data, SSH_SCP_CHANNEL_FREE); sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err); break; } @@ -2648,19 +2640,19 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) conn->cselect_bits = CURL_CSELECT_IN; if(result) { - state(conn, SSH_SCP_CHANNEL_FREE); + state(data, SSH_SCP_CHANNEL_FREE); sshc->actualcode = result; } else - state(conn, SSH_STOP); + state(data, SSH_STOP); } break; case SSH_SCP_DONE: if(data->set.upload) - state(conn, SSH_SCP_SEND_EOF); + state(data, SSH_SCP_SEND_EOF); else - state(conn, SSH_SCP_CHANNEL_FREE); + state(data, SSH_SCP_CHANNEL_FREE); break; case SSH_SCP_SEND_EOF: @@ -2677,7 +2669,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) rc, err_msg); } } - state(conn, SSH_SCP_WAIT_EOF); + state(data, SSH_SCP_WAIT_EOF); break; case SSH_SCP_WAIT_EOF: @@ -2693,7 +2685,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) infof(data, "Failed to get channel EOF: %d %s\n", rc, err_msg); } } - state(conn, SSH_SCP_WAIT_CLOSE); + state(data, SSH_SCP_WAIT_CLOSE); break; case SSH_SCP_WAIT_CLOSE: @@ -2709,7 +2701,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) infof(data, "Channel failed to close: %d %s\n", rc, err_msg); } } - state(conn, SSH_SCP_CHANNEL_FREE); + state(data, SSH_SCP_CHANNEL_FREE); break; case SSH_SCP_CHANNEL_FREE: @@ -2729,9 +2721,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) } DEBUGF(infof(data, "SCP DONE phase complete\n")); #if 0 /* PREV */ - state(conn, SSH_SESSION_DISCONNECT); + state(data, SSH_SESSION_DISCONNECT); #endif - state(conn, SSH_STOP); + state(data, SSH_STOP); result = sshc->actualcode; break; @@ -2769,9 +2761,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) } Curl_safefree(sshc->homedir); - conn->data->state.most_recent_ftp_entrypath = NULL; + data->state.most_recent_ftp_entrypath = NULL; - state(conn, SSH_SESSION_FREE); + state(data, SSH_SESSION_FREE); break; case SSH_SESSION_FREE: @@ -2839,11 +2831,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) Curl_safefree(sshc->quote_path2); Curl_safefree(sshc->homedir); - - Curl_safefree(sshc->readdir_filename); - Curl_safefree(sshc->readdir_longentry); Curl_safefree(sshc->readdir_line); - Curl_dyn_free(&sshc->readdir); /* the code we are about to return */ result = sshc->actualcode; @@ -2853,7 +2841,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) connclose(conn, "SSH session free"); sshc->state = SSH_SESSION_FREE; /* current */ sshc->nextstate = SSH_NO_STATE; - state(conn, SSH_STOP); + state(data, SSH_STOP); break; case SSH_QUIT: @@ -2861,7 +2849,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) default: /* internal error */ sshc->nextstate = SSH_NO_STATE; - state(conn, SSH_STOP); + state(data, SSH_STOP); break; } @@ -2878,10 +2866,12 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) /* called by the multi interface to figure out what socket(s) to wait for and for what actions in the DO_DONE, PERFORM and WAITPERFORM states */ -static int ssh_perform_getsock(const struct connectdata *conn, - curl_socket_t *sock) +static int ssh_getsock(struct Curl_easy *data, + struct connectdata *conn, + curl_socket_t *sock) { int bitmap = GETSOCK_BLANK; + (void)data; sock[0] = conn->sock[FIRSTSOCKET]; @@ -2894,16 +2884,6 @@ static int ssh_perform_getsock(const struct connectdata *conn, return bitmap; } -/* Generic function called by the multi interface to figure out what socket(s) - to wait for and for what actions during the DOING and PROTOCONNECT states*/ -static int ssh_getsock(struct connectdata *conn, - curl_socket_t *sock) -{ - /* if we know the direction we can use the generic *_getsock() function even - for the protocol_connect and doing states */ - return ssh_perform_getsock(conn, sock); -} - /* * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this * function is used to figure out in what direction and stores this info so @@ -2911,8 +2891,9 @@ static int ssh_getsock(struct connectdata *conn, * function in all cases so that when it _doesn't_ return EAGAIN we can * restore the default wait bits. */ -static void ssh_block2waitfor(struct connectdata *conn, bool block) +static void ssh_block2waitfor(struct Curl_easy *data, bool block) { + struct connectdata *conn = data->conn; struct ssh_conn *sshc = &conn->proto.sshc; int dir = 0; if(block) { @@ -2930,40 +2911,41 @@ static void ssh_block2waitfor(struct connectdata *conn, bool block) } /* called repeatedly until done from multi.c */ -static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done) +static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done) { + struct connectdata *conn = data->conn; struct ssh_conn *sshc = &conn->proto.sshc; CURLcode result = CURLE_OK; bool block; /* we store the status and use that to provide a ssh_getsock() implementation */ do { - result = ssh_statemach_act(conn, &block); + result = ssh_statemach_act(data, &block); *done = (sshc->state == SSH_STOP) ? TRUE : FALSE; /* if there's no error, it isn't done and it didn't EWOULDBLOCK, then try again */ } while(!result && !*done && !block); - ssh_block2waitfor(conn, block); + ssh_block2waitfor(data, block); return result; } -static CURLcode ssh_block_statemach(struct connectdata *conn, - bool duringconnect) +static CURLcode ssh_block_statemach(struct Curl_easy *data, + struct connectdata *conn, + bool duringconnect) { struct ssh_conn *sshc = &conn->proto.sshc; CURLcode result = CURLE_OK; - struct Curl_easy *data = conn->data; while((sshc->state != SSH_STOP) && !result) { bool block; timediff_t left = 1000; struct curltime now = Curl_now(); - result = ssh_statemach_act(conn, &block); + result = ssh_statemach_act(data, &block); if(result) break; - if(Curl_pgrsUpdate(conn)) + if(Curl_pgrsUpdate(data)) return CURLE_ABORTED_BY_CALLBACK; result = Curl_speedcheck(data, now); @@ -2997,11 +2979,13 @@ static CURLcode ssh_block_statemach(struct connectdata *conn, /* * SSH setup and connection */ -static CURLcode ssh_setup_connection(struct connectdata *conn) +static CURLcode ssh_setup_connection(struct Curl_easy *data, + struct connectdata *conn) { struct SSHPROTO *ssh; + (void)conn; - conn->data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO)); + data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO)); if(!ssh) return CURLE_OUT_OF_MEMORY; @@ -3015,9 +2999,10 @@ static Curl_send scp_send, sftp_send; static ssize_t ssh_tls_recv(libssh2_socket_t sock, void *buffer, size_t length, int flags, void **abstract) { - struct connectdata *conn = (struct connectdata *)*abstract; + struct Curl_easy *data = (struct Curl_easy *)*abstract; ssize_t nread; CURLcode result; + struct connectdata *conn = data->conn; Curl_recv *backup = conn->recv[0]; struct ssh_conn *ssh = &conn->proto.sshc; (void)flags; @@ -3025,22 +3010,23 @@ static ssize_t ssh_tls_recv(libssh2_socket_t sock, void *buffer, /* swap in the TLS reader function for this call only, and then swap back the SSH one again */ conn->recv[0] = ssh->tls_recv; - result = Curl_read(conn, sock, buffer, length, &nread); + result = Curl_read(data, sock, buffer, length, &nread); conn->recv[0] = backup; if(result == CURLE_AGAIN) return -EAGAIN; /* magic return code for libssh2 */ else if(result) return -1; /* generic error */ - Curl_debug(conn->data, CURLINFO_DATA_IN, (char *)buffer, (size_t)nread); + Curl_debug(data, CURLINFO_DATA_IN, (char *)buffer, (size_t)nread); return nread; } static ssize_t ssh_tls_send(libssh2_socket_t sock, const void *buffer, size_t length, int flags, void **abstract) { - struct connectdata *conn = (struct connectdata *)*abstract; + struct Curl_easy *data = (struct Curl_easy *)*abstract; ssize_t nwrite; CURLcode result; + struct connectdata *conn = data->conn; Curl_send *backup = conn->send[0]; struct ssh_conn *ssh = &conn->proto.sshc; (void)flags; @@ -3048,13 +3034,13 @@ static ssize_t ssh_tls_send(libssh2_socket_t sock, const void *buffer, /* swap in the TLS writer function for this call only, and then swap back the SSH one again */ conn->send[0] = ssh->tls_send; - result = Curl_write(conn, sock, buffer, length, &nwrite); + result = Curl_write(data, sock, buffer, length, &nwrite); conn->send[0] = backup; if(result == CURLE_AGAIN) return -EAGAIN; /* magic return code for libssh2 */ else if(result) return -1; /* error */ - Curl_debug(conn->data, CURLINFO_DATA_OUT, (char *)buffer, (size_t)nwrite); + Curl_debug(data, CURLINFO_DATA_OUT, (char *)buffer, (size_t)nwrite); return nwrite; } #endif @@ -3063,24 +3049,29 @@ static ssize_t ssh_tls_send(libssh2_socket_t sock, const void *buffer, * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to * do protocol-specific actions at connect-time. */ -static CURLcode ssh_connect(struct connectdata *conn, bool *done) +static CURLcode ssh_connect(struct Curl_easy *data, bool *done) { #ifdef CURL_LIBSSH2_DEBUG curl_socket_t sock; #endif - struct ssh_conn *ssh; + struct SSHPROTO *sshp = data->req.p.ssh; + struct ssh_conn *sshc; CURLcode result; - struct Curl_easy *data = conn->data; + struct connectdata *conn = data->conn; /* initialize per-handle data if not already */ - if(!data->req.p.ssh) - ssh_setup_connection(conn); + if(!sshp) { + result = ssh_setup_connection(data, conn); + if(result) + return result; + sshp = data->req.p.ssh; + } /* We default to persistent connections. We set this already in this connect function to make the re-use checks properly be able to check this bit. */ connkeep(conn, "SSH default"); - ssh = &conn->proto.sshc; + sshc = &conn->proto.sshc; #ifdef CURL_LIBSSH2_DEBUG if(conn->user) { @@ -3092,10 +3083,10 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done) sock = conn->sock[FIRSTSOCKET]; #endif /* CURL_LIBSSH2_DEBUG */ - ssh->ssh_session = libssh2_session_init_ex(my_libssh2_malloc, - my_libssh2_free, - my_libssh2_realloc, conn); - if(ssh->ssh_session == NULL) { + sshc->ssh_session = libssh2_session_init_ex(my_libssh2_malloc, + my_libssh2_free, + my_libssh2_realloc, data); + if(sshc->ssh_session == NULL) { failf(data, "Failure initialising ssh session"); return CURLE_FAILED_INIT; } @@ -3134,15 +3125,15 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done) int flags, void **abstract); */ - libssh2_session_callback_set(ssh->ssh_session, + libssh2_session_callback_set(sshc->ssh_session, LIBSSH2_CALLBACK_RECV, sshrecv.recvp); - libssh2_session_callback_set(ssh->ssh_session, + libssh2_session_callback_set(sshc->ssh_session, LIBSSH2_CALLBACK_SEND, sshsend.sendp); /* Store the underlying TLS recv/send function pointers to be used when reading from the proxy */ - ssh->tls_recv = conn->recv[FIRSTSOCKET]; - ssh->tls_send = conn->send[FIRSTSOCKET]; + sshc->tls_recv = conn->recv[FIRSTSOCKET]; + sshc->tls_send = conn->send[FIRSTSOCKET]; } #endif /* CURL_DISABLE_PROXY */ @@ -3157,7 +3148,7 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done) if(data->set.ssh_compression) { #if LIBSSH2_VERSION_NUM >= 0x010208 - if(libssh2_session_flag(ssh->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0) + if(libssh2_session_flag(sshc->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0) #endif infof(data, "Failed to enable compression for ssh session\n"); } @@ -3165,14 +3156,14 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done) #ifdef HAVE_LIBSSH2_KNOWNHOST_API if(data->set.str[STRING_SSH_KNOWNHOSTS]) { int rc; - ssh->kh = libssh2_knownhost_init(ssh->ssh_session); - if(!ssh->kh) { - libssh2_session_free(ssh->ssh_session); + sshc->kh = libssh2_knownhost_init(sshc->ssh_session); + if(!sshc->kh) { + libssh2_session_free(sshc->ssh_session); return CURLE_FAILED_INIT; } /* read all known hosts from there */ - rc = libssh2_knownhost_readfile(ssh->kh, + rc = libssh2_knownhost_readfile(sshc->kh, data->set.str[STRING_SSH_KNOWNHOSTS], LIBSSH2_KNOWNHOST_FILE_OPENSSH); if(rc < 0) @@ -3182,13 +3173,13 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done) #endif /* HAVE_LIBSSH2_KNOWNHOST_API */ #ifdef CURL_LIBSSH2_DEBUG - libssh2_trace(ssh->ssh_session, ~0); + libssh2_trace(sshc->ssh_session, ~0); infof(data, "SSH socket: %d\n", (int)sock); #endif /* CURL_LIBSSH2_DEBUG */ - state(conn, SSH_INIT); + state(data, SSH_INIT); - result = ssh_multi_statemach(conn, done); + result = ssh_multi_statemach(data, done); return result; } @@ -3203,40 +3194,41 @@ static CURLcode ssh_connect(struct connectdata *conn, bool *done) */ static -CURLcode scp_perform(struct connectdata *conn, - bool *connected, - bool *dophase_done) +CURLcode scp_perform(struct Curl_easy *data, + bool *connected, + bool *dophase_done) { CURLcode result = CURLE_OK; + struct connectdata *conn = data->conn; - DEBUGF(infof(conn->data, "DO phase starts\n")); + DEBUGF(infof(data, "DO phase starts\n")); *dophase_done = FALSE; /* not done yet */ /* start the first command in the DO phase */ - state(conn, SSH_SCP_TRANS_INIT); + state(data, SSH_SCP_TRANS_INIT); /* run the state-machine */ - result = ssh_multi_statemach(conn, dophase_done); + result = ssh_multi_statemach(data, dophase_done); *connected = conn->bits.tcpconnect[FIRSTSOCKET]; if(*dophase_done) { - DEBUGF(infof(conn->data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete\n")); } return result; } /* called from multi.c while DOing */ -static CURLcode scp_doing(struct connectdata *conn, - bool *dophase_done) +static CURLcode scp_doing(struct Curl_easy *data, + bool *dophase_done) { CURLcode result; - result = ssh_multi_statemach(conn, dophase_done); + result = ssh_multi_statemach(data, dophase_done); if(*dophase_done) { - DEBUGF(infof(conn->data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete\n")); } return result; } @@ -3246,11 +3238,11 @@ static CURLcode scp_doing(struct connectdata *conn, * separate ones but this way means less duplicated code. */ -static CURLcode ssh_do(struct connectdata *conn, bool *done) +static CURLcode ssh_do(struct Curl_easy *data, bool *done) { CURLcode result; bool connected = 0; - struct Curl_easy *data = conn->data; + struct connectdata *conn = data->conn; struct ssh_conn *sshc = &conn->proto.sshc; *done = FALSE; /* default to false */ @@ -3267,9 +3259,9 @@ static CURLcode ssh_do(struct connectdata *conn, bool *done) Curl_pgrsSetDownloadSize(data, -1); if(conn->handler->protocol & CURLPROTO_SCP) - result = scp_perform(conn, &connected, done); + result = scp_perform(data, &connected, done); else - result = sftp_perform(conn, &connected, done); + result = sftp_perform(data, &connected, done); return result; } @@ -3277,18 +3269,20 @@ static CURLcode ssh_do(struct connectdata *conn, bool *done) /* BLOCKING, but the function is using the state machine so the only reason this is still blocking is that the multi interface code has no support for disconnecting operations that takes a while */ -static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection) +static CURLcode scp_disconnect(struct Curl_easy *data, + struct connectdata *conn, + bool dead_connection) { CURLcode result = CURLE_OK; - struct ssh_conn *ssh = &conn->proto.sshc; + struct ssh_conn *sshc = &conn->proto.sshc; (void) dead_connection; - if(ssh->ssh_session) { + if(sshc->ssh_session) { /* only if there's a session still around to use! */ - state(conn, SSH_SESSION_DISCONNECT); + state(data, SSH_SESSION_DISCONNECT); - result = ssh_block_statemach(conn, FALSE); + result = ssh_block_statemach(data, conn, FALSE); } return result; @@ -3296,51 +3290,56 @@ static CURLcode scp_disconnect(struct connectdata *conn, bool dead_connection) /* generic done function for both SCP and SFTP called from their specific done functions */ -static CURLcode ssh_done(struct connectdata *conn, CURLcode status) +static CURLcode ssh_done(struct Curl_easy *data, CURLcode status) { CURLcode result = CURLE_OK; - struct SSHPROTO *sftp_scp = conn->data->req.p.ssh; + struct SSHPROTO *sshp = data->req.p.ssh; + struct connectdata *conn = data->conn; if(!status) { /* run the state-machine */ - result = ssh_block_statemach(conn, FALSE); + result = ssh_block_statemach(data, conn, FALSE); } else result = status; - if(sftp_scp) - Curl_safefree(sftp_scp->path); - if(Curl_pgrsDone(conn)) + Curl_safefree(sshp->path); + Curl_safefree(sshp->readdir_filename); + Curl_safefree(sshp->readdir_longentry); + Curl_dyn_free(&sshp->readdir); + + if(Curl_pgrsDone(data)) return CURLE_ABORTED_BY_CALLBACK; - conn->data->req.keepon = 0; /* clear all bits */ + data->req.keepon = 0; /* clear all bits */ return result; } -static CURLcode scp_done(struct connectdata *conn, CURLcode status, +static CURLcode scp_done(struct Curl_easy *data, CURLcode status, bool premature) { (void)premature; /* not used */ if(!status) - state(conn, SSH_SCP_DONE); + state(data, SSH_SCP_DONE); - return ssh_done(conn, status); + return ssh_done(data, status); } -static ssize_t scp_send(struct connectdata *conn, int sockindex, +static ssize_t scp_send(struct Curl_easy *data, int sockindex, const void *mem, size_t len, CURLcode *err) { ssize_t nwrite; + struct connectdata *conn = data->conn; + struct ssh_conn *sshc = &conn->proto.sshc; (void)sockindex; /* we only support SCP on the fixed known primary socket */ /* libssh2_channel_write() returns int! */ - nwrite = (ssize_t) - libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len); + nwrite = (ssize_t) libssh2_channel_write(sshc->ssh_channel, mem, len); - ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); + ssh_block2waitfor(data, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); if(nwrite == LIBSSH2_ERROR_EAGAIN) { *err = CURLE_AGAIN; @@ -3354,17 +3353,18 @@ static ssize_t scp_send(struct connectdata *conn, int sockindex, return nwrite; } -static ssize_t scp_recv(struct connectdata *conn, int sockindex, +static ssize_t scp_recv(struct Curl_easy *data, int sockindex, char *mem, size_t len, CURLcode *err) { ssize_t nread; + struct connectdata *conn = data->conn; + struct ssh_conn *sshc = &conn->proto.sshc; (void)sockindex; /* we only support SCP on the fixed known primary socket */ /* libssh2_channel_read() returns int */ - nread = (ssize_t) - libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len); + nread = (ssize_t) libssh2_channel_read(sshc->ssh_channel, mem, len); - ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); + ssh_block2waitfor(data, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); if(nread == LIBSSH2_ERROR_EAGAIN) { *err = CURLE_AGAIN; nread = -1; @@ -3387,39 +3387,39 @@ static ssize_t scp_recv(struct connectdata *conn, int sockindex, */ static -CURLcode sftp_perform(struct connectdata *conn, +CURLcode sftp_perform(struct Curl_easy *data, bool *connected, bool *dophase_done) { CURLcode result = CURLE_OK; - DEBUGF(infof(conn->data, "DO phase starts\n")); + DEBUGF(infof(data, "DO phase starts\n")); *dophase_done = FALSE; /* not done yet */ /* start the first command in the DO phase */ - state(conn, SSH_SFTP_QUOTE_INIT); + state(data, SSH_SFTP_QUOTE_INIT); /* run the state-machine */ - result = ssh_multi_statemach(conn, dophase_done); + result = ssh_multi_statemach(data, dophase_done); - *connected = conn->bits.tcpconnect[FIRSTSOCKET]; + *connected = data->conn->bits.tcpconnect[FIRSTSOCKET]; if(*dophase_done) { - DEBUGF(infof(conn->data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete\n")); } return result; } /* called from multi.c while DOing */ -static CURLcode sftp_doing(struct connectdata *conn, +static CURLcode sftp_doing(struct Curl_easy *data, bool *dophase_done) { - CURLcode result = ssh_multi_statemach(conn, dophase_done); + CURLcode result = ssh_multi_statemach(data, dophase_done); if(*dophase_done) { - DEBUGF(infof(conn->data, "DO phase is complete\n")); + DEBUGF(infof(data, "DO phase is complete\n")); } return result; } @@ -3427,53 +3427,56 @@ static CURLcode sftp_doing(struct connectdata *conn, /* BLOCKING, but the function is using the state machine so the only reason this is still blocking is that the multi interface code has no support for disconnecting operations that takes a while */ -static CURLcode sftp_disconnect(struct connectdata *conn, bool dead_connection) +static CURLcode sftp_disconnect(struct Curl_easy *data, + struct connectdata *conn, bool dead_connection) { CURLcode result = CURLE_OK; + struct ssh_conn *sshc = &conn->proto.sshc; (void) dead_connection; - DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n")); + DEBUGF(infof(data, "SSH DISCONNECT starts now\n")); - if(conn->proto.sshc.ssh_session) { + if(sshc->ssh_session) { /* only if there's a session still around to use! */ - state(conn, SSH_SFTP_SHUTDOWN); - result = ssh_block_statemach(conn, FALSE); + state(data, SSH_SFTP_SHUTDOWN); + result = ssh_block_statemach(data, conn, FALSE); } - DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n")); + DEBUGF(infof(data, "SSH DISCONNECT is done\n")); return result; } -static CURLcode sftp_done(struct connectdata *conn, CURLcode status, +static CURLcode sftp_done(struct Curl_easy *data, CURLcode status, bool premature) { + struct connectdata *conn = data->conn; struct ssh_conn *sshc = &conn->proto.sshc; if(!status) { /* Post quote commands are executed after the SFTP_CLOSE state to avoid errors that could happen due to open file handles during POSTQUOTE operation */ - if(!premature && conn->data->set.postquote && !conn->bits.retry) + if(!premature && data->set.postquote && !conn->bits.retry) sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT; - state(conn, SSH_SFTP_CLOSE); + state(data, SSH_SFTP_CLOSE); } - return ssh_done(conn, status); + return ssh_done(data, status); } /* return number of sent bytes */ -static ssize_t sftp_send(struct connectdata *conn, int sockindex, +static ssize_t sftp_send(struct Curl_easy *data, int sockindex, const void *mem, size_t len, CURLcode *err) { - ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14 - but is changed to ssize_t in 0.15. These days we don't - support libssh2 0.15*/ + ssize_t nwrite; + struct connectdata *conn = data->conn; + struct ssh_conn *sshc = &conn->proto.sshc; (void)sockindex; - nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len); + nwrite = libssh2_sftp_write(sshc->sftp_handle, mem, len); - ssh_block2waitfor(conn, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); + ssh_block2waitfor(data, (nwrite == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); if(nwrite == LIBSSH2_ERROR_EAGAIN) { *err = CURLE_AGAIN; @@ -3491,15 +3494,17 @@ static ssize_t sftp_send(struct connectdata *conn, int sockindex, * Return number of received (decrypted) bytes * or <0 on error */ -static ssize_t sftp_recv(struct connectdata *conn, int sockindex, +static ssize_t sftp_recv(struct Curl_easy *data, int sockindex, char *mem, size_t len, CURLcode *err) { ssize_t nread; + struct connectdata *conn = data->conn; + struct ssh_conn *sshc = &conn->proto.sshc; (void)sockindex; - nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len); + nread = libssh2_sftp_read(sshc->sftp_handle, mem, len); - ssh_block2waitfor(conn, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); + ssh_block2waitfor(data, (nread == LIBSSH2_ERROR_EAGAIN)?TRUE:FALSE); if(nread == LIBSSH2_ERROR_EAGAIN) { *err = CURLE_AGAIN; |