=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/sftp-server.c,v retrieving revision 1.78 retrieving revision 1.79 diff -u -r1.78 -r1.79 --- src/usr.bin/ssh/sftp-server.c 2008/02/27 20:21:15 1.78 +++ src/usr.bin/ssh/sftp-server.c 2008/04/18 12:32:11 1.79 @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.78 2008/02/27 20:21:15 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.79 2008/04/18 12:32:11 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include @@ -470,6 +472,33 @@ buffer_free(&msg); } +static void +send_statvfs(u_int32_t id, struct statvfs *st) +{ + Buffer msg; + u_int64_t flag; + + flag = (st->f_flag & ST_RDONLY) ? SSH2_FXE_STATVFS_ST_RDONLY : 0; + flag |= (st->f_flag & ST_NOSUID) ? SSH2_FXE_STATVFS_ST_NOSUID : 0; + + buffer_init(&msg); + buffer_put_char(&msg, SSH2_FXP_EXTENDED_REPLY); + buffer_put_int(&msg, id); + buffer_put_int(&msg, st->f_bsize); + buffer_put_int(&msg, st->f_frsize); + buffer_put_int64(&msg, st->f_blocks); + buffer_put_int64(&msg, st->f_bfree); + buffer_put_int64(&msg, st->f_bavail); + buffer_put_int64(&msg, st->f_files); + buffer_put_int64(&msg, st->f_ffree); + buffer_put_int64(&msg, st->f_favail); + buffer_put_int(&msg, st->f_fsid); + buffer_put_int(&msg, flag); + buffer_put_int(&msg, st->f_namemax); + send_msg(&msg); + buffer_free(&msg); +} + /* parse incoming */ static void @@ -485,6 +514,10 @@ /* POSIX rename extension */ buffer_put_cstring(&msg, "posix-rename@openssh.com"); buffer_put_cstring(&msg, "1"); /* version */ + buffer_put_cstring(&msg, "statvfs@openssh.com"); + buffer_put_cstring(&msg, "1"); /* version */ + buffer_put_cstring(&msg, "fstatvfs@openssh.com"); + buffer_put_cstring(&msg, "1"); /* version */ send_msg(&msg); buffer_free(&msg); } @@ -1079,6 +1112,42 @@ } static void +process_extended_statvfs(u_int32_t id) +{ + char *path; + struct statvfs st; + + path = get_string(NULL); + debug3("request %u: statfs", id); + logit("statfs \"%s\"", path); + + if (statvfs(path, &st) != 0) + send_status(id, errno_to_portable(errno)); + else + send_statvfs(id, &st); + xfree(path); +} + +static void +process_extended_fstatvfs(u_int32_t id) +{ + int handle, fd; + struct statvfs st; + + handle = get_handle(); + debug("request %u: fstatvfs \"%s\" (handle %u)", + id, handle_to_name(handle), handle); + if ((fd = handle_to_fd(handle)) < 0) { + send_status(id, SSH2_FX_FAILURE); + return; + } + if (fstatvfs(fd, &st) != 0) + send_status(id, errno_to_portable(errno)); + else + send_statvfs(id, &st); +} + +static void process_extended(void) { u_int32_t id; @@ -1088,6 +1157,10 @@ request = get_string(NULL); if (strcmp(request, "posix-rename@openssh.com") == 0) process_extended_posix_rename(id); + else if (strcmp(request, "statvfs@openssh.com") == 0) + process_extended_statvfs(id); + else if (strcmp(request, "fstatvfs@openssh.com") == 0) + process_extended_fstatvfs(id); else send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ xfree(request);