1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-21 23:58:49 -05:00

* 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, ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
char *mem, size_t len); 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 /* USE_LIBSSH2 */
#endif /* __SSH_H */ #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 /* 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 */ 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; 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; fd_read = CURL_SOCKET_BAD;
if((k->keepon & (KEEP_WRITE|KEEP_WRITE_HOLD)) == KEEP_WRITE) if((k->keepon & (KEEP_WRITE|KEEP_WRITE_HOLD)) == KEEP_WRITE)
@ -340,11 +344,11 @@ CURLcode Curl_readwrite(struct connectdata *conn,
else else
fd_write = CURL_SOCKET_BAD; 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. */ status is not known. */
select_res = Curl_socket_ready(fd_read, fd_write, 0); select_res = Curl_socket_ready(fd_read, fd_write, 0);
} }
if(select_res == CURL_CSELECT_ERR) { if(select_res == CURL_CSELECT_ERR) {
failf(data, "select/poll returned error"); failf(data, "select/poll returned error");
return CURLE_SEND_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_connect = Curl_ssh_connect; /* ssh_connect? */
conn->curl_do = Curl_scp_do; conn->curl_do = Curl_scp_do;
conn->curl_done = Curl_scp_done; 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; conn->curl_do_more = (Curl_do_more_func)ZERO_NULL;
#else #else
failf(data, LIBCURL_NAME failf(data, LIBCURL_NAME
@ -3376,14 +3380,18 @@ static CURLcode CreateConnection(struct SessionHandle *data,
conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */ conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */
conn->curl_do = Curl_sftp_do; conn->curl_do = Curl_sftp_do;
conn->curl_done = Curl_sftp_done; 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 #else
failf(data, LIBCURL_NAME failf(data, LIBCURL_NAME
" was built without LIBSSH2, scp: not supported!"); " was built without LIBSSH2, scp: not supported!");
return CURLE_UNSUPPORTED_PROTOCOL; return CURLE_UNSUPPORTED_PROTOCOL;
#endif #endif
} }
else { else {
/* We fell through all checks and thus we don't support the specified /* We fell through all checks and thus we don't support the specified
protocol */ protocol */
failf(data, "Unsupported protocol: %s", conn->protostr); failf(data, "Unsupported protocol: %s", conn->protostr);

View File

@ -411,8 +411,9 @@ struct ftp_conn {
* SSH unique setup * SSH unique setup
***************************************************************************/ ***************************************************************************/
typedef enum { typedef enum {
SSH_STOP, /* do nothing state, stops the state machine */ SSH_NO_STATE = -1, /* Used for "nextState" so say there is none */
SSH_S_STARTUP, /* Session startup */ SSH_STOP = 0, /* do nothing state, stops the state machine */
SSH_S_STARTUP, /* Session startup */
SSH_AUTHLIST, SSH_AUTHLIST,
SSH_AUTH_PKEY_INIT, SSH_AUTH_PKEY_INIT,
SSH_AUTH_PKEY, SSH_AUTH_PKEY,
@ -426,7 +427,41 @@ typedef enum {
SSH_SFTP_INIT, SSH_SFTP_INIT,
SSH_SFTP_REALPATH, SSH_SFTP_REALPATH,
SSH_GET_WORKINGPATH, 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_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_SESSION_FREE,
SSH_QUIT, SSH_QUIT,
SSH_LAST /* never used */ SSH_LAST /* never used */
@ -451,12 +486,27 @@ struct SSHPROTO {
struct */ struct */
struct ssh_conn { struct ssh_conn {
const char *authlist; /* List of auth. methods, managed by libssh2 */ const char *authlist; /* List of auth. methods, managed by libssh2 */
#ifdef USE_LIBSSH2
const char *passphrase; const char *passphrase;
char *rsa_pub; char *rsa_pub;
char *rsa; char *rsa;
bool authed; bool authed;
sshstate state; /* always use ssh.c:state() to change state! */ sshstate state; /* always use ssh.c:state() to change state! */
sshstate nextState; /* the state to goto after stopping */
CURLcode actualCode; /* the actual error code */ 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 struct curl_llist *recv_pipe; /* List of handles waiting to read
their responses on this pipeline */ 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. */ used for pipelining. */
size_t read_pos; /* Current read position in the master buffer */ size_t read_pos; /* Current read position in the master buffer */
size_t buf_len; /* Length of the buffer?? */ size_t buf_len; /* Length of the buffer?? */