version 1.47, 2004/03/03 09:30:42 |
version 1.47.2.1, 2004/08/19 04:13:27 |
|
|
#include "sftp-common.h" |
#include "sftp-common.h" |
#include "sftp-client.h" |
#include "sftp-client.h" |
|
|
|
extern volatile sig_atomic_t interrupted; |
extern int showprogress; |
extern int showprogress; |
|
|
/* Minimum amount of data to read at at time */ |
/* Minimum amount of data to read at at time */ |
|
|
(*dir)[0] = NULL; |
(*dir)[0] = NULL; |
} |
} |
|
|
for (;;) { |
for (; !interrupted;) { |
int count; |
int count; |
|
|
id = expected_id = conn->msg_id++; |
id = expected_id = conn->msg_id++; |
|
|
do_close(conn, handle, handle_len); |
do_close(conn, handle, handle_len); |
xfree(handle); |
xfree(handle); |
|
|
|
/* Don't return partial matches on interrupt */ |
|
if (interrupted && dir != NULL && *dir != NULL) { |
|
free_sftp_dirents(*dir); |
|
*dir = xmalloc(sizeof(**dir)); |
|
**dir = NULL; |
|
} |
|
|
return(0); |
return(0); |
} |
} |
|
|
|
|
|
|
buffer_init(&msg); |
buffer_init(&msg); |
|
|
/* Send rename request */ |
/* Send symlink request */ |
id = conn->msg_id++; |
id = conn->msg_id++; |
buffer_put_char(&msg, SSH2_FXP_SYMLINK); |
buffer_put_char(&msg, SSH2_FXP_SYMLINK); |
buffer_put_int(&msg, id); |
buffer_put_int(&msg, id); |
|
|
char *data; |
char *data; |
u_int len; |
u_int len; |
|
|
|
/* |
|
* Simulate EOF on interrupt: stop sending new requests and |
|
* allow outstanding requests to drain gracefully |
|
*/ |
|
if (interrupted) { |
|
if (num_req == 0) /* If we haven't started yet... */ |
|
break; |
|
max_req = 0; |
|
} |
|
|
/* Send some more requests */ |
/* Send some more requests */ |
while (num_req < max_req) { |
while (num_req < max_req) { |
debug3("Request range %llu -> %llu (%d/%d)", |
debug3("Request range %llu -> %llu (%d/%d)", |
|
|
(unsigned long long)offset, |
(unsigned long long)offset, |
num_req); |
num_req); |
max_req = 1; |
max_req = 1; |
} |
} else if (max_req <= conn->num_requests) { |
else if (max_req < conn->num_requests + 1) { |
|
++max_req; |
++max_req; |
} |
} |
} |
} |
|
|
TAILQ_ENTRY(outstanding_ack) tq; |
TAILQ_ENTRY(outstanding_ack) tq; |
}; |
}; |
TAILQ_HEAD(ackhead, outstanding_ack) acks; |
TAILQ_HEAD(ackhead, outstanding_ack) acks; |
struct outstanding_ack *ack; |
struct outstanding_ack *ack = NULL; |
|
|
TAILQ_INIT(&acks); |
TAILQ_INIT(&acks); |
|
|
|
|
int len; |
int len; |
|
|
/* |
/* |
* Can't use atomicio here because it returns 0 on EOF, thus losing |
* Can't use atomicio here because it returns 0 on EOF, |
* the last block of the file |
* thus losing the last block of the file. |
|
* Simulate an EOF on interrupt, allowing ACKs from the |
|
* server to drain. |
*/ |
*/ |
do |
if (interrupted) |
|
len = 0; |
|
else do |
len = read(local_fd, data, conn->transfer_buflen); |
len = read(local_fd, data, conn->transfer_buflen); |
while ((len == -1) && (errno == EINTR || errno == EAGAIN)); |
while ((len == -1) && (errno == EINTR || errno == EAGAIN)); |
|
|