mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-05 21:42:47 -05:00
First cut at speeding up SFTP. Generic download-management code in
sftp.c, and psftp.c now uses that instead of going it alone. Should in principle be easily installed in PSCP as well, but I haven't done it yet; also it only handles downloads, not uploads, and finally it doesn't yet properly calculate the correct number of parallel requests to queue. Still, it's a start, and in my own tests it seemed to perform as expected (download speed suddenly became roughly what you'd expect from the available bandwidth, and decreased by roughly the expected number of round-trip times). [originally from svn r3468]
This commit is contained in:
55
psftp.c
55
psftp.c
@ -370,6 +370,7 @@ int sftp_general_get(struct sftp_command *cmd, int restart)
|
||||
struct fxp_handle *fh;
|
||||
struct sftp_packet *pktin;
|
||||
struct sftp_request *req, *rreq;
|
||||
struct fxp_xfer *xfer;
|
||||
char *fname, *outfname;
|
||||
uint64 offset;
|
||||
FILE *fp;
|
||||
@ -439,41 +440,43 @@ int sftp_general_get(struct sftp_command *cmd, int restart)
|
||||
* thus put up a progress bar.
|
||||
*/
|
||||
ret = 1;
|
||||
while (1) {
|
||||
char buffer[4096];
|
||||
int len;
|
||||
xfer = xfer_download_init(fh, offset);
|
||||
while (!xfer_download_done(xfer)) {
|
||||
void *vbuf;
|
||||
int ret, len;
|
||||
int wpos, wlen;
|
||||
|
||||
sftp_register(req = fxp_read_send(fh, offset, sizeof(buffer)));
|
||||
rreq = sftp_find_request(pktin = sftp_recv());
|
||||
assert(rreq == req);
|
||||
len = fxp_read_recv(pktin, rreq, buffer, sizeof(buffer));
|
||||
xfer_download_queue(xfer);
|
||||
pktin = sftp_recv();
|
||||
ret = xfer_download_gotpkt(xfer, pktin);
|
||||
|
||||
if ((len == -1 && fxp_error_type() == SSH_FX_EOF) || len == 0)
|
||||
break;
|
||||
if (len == -1) {
|
||||
printf("error while reading: %s\n", fxp_error());
|
||||
ret = 0;
|
||||
break;
|
||||
if (ret < 0) {
|
||||
printf("error while reading: %s\n", fxp_error());
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
wpos = 0;
|
||||
while (wpos < len) {
|
||||
wlen = fwrite(buffer, 1, len - wpos, fp);
|
||||
if (wlen <= 0) {
|
||||
printf("error while writing local file\n");
|
||||
ret = 0;
|
||||
break;
|
||||
while (xfer_download_data(xfer, &vbuf, &len)) {
|
||||
unsigned char *buf = (unsigned char *)vbuf;
|
||||
|
||||
wpos = 0;
|
||||
while (wpos < len) {
|
||||
wlen = fwrite(buf + wpos, 1, len - wpos, fp);
|
||||
if (wlen <= 0) {
|
||||
printf("error while writing local file\n");
|
||||
ret = 0;
|
||||
xfer_set_error(xfer);
|
||||
}
|
||||
wpos += wlen;
|
||||
}
|
||||
if (wpos < len) { /* we had an error */
|
||||
ret = 0;
|
||||
xfer_set_error(xfer);
|
||||
}
|
||||
wpos += wlen;
|
||||
}
|
||||
if (wpos < len) { /* we had an error */
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
offset = uint64_add32(offset, len);
|
||||
}
|
||||
|
||||
xfer_cleanup(xfer);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
sftp_register(req = fxp_close_send(fh));
|
||||
|
Reference in New Issue
Block a user