I'd like to propose the following extensions to the SFTP protocol. - statvfs operation - atomic rename (just plain POSIX rename() without the existence check) These are the most requested features in SSHFS, which need support in sftp-server too. They could be added to the current protocol with the SSH_FXP_EXTENDED message type. Here's a patch implementing the statvfs operation. It looks like OpenBSD current doesn't have statvfs(), but it works on Linux, and should be pretty trivial to port to OBSD, although it would be even nicer to add a statvfs (defined by SUS) impementation. Comments are welcome. Thanks, Miklos Index: sftp-server.c ==================================================================RCS file: /cvs/src/usr.bin/ssh/sftp-server.c,v retrieving revision 1.70 diff -u -r1.70 sftp-server.c --- sftp-server.c 3 Aug 2006 03:34:42 -0000 1.70 +++ sftp-server.c 17 Aug 2006 22:43:04 -0000 @@ -462,6 +463,35 @@ buffer_free(&msg); } +static void +send_statvfs(u_int32_t id, struct statvfs *st) +{ + Buffer msg; + int flag = 0; + + if (st->f_flag & ST_RDONLY) + flag |= SSH2_FX_ST_RDONLY; + if (st->f_flag & ST_NOSUID) + flag |= SSH2_FX_ST_NOSUID; + + 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 @@ -1049,6 +1079,24 @@ } static void +process_extended_statvfs(u_int32_t id) +{ + char *path; + struct statvfs st; + int ret; + + path = get_string(NULL); + debug3("request %u: statvfs", id); + verbose("statvfs \"%s\"", path); + + ret = statvfs(path, &st); + if (ret == -1) + send_status(id, errno_to_portable(errno)); + else + send_statvfs(id, &st); +} + +static void process_extended(void) { u_int32_t id; @@ -1056,7 +1104,10 @@ id = get_int(); request = get_string(NULL); - send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ + if (strcmp(request, "statvfs at openssh.org") == 0) + process_extended_statvfs(id); + else + send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ xfree(request); } Index: sftp.h ==================================================================RCS file: /cvs/src/usr.bin/ssh/sftp.h,v retrieving revision 1.5 diff -u -r1.5 sftp.h --- sftp.h 25 Mar 2006 22:22:43 -0000 1.5 +++ sftp.h 17 Aug 2006 22:43:04 -0000 @@ -90,3 +90,7 @@ #define SSH2_FX_CONNECTION_LOST 7 #define SSH2_FX_OP_UNSUPPORTED 8 #define SSH2_FX_MAX 8 + +/* statvfs flags */ +#define SSH2_FX_ST_RDONLY 0x00000001 +#define SSH2_FX_ST_NOSUID 0x00000002