version 1.150, 2021/08/07 00:12:09 |
version 1.151, 2021/08/07 00:14:17 |
|
|
get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len, |
get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len, |
const char *errfmt, ...) __attribute__((format(printf, 4, 5))); |
const char *errfmt, ...) __attribute__((format(printf, 4, 5))); |
|
|
|
static struct request * |
|
request_enqueue(struct requests *requests, u_int id, size_t len, |
|
uint64_t offset) |
|
{ |
|
struct request *req; |
|
|
|
req = xcalloc(1, sizeof(*req)); |
|
req->id = id; |
|
req->len = len; |
|
req->offset = offset; |
|
TAILQ_INSERT_TAIL(requests, req, tq); |
|
return req; |
|
} |
|
|
|
static struct request * |
|
request_find(struct requests *requests, u_int id) |
|
{ |
|
struct request *req; |
|
|
|
for (req = TAILQ_FIRST(requests); |
|
req != NULL && req->id != id; |
|
req = TAILQ_NEXT(req, tq)) |
|
; |
|
return req; |
|
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
static int |
static int |
sftpio(void *_bwlimit, size_t amount) |
sftpio(void *_bwlimit, size_t amount) |
|
|
(unsigned long long)offset, |
(unsigned long long)offset, |
(unsigned long long)offset + buflen - 1, |
(unsigned long long)offset + buflen - 1, |
num_req, max_req); |
num_req, max_req); |
req = xcalloc(1, sizeof(*req)); |
req = request_enqueue(&requests, conn->msg_id++, |
req->id = conn->msg_id++; |
buflen, offset); |
req->len = buflen; |
|
req->offset = offset; |
|
offset += buflen; |
offset += buflen; |
num_req++; |
num_req++; |
TAILQ_INSERT_TAIL(&requests, req, tq); |
|
send_read_request(conn, req->id, req->offset, |
send_read_request(conn, req->id, req->offset, |
req->len, handle, handle_len); |
req->len, handle, handle_len); |
} |
} |
|
|
debug3("Received reply T:%u I:%u R:%d", type, id, max_req); |
debug3("Received reply T:%u I:%u R:%d", type, id, max_req); |
|
|
/* Find the request in our queue */ |
/* Find the request in our queue */ |
for (req = TAILQ_FIRST(&requests); |
if ((req = request_find(&requests, id)) == NULL) |
req != NULL && req->id != id; |
|
req = TAILQ_NEXT(req, tq)) |
|
; |
|
if (req == NULL) |
|
fatal("Unexpected reply %u", id); |
fatal("Unexpected reply %u", id); |
|
|
switch (type) { |
switch (type) { |
|
|
Attrib a, *c = NULL; |
Attrib a, *c = NULL; |
u_int32_t startid; |
u_int32_t startid; |
u_int32_t ackid; |
u_int32_t ackid; |
struct outstanding_ack { |
struct request *ack = NULL; |
u_int id; |
struct requests acks; |
u_int len; |
|
off_t offset; |
|
TAILQ_ENTRY(outstanding_ack) tq; |
|
}; |
|
TAILQ_HEAD(ackhead, outstanding_ack) acks; |
|
struct outstanding_ack *ack = NULL; |
|
size_t handle_len; |
size_t handle_len; |
|
|
TAILQ_INIT(&acks); |
TAILQ_INIT(&acks); |
|
|
strerror(errno)); |
strerror(errno)); |
|
|
if (len != 0) { |
if (len != 0) { |
ack = xcalloc(1, sizeof(*ack)); |
ack = request_enqueue(&acks, ++id, len, offset); |
ack->id = ++id; |
|
ack->offset = offset; |
|
ack->len = len; |
|
TAILQ_INSERT_TAIL(&acks, ack, tq); |
|
|
|
sshbuf_reset(msg); |
sshbuf_reset(msg); |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_WRITE)) != 0 || |
if ((r = sshbuf_put_u8(msg, SSH2_FXP_WRITE)) != 0 || |
(r = sshbuf_put_u32(msg, ack->id)) != 0 || |
(r = sshbuf_put_u32(msg, ack->id)) != 0 || |
|
|
debug3("SSH2_FXP_STATUS %u", status); |
debug3("SSH2_FXP_STATUS %u", status); |
|
|
/* Find the request in our queue */ |
/* Find the request in our queue */ |
for (ack = TAILQ_FIRST(&acks); |
if ((ack = request_find(&acks, rid)) == NULL) |
ack != NULL && ack->id != rid; |
|
ack = TAILQ_NEXT(ack, tq)) |
|
; |
|
if (ack == NULL) |
|
fatal("Can't find request for ID %u", rid); |
fatal("Can't find request for ID %u", rid); |
TAILQ_REMOVE(&acks, ack, tq); |
TAILQ_REMOVE(&acks, ack, tq); |
debug3("In write loop, ack for %u %u bytes at %lld", |
debug3("In write loop, ack for %u %zu bytes at %lld", |
ack->id, ack->len, (long long)ack->offset); |
ack->id, ack->len, (unsigned long long)ack->offset); |
++ackid; |
++ackid; |
progress_counter += ack->len; |
progress_counter += ack->len; |
free(ack); |
free(ack); |
|
|
(unsigned long long)offset, |
(unsigned long long)offset, |
(unsigned long long)offset + buflen - 1, |
(unsigned long long)offset + buflen - 1, |
num_req, max_req); |
num_req, max_req); |
req = xcalloc(1, sizeof(*req)); |
req = request_enqueue(&requests, from->msg_id++, |
req->id = from->msg_id++; |
buflen, offset); |
req->len = buflen; |
|
req->offset = offset; |
|
offset += buflen; |
offset += buflen; |
num_req++; |
num_req++; |
TAILQ_INSERT_TAIL(&requests, req, tq); |
|
send_read_request(from, req->id, req->offset, |
send_read_request(from, req->id, req->offset, |
req->len, from_handle, from_handle_len); |
req->len, from_handle, from_handle_len); |
} |
} |
|
|
type, id, max_req); |
type, id, max_req); |
|
|
/* Find the request in our queue */ |
/* Find the request in our queue */ |
for (req = TAILQ_FIRST(&requests); |
if ((req = request_find(&requests, id)) == NULL) |
req != NULL && req->id != id; |
|
req = TAILQ_NEXT(req, tq)) |
|
; |
|
if (req == NULL) |
|
fatal("Unexpected reply %u", id); |
fatal("Unexpected reply %u", id); |
|
|
switch (type) { |
switch (type) { |