View | Details | Raw Unified | Return to bug 1399 | Differences between
and this patch

Collapse All | Expand All

(-)sftp/Makefile (-1 / +1 lines)
Lines 14-17 SRCS= sftp.c sftp-client.c sftp-common.c Link Here
14
14
15
.include <bsd.prog.mk>
15
.include <bsd.prog.mk>
16
16
17
LDADD+=	-ledit -ltermcap
17
LDADD+=	-ledit -ltermcap -lutil
(-)sftp.h (+4 lines)
Lines 79-84 Link Here
79
#define SSH2_FXF_TRUNC			0x00000010
79
#define SSH2_FXF_TRUNC			0x00000010
80
#define SSH2_FXF_EXCL			0x00000020
80
#define SSH2_FXF_EXCL			0x00000020
81
81
82
/* statvfs@openssh.com f_flag flags */
83
#define SSH2_FXE_STATVFS_ST_RDONLY	0x00000001
84
#define SSH2_FXE_STATVFS_ST_NOSUID	0x00000002
85
82
/* status messages */
86
/* status messages */
83
#define SSH2_FX_OK			0
87
#define SSH2_FX_OK			0
84
#define SSH2_FX_EOF			1
88
#define SSH2_FX_EOF			1
(-)sftp.c (-4 / +106 lines)
Lines 21-26 Link Here
21
#include <sys/stat.h>
21
#include <sys/stat.h>
22
#include <sys/socket.h>
22
#include <sys/socket.h>
23
#include <sys/param.h>
23
#include <sys/param.h>
24
#include <sys/statvfs.h>
24
25
25
#include <ctype.h>
26
#include <ctype.h>
26
#include <errno.h>
27
#include <errno.h>
Lines 32-37 Link Here
32
#include <stdio.h>
33
#include <stdio.h>
33
#include <string.h>
34
#include <string.h>
34
#include <unistd.h>
35
#include <unistd.h>
36
#include <util.h>
35
#include <stdarg.h>
37
#include <stdarg.h>
36
38
37
#include "xmalloc.h"
39
#include "xmalloc.h"
Lines 92-97 int remote_glob(struct sftp_conn *, cons Link Here
92
#define I_CHGRP		2
94
#define I_CHGRP		2
93
#define I_CHMOD		3
95
#define I_CHMOD		3
94
#define I_CHOWN		4
96
#define I_CHOWN		4
97
#define I_DF		24
95
#define I_GET		5
98
#define I_GET		5
96
#define I_HELP		6
99
#define I_HELP		6
97
#define I_LCHDIR	7
100
#define I_LCHDIR	7
Lines 124-129 static const struct CMD cmds[] = { Link Here
124
	{ "chgrp",	I_CHGRP },
127
	{ "chgrp",	I_CHGRP },
125
	{ "chmod",	I_CHMOD },
128
	{ "chmod",	I_CHMOD },
126
	{ "chown",	I_CHOWN },
129
	{ "chown",	I_CHOWN },
130
	{ "df",		I_DF },
127
	{ "dir",	I_LS },
131
	{ "dir",	I_LS },
128
	{ "exit",	I_QUIT },
132
	{ "exit",	I_QUIT },
129
	{ "get",	I_GET },
133
	{ "get",	I_GET },
Lines 188-193 help(void) Link Here
188
	printf("chgrp grp path                Change group of file 'path' to 'grp'\n");
192
	printf("chgrp grp path                Change group of file 'path' to 'grp'\n");
189
	printf("chmod mode path               Change permissions of file 'path' to 'mode'\n");
193
	printf("chmod mode path               Change permissions of file 'path' to 'mode'\n");
190
	printf("chown own path                Change owner of file 'path' to 'own'\n");
194
	printf("chown own path                Change owner of file 'path' to 'own'\n");
195
	printf("df [path]                     Display statistics for current directory or\n");
196
	printf("                              filesystem containing 'path'\n");
191
	printf("help                          Display this help text\n");
197
	printf("help                          Display this help text\n");
192
	printf("get remote-path [local-path]  Download file\n");
198
	printf("get remote-path [local-path]  Download file\n");
193
	printf("lls [ls-options [path]]       Display local directory listing\n");
199
	printf("lls [ls-options [path]]       Display local directory listing\n");
Lines 410-415 parse_ls_flags(char **argv, int argc, in Link Here
410
}
416
}
411
417
412
static int
418
static int
419
parse_df_flags(const char *cmd, char **argv, int argc, int *hflag, int *iflag)
420
{
421
	extern int optind, optreset, opterr;
422
	int ch;
423
424
	optind = optreset = 1;
425
	opterr = 0;
426
427
	*hflag = *iflag = 0;
428
	while ((ch = getopt(argc, argv, "hi")) != -1) {
429
		switch (ch) {
430
		case 'h':
431
			*hflag = 1;
432
			break;
433
		case 'i':
434
			*iflag = 1;
435
			break;
436
		default:
437
			error("%s: Invalid flag -%c", cmd, ch);
438
			return -1;
439
		}
440
	}
441
442
	return optind;
443
}
444
445
static int
413
is_dir(char *path)
446
is_dir(char *path)
414
{
447
{
415
	struct stat sb;
448
	struct stat sb;
Lines 785-790 do_globbed_ls(struct sftp_conn *conn, ch Link Here
785
	return (0);
818
	return (0);
786
}
819
}
787
820
821
static int
822
do_df(struct sftp_conn *conn, char *path, int hflag, int iflag)
823
{
824
	struct statvfs st;
825
	char s_used[FMT_SCALED_STRSIZE];
826
	char s_avail[FMT_SCALED_STRSIZE];
827
	char s_root[FMT_SCALED_STRSIZE];
828
	char s_total[FMT_SCALED_STRSIZE];
829
830
	if (do_statvfs(conn, path, &st, 1) == -1)
831
		return -1;
832
	if (iflag) {
833
		printf("     Inodes        Used       Avail      "
834
		    "(root)    %%Capacity\n");
835
		printf("%11llu %11llu %11llu %11llu         %3llu%%\n",
836
		    (unsigned long long)st.f_files,
837
		    (unsigned long long)(st.f_files - st.f_ffree),
838
		    (unsigned long long)st.f_favail,
839
		    (unsigned long long)st.f_ffree,
840
		    (unsigned long long)(100 * (st.f_files - st.f_ffree) /
841
		    st.f_files));
842
	} else if (hflag) {
843
		strlcpy(s_used, "error", sizeof(s_used));
844
		strlcpy(s_avail, "error", sizeof(s_avail));
845
		strlcpy(s_root, "error", sizeof(s_root));
846
		strlcpy(s_total, "error", sizeof(s_total));
847
		fmt_scaled((st.f_blocks - st.f_bfree) * st.f_bsize, s_used);
848
		fmt_scaled(st.f_bavail * st.f_bsize, s_avail);
849
		fmt_scaled(st.f_bfree * st.f_bsize, s_root);
850
		fmt_scaled(st.f_blocks * st.f_bsize, s_total);
851
		printf("    Size     Used    Avail   (root)    %%Capacity\n");
852
		printf("%7sB %7sB %7sB %7sB         %3llu%%\n",
853
		    s_total, s_used, s_avail, s_root,
854
		    (unsigned long long)(100 * (st.f_blocks - st.f_bfree) /
855
		    st.f_blocks));
856
	} else {
857
		printf("        Size         Used        Avail       "
858
		    "(root)    %%Capacity\n");
859
		printf("%12llu %12llu %12llu %12llu         %3llu%%\n",
860
		    (unsigned long long)(st.f_bsize * st.f_blocks / 1024),
861
		    (unsigned long long)(st.f_bsize *
862
		    (st.f_blocks - st.f_bfree) / 1024),
863
		    (unsigned long long)(st.f_bsize * st.f_bavail / 1024),
864
		    (unsigned long long)(st.f_bsize * st.f_bfree / 1024),
865
		    (unsigned long long)(100 * (st.f_blocks - st.f_bfree) /
866
		    st.f_blocks));
867
	}
868
	return 0;
869
}
870
788
/*
871
/*
789
 * Undo escaping of glob sequences in place. Used to undo extra escaping
872
 * Undo escaping of glob sequences in place. Used to undo extra escaping
790
 * applied in makeargv() when the string is destined for a function that
873
 * applied in makeargv() when the string is destined for a function that
Lines 960-966 makeargv(const char *arg, int *argcp) Link Here
960
}
1043
}
961
1044
962
static int
1045
static int
963
parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
1046
parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, int *hflag,
964
    unsigned long *n_arg, char **path1, char **path2)
1047
    unsigned long *n_arg, char **path1, char **path2)
965
{
1048
{
966
	const char *cmd, *cp = *cpp;
1049
	const char *cmd, *cp = *cpp;
Lines 1004-1010 parse_args(const char **cpp, int *pflag, Link Here
1004
	}
1087
	}
1005
1088
1006
	/* Get arguments and parse flags */
1089
	/* Get arguments and parse flags */
1007
	*lflag = *pflag = *n_arg = 0;
1090
	*lflag = *pflag = *hflag = *n_arg = 0;
1008
	*path1 = *path2 = NULL;
1091
	*path1 = *path2 = NULL;
1009
	optidx = 1;
1092
	optidx = 1;
1010
	switch (cmdnum) {
1093
	switch (cmdnum) {
Lines 1056-1061 parse_args(const char **cpp, int *pflag, Link Here
1056
		if (cmdnum != I_RM)
1139
		if (cmdnum != I_RM)
1057
			undo_glob_escape(*path1);
1140
			undo_glob_escape(*path1);
1058
		break;
1141
		break;
1142
	case I_DF:
1143
		if ((optidx = parse_df_flags(cmd, argv, argc, hflag,
1144
		    iflag)) == -1)
1145
			return -1;
1146
		/* Default to current directory if no path specified */
1147
		if (argc - optidx < 1)
1148
			*path1 = NULL;
1149
		else {
1150
			*path1 = xstrdup(argv[optidx]);
1151
			undo_glob_escape(*path1);
1152
		}
1153
		break;
1059
	case I_LS:
1154
	case I_LS:
1060
		if ((optidx = parse_ls_flags(argv, argc, lflag)) == -1)
1155
		if ((optidx = parse_ls_flags(argv, argc, lflag)) == -1)
1061
			return(-1);
1156
			return(-1);
Lines 1118-1124 parse_dispatch_command(struct sftp_conn Link Here
1118
    int err_abort)
1213
    int err_abort)
1119
{
1214
{
1120
	char *path1, *path2, *tmp;
1215
	char *path1, *path2, *tmp;
1121
	int pflag, lflag, iflag, cmdnum, i;
1216
	int pflag, lflag, iflag, hflag, cmdnum, i;
1122
	unsigned long n_arg;
1217
	unsigned long n_arg;
1123
	Attrib a, *aa;
1218
	Attrib a, *aa;
1124
	char path_buf[MAXPATHLEN];
1219
	char path_buf[MAXPATHLEN];
Lines 1126-1132 parse_dispatch_command(struct sftp_conn Link Here
1126
	glob_t g;
1221
	glob_t g;
1127
1222
1128
	path1 = path2 = NULL;
1223
	path1 = path2 = NULL;
1129
	cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &n_arg,
1224
	cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &hflag, &n_arg,
1130
	    &path1, &path2);
1225
	    &path1, &path2);
1131
1226
1132
	if (iflag != 0)
1227
	if (iflag != 0)
Lines 1219-1224 parse_dispatch_command(struct sftp_conn Link Here
1219
1314
1220
		path1 = make_absolute(path1, *pwd);
1315
		path1 = make_absolute(path1, *pwd);
1221
		err = do_globbed_ls(conn, path1, tmp, lflag);
1316
		err = do_globbed_ls(conn, path1, tmp, lflag);
1317
		break;
1318
	case I_DF:
1319
		/* Default to current directory if no path specified */
1320
		if (path1 == NULL)
1321
			path1 = xstrdup(*pwd);
1322
		path1 = make_absolute(path1, *pwd);
1323
		err = do_df(conn, path1, hflag, iflag);
1222
		break;
1324
		break;
1223
	case I_LCHDIR:
1325
	case I_LCHDIR:
1224
		if (chdir(path1) == -1) {
1326
		if (chdir(path1) == -1) {
(-)sftp.1 (-1 / +19 lines)
Lines 112-118 will abort if any of the following Link Here
112
commands fail:
112
commands fail:
113
.Ic get , put , rename , ln ,
113
.Ic get , put , rename , ln ,
114
.Ic rm , mkdir , chdir , ls ,
114
.Ic rm , mkdir , chdir , ls ,
115
.Ic lchdir , chmod , chown , chgrp , lpwd
115
.Ic lchdir , chmod , chown , chgrp , lpwd, df,
116
and
116
and
117
.Ic lmkdir .
117
.Ic lmkdir .
118
Termination on error can be suppressed on a command by command basis by
118
Termination on error can be suppressed on a command by command basis by
Lines 272-277 may contain Link Here
272
characters and may match multiple files.
272
characters and may match multiple files.
273
.Ar own
273
.Ar own
274
must be a numeric UID.
274
must be a numeric UID.
275
.It Xo Ic df
276
.Op Fl hi
277
.Op Ar path
278
.Xc
279
Display usage information for the filesystem holding the current directory
280
(or
281
.Ar path
282
if specified).
283
If the
284
.Fl h
285
flag is specified, the capacity information will be displayed using
286
"human-readable" suffixes.
287
The
288
.Fl i
289
flag requests display of inode information in addition to capacity information.
290
This command is only supported on servers that implement the
291
.Dq statvfs@openssh.com
292
extension.
275
.It Ic exit
293
.It Ic exit
276
Quit
294
Quit
277
.Nm sftp .
295
.Nm sftp .
(-)sftp-server.c (-1 / +75 lines)
Lines 19-24 Link Here
19
#include <sys/stat.h>
19
#include <sys/stat.h>
20
#include <sys/time.h>
20
#include <sys/time.h>
21
#include <sys/param.h>
21
#include <sys/param.h>
22
#include <sys/mount.h>
23
#include <sys/statvfs.h>
22
24
23
#include <dirent.h>
25
#include <dirent.h>
24
#include <errno.h>
26
#include <errno.h>
Lines 470-475 send_attrib(u_int32_t id, const Attrib * Link Here
470
	buffer_free(&msg);
472
	buffer_free(&msg);
471
}
473
}
472
474
475
static void
476
send_statvfs(u_int32_t id, struct statvfs *st)
477
{
478
	Buffer msg;
479
	u_int64_t flag;
480
481
	flag = (st->f_flag & ST_RDONLY) ? SSH2_FXE_STATVFS_ST_RDONLY : 0;
482
	flag |= (st->f_flag & ST_NOSUID) ? SSH2_FXE_STATVFS_ST_NOSUID : 0;
483
484
	buffer_init(&msg);
485
	buffer_put_char(&msg, SSH2_FXP_EXTENDED_REPLY);
486
	buffer_put_int(&msg, id);
487
	buffer_put_int(&msg, st->f_bsize);
488
	buffer_put_int(&msg, st->f_frsize);
489
	buffer_put_int64(&msg, st->f_blocks);
490
	buffer_put_int64(&msg, st->f_bfree);
491
	buffer_put_int64(&msg, st->f_bavail);
492
	buffer_put_int64(&msg, st->f_files);
493
	buffer_put_int64(&msg, st->f_ffree);
494
	buffer_put_int64(&msg, st->f_favail);
495
	buffer_put_int(&msg, st->f_fsid);
496
	buffer_put_int(&msg, flag);
497
	buffer_put_int(&msg, st->f_namemax);
498
	send_msg(&msg);
499
	buffer_free(&msg);
500
}
501
473
/* parse incoming */
502
/* parse incoming */
474
503
475
static void
504
static void
Lines 485-490 process_init(void) Link Here
485
	/* POSIX rename extension */
514
	/* POSIX rename extension */
486
	buffer_put_cstring(&msg, "posix-rename@openssh.com");
515
	buffer_put_cstring(&msg, "posix-rename@openssh.com");
487
	buffer_put_cstring(&msg, "1"); /* version */
516
	buffer_put_cstring(&msg, "1"); /* version */
517
	buffer_put_cstring(&msg, "statvfs@openssh.com");
518
	buffer_put_cstring(&msg, "1"); /* version */
519
	buffer_put_cstring(&msg, "fstatvfs@openssh.com");
520
	buffer_put_cstring(&msg, "1"); /* version */
488
	send_msg(&msg);
521
	send_msg(&msg);
489
	buffer_free(&msg);
522
	buffer_free(&msg);
490
}
523
}
Lines 1079-1084 process_extended_posix_rename(u_int32_t Link Here
1079
}
1112
}
1080
1113
1081
static void
1114
static void
1115
process_extended_statvfs(u_int32_t id)
1116
{
1117
	char *path;
1118
	struct statvfs st;
1119
1120
	path = get_string(NULL);
1121
	debug3("request %u: statfs", id);
1122
	logit("statfs \"%s\"", path);
1123
1124
	if (statvfs(path, &st) != 0)
1125
		send_status(id, errno_to_portable(errno));
1126
	else
1127
		send_statvfs(id, &st);
1128
        xfree(path);
1129
}
1130
1131
static void
1132
process_extended_fstatvfs(u_int32_t id)
1133
{
1134
	int handle, fd;
1135
	struct statvfs st;
1136
1137
	id = get_int();
1138
	handle = get_handle();
1139
	debug("request %u: fstatvfs \"%s\" (handle %u)",
1140
	    id, handle_to_name(handle), handle);
1141
	if ((fd = handle_to_fd(handle)) < 0) {
1142
		send_status(id, SSH2_FX_FAILURE);
1143
		return;
1144
	}
1145
	if (fstatvfs(fd, &st) != 0)
1146
		send_status(id, errno_to_portable(errno));
1147
	else
1148
		send_statvfs(id, &st);
1149
}
1150
1151
static void
1082
process_extended(void)
1152
process_extended(void)
1083
{
1153
{
1084
	u_int32_t id;
1154
	u_int32_t id;
Lines 1088-1095 process_extended(void) Link Here
1088
	request = get_string(NULL);
1158
	request = get_string(NULL);
1089
	if (strcmp(request, "posix-rename@openssh.com") == 0)
1159
	if (strcmp(request, "posix-rename@openssh.com") == 0)
1090
		process_extended_posix_rename(id);
1160
		process_extended_posix_rename(id);
1161
	else if (strcmp(request, "statvfs@openssh.com") == 0)
1162
		process_extended_statvfs(id);
1163
	else if (strcmp(request, "fstatvfs@openssh.com") == 0)
1164
		process_extended_fstatvfs(id);
1091
	else
1165
	else
1092
		send_status(id, SSH2_FX_OP_UNSUPPORTED);	/* MUST */
1166
	send_status(id, SSH2_FX_OP_UNSUPPORTED);	/* MUST */
1093
	xfree(request);
1167
	xfree(request);
1094
}
1168
}
1095
1169
(-)sftp-client.h (+4 lines)
Lines 70-75 int do_fsetstat(struct sftp_conn *, char Link Here
70
/* Canonicalise 'path' - caller must free result */
70
/* Canonicalise 'path' - caller must free result */
71
char *do_realpath(struct sftp_conn *, char *);
71
char *do_realpath(struct sftp_conn *, char *);
72
72
73
/* Get statistics for filesystem hosting file at "path" */
74
struct statvfs;
75
int do_statvfs(struct sftp_conn *, const char *, struct statvfs *, int);
76
73
/* Rename 'oldpath' to 'newpath' */
77
/* Rename 'oldpath' to 'newpath' */
74
int do_rename(struct sftp_conn *, char *, char *);
78
int do_rename(struct sftp_conn *, char *, char *);
75
79
(-)sftp-client.c (-2 / +116 lines)
Lines 25-30 Link Here
25
#include <sys/stat.h>
25
#include <sys/stat.h>
26
#include <sys/time.h>
26
#include <sys/time.h>
27
#include <sys/param.h>
27
#include <sys/param.h>
28
#include <sys/statvfs.h>
28
#include <sys/uio.h>
29
#include <sys/uio.h>
29
30
30
#include <errno.h>
31
#include <errno.h>
Lines 59-65 struct sftp_conn { Link Here
59
	u_int num_requests;
60
	u_int num_requests;
60
	u_int version;
61
	u_int version;
61
	u_int msg_id;
62
	u_int msg_id;
62
#define SFTP_EXT_POSIX_RENAME	1
63
#define SFTP_EXT_POSIX_RENAME	0x00000001
64
#define SFTP_EXT_STATVFS	0x00000002
65
#define SFTP_EXT_FSTATVFS	0x00000004
63
	u_int exts;
66
	u_int exts;
64
};
67
};
65
68
Lines 232-237 get_decode_stat(int fd, u_int expected_i Link Here
232
	return(a);
235
	return(a);
233
}
236
}
234
237
238
static int
239
get_decode_statvfs(int fd, struct statvfs *st, u_int expected_id, int quiet)
240
{
241
	Buffer msg;
242
	u_int type, id, flag;
243
244
	buffer_init(&msg);
245
	get_msg(fd, &msg);
246
247
	type = buffer_get_char(&msg);
248
	id = buffer_get_int(&msg);
249
250
	debug3("Received statvfs reply T:%u I:%u", type, id);
251
	if (id != expected_id)
252
		fatal("ID mismatch (%u != %u)", id, expected_id);
253
	if (type == SSH2_FXP_STATUS) {
254
		int status = buffer_get_int(&msg);
255
256
		if (quiet)
257
			debug("Couldn't statvfs: %s", fx2txt(status));
258
		else
259
			error("Couldn't statvfs: %s", fx2txt(status));
260
		buffer_free(&msg);
261
		return -1;
262
	} else if (type != SSH2_FXP_EXTENDED_REPLY) {
263
		fatal("Expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u",
264
		    SSH2_FXP_EXTENDED_REPLY, type);
265
	}
266
267
	bzero(st, sizeof(*st));
268
	st->f_bsize = buffer_get_int(&msg);
269
	st->f_frsize = buffer_get_int(&msg);
270
	st->f_blocks = buffer_get_int64(&msg);
271
	st->f_bfree = buffer_get_int64(&msg);
272
	st->f_bavail = buffer_get_int64(&msg);
273
	st->f_files = buffer_get_int64(&msg);
274
	st->f_ffree = buffer_get_int64(&msg);
275
	st->f_favail = buffer_get_int64(&msg);
276
	st->f_fsid = buffer_get_int(&msg);
277
	flag = buffer_get_int(&msg);
278
	st->f_namemax = buffer_get_int(&msg);
279
280
	st->f_flag = (flag & SSH2_FXE_STATVFS_ST_RDONLY) ? ST_RDONLY : 0;
281
	st->f_flag |= (flag & SSH2_FXE_STATVFS_ST_NOSUID) ? ST_NOSUID : 0;
282
283
	buffer_free(&msg);
284
285
	return 0;
286
}
287
235
struct sftp_conn *
288
struct sftp_conn *
236
do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
289
do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
237
{
290
{
Lines 266-273 do_init(int fd_in, int fd_out, u_int tra Link Here
266
		char *value = buffer_get_string(&msg, NULL);
319
		char *value = buffer_get_string(&msg, NULL);
267
320
268
		debug2("Init extension: \"%s\"", name);
321
		debug2("Init extension: \"%s\"", name);
269
		if (strcmp(name, "posix-rename@openssh.com") == 0)
322
		if (strcmp(name, "posix-rename@openssh.com") == 0 &&
323
		    strcmp(value, "1") == 0)
270
			exts |= SFTP_EXT_POSIX_RENAME;
324
			exts |= SFTP_EXT_POSIX_RENAME;
325
		if (strcmp(name, "statvfs@openssh.com") == 0 &&
326
		    strcmp(value, "1") == 0)
327
			exts |= SFTP_EXT_STATVFS;
328
		if (strcmp(name, "fstatvfs@openssh.com") == 0 &&
329
		    strcmp(value, "1") == 0)
330
			exts |= SFTP_EXT_FSTATVFS;
271
		xfree(name);
331
		xfree(name);
272
		xfree(value);
332
		xfree(value);
273
	}
333
	}
Lines 740-745 do_readlink(struct sftp_conn *conn, char Link Here
740
	buffer_free(&msg);
800
	buffer_free(&msg);
741
801
742
	return(filename);
802
	return(filename);
803
}
804
#endif
805
806
int
807
do_statvfs(struct sftp_conn *conn, const char *path, struct statvfs *st,
808
    int quiet)
809
{
810
	Buffer msg;
811
	u_int id;
812
813
	if ((conn->exts & SFTP_EXT_STATVFS) == 0) {
814
		error("Server does not support statvfs@openssh.com extension");
815
		return -1;
816
	}
817
818
	id = conn->msg_id++;
819
820
	buffer_init(&msg);
821
	buffer_clear(&msg);
822
	buffer_put_char(&msg, SSH2_FXP_EXTENDED);
823
	buffer_put_int(&msg, id);
824
	buffer_put_cstring(&msg, "statvfs@openssh.com");
825
	buffer_put_cstring(&msg, path);
826
	send_msg(conn->fd_out, &msg);
827
	buffer_free(&msg);
828
829
	return get_decode_statvfs(conn->fd_in, st, id, quiet);
830
}
831
832
#ifdef notyet
833
int
834
do_fstatvfs(struct sftp_conn *conn, const char *handle, u_int handle_len,
835
    struct statvfs *st, int quiet)
836
{
837
	Buffer msg;
838
	u_int id;
839
840
	if ((conn->exts & SFTP_EXT_FSTATVFS) == 0) {
841
		error("Server does not support fstatvfs@openssh.com extension");
842
		return -1;
843
	}
844
845
	id = conn->msg_id++;
846
847
	buffer_init(&msg);
848
	buffer_clear(&msg);
849
	buffer_put_char(&msg, SSH2_FXP_EXTENDED);
850
	buffer_put_int(&msg, id);
851
	buffer_put_cstring(&msg, "fstatvfs@openssh.com");
852
	buffer_put_string(&msg, handle, handle_len);
853
	send_msg(conn->fd_out, &msg);
854
	buffer_free(&msg);
855
856
	return get_decode_statvfs(conn->fd_in, st, id, quiet);
743
}
857
}
744
#endif
858
#endif
745
859

Return to bug 1399