unsigned char *p = (unsigned char *) data;
unsigned len = (unsigned) datalen;
- assert(len > 0);
-
/*
* stderr data is just spouted to local stderr and otherwise
* ignored.
*/
if (is_stderr) {
- fwrite(data, 1, len, stderr);
+ if (len > 0)
+ fwrite(data, 1, len, stderr);
return 0;
}
if (!outptr)
return 0;
- if (outlen > 0) {
+ if ((outlen > 0) && (len > 0)) {
unsigned used = outlen;
if (used > len)
used = len;
if (back != NULL && back->socket(backhandle) != NULL) {
char ch;
back->special(backhandle, TS_EOF);
- ssh_scp_recv(&ch, 1);
+ ssh_scp_recv((unsigned char *) &ch, 1);
}
if (gui_mode)
pct = (int) (100 * (done * 1.0 / size));
if (gui_mode) {
- gui_update_stats(name, size, pct, elap, done, eta,
+ gui_update_stats(name, size, pct, elap, done, eta,
(unsigned long) ratebs);
} else {
len = printf("\r%-25.25s | %10ld kB | %5.1f kB/s | ETA: %8s | %3d%%",
if (done == size)
printf("\n");
+
+ fflush(stdout);
}
}
char ch, resp, rbuf[2048];
int p;
- if (ssh_scp_recv(&resp, 1) <= 0)
+ if (ssh_scp_recv((unsigned char *) &resp, 1) <= 0)
bump("Lost connection");
p = 0;
case 1: /* error */
case 2: /* fatal error */
do {
- if (ssh_scp_recv(&ch, 1) <= 0)
+ if (ssh_scp_recv((unsigned char *) &ch, 1) <= 0)
bump("Protocol error: Lost connection");
rbuf[p++] = ch;
} while (p < sizeof(rbuf) && ch != '\n');
int sftp_recvdata(char *buf, int len)
{
- return ssh_scp_recv(buf, len);
+ return ssh_scp_recv((unsigned char *) buf, len);
}
int sftp_senddata(char *buf, int len)
{
- back->send(backhandle, (unsigned char *) buf, len);
+ back->send(backhandle, buf, len);
return 1;
}
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)
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 {
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 {
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;
}
bufsize = 0;
while (!done) {
- if (ssh_scp_recv(&ch, 1) <= 0)
+ if (ssh_scp_recv((unsigned char *) &ch, 1) <= 0)
return 1;
if (ch == '\n')
bump("Protocol error: Unexpected newline");
i = 0;
action = ch;
do {
- if (ssh_scp_recv(&ch, 1) <= 0)
+ if (ssh_scp_recv((unsigned char *) &ch, 1) <= 0)
bump("Lost connection");
if (i >= bufsize) {
bufsize = i + 128;
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 {
{
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);
return actuallen;
} else {
- return ssh_scp_recv(data, len);
+ return ssh_scp_recv((unsigned char *) data, len);
}
}
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);
if (using_sftp) {
scp_sftp_listdir(src);
} else {
- while (ssh_scp_recv(&c, 1) > 0)
+ while (ssh_scp_recv((unsigned char *) &c, 1) > 0)
tell_char(stdout, c);
}
}
printf("Usage: pscp [options] [user@]host:source target\n");
printf
(" pscp [options] source [source...] [user@]host:target\n");
- printf(" pscp [options] -ls user@host:filespec\n");
+ printf(" pscp [options] -ls [user@]host:filespec\n");
printf("Options:\n");
printf(" -p preserve file attributes\n");
printf(" -q quiet, don't show statistics\n");
if (back != NULL && back->socket(backhandle) != NULL) {
char ch;
back->special(backhandle, TS_EOF);
- ssh_scp_recv(&ch, 1);
+ ssh_scp_recv((unsigned char *) &ch, 1);
}
random_save_seed();
if (gui_mode)
gui_send_errcount(list, errs);
+ cmdline_cleanup();
+ console_provide_logctx(NULL);
+ back->free(backhandle);
+ backhandle = NULL;
+ back = NULL;
+ sk_cleanup();
return (errs == 0 ? 0 : 1);
}