* Finish moving sftp:// into a state machine so it won't block in multi mode

* Move scp:// into a state machine so it won't block in multi mode
* When available use the full directory entry from the sftp:// server
This commit is contained in:
James Housley 2007-07-10 22:26:32 +00:00
parent 93bd512357
commit 8026d94c07
5 changed files with 1709 additions and 559 deletions

2179
lib/ssh.c

File diff suppressed because it is too large Load Diff

View File

@ -45,6 +45,13 @@ ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex,
ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
char *mem, size_t len);
#if (LIBSSH2_APINO >= 200706012030)
CURLcode Curl_sftp_doing(struct connectdata *conn,
bool *dophase_done);
CURLcode Curl_scp_doing(struct connectdata *conn,
bool *dophase_done);
#endif (LIBSSH2_APINO >= 200706012030)
#endif /* USE_LIBSSH2 */
#endif /* __SSH_H */

View File

@ -330,9 +330,13 @@ CURLcode Curl_readwrite(struct connectdata *conn,
/* only use the proper socket if the *_HOLD bit is not set simultaneously as
then we are in rate limiting state in that transfer direction */
if((k->keepon & (KEEP_READ|KEEP_READ_HOLD)) == KEEP_READ)
if((k->keepon & (KEEP_READ|KEEP_READ_HOLD)) == KEEP_READ) {
fd_read = conn->sockfd;
else
#if defined(USE_LIBSSH2) && (LIBSSH2_APINO >= 200706012030)
if (conn->protocol & (PROT_SCP|PROT_SFTP))
select_res |= CURL_CSELECT_IN;
#endif /* USE_LIBSSH2 && (LIBSSH2_APINO >= 200706012030) */
} else
fd_read = CURL_SOCKET_BAD;
if((k->keepon & (KEEP_WRITE|KEEP_WRITE_HOLD)) == KEEP_WRITE)
@ -340,11 +344,11 @@ CURLcode Curl_readwrite(struct connectdata *conn,
else
fd_write = CURL_SOCKET_BAD;
if (!select_res) { /* Call for select()/poll() only, if read/write/error
if (!select_res) { /* Call for select()/poll() only, if read/write/error
status is not known. */
select_res = Curl_socket_ready(fd_read, fd_write, 0);
}
if(select_res == CURL_CSELECT_ERR) {
failf(data, "select/poll returned error");
return CURLE_SEND_ERROR;

View File

@ -3361,6 +3361,10 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */
conn->curl_do = Curl_scp_do;
conn->curl_done = Curl_scp_done;
#if (LIBSSH2_APINO >= 200706012030)
conn->curl_connecting = Curl_ssh_multi_statemach;
conn->curl_doing = Curl_scp_doing;
#endif (LIBSSH2_APINO >= 200706012030)
conn->curl_do_more = (Curl_do_more_func)ZERO_NULL;
#else
failf(data, LIBCURL_NAME
@ -3376,14 +3380,18 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */
conn->curl_do = Curl_sftp_do;
conn->curl_done = Curl_sftp_done;
conn->curl_do_more = (Curl_do_more_func)NULL;
#if (LIBSSH2_APINO >= 200706012030)
conn->curl_connecting = Curl_ssh_multi_statemach;
conn->curl_doing = Curl_sftp_doing;
#endif (LIBSSH2_APINO >= 200706012030)
conn->curl_do_more = (Curl_do_more_func)ZERO_NULL;
#else
failf(data, LIBCURL_NAME
" was built without LIBSSH2, scp: not supported!");
return CURLE_UNSUPPORTED_PROTOCOL;
#endif
}
else {
}
else {
/* We fell through all checks and thus we don't support the specified
protocol */
failf(data, "Unsupported protocol: %s", conn->protostr);

View File

@ -411,8 +411,9 @@ struct ftp_conn {
* SSH unique setup
***************************************************************************/
typedef enum {
SSH_STOP, /* do nothing state, stops the state machine */
SSH_S_STARTUP, /* Session startup */
SSH_NO_STATE = -1, /* Used for "nextState" so say there is none */
SSH_STOP = 0, /* do nothing state, stops the state machine */
SSH_S_STARTUP, /* Session startup */
SSH_AUTHLIST,
SSH_AUTH_PKEY_INIT,
SSH_AUTH_PKEY,
@ -426,7 +427,41 @@ typedef enum {
SSH_SFTP_INIT,
SSH_SFTP_REALPATH,
SSH_GET_WORKINGPATH,
SSH_SFTP_QUOTE_INIT,
SSH_SFTP_POSTQUOTE_INIT,
SSH_SFTP_QUOTE,
SSH_SFTP_NEXT_QUOTE,
SSH_SFTP_QUOTE_STAT,
SSH_SFTP_QUOTE_SETSTAT,
SSH_SFTP_QUOTE_SYMLINK,
SSH_SFTP_QUOTE_MKDIR,
SSH_SFTP_QUOTE_RENAME,
SSH_SFTP_QUOTE_RMDIR,
SSH_SFTP_QUOTE_UNLINK,
SSH_SFTP_TRANS_INIT,
SSH_SFTP_UPLOAD_INIT,
SSH_SFTP_CREATE_DIRS_INIT,
SSH_SFTP_CREATE_DIRS,
SSH_SFTP_CREATE_DIRS_MKDIR,
SSH_SFTP_READDIR_INIT,
SSH_SFTP_READDIR,
SSH_SFTP_READDIR_LINK,
SSH_SFTP_READDIR_BOTTOM,
SSH_SFTP_READDIR_DONE,
SSH_SFTP_DOWNLOAD_INIT,
SSH_SFTP_DOWNLOAD_STAT,
SSH_SFTP_CLOSE,
SSH_SFTP_SHUTDOWN,
SSH_SCP_TRANS_INIT,
SSH_SCP_UPLOAD_INIT,
SSH_SCP_DOWNLOAD_INIT,
SSH_SCP_DONE,
SSH_SCP_SEND_EOF,
SSH_SCP_WAIT_EOF,
SSH_SCP_WAIT_CLOSE,
SSH_SCP_CHANNEL_FREE,
SSH_CHANNEL_CLOSE,
SSH_SESSION_DISCONECT,
SSH_SESSION_FREE,
SSH_QUIT,
SSH_LAST /* never used */
@ -451,12 +486,27 @@ struct SSHPROTO {
struct */
struct ssh_conn {
const char *authlist; /* List of auth. methods, managed by libssh2 */
#ifdef USE_LIBSSH2
const char *passphrase;
char *rsa_pub;
char *rsa;
bool authed;
sshstate state; /* always use ssh.c:state() to change state! */
sshstate nextState; /* the state to goto after stopping */
CURLcode actualCode; /* the actual error code */
struct curl_slist *quote_item;
char *quote_path1;
char *quote_path2;
LIBSSH2_SFTP_ATTRIBUTES quote_attrs;
LIBSSH2_SFTP_ATTRIBUTES readdir_attrs;
char *readdir_filename;
char *readdir_longentry;
int readdir_len, readdir_totalLen, readdir_currLen;
char *readdir_line;
char *readdir_linkPath;
int secondCreateDirs;
char *slash_pos;
#endif /* USE_LIBSSH2 */
};
@ -906,7 +956,7 @@ struct connectdata {
struct curl_llist *recv_pipe; /* List of handles waiting to read
their responses on this pipeline */
char* master_buffer; /* The master buffer allocated on-demand;
char* master_buffer; /* The master buffer allocated on-demand;
used for pipelining. */
size_t read_pos; /* Current read position in the master buffer */
size_t buf_len; /* Length of the buffer?? */