version 1.19, 2001/12/19 07:18:56 |
version 1.20, 2002/02/05 00:00:46 |
|
|
#include "sftp-common.h" |
#include "sftp-common.h" |
#include "sftp-client.h" |
#include "sftp-client.h" |
|
|
/* How much data to read/write at at time during copies */ |
|
/* XXX: what should this be? */ |
|
#define COPY_SIZE 8192 |
|
|
|
/* Message ID */ |
/* Message ID */ |
static u_int msg_id = 1; |
static u_int msg_id = 1; |
|
|
|
|
|
|
int |
int |
do_download(int fd_in, int fd_out, char *remote_path, char *local_path, |
do_download(int fd_in, int fd_out, char *remote_path, char *local_path, |
int pflag) |
int pflag, size_t buflen) |
{ |
{ |
int local_fd; |
int local_fd, status; |
u_int expected_id, handle_len, mode, type, id; |
u_int expected_id, handle_len, mode, type, id; |
u_int64_t offset; |
u_int64_t offset; |
char *handle; |
char *handle; |
Buffer msg; |
Buffer msg; |
Attrib junk, *a; |
Attrib junk, *a; |
int status; |
|
|
|
a = do_stat(fd_in, fd_out, remote_path, 0); |
a = do_stat(fd_in, fd_out, remote_path, 0); |
if (a == NULL) |
if (a == NULL) |
|
|
buffer_put_int(&msg, id); |
buffer_put_int(&msg, id); |
buffer_put_string(&msg, handle, handle_len); |
buffer_put_string(&msg, handle, handle_len); |
buffer_put_int64(&msg, offset); |
buffer_put_int64(&msg, offset); |
buffer_put_int(&msg, COPY_SIZE); |
buffer_put_int(&msg, buflen); |
send_msg(fd_out, &msg); |
send_msg(fd_out, &msg); |
debug3("Sent message SSH2_FXP_READ I:%d O:%llu S:%u", |
debug3("Sent message SSH2_FXP_READ I:%d O:%llu S:%u", |
id, (unsigned long long)offset, COPY_SIZE); |
id, (unsigned long long)offset, buflen); |
|
|
buffer_clear(&msg); |
buffer_clear(&msg); |
|
|
|
|
} |
} |
|
|
data = buffer_get_string(&msg, &len); |
data = buffer_get_string(&msg, &len); |
if (len > COPY_SIZE) |
if (len > buflen) |
fatal("Received more data than asked for %d > %d", |
fatal("Received more data than asked for %d > %d", |
len, COPY_SIZE); |
len, buflen); |
|
|
debug3("In read loop, got %d offset %llu", len, |
debug3("In read loop, got %d offset %llu", len, |
(unsigned long long)offset); |
(unsigned long long)offset); |
|
|
|
|
int |
int |
do_upload(int fd_in, int fd_out, char *local_path, char *remote_path, |
do_upload(int fd_in, int fd_out, char *local_path, char *remote_path, |
int pflag) |
int pflag, size_t buflen) |
{ |
{ |
int local_fd; |
int local_fd, status; |
u_int handle_len, id; |
u_int handle_len, id; |
u_int64_t offset; |
u_int64_t offset; |
char *handle; |
char *handle, *data; |
Buffer msg; |
Buffer msg; |
struct stat sb; |
struct stat sb; |
Attrib a; |
Attrib a; |
int status; |
|
|
|
if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) { |
if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) { |
error("Couldn't open local file \"%s\" for reading: %s", |
error("Couldn't open local file \"%s\" for reading: %s", |
|
|
return(-1); |
return(-1); |
} |
} |
|
|
|
data = xmalloc(buflen); |
|
|
/* Read from local and write to remote */ |
/* Read from local and write to remote */ |
offset = 0; |
offset = 0; |
for (;;) { |
for (;;) { |
int len; |
int len; |
char data[COPY_SIZE]; |
|
|
|
/* |
/* |
* Can't use atomicio here because it returns 0 on EOF, thus losing |
* Can't use atomicio here because it returns 0 on EOF, thus losing |
* the last block of the file |
* the last block of the file |
*/ |
*/ |
do |
do |
len = read(local_fd, data, COPY_SIZE); |
len = read(local_fd, data, buflen); |
while ((len == -1) && (errno == EINTR || errno == EAGAIN)); |
while ((len == -1) && (errno == EINTR || errno == EAGAIN)); |
|
|
if (len == -1) |
if (len == -1) |
|
|
|
|
offset += len; |
offset += len; |
} |
} |
|
xfree(data); |
|
|
if (close(local_fd) == -1) { |
if (close(local_fd) == -1) { |
error("Couldn't close local file \"%s\": %s", local_path, |
error("Couldn't close local file \"%s\": %s", local_path, |