diff options
author | Damien Miller <djm@mindrot.org> | 2008-05-19 14:53:33 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2008-05-19 14:53:33 +1000 |
commit | d671e5a978efd5ba949d3fdcd03f728dcd68c636 (patch) | |
tree | f63127fe29690fbe2c00f7b50d7807dc24288e29 /sftp-server.c | |
parent | 354c48c641e7fbdc273ee8e1239ff71d73a1ec3e (diff) |
- djm@cvs.openbsd.org 2008/04/18 12:32:11
[sftp-client.c sftp-client.h sftp-server.c sftp.1 sftp.c sftp.h]
introduce sftp extension methods statvfs@openssh.com and
fstatvfs@openssh.com that implement statvfs(2)-like operations,
based on a patch from miklos AT szeredi.hu (bz#1399)
also add a "df" command to the sftp client that uses the
statvfs@openssh.com to produce a df(1)-like display of filesystem
space and inode utilisation
ok markus@
Diffstat (limited to 'sftp-server.c')
-rw-r--r-- | sftp-server.c | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/sftp-server.c b/sftp-server.c index d9549f5bc..300fd5cfd 100644 --- a/sftp-server.c +++ b/sftp-server.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sftp-server.c,v 1.78 2008/02/27 20:21:15 djm Exp $ */ | 1 | /* $OpenBSD: sftp-server.c,v 1.79 2008/04/18 12:32:11 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -23,6 +23,8 @@ | |||
23 | #ifdef HAVE_SYS_TIME_H | 23 | #ifdef HAVE_SYS_TIME_H |
24 | # include <sys/time.h> | 24 | # include <sys/time.h> |
25 | #endif | 25 | #endif |
26 | #include <sys/mount.h> | ||
27 | #include <sys/statvfs.h> | ||
26 | 28 | ||
27 | #include <dirent.h> | 29 | #include <dirent.h> |
28 | #include <errno.h> | 30 | #include <errno.h> |
@@ -475,6 +477,33 @@ send_attrib(u_int32_t id, const Attrib *a) | |||
475 | buffer_free(&msg); | 477 | buffer_free(&msg); |
476 | } | 478 | } |
477 | 479 | ||
480 | static void | ||
481 | send_statvfs(u_int32_t id, struct statvfs *st) | ||
482 | { | ||
483 | Buffer msg; | ||
484 | u_int64_t flag; | ||
485 | |||
486 | flag = (st->f_flag & ST_RDONLY) ? SSH2_FXE_STATVFS_ST_RDONLY : 0; | ||
487 | flag |= (st->f_flag & ST_NOSUID) ? SSH2_FXE_STATVFS_ST_NOSUID : 0; | ||
488 | |||
489 | buffer_init(&msg); | ||
490 | buffer_put_char(&msg, SSH2_FXP_EXTENDED_REPLY); | ||
491 | buffer_put_int(&msg, id); | ||
492 | buffer_put_int(&msg, st->f_bsize); | ||
493 | buffer_put_int(&msg, st->f_frsize); | ||
494 | buffer_put_int64(&msg, st->f_blocks); | ||
495 | buffer_put_int64(&msg, st->f_bfree); | ||
496 | buffer_put_int64(&msg, st->f_bavail); | ||
497 | buffer_put_int64(&msg, st->f_files); | ||
498 | buffer_put_int64(&msg, st->f_ffree); | ||
499 | buffer_put_int64(&msg, st->f_favail); | ||
500 | buffer_put_int(&msg, st->f_fsid); | ||
501 | buffer_put_int(&msg, flag); | ||
502 | buffer_put_int(&msg, st->f_namemax); | ||
503 | send_msg(&msg); | ||
504 | buffer_free(&msg); | ||
505 | } | ||
506 | |||
478 | /* parse incoming */ | 507 | /* parse incoming */ |
479 | 508 | ||
480 | static void | 509 | static void |
@@ -490,6 +519,10 @@ process_init(void) | |||
490 | /* POSIX rename extension */ | 519 | /* POSIX rename extension */ |
491 | buffer_put_cstring(&msg, "posix-rename@openssh.com"); | 520 | buffer_put_cstring(&msg, "posix-rename@openssh.com"); |
492 | buffer_put_cstring(&msg, "1"); /* version */ | 521 | buffer_put_cstring(&msg, "1"); /* version */ |
522 | buffer_put_cstring(&msg, "statvfs@openssh.com"); | ||
523 | buffer_put_cstring(&msg, "1"); /* version */ | ||
524 | buffer_put_cstring(&msg, "fstatvfs@openssh.com"); | ||
525 | buffer_put_cstring(&msg, "1"); /* version */ | ||
493 | send_msg(&msg); | 526 | send_msg(&msg); |
494 | buffer_free(&msg); | 527 | buffer_free(&msg); |
495 | } | 528 | } |
@@ -1100,6 +1133,42 @@ process_extended_posix_rename(u_int32_t id) | |||
1100 | } | 1133 | } |
1101 | 1134 | ||
1102 | static void | 1135 | static void |
1136 | process_extended_statvfs(u_int32_t id) | ||
1137 | { | ||
1138 | char *path; | ||
1139 | struct statvfs st; | ||
1140 | |||
1141 | path = get_string(NULL); | ||
1142 | debug3("request %u: statfs", id); | ||
1143 | logit("statfs \"%s\"", path); | ||
1144 | |||
1145 | if (statvfs(path, &st) != 0) | ||
1146 | send_status(id, errno_to_portable(errno)); | ||
1147 | else | ||
1148 | send_statvfs(id, &st); | ||
1149 | xfree(path); | ||
1150 | } | ||
1151 | |||
1152 | static void | ||
1153 | process_extended_fstatvfs(u_int32_t id) | ||
1154 | { | ||
1155 | int handle, fd; | ||
1156 | struct statvfs st; | ||
1157 | |||
1158 | handle = get_handle(); | ||
1159 | debug("request %u: fstatvfs \"%s\" (handle %u)", | ||
1160 | id, handle_to_name(handle), handle); | ||
1161 | if ((fd = handle_to_fd(handle)) < 0) { | ||
1162 | send_status(id, SSH2_FX_FAILURE); | ||
1163 | return; | ||
1164 | } | ||
1165 | if (fstatvfs(fd, &st) != 0) | ||
1166 | send_status(id, errno_to_portable(errno)); | ||
1167 | else | ||
1168 | send_statvfs(id, &st); | ||
1169 | } | ||
1170 | |||
1171 | static void | ||
1103 | process_extended(void) | 1172 | process_extended(void) |
1104 | { | 1173 | { |
1105 | u_int32_t id; | 1174 | u_int32_t id; |
@@ -1109,6 +1178,10 @@ process_extended(void) | |||
1109 | request = get_string(NULL); | 1178 | request = get_string(NULL); |
1110 | if (strcmp(request, "posix-rename@openssh.com") == 0) | 1179 | if (strcmp(request, "posix-rename@openssh.com") == 0) |
1111 | process_extended_posix_rename(id); | 1180 | process_extended_posix_rename(id); |
1181 | else if (strcmp(request, "statvfs@openssh.com") == 0) | ||
1182 | process_extended_statvfs(id); | ||
1183 | else if (strcmp(request, "fstatvfs@openssh.com") == 0) | ||
1184 | process_extended_fstatvfs(id); | ||
1112 | else | 1185 | else |
1113 | send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ | 1186 | send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */ |
1114 | xfree(request); | 1187 | xfree(request); |