From 65857773290a7bacd6f5d84ab51a9c1228e61e99 Mon Sep 17 00:00:00 2001 From: simon Date: Thu, 16 Dec 2004 19:15:38 +0000 Subject: [PATCH] Jacob points out that I introduced a bug in PSFTP when I did the timing shakeup: just running `psftp' caused the net/stdin select loop (on both Unix and Windows) to get confused at the lack of any network connection and give up immediately. Should now be fixed. git-svn-id: svn://svn.tartarus.org/sgt/putty@4993 cda61777-01e9-0310-a592-d414129be87e --- psftp.c | 4 +++- psftp.h | 9 ++++++++- unix/uxsftp.c | 10 +++++----- windows/winsftp.c | 7 ++++--- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/psftp.c b/psftp.c index de1964e8..8dcee0e2 100644 --- a/psftp.c +++ b/psftp.c @@ -1866,7 +1866,7 @@ struct sftp_command *sftp_getcmd(FILE *fp, int mode, int modeflags) printf("psftp> "); line = fgetline(fp); } else { - line = ssh_sftp_get_cmdline("psftp> "); + line = ssh_sftp_get_cmdline("psftp> ", back == NULL); } if (!line || !*line) { @@ -2004,6 +2004,8 @@ void do_sftp_cleanup() sftp_recvdata(&ch, 1); back->free(backhandle); sftp_cleanup_request(); + back = NULL; + backhandle = NULL; } if (pwd) { sfree(pwd); diff --git a/psftp.h b/psftp.h index 6ce24e8f..af8917db 100644 --- a/psftp.h +++ b/psftp.h @@ -35,8 +35,15 @@ int ssh_sftp_loop_iteration(void); /* * Read a command line for PSFTP from standard input. Caller must * free. + * + * If `backend_required' is TRUE, should also listen for activity + * at the backend (rekeys, clientalives, unexpected closures etc) + * and respond as necessary, and if the backend closes it should + * treat this as a failure condition. If `backend_required' is + * FALSE, a back end is not (intentionally) active at all (e.g. + * psftp before an `open' command). */ -char *ssh_sftp_get_cmdline(char *prompt); +char *ssh_sftp_get_cmdline(char *prompt, int backend_required); /* * The main program in psftp.c. Called from main() in the platform- diff --git a/unix/uxsftp.c b/unix/uxsftp.c index 0862bc4c..9958a798 100644 --- a/unix/uxsftp.c +++ b/unix/uxsftp.c @@ -355,7 +355,7 @@ char *dir_file_cat(char *dir, char *file) * Do a select() between all currently active network fds and * optionally stdin. */ -static int ssh_sftp_do_select(int include_stdin) +static int ssh_sftp_do_select(int include_stdin, int no_fds_ok) { fd_set rset, wset, xset; int i, fdcount, fdsize, *fdlist; @@ -372,7 +372,7 @@ static int ssh_sftp_do_select(int include_stdin) for (fd = first_fd(&fdstate, &rwx); fd >= 0; fd = next_fd(&fdstate, &rwx)) i++; - if (i < 1) + if (i < 1 && !no_fds_ok) return -1; /* doom */ /* Expand the fdlist buffer if necessary. */ @@ -457,13 +457,13 @@ static int ssh_sftp_do_select(int include_stdin) */ int ssh_sftp_loop_iteration(void) { - return ssh_sftp_do_select(FALSE); + return ssh_sftp_do_select(FALSE, FALSE); } /* * Read a PSFTP command line from stdin. */ -char *ssh_sftp_get_cmdline(char *prompt) +char *ssh_sftp_get_cmdline(char *prompt, int no_fds_ok) { char *buf; int buflen, bufsize, ret; @@ -475,7 +475,7 @@ char *ssh_sftp_get_cmdline(char *prompt) buflen = bufsize = 0; while (1) { - ret = ssh_sftp_do_select(TRUE); + ret = ssh_sftp_do_select(TRUE, no_fds_ok); if (ret < 0) { printf("connection died\n"); return NULL; /* woop woop */ diff --git a/windows/winsftp.c b/windows/winsftp.c index d9ea3cac..c0712571 100644 --- a/windows/winsftp.c +++ b/windows/winsftp.c @@ -462,7 +462,7 @@ char *dir_file_cat(char *dir, char *file) /* * Be told what socket we're supposed to be using. */ -static SOCKET sftp_ssh_socket; +static SOCKET sftp_ssh_socket = INVALID_SOCKET; static HANDLE netevent = NULL; char *do_select(SOCKET skt, int startup) { @@ -676,7 +676,7 @@ static DWORD WINAPI command_read_thread(void *param) return 0; } -char *ssh_sftp_get_cmdline(char *prompt) +char *ssh_sftp_get_cmdline(char *prompt, int no_fds_ok) { int ret; struct command_read_ctx actx, *ctx = &actx; @@ -685,7 +685,8 @@ char *ssh_sftp_get_cmdline(char *prompt) fputs(prompt, stdout); fflush(stdout); - if (sftp_ssh_socket == INVALID_SOCKET || p_WSAEventSelect == NULL) { + if ((sftp_ssh_socket == INVALID_SOCKET && no_fds_ok) || + p_WSAEventSelect == NULL) { return fgetline(stdin); /* very simple */ } -- 2.11.0