247
get_decode_statvfs(int fd, struct sftp_statvfs *st, u_int expected_id,
251
u_int type, id, flag;
256
type = buffer_get_char(&msg);
257
id = buffer_get_int(&msg);
259
debug3("Received statvfs reply T:%u I:%u", type, id);
260
if (id != expected_id)
261
fatal("ID mismatch (%u != %u)", id, expected_id);
262
if (type == SSH2_FXP_STATUS) {
263
int status = buffer_get_int(&msg);
266
debug("Couldn't statvfs: %s", fx2txt(status));
268
error("Couldn't statvfs: %s", fx2txt(status));
271
} else if (type != SSH2_FXP_EXTENDED_REPLY) {
272
fatal("Expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u",
273
SSH2_FXP_EXTENDED_REPLY, type);
276
bzero(st, sizeof(*st));
277
st->f_bsize = buffer_get_int64(&msg);
278
st->f_frsize = buffer_get_int64(&msg);
279
st->f_blocks = buffer_get_int64(&msg);
280
st->f_bfree = buffer_get_int64(&msg);
281
st->f_bavail = buffer_get_int64(&msg);
282
st->f_files = buffer_get_int64(&msg);
283
st->f_ffree = buffer_get_int64(&msg);
284
st->f_favail = buffer_get_int64(&msg);
285
st->f_fsid = buffer_get_int64(&msg);
286
flag = buffer_get_int64(&msg);
287
st->f_namemax = buffer_get_int64(&msg);
289
st->f_flag = (flag & SSH2_FXE_STATVFS_ST_RDONLY) ? ST_RDONLY : 0;
290
st->f_flag |= (flag & SSH2_FXE_STATVFS_ST_NOSUID) ? ST_NOSUID : 0;
239
297
struct sftp_conn *
240
298
do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
300
u_int type, exts = 0;
245
303
struct sftp_conn *ret;
268
326
while (buffer_len(&msg) > 0) {
269
327
char *name = buffer_get_string(&msg, NULL);
270
328
char *value = buffer_get_string(&msg, NULL);
272
debug2("Init extension: \"%s\"", name);
331
if (strcmp(name, "posix-rename@openssh.com") == 0 &&
332
strcmp(value, "1") == 0) {
333
exts |= SFTP_EXT_POSIX_RENAME;
335
} else if (strcmp(name, "statvfs@openssh.com") == 0 &&
336
strcmp(value, "2") == 0) {
337
exts |= SFTP_EXT_STATVFS;
339
} if (strcmp(name, "fstatvfs@openssh.com") == 0 &&
340
strcmp(value, "2") == 0) {
341
exts |= SFTP_EXT_FSTATVFS;
345
debug2("Server supports extension \"%s\" revision %s",
348
debug2("Unrecognised server extension \"%s\"", name);
534
612
return(get_decode_stat(conn->fd_in, id, quiet));
538
617
do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet)
638
718
/* Send rename request */
639
719
id = conn->msg_id++;
640
buffer_put_char(&msg, SSH2_FXP_RENAME);
641
buffer_put_int(&msg, id);
720
if ((conn->exts & SFTP_EXT_POSIX_RENAME)) {
721
buffer_put_char(&msg, SSH2_FXP_EXTENDED);
722
buffer_put_int(&msg, id);
723
buffer_put_cstring(&msg, "posix-rename@openssh.com");
725
buffer_put_char(&msg, SSH2_FXP_RENAME);
726
buffer_put_int(&msg, id);
642
728
buffer_put_cstring(&msg, oldpath);
643
729
buffer_put_cstring(&msg, newpath);
644
730
send_msg(conn->fd_out, &msg);
645
debug3("Sent message SSH2_FXP_RENAME \"%s\" -> \"%s\"", oldpath,
731
debug3("Sent message %s \"%s\" -> \"%s\"",
732
(conn->exts & SFTP_EXT_POSIX_RENAME) ? "posix-rename@openssh.com" :
733
"SSH2_FXP_RENAME", oldpath, newpath);
647
734
buffer_free(&msg);
649
736
status = get_status(conn->fd_in, id);
733
821
return(filename);
826
do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st,
832
if ((conn->exts & SFTP_EXT_STATVFS) == 0) {
833
error("Server does not support statvfs@openssh.com extension");
841
buffer_put_char(&msg, SSH2_FXP_EXTENDED);
842
buffer_put_int(&msg, id);
843
buffer_put_cstring(&msg, "statvfs@openssh.com");
844
buffer_put_cstring(&msg, path);
845
send_msg(conn->fd_out, &msg);
848
return get_decode_statvfs(conn->fd_in, st, id, quiet);
853
do_fstatvfs(struct sftp_conn *conn, const char *handle, u_int handle_len,
854
struct sftp_statvfs *st, int quiet)
859
if ((conn->exts & SFTP_EXT_FSTATVFS) == 0) {
860
error("Server does not support fstatvfs@openssh.com extension");
868
buffer_put_char(&msg, SSH2_FXP_EXTENDED);
869
buffer_put_int(&msg, id);
870
buffer_put_cstring(&msg, "fstatvfs@openssh.com");
871
buffer_put_string(&msg, handle, handle_len);
872
send_msg(conn->fd_out, &msg);
875
return get_decode_statvfs(conn->fd_in, st, id, quiet);
737
880
send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len,
819
962
if (local_fd == -1) {
820
963
error("Couldn't open local file \"%s\" for writing: %s",
821
964
local_path, strerror(errno));
965
do_close(conn, handle, handle_len);
822
966
buffer_free(&msg);
1074
1219
* Simulate an EOF on interrupt, allowing ACKs from the
1075
1220
* server to drain.
1222
if (interrupted || status != SSH2_FX_OK)
1080
1225
len = read(local_fd, data, conn->transfer_buflen);
1081
while ((len == -1) && (errno == EINTR || errno == EAGAIN));
1226
while ((len == -1) &&
1227
(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
1084
1230
fatal("Couldn't read from \"%s\": %s", local_path,
1130
1276
if (ack == NULL)
1131
1277
fatal("Can't find request for ID %u", r_id);
1132
1278
TAILQ_REMOVE(&acks, ack, tq);
1134
if (status != SSH2_FX_OK) {
1135
error("Couldn't write to remote file \"%s\": %s",
1136
remote_path, fx2txt(status));
1138
stop_progress_meter();
1139
do_close(conn, handle, handle_len);
1146
debug3("In write loop, ack for %u %u bytes at %llu",
1147
ack->id, ack->len, (unsigned long long)ack->offset);
1279
debug3("In write loop, ack for %u %u bytes at %lld",
1280
ack->id, ack->len, (long long)ack->offset);
1286
fatal("%s: offset < 0", __func__);
1153
1290
if (showprogress)
1154
1291
stop_progress_meter();
1294
if (status != SSH2_FX_OK) {
1295
error("Couldn't write to remote file \"%s\": %s",
1296
remote_path, fx2txt(status));
1157
1300
if (close(local_fd) == -1) {
1158
1301
error("Couldn't close local file \"%s\": %s", local_path,
1159
1302
strerror(errno));
1160
do_close(conn, handle, handle_len);
1165
1306
/* Override umask and utimes if asked */
1167
1308
do_fsetstat(conn, handle, handle_len, &a);
1169
status = do_close(conn, handle, handle_len);
1310
if (do_close(conn, handle, handle_len) != SSH2_FX_OK)