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@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
_______________________________________________
openssh-unix-dev mailing list
openssh-unix-dev@mindrot.org
http://lists.mindrot.org/mailman/lis...enssh-unix-dev