version 1.32, 2002/06/09 13:32:01 |
version 1.33, 2002/06/23 09:30:14 |
|
|
|
|
msg_len = GET_32BIT(buf); |
msg_len = GET_32BIT(buf); |
if (msg_len > 256 * 1024) |
if (msg_len > 256 * 1024) |
fatal("Received message too long %d", msg_len); |
fatal("Received message too long %u", msg_len); |
|
|
while (msg_len) { |
while (msg_len) { |
len = atomicio(read, fd, buf, MIN(msg_len, sizeof(buf))); |
len = atomicio(read, fd, buf, MIN(msg_len, sizeof(buf))); |
|
|
buffer_put_int(&msg, id); |
buffer_put_int(&msg, id); |
buffer_put_string(&msg, s, len); |
buffer_put_string(&msg, s, len); |
send_msg(fd, &msg); |
send_msg(fd, &msg); |
debug3("Sent message fd %d T:%d I:%d", fd, code, id); |
debug3("Sent message fd %d T:%u I:%u", fd, code, id); |
buffer_free(&msg); |
buffer_free(&msg); |
} |
} |
|
|
|
|
buffer_put_string(&msg, s, len); |
buffer_put_string(&msg, s, len); |
encode_attrib(&msg, a); |
encode_attrib(&msg, a); |
send_msg(fd, &msg); |
send_msg(fd, &msg); |
debug3("Sent message fd %d T:%d I:%d", fd, code, id); |
debug3("Sent message fd %d T:%u I:%u", fd, code, id); |
buffer_free(&msg); |
buffer_free(&msg); |
} |
} |
|
|
static u_int |
static u_int |
get_status(int fd, int expected_id) |
get_status(int fd, u_int expected_id) |
{ |
{ |
Buffer msg; |
Buffer msg; |
u_int type, id, status; |
u_int type, id, status; |
|
|
id = buffer_get_int(&msg); |
id = buffer_get_int(&msg); |
|
|
if (id != expected_id) |
if (id != expected_id) |
fatal("ID mismatch (%d != %d)", id, expected_id); |
fatal("ID mismatch (%u != %u)", id, expected_id); |
if (type != SSH2_FXP_STATUS) |
if (type != SSH2_FXP_STATUS) |
fatal("Expected SSH2_FXP_STATUS(%d) packet, got %d", |
fatal("Expected SSH2_FXP_STATUS(%u) packet, got %u", |
SSH2_FXP_STATUS, type); |
SSH2_FXP_STATUS, type); |
|
|
status = buffer_get_int(&msg); |
status = buffer_get_int(&msg); |
buffer_free(&msg); |
buffer_free(&msg); |
|
|
debug3("SSH2_FXP_STATUS %d", status); |
debug3("SSH2_FXP_STATUS %u", status); |
|
|
return(status); |
return(status); |
} |
} |
|
|
id = buffer_get_int(&msg); |
id = buffer_get_int(&msg); |
|
|
if (id != expected_id) |
if (id != expected_id) |
fatal("ID mismatch (%d != %d)", id, expected_id); |
fatal("ID mismatch (%u != %u)", id, expected_id); |
if (type == SSH2_FXP_STATUS) { |
if (type == SSH2_FXP_STATUS) { |
int status = buffer_get_int(&msg); |
int status = buffer_get_int(&msg); |
|
|
error("Couldn't get handle: %s", fx2txt(status)); |
error("Couldn't get handle: %s", fx2txt(status)); |
return(NULL); |
return(NULL); |
} else if (type != SSH2_FXP_HANDLE) |
} else if (type != SSH2_FXP_HANDLE) |
fatal("Expected SSH2_FXP_HANDLE(%d) packet, got %d", |
fatal("Expected SSH2_FXP_HANDLE(%u) packet, got %u", |
SSH2_FXP_HANDLE, type); |
SSH2_FXP_HANDLE, type); |
|
|
handle = buffer_get_string(&msg, len); |
handle = buffer_get_string(&msg, len); |
|
|
type = buffer_get_char(&msg); |
type = buffer_get_char(&msg); |
id = buffer_get_int(&msg); |
id = buffer_get_int(&msg); |
|
|
debug3("Received stat reply T:%d I:%d", type, id); |
debug3("Received stat reply T:%u I:%u", type, id); |
if (id != expected_id) |
if (id != expected_id) |
fatal("ID mismatch (%d != %d)", id, expected_id); |
fatal("ID mismatch (%u != %u)", id, expected_id); |
if (type == SSH2_FXP_STATUS) { |
if (type == SSH2_FXP_STATUS) { |
int status = buffer_get_int(&msg); |
int status = buffer_get_int(&msg); |
|
|
|
|
error("Couldn't stat remote file: %s", fx2txt(status)); |
error("Couldn't stat remote file: %s", fx2txt(status)); |
return(NULL); |
return(NULL); |
} else if (type != SSH2_FXP_ATTRS) { |
} else if (type != SSH2_FXP_ATTRS) { |
fatal("Expected SSH2_FXP_ATTRS(%d) packet, got %d", |
fatal("Expected SSH2_FXP_ATTRS(%u) packet, got %u", |
SSH2_FXP_ATTRS, type); |
SSH2_FXP_ATTRS, type); |
} |
} |
a = decode_attrib(&msg); |
a = decode_attrib(&msg); |
|
|
struct sftp_conn * |
struct sftp_conn * |
do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) |
do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) |
{ |
{ |
int type, version; |
u_int type; |
|
int version; |
Buffer msg; |
Buffer msg; |
struct sftp_conn *ret; |
struct sftp_conn *ret; |
|
|
|
|
|
|
/* Expecting a VERSION reply */ |
/* Expecting a VERSION reply */ |
if ((type = buffer_get_char(&msg)) != SSH2_FXP_VERSION) { |
if ((type = buffer_get_char(&msg)) != SSH2_FXP_VERSION) { |
error("Invalid packet back from SSH2_FXP_INIT (type %d)", |
error("Invalid packet back from SSH2_FXP_INIT (type %u)", |
type); |
type); |
buffer_free(&msg); |
buffer_free(&msg); |
return(NULL); |
return(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); |
send_msg(conn->fd_out, &msg); |
send_msg(conn->fd_out, &msg); |
debug3("Sent message SSH2_FXP_CLOSE I:%d", id); |
debug3("Sent message SSH2_FXP_CLOSE I:%u", id); |
|
|
status = get_status(conn->fd_in, id); |
status = get_status(conn->fd_in, id); |
if (status != SSH2_FX_OK) |
if (status != SSH2_FX_OK) |
|
|
|
|
id = expected_id = conn->msg_id++; |
id = expected_id = conn->msg_id++; |
|
|
debug3("Sending SSH2_FXP_READDIR I:%d", id); |
debug3("Sending SSH2_FXP_READDIR I:%u", id); |
|
|
buffer_clear(&msg); |
buffer_clear(&msg); |
buffer_put_char(&msg, SSH2_FXP_READDIR); |
buffer_put_char(&msg, SSH2_FXP_READDIR); |
|
|
type = buffer_get_char(&msg); |
type = buffer_get_char(&msg); |
id = buffer_get_int(&msg); |
id = buffer_get_int(&msg); |
|
|
debug3("Received reply T:%d I:%d", type, id); |
debug3("Received reply T:%u I:%u", type, id); |
|
|
if (id != expected_id) |
if (id != expected_id) |
fatal("ID mismatch (%d != %d)", id, expected_id); |
fatal("ID mismatch (%u != %u)", id, expected_id); |
|
|
if (type == SSH2_FXP_STATUS) { |
if (type == SSH2_FXP_STATUS) { |
int status = buffer_get_int(&msg); |
int status = buffer_get_int(&msg); |
|
|
return(status); |
return(status); |
} |
} |
} else if (type != SSH2_FXP_NAME) |
} else if (type != SSH2_FXP_NAME) |
fatal("Expected SSH2_FXP_NAME(%d) packet, got %d", |
fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", |
SSH2_FXP_NAME, type); |
SSH2_FXP_NAME, type); |
|
|
count = buffer_get_int(&msg); |
count = buffer_get_int(&msg); |
|
|
id = buffer_get_int(&msg); |
id = buffer_get_int(&msg); |
|
|
if (id != expected_id) |
if (id != expected_id) |
fatal("ID mismatch (%d != %d)", id, expected_id); |
fatal("ID mismatch (%u != %u)", id, expected_id); |
|
|
if (type == SSH2_FXP_STATUS) { |
if (type == SSH2_FXP_STATUS) { |
u_int status = buffer_get_int(&msg); |
u_int status = buffer_get_int(&msg); |
|
|
error("Couldn't canonicalise: %s", fx2txt(status)); |
error("Couldn't canonicalise: %s", fx2txt(status)); |
return(NULL); |
return(NULL); |
} else if (type != SSH2_FXP_NAME) |
} else if (type != SSH2_FXP_NAME) |
fatal("Expected SSH2_FXP_NAME(%d) packet, got %d", |
fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", |
SSH2_FXP_NAME, type); |
SSH2_FXP_NAME, type); |
|
|
count = buffer_get_int(&msg); |
count = buffer_get_int(&msg); |
|
|
id = buffer_get_int(&msg); |
id = buffer_get_int(&msg); |
|
|
if (id != expected_id) |
if (id != expected_id) |
fatal("ID mismatch (%d != %d)", id, expected_id); |
fatal("ID mismatch (%u != %u)", id, expected_id); |
|
|
if (type == SSH2_FXP_STATUS) { |
if (type == SSH2_FXP_STATUS) { |
u_int status = buffer_get_int(&msg); |
u_int status = buffer_get_int(&msg); |
|
|
error("Couldn't readlink: %s", fx2txt(status)); |
error("Couldn't readlink: %s", fx2txt(status)); |
return(NULL); |
return(NULL); |
} else if (type != SSH2_FXP_NAME) |
} else if (type != SSH2_FXP_NAME) |
fatal("Expected SSH2_FXP_NAME(%d) packet, got %d", |
fatal("Expected SSH2_FXP_NAME(%u) packet, got %u", |
SSH2_FXP_NAME, type); |
SSH2_FXP_NAME, type); |
|
|
count = buffer_get_int(&msg); |
count = buffer_get_int(&msg); |
|
|
attrib_clear(&junk); /* Send empty attributes */ |
attrib_clear(&junk); /* Send empty attributes */ |
encode_attrib(&msg, &junk); |
encode_attrib(&msg, &junk); |
send_msg(conn->fd_out, &msg); |
send_msg(conn->fd_out, &msg); |
debug3("Sent message SSH2_FXP_OPEN I:%d P:%s", id, remote_path); |
debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); |
|
|
handle = get_handle(conn->fd_in, id, &handle_len); |
handle = get_handle(conn->fd_in, id, &handle_len); |
if (handle == NULL) { |
if (handle == NULL) { |
|
|
get_msg(conn->fd_in, &msg); |
get_msg(conn->fd_in, &msg); |
type = buffer_get_char(&msg); |
type = buffer_get_char(&msg); |
id = buffer_get_int(&msg); |
id = buffer_get_int(&msg); |
debug3("Received reply T:%d I:%d 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); |
for(req = TAILQ_FIRST(&requests); |
|
|
(unsigned long long)req->offset + len - 1); |
(unsigned long long)req->offset + len - 1); |
if (len > req->len) |
if (len > req->len) |
fatal("Received more data than asked for " |
fatal("Received more data than asked for " |
"%d > %d", len, req->len); |
"%u > %u", len, req->len); |
if ((lseek(local_fd, req->offset, SEEK_SET) == -1 || |
if ((lseek(local_fd, req->offset, SEEK_SET) == -1 || |
atomicio(write, local_fd, data, len) != len) && |
atomicio(write, local_fd, data, len) != len) && |
!write_error) { |
!write_error) { |
|
|
} |
} |
break; |
break; |
default: |
default: |
fatal("Expected SSH2_FXP_DATA(%d) packet, got %d", |
fatal("Expected SSH2_FXP_DATA(%u) packet, got %u", |
SSH2_FXP_DATA, type); |
SSH2_FXP_DATA, type); |
} |
} |
} |
} |
|
|
buffer_put_int(&msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC); |
buffer_put_int(&msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC); |
encode_attrib(&msg, &a); |
encode_attrib(&msg, &a); |
send_msg(conn->fd_out, &msg); |
send_msg(conn->fd_out, &msg); |
debug3("Sent message SSH2_FXP_OPEN I:%d P:%s", id, remote_path); |
debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path); |
|
|
buffer_clear(&msg); |
buffer_clear(&msg); |
|
|
|
|
buffer_put_int64(&msg, offset); |
buffer_put_int64(&msg, offset); |
buffer_put_string(&msg, data, len); |
buffer_put_string(&msg, data, len); |
send_msg(conn->fd_out, &msg); |
send_msg(conn->fd_out, &msg); |
debug3("Sent message SSH2_FXP_WRITE I:%d O:%llu S:%u", |
debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%u", |
id, (unsigned long long)offset, len); |
id, (unsigned long long)offset, len); |
} else if (TAILQ_FIRST(&acks) == NULL) |
} else if (TAILQ_FIRST(&acks) == NULL) |
break; |
break; |
|
|
ack = TAILQ_NEXT(ack, tq)) |
ack = TAILQ_NEXT(ack, tq)) |
; |
; |
if (ack == NULL) |
if (ack == NULL) |
fatal("Can't find request for ID %d", r_id); |
fatal("Can't find request for ID %u", r_id); |
TAILQ_REMOVE(&acks, ack, tq); |
TAILQ_REMOVE(&acks, ack, tq); |
|
|
if (status != SSH2_FX_OK) { |
if (status != SSH2_FX_OK) { |
|
|
close(local_fd); |
close(local_fd); |
goto done; |
goto done; |
} |
} |
debug3("In write loop, ack for %u %d bytes at %llu", |
debug3("In write loop, ack for %u %u bytes at %llu", |
ack->id, ack->len, (unsigned long long)ack->offset); |
ack->id, ack->len, (unsigned long long)ack->offset); |
++ackid; |
++ackid; |
free(ack); |
free(ack); |