From 7fd264b27bed0b1cb0b7bf7d75d9d3eabc93cba8 Mon Sep 17 00:00:00 2001 From: simon Date: Mon, 29 Sep 2003 15:39:56 +0000 Subject: [PATCH] PSCP in SFTP mode now uses the fast download/upload manager. git-svn-id: svn://svn.tartarus.org/sgt/putty@3472 cda61777-01e9-0310-a592-d414129be87e --- scp.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 20 deletions(-) diff --git a/scp.c b/scp.c index 00852bc4..de394840 100644 --- a/scp.c +++ b/scp.c @@ -673,6 +673,7 @@ static int scp_sftp_preserve, scp_sftp_recursive; static unsigned long scp_sftp_mtime, scp_sftp_atime; static int scp_has_times; static struct fxp_handle *scp_sftp_filehandle; +static struct fxp_xfer *scp_sftp_xfer; static uint64 scp_sftp_fileoffset; void scp_source_setup(char *target, int shouldbedir) @@ -767,6 +768,8 @@ int scp_send_filename(char *name, unsigned long size, int modes) return 1; } scp_sftp_fileoffset = uint64_make(0, 0); + scp_sftp_xfer = xfer_upload_init(scp_sftp_filehandle, + scp_sftp_fileoffset); sfree(fullname); return 0; } else { @@ -784,23 +787,23 @@ int scp_send_filedata(char *data, int len) if (using_sftp) { int ret; struct sftp_packet *pktin; - struct sftp_request *req, *rreq; if (!scp_sftp_filehandle) { return 1; } - sftp_register(req = fxp_write_send(scp_sftp_filehandle, - data, scp_sftp_fileoffset, len)); - rreq = sftp_find_request(pktin = sftp_recv()); - assert(rreq == req); - ret = fxp_write_recv(pktin, rreq); - - if (!ret) { - tell_user(stderr, "error while writing: %s\n", fxp_error()); - errs++; - return 1; + while (!xfer_upload_ready(scp_sftp_xfer)) { + pktin = sftp_recv(); + ret = xfer_upload_gotpkt(scp_sftp_xfer, pktin); + if (!ret) { + tell_user(stderr, "error while writing: %s\n", fxp_error()); + errs++; + return 1; + } } + + xfer_upload_data(scp_sftp_xfer, data, len); + scp_sftp_fileoffset = uint64_add32(scp_sftp_fileoffset, len); return 0; } else { @@ -830,6 +833,12 @@ int scp_send_finish(void) struct sftp_request *req, *rreq; int ret; + while (!xfer_done(scp_sftp_xfer)) { + pktin = sftp_recv(); + xfer_upload_gotpkt(scp_sftp_xfer, pktin); + } + xfer_cleanup(scp_sftp_xfer); + if (!scp_sftp_filehandle) { return 1; } @@ -1388,6 +1397,8 @@ int scp_accept_filexfer(void) return 1; } scp_sftp_fileoffset = uint64_make(0, 0); + scp_sftp_xfer = xfer_download_init(scp_sftp_filehandle, + scp_sftp_fileoffset); sfree(scp_sftp_currentname); return 0; } else { @@ -1400,21 +1411,30 @@ int scp_recv_filedata(char *data, int len) { if (using_sftp) { struct sftp_packet *pktin; - struct sftp_request *req, *rreq; - int actuallen; + int ret, actuallen; + void *vbuf; - sftp_register(req = fxp_read_send(scp_sftp_filehandle, - scp_sftp_fileoffset, len)); - rreq = sftp_find_request(pktin = sftp_recv()); - assert(rreq == req); - actuallen = fxp_read_recv(pktin, rreq, data, len); + xfer_download_queue(scp_sftp_xfer); + pktin = sftp_recv(); + ret = xfer_download_gotpkt(scp_sftp_xfer, pktin); - if (actuallen == -1 && fxp_error_type() != SSH_FX_EOF) { + if (ret < 0) { tell_user(stderr, "pscp: error while reading: %s", fxp_error()); errs++; return -1; } - if (actuallen < 0) + + if (xfer_download_data(scp_sftp_xfer, &vbuf, &actuallen)) { + /* + * This assertion relies on the fact that the natural + * block size used in the xfer manager is at most that + * used in this module. I don't like crossing layers in + * this way, but it'll do for now. + */ + assert(actuallen <= len); + memcpy(data, vbuf, actuallen); + sfree(vbuf); + } else actuallen = 0; scp_sftp_fileoffset = uint64_add32(scp_sftp_fileoffset, actuallen); @@ -1431,6 +1451,23 @@ int scp_finish_filerecv(void) struct sftp_packet *pktin; struct sftp_request *req, *rreq; + /* + * Ensure that xfer_done() will work correctly, so we can + * clean up any outstanding requests from the file + * transfer. + */ + xfer_set_error(scp_sftp_xfer); + while (!xfer_done(scp_sftp_xfer)) { + void *vbuf; + int len; + + pktin = sftp_recv(); + xfer_download_gotpkt(scp_sftp_xfer, pktin); + if (xfer_download_data(scp_sftp_xfer, &vbuf, &len)) + sfree(vbuf); + } + xfer_cleanup(scp_sftp_xfer); + sftp_register(req = fxp_close_send(scp_sftp_filehandle)); rreq = sftp_find_request(pktin = sftp_recv()); assert(rreq == req); -- 2.11.0