diff options
Diffstat (limited to 'sftp-client.c')
-rw-r--r-- | sftp-client.c | 120 |
1 files changed, 117 insertions, 3 deletions
diff --git a/sftp-client.c b/sftp-client.c index 69c637785..1e54348b7 100644 --- a/sftp-client.c +++ b/sftp-client.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sftp-client.c,v 1.81 2008/03/23 12:54:01 djm Exp $ */ | 1 | /* $OpenBSD: sftp-client.c,v 1.82 2008/04/18 12:32:11 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 | * |
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include <sys/types.h> | 25 | #include <sys/types.h> |
26 | #include <sys/param.h> | 26 | #include <sys/param.h> |
27 | #include <sys/statvfs.h> | ||
27 | #include "openbsd-compat/sys-queue.h" | 28 | #include "openbsd-compat/sys-queue.h" |
28 | #ifdef HAVE_SYS_STAT_H | 29 | #ifdef HAVE_SYS_STAT_H |
29 | # include <sys/stat.h> | 30 | # include <sys/stat.h> |
@@ -65,7 +66,9 @@ struct sftp_conn { | |||
65 | u_int num_requests; | 66 | u_int num_requests; |
66 | u_int version; | 67 | u_int version; |
67 | u_int msg_id; | 68 | u_int msg_id; |
68 | #define SFTP_EXT_POSIX_RENAME 1 | 69 | #define SFTP_EXT_POSIX_RENAME 0x00000001 |
70 | #define SFTP_EXT_STATVFS 0x00000002 | ||
71 | #define SFTP_EXT_FSTATVFS 0x00000004 | ||
69 | u_int exts; | 72 | u_int exts; |
70 | }; | 73 | }; |
71 | 74 | ||
@@ -238,6 +241,56 @@ get_decode_stat(int fd, u_int expected_id, int quiet) | |||
238 | return(a); | 241 | return(a); |
239 | } | 242 | } |
240 | 243 | ||
244 | static int | ||
245 | get_decode_statvfs(int fd, struct statvfs *st, u_int expected_id, int quiet) | ||
246 | { | ||
247 | Buffer msg; | ||
248 | u_int type, id, flag; | ||
249 | |||
250 | buffer_init(&msg); | ||
251 | get_msg(fd, &msg); | ||
252 | |||
253 | type = buffer_get_char(&msg); | ||
254 | id = buffer_get_int(&msg); | ||
255 | |||
256 | debug3("Received statvfs reply T:%u I:%u", type, id); | ||
257 | if (id != expected_id) | ||
258 | fatal("ID mismatch (%u != %u)", id, expected_id); | ||
259 | if (type == SSH2_FXP_STATUS) { | ||
260 | int status = buffer_get_int(&msg); | ||
261 | |||
262 | if (quiet) | ||
263 | debug("Couldn't statvfs: %s", fx2txt(status)); | ||
264 | else | ||
265 | error("Couldn't statvfs: %s", fx2txt(status)); | ||
266 | buffer_free(&msg); | ||
267 | return -1; | ||
268 | } else if (type != SSH2_FXP_EXTENDED_REPLY) { | ||
269 | fatal("Expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u", | ||
270 | SSH2_FXP_EXTENDED_REPLY, type); | ||
271 | } | ||
272 | |||
273 | bzero(st, sizeof(*st)); | ||
274 | st->f_bsize = buffer_get_int(&msg); | ||
275 | st->f_frsize = buffer_get_int(&msg); | ||
276 | st->f_blocks = buffer_get_int64(&msg); | ||
277 | st->f_bfree = buffer_get_int64(&msg); | ||
278 | st->f_bavail = buffer_get_int64(&msg); | ||
279 | st->f_files = buffer_get_int64(&msg); | ||
280 | st->f_ffree = buffer_get_int64(&msg); | ||
281 | st->f_favail = buffer_get_int64(&msg); | ||
282 | st->f_fsid = buffer_get_int(&msg); | ||
283 | flag = buffer_get_int(&msg); | ||
284 | st->f_namemax = buffer_get_int(&msg); | ||
285 | |||
286 | st->f_flag = (flag & SSH2_FXE_STATVFS_ST_RDONLY) ? ST_RDONLY : 0; | ||
287 | st->f_flag |= (flag & SSH2_FXE_STATVFS_ST_NOSUID) ? ST_NOSUID : 0; | ||
288 | |||
289 | buffer_free(&msg); | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
241 | struct sftp_conn * | 294 | struct sftp_conn * |
242 | do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) | 295 | do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) |
243 | { | 296 | { |
@@ -272,8 +325,15 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests) | |||
272 | char *value = buffer_get_string(&msg, NULL); | 325 | char *value = buffer_get_string(&msg, NULL); |
273 | 326 | ||
274 | debug2("Init extension: \"%s\"", name); | 327 | debug2("Init extension: \"%s\"", name); |
275 | if (strcmp(name, "posix-rename@openssh.com") == 0) | 328 | if (strcmp(name, "posix-rename@openssh.com") == 0 && |
329 | strcmp(value, "1") == 0) | ||
276 | exts |= SFTP_EXT_POSIX_RENAME; | 330 | exts |= SFTP_EXT_POSIX_RENAME; |
331 | if (strcmp(name, "statvfs@openssh.com") == 0 && | ||
332 | strcmp(value, "1") == 0) | ||
333 | exts |= SFTP_EXT_STATVFS; | ||
334 | if (strcmp(name, "fstatvfs@openssh.com") == 0 && | ||
335 | strcmp(value, "1") == 0) | ||
336 | exts |= SFTP_EXT_FSTATVFS; | ||
277 | xfree(name); | 337 | xfree(name); |
278 | xfree(value); | 338 | xfree(value); |
279 | } | 339 | } |
@@ -749,6 +809,60 @@ do_readlink(struct sftp_conn *conn, char *path) | |||
749 | } | 809 | } |
750 | #endif | 810 | #endif |
751 | 811 | ||
812 | int | ||
813 | do_statvfs(struct sftp_conn *conn, const char *path, struct statvfs *st, | ||
814 | int quiet) | ||
815 | { | ||
816 | Buffer msg; | ||
817 | u_int id; | ||
818 | |||
819 | if ((conn->exts & SFTP_EXT_STATVFS) == 0) { | ||
820 | error("Server does not support statvfs@openssh.com extension"); | ||
821 | return -1; | ||
822 | } | ||
823 | |||
824 | id = conn->msg_id++; | ||
825 | |||
826 | buffer_init(&msg); | ||
827 | buffer_clear(&msg); | ||
828 | buffer_put_char(&msg, SSH2_FXP_EXTENDED); | ||
829 | buffer_put_int(&msg, id); | ||
830 | buffer_put_cstring(&msg, "statvfs@openssh.com"); | ||
831 | buffer_put_cstring(&msg, path); | ||
832 | send_msg(conn->fd_out, &msg); | ||
833 | buffer_free(&msg); | ||
834 | |||
835 | return get_decode_statvfs(conn->fd_in, st, id, quiet); | ||
836 | } | ||
837 | |||
838 | #ifdef notyet | ||
839 | int | ||
840 | do_fstatvfs(struct sftp_conn *conn, const char *handle, u_int handle_len, | ||
841 | struct statvfs *st, int quiet) | ||
842 | { | ||
843 | Buffer msg; | ||
844 | u_int id; | ||
845 | |||
846 | if ((conn->exts & SFTP_EXT_FSTATVFS) == 0) { | ||
847 | error("Server does not support fstatvfs@openssh.com extension"); | ||
848 | return -1; | ||
849 | } | ||
850 | |||
851 | id = conn->msg_id++; | ||
852 | |||
853 | buffer_init(&msg); | ||
854 | buffer_clear(&msg); | ||
855 | buffer_put_char(&msg, SSH2_FXP_EXTENDED); | ||
856 | buffer_put_int(&msg, id); | ||
857 | buffer_put_cstring(&msg, "fstatvfs@openssh.com"); | ||
858 | buffer_put_string(&msg, handle, handle_len); | ||
859 | send_msg(conn->fd_out, &msg); | ||
860 | buffer_free(&msg); | ||
861 | |||
862 | return get_decode_statvfs(conn->fd_in, st, id, quiet); | ||
863 | } | ||
864 | #endif | ||
865 | |||
752 | static void | 866 | static void |
753 | send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len, | 867 | send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len, |
754 | char *handle, u_int handle_len) | 868 | char *handle, u_int handle_len) |