Commit 8026d94c authored by James Housley's avatar James Housley
Browse files

* 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
parent 93bd5123
Loading
Loading
Loading
Loading
+1631 −550

File changed.

Preview size limit exceeded, changes collapsed.

+7 −0
Original line number Diff line number Diff line
@@ -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 */
+8 −4
Original line number Diff line number Diff line
@@ -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)
+11 −3
Original line number Diff line number Diff line
@@ -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,7 +3380,11 @@ 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!");
+53 −3
Original line number Diff line number Diff line
@@ -411,7 +411,8 @@ struct ftp_conn {
 * SSH unique setup
 ***************************************************************************/
typedef enum {
  SSH_STOP,    /* do nothing state, stops the state machine */
  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,
@@ -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 */
};