diff options
Diffstat (limited to 'sftp-client.c')
-rw-r--r-- | sftp-client.c | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/sftp-client.c b/sftp-client.c index 4986d6d8d..d3f80e5a0 100644 --- a/sftp-client.c +++ b/sftp-client.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sftp-client.c,v 1.130 2018/07/31 03:07:24 djm Exp $ */ | 1 | /* $OpenBSD: sftp-client.c,v 1.131 2019/01/16 23:23:45 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> | 3 | * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> |
4 | * | 4 | * |
@@ -86,6 +86,7 @@ struct sftp_conn { | |||
86 | #define SFTP_EXT_FSTATVFS 0x00000004 | 86 | #define SFTP_EXT_FSTATVFS 0x00000004 |
87 | #define SFTP_EXT_HARDLINK 0x00000008 | 87 | #define SFTP_EXT_HARDLINK 0x00000008 |
88 | #define SFTP_EXT_FSYNC 0x00000010 | 88 | #define SFTP_EXT_FSYNC 0x00000010 |
89 | #define SFTP_EXT_LSETSTAT 0x00000020 | ||
89 | u_int exts; | 90 | u_int exts; |
90 | u_int64_t limit_kbps; | 91 | u_int64_t limit_kbps; |
91 | struct bwlimit bwlimit_in, bwlimit_out; | 92 | struct bwlimit bwlimit_in, bwlimit_out; |
@@ -463,6 +464,10 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests, | |||
463 | strcmp((char *)value, "1") == 0) { | 464 | strcmp((char *)value, "1") == 0) { |
464 | ret->exts |= SFTP_EXT_FSYNC; | 465 | ret->exts |= SFTP_EXT_FSYNC; |
465 | known = 1; | 466 | known = 1; |
467 | } else if (strcmp(name, "lsetstat@openssh.com") == 0 && | ||
468 | strcmp((char *)value, "1") == 0) { | ||
469 | ret->exts |= SFTP_EXT_LSETSTAT; | ||
470 | known = 1; | ||
466 | } | 471 | } |
467 | if (known) { | 472 | if (known) { |
468 | debug2("Server supports extension \"%s\" revision %s", | 473 | debug2("Server supports extension \"%s\" revision %s", |
@@ -1096,7 +1101,6 @@ do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st, | |||
1096 | 1101 | ||
1097 | if ((msg = sshbuf_new()) == NULL) | 1102 | if ((msg = sshbuf_new()) == NULL) |
1098 | fatal("%s: sshbuf_new failed", __func__); | 1103 | fatal("%s: sshbuf_new failed", __func__); |
1099 | sshbuf_reset(msg); | ||
1100 | if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || | 1104 | if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || |
1101 | (r = sshbuf_put_u32(msg, id)) != 0 || | 1105 | (r = sshbuf_put_u32(msg, id)) != 0 || |
1102 | (r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0 || | 1106 | (r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0 || |
@@ -1125,7 +1129,6 @@ do_fstatvfs(struct sftp_conn *conn, const u_char *handle, u_int handle_len, | |||
1125 | 1129 | ||
1126 | if ((msg = sshbuf_new()) == NULL) | 1130 | if ((msg = sshbuf_new()) == NULL) |
1127 | fatal("%s: sshbuf_new failed", __func__); | 1131 | fatal("%s: sshbuf_new failed", __func__); |
1128 | sshbuf_reset(msg); | ||
1129 | if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || | 1132 | if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || |
1130 | (r = sshbuf_put_u32(msg, id)) != 0 || | 1133 | (r = sshbuf_put_u32(msg, id)) != 0 || |
1131 | (r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0 || | 1134 | (r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0 || |
@@ -1138,6 +1141,38 @@ do_fstatvfs(struct sftp_conn *conn, const u_char *handle, u_int handle_len, | |||
1138 | } | 1141 | } |
1139 | #endif | 1142 | #endif |
1140 | 1143 | ||
1144 | int | ||
1145 | do_lsetstat(struct sftp_conn *conn, const char *path, Attrib *a) | ||
1146 | { | ||
1147 | struct sshbuf *msg; | ||
1148 | u_int status, id; | ||
1149 | int r; | ||
1150 | |||
1151 | if ((conn->exts & SFTP_EXT_LSETSTAT) == 0) { | ||
1152 | error("Server does not support lsetstat@openssh.com extension"); | ||
1153 | return -1; | ||
1154 | } | ||
1155 | |||
1156 | id = conn->msg_id++; | ||
1157 | if ((msg = sshbuf_new()) == NULL) | ||
1158 | fatal("%s: sshbuf_new failed", __func__); | ||
1159 | if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 || | ||
1160 | (r = sshbuf_put_u32(msg, id)) != 0 || | ||
1161 | (r = sshbuf_put_cstring(msg, "lsetstat@openssh.com")) != 0 || | ||
1162 | (r = sshbuf_put_cstring(msg, path)) != 0 || | ||
1163 | (r = encode_attrib(msg, a)) != 0) | ||
1164 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1165 | send_msg(conn, msg); | ||
1166 | sshbuf_free(msg); | ||
1167 | |||
1168 | status = get_status(conn, id); | ||
1169 | if (status != SSH2_FX_OK) | ||
1170 | error("Couldn't setstat on \"%s\": %s", path, | ||
1171 | fx2txt(status)); | ||
1172 | |||
1173 | return status == SSH2_FX_OK ? 0 : -1; | ||
1174 | } | ||
1175 | |||
1141 | static void | 1176 | static void |
1142 | send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset, | 1177 | send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset, |
1143 | u_int len, const u_char *handle, u_int handle_len) | 1178 | u_int len, const u_char *handle, u_int handle_len) |
@@ -1147,7 +1182,6 @@ send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset, | |||
1147 | 1182 | ||
1148 | if ((msg = sshbuf_new()) == NULL) | 1183 | if ((msg = sshbuf_new()) == NULL) |
1149 | fatal("%s: sshbuf_new failed", __func__); | 1184 | fatal("%s: sshbuf_new failed", __func__); |
1150 | sshbuf_reset(msg); | ||
1151 | if ((r = sshbuf_put_u8(msg, SSH2_FXP_READ)) != 0 || | 1185 | if ((r = sshbuf_put_u8(msg, SSH2_FXP_READ)) != 0 || |
1152 | (r = sshbuf_put_u32(msg, id)) != 0 || | 1186 | (r = sshbuf_put_u32(msg, id)) != 0 || |
1153 | (r = sshbuf_put_string(msg, handle, handle_len)) != 0 || | 1187 | (r = sshbuf_put_string(msg, handle, handle_len)) != 0 || |