upstream: do_upload() used a near-identical structure for
tracking expected status replies from the server to what do_download() was using. Refactor it to use the same structure and factor out some common code into helper functions. OpenBSD-Commit-ID: 0c167df8ab6df4a5292c32421922b0cf379e9054
This commit is contained in:
parent
7b1cbcb759
commit
a9e2c53319
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: sftp-client.c,v 1.150 2021/08/07 00:12:09 djm Exp $ */
|
||||
/* $OpenBSD: sftp-client.c,v 1.151 2021/08/07 00:14:17 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
|
@ -113,6 +113,32 @@ static u_char *
|
|||
get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len,
|
||||
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 */
|
||||
static int
|
||||
sftpio(void *_bwlimit, size_t amount)
|
||||
|
@ -1446,13 +1472,10 @@ do_download(struct sftp_conn *conn, const char *remote_path,
|
|||
(unsigned long long)offset,
|
||||
(unsigned long long)offset + buflen - 1,
|
||||
num_req, max_req);
|
||||
req = xcalloc(1, sizeof(*req));
|
||||
req->id = conn->msg_id++;
|
||||
req->len = buflen;
|
||||
req->offset = offset;
|
||||
req = request_enqueue(&requests, conn->msg_id++,
|
||||
buflen, offset);
|
||||
offset += buflen;
|
||||
num_req++;
|
||||
TAILQ_INSERT_TAIL(&requests, req, tq);
|
||||
send_read_request(conn, req->id, req->offset,
|
||||
req->len, handle, handle_len);
|
||||
}
|
||||
|
@ -1465,11 +1488,7 @@ do_download(struct sftp_conn *conn, const char *remote_path,
|
|||
debug3("Received reply T:%u I:%u R:%d", type, id, max_req);
|
||||
|
||||
/* Find the request in our queue */
|
||||
for (req = TAILQ_FIRST(&requests);
|
||||
req != NULL && req->id != id;
|
||||
req = TAILQ_NEXT(req, tq))
|
||||
;
|
||||
if (req == NULL)
|
||||
if ((req = request_find(&requests, id)) == NULL)
|
||||
fatal("Unexpected reply %u", id);
|
||||
|
||||
switch (type) {
|
||||
|
@ -1754,14 +1773,8 @@ do_upload(struct sftp_conn *conn, const char *local_path,
|
|||
Attrib a, *c = NULL;
|
||||
u_int32_t startid;
|
||||
u_int32_t ackid;
|
||||
struct outstanding_ack {
|
||||
u_int id;
|
||||
u_int len;
|
||||
off_t offset;
|
||||
TAILQ_ENTRY(outstanding_ack) tq;
|
||||
};
|
||||
TAILQ_HEAD(ackhead, outstanding_ack) acks;
|
||||
struct outstanding_ack *ack = NULL;
|
||||
struct request *ack = NULL;
|
||||
struct requests acks;
|
||||
size_t handle_len;
|
||||
|
||||
TAILQ_INIT(&acks);
|
||||
|
@ -1851,12 +1864,7 @@ do_upload(struct sftp_conn *conn, const char *local_path,
|
|||
strerror(errno));
|
||||
|
||||
if (len != 0) {
|
||||
ack = xcalloc(1, sizeof(*ack));
|
||||
ack->id = ++id;
|
||||
ack->offset = offset;
|
||||
ack->len = len;
|
||||
TAILQ_INSERT_TAIL(&acks, ack, tq);
|
||||
|
||||
ack = request_enqueue(&acks, ++id, len, offset);
|
||||
sshbuf_reset(msg);
|
||||
if ((r = sshbuf_put_u8(msg, SSH2_FXP_WRITE)) != 0 ||
|
||||
(r = sshbuf_put_u32(msg, ack->id)) != 0 ||
|
||||
|
@ -1893,15 +1901,11 @@ do_upload(struct sftp_conn *conn, const char *local_path,
|
|||
debug3("SSH2_FXP_STATUS %u", status);
|
||||
|
||||
/* Find the request in our queue */
|
||||
for (ack = TAILQ_FIRST(&acks);
|
||||
ack != NULL && ack->id != rid;
|
||||
ack = TAILQ_NEXT(ack, tq))
|
||||
;
|
||||
if (ack == NULL)
|
||||
if ((ack = request_find(&acks, rid)) == NULL)
|
||||
fatal("Can't find request for ID %u", rid);
|
||||
TAILQ_REMOVE(&acks, ack, tq);
|
||||
debug3("In write loop, ack for %u %u bytes at %lld",
|
||||
ack->id, ack->len, (long long)ack->offset);
|
||||
debug3("In write loop, ack for %u %zu bytes at %lld",
|
||||
ack->id, ack->len, (unsigned long long)ack->offset);
|
||||
++ackid;
|
||||
progress_counter += ack->len;
|
||||
free(ack);
|
||||
|
@ -2216,13 +2220,10 @@ do_crossload(struct sftp_conn *from, struct sftp_conn *to,
|
|||
(unsigned long long)offset,
|
||||
(unsigned long long)offset + buflen - 1,
|
||||
num_req, max_req);
|
||||
req = xcalloc(1, sizeof(*req));
|
||||
req->id = from->msg_id++;
|
||||
req->len = buflen;
|
||||
req->offset = offset;
|
||||
req = request_enqueue(&requests, from->msg_id++,
|
||||
buflen, offset);
|
||||
offset += buflen;
|
||||
num_req++;
|
||||
TAILQ_INSERT_TAIL(&requests, req, tq);
|
||||
send_read_request(from, req->id, req->offset,
|
||||
req->len, from_handle, from_handle_len);
|
||||
}
|
||||
|
@ -2240,11 +2241,7 @@ do_crossload(struct sftp_conn *from, struct sftp_conn *to,
|
|||
type, id, max_req);
|
||||
|
||||
/* Find the request in our queue */
|
||||
for (req = TAILQ_FIRST(&requests);
|
||||
req != NULL && req->id != id;
|
||||
req = TAILQ_NEXT(req, tq))
|
||||
;
|
||||
if (req == NULL)
|
||||
if ((req = request_find(&requests, id)) == NULL)
|
||||
fatal("Unexpected reply %u", id);
|
||||
|
||||
switch (type) {
|
||||
|
|
Loading…
Reference in New Issue