mirror of
git://anongit.mindrot.org/openssh.git
synced 2025-04-01 00:06:45 +00:00
- 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@
This commit is contained in:
parent
354c48c641
commit
d671e5a978
11
ChangeLog
11
ChangeLog
@ -21,6 +21,15 @@
|
||||
Use arc4random_uniform() when the desired random number upper bound
|
||||
is not a power of two
|
||||
ok deraadt@ millert@
|
||||
- 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@
|
||||
|
||||
20080403
|
||||
- (djm) [openbsd-compat/bsd-poll.c] Include stdlib.h to avoid compile-
|
||||
@ -3881,4 +3890,4 @@
|
||||
OpenServer 6 and add osr5bigcrypt support so when someone migrates
|
||||
passwords between UnixWare and OpenServer they will still work. OK dtucker@
|
||||
|
||||
$Id: ChangeLog,v 1.4910 2008/05/19 04:50:00 djm Exp $
|
||||
$Id: ChangeLog,v 1.4911 2008/05/19 04:53:33 djm Exp $
|
||||
|
120
sftp-client.c
120
sftp-client.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sftp-client.c,v 1.81 2008/03/23 12:54:01 djm Exp $ */
|
||||
/* $OpenBSD: sftp-client.c,v 1.82 2008/04/18 12:32:11 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
@ -24,6 +24,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/statvfs.h>
|
||||
#include "openbsd-compat/sys-queue.h"
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
# include <sys/stat.h>
|
||||
@ -65,7 +66,9 @@ struct sftp_conn {
|
||||
u_int num_requests;
|
||||
u_int version;
|
||||
u_int msg_id;
|
||||
#define SFTP_EXT_POSIX_RENAME 1
|
||||
#define SFTP_EXT_POSIX_RENAME 0x00000001
|
||||
#define SFTP_EXT_STATVFS 0x00000002
|
||||
#define SFTP_EXT_FSTATVFS 0x00000004
|
||||
u_int exts;
|
||||
};
|
||||
|
||||
@ -238,6 +241,56 @@ get_decode_stat(int fd, u_int expected_id, int quiet)
|
||||
return(a);
|
||||
}
|
||||
|
||||
static int
|
||||
get_decode_statvfs(int fd, struct statvfs *st, u_int expected_id, int quiet)
|
||||
{
|
||||
Buffer msg;
|
||||
u_int type, id, flag;
|
||||
|
||||
buffer_init(&msg);
|
||||
get_msg(fd, &msg);
|
||||
|
||||
type = buffer_get_char(&msg);
|
||||
id = buffer_get_int(&msg);
|
||||
|
||||
debug3("Received statvfs reply T:%u I:%u", type, id);
|
||||
if (id != expected_id)
|
||||
fatal("ID mismatch (%u != %u)", id, expected_id);
|
||||
if (type == SSH2_FXP_STATUS) {
|
||||
int status = buffer_get_int(&msg);
|
||||
|
||||
if (quiet)
|
||||
debug("Couldn't statvfs: %s", fx2txt(status));
|
||||
else
|
||||
error("Couldn't statvfs: %s", fx2txt(status));
|
||||
buffer_free(&msg);
|
||||
return -1;
|
||||
} else if (type != SSH2_FXP_EXTENDED_REPLY) {
|
||||
fatal("Expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u",
|
||||
SSH2_FXP_EXTENDED_REPLY, type);
|
||||
}
|
||||
|
||||
bzero(st, sizeof(*st));
|
||||
st->f_bsize = buffer_get_int(&msg);
|
||||
st->f_frsize = buffer_get_int(&msg);
|
||||
st->f_blocks = buffer_get_int64(&msg);
|
||||
st->f_bfree = buffer_get_int64(&msg);
|
||||
st->f_bavail = buffer_get_int64(&msg);
|
||||
st->f_files = buffer_get_int64(&msg);
|
||||
st->f_ffree = buffer_get_int64(&msg);
|
||||
st->f_favail = buffer_get_int64(&msg);
|
||||
st->f_fsid = buffer_get_int(&msg);
|
||||
flag = buffer_get_int(&msg);
|
||||
st->f_namemax = buffer_get_int(&msg);
|
||||
|
||||
st->f_flag = (flag & SSH2_FXE_STATVFS_ST_RDONLY) ? ST_RDONLY : 0;
|
||||
st->f_flag |= (flag & SSH2_FXE_STATVFS_ST_NOSUID) ? ST_NOSUID : 0;
|
||||
|
||||
buffer_free(&msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct sftp_conn *
|
||||
do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
|
||||
{
|
||||
@ -272,8 +325,15 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
|
||||
char *value = buffer_get_string(&msg, NULL);
|
||||
|
||||
debug2("Init extension: \"%s\"", name);
|
||||
if (strcmp(name, "posix-rename@openssh.com") == 0)
|
||||
if (strcmp(name, "posix-rename@openssh.com") == 0 &&
|
||||
strcmp(value, "1") == 0)
|
||||
exts |= SFTP_EXT_POSIX_RENAME;
|
||||
if (strcmp(name, "statvfs@openssh.com") == 0 &&
|
||||
strcmp(value, "1") == 0)
|
||||
exts |= SFTP_EXT_STATVFS;
|
||||
if (strcmp(name, "fstatvfs@openssh.com") == 0 &&
|
||||
strcmp(value, "1") == 0)
|
||||
exts |= SFTP_EXT_FSTATVFS;
|
||||
xfree(name);
|
||||
xfree(value);
|
||||
}
|
||||
@ -749,6 +809,60 @@ do_readlink(struct sftp_conn *conn, char *path)
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
do_statvfs(struct sftp_conn *conn, const char *path, struct statvfs *st,
|
||||
int quiet)
|
||||
{
|
||||
Buffer msg;
|
||||
u_int id;
|
||||
|
||||
if ((conn->exts & SFTP_EXT_STATVFS) == 0) {
|
||||
error("Server does not support statvfs@openssh.com extension");
|
||||
return -1;
|
||||
}
|
||||
|
||||
id = conn->msg_id++;
|
||||
|
||||
buffer_init(&msg);
|
||||
buffer_clear(&msg);
|
||||
buffer_put_char(&msg, SSH2_FXP_EXTENDED);
|
||||
buffer_put_int(&msg, id);
|
||||
buffer_put_cstring(&msg, "statvfs@openssh.com");
|
||||
buffer_put_cstring(&msg, path);
|
||||
send_msg(conn->fd_out, &msg);
|
||||
buffer_free(&msg);
|
||||
|
||||
return get_decode_statvfs(conn->fd_in, st, id, quiet);
|
||||
}
|
||||
|
||||
#ifdef notyet
|
||||
int
|
||||
do_fstatvfs(struct sftp_conn *conn, const char *handle, u_int handle_len,
|
||||
struct statvfs *st, int quiet)
|
||||
{
|
||||
Buffer msg;
|
||||
u_int id;
|
||||
|
||||
if ((conn->exts & SFTP_EXT_FSTATVFS) == 0) {
|
||||
error("Server does not support fstatvfs@openssh.com extension");
|
||||
return -1;
|
||||
}
|
||||
|
||||
id = conn->msg_id++;
|
||||
|
||||
buffer_init(&msg);
|
||||
buffer_clear(&msg);
|
||||
buffer_put_char(&msg, SSH2_FXP_EXTENDED);
|
||||
buffer_put_int(&msg, id);
|
||||
buffer_put_cstring(&msg, "fstatvfs@openssh.com");
|
||||
buffer_put_string(&msg, handle, handle_len);
|
||||
send_msg(conn->fd_out, &msg);
|
||||
buffer_free(&msg);
|
||||
|
||||
return get_decode_statvfs(conn->fd_in, st, id, quiet);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len,
|
||||
char *handle, u_int handle_len)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sftp-client.h,v 1.15 2008/01/11 07:22:28 chl Exp $ */
|
||||
/* $OpenBSD: sftp-client.h,v 1.16 2008/04/18 12:32:11 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
||||
@ -70,6 +70,10 @@ int do_fsetstat(struct sftp_conn *, char *, u_int, Attrib *);
|
||||
/* Canonicalise 'path' - caller must free result */
|
||||
char *do_realpath(struct sftp_conn *, char *);
|
||||
|
||||
/* Get statistics for filesystem hosting file at "path" */
|
||||
struct statvfs;
|
||||
int do_statvfs(struct sftp_conn *, const char *, struct statvfs *, int);
|
||||
|
||||
/* Rename 'oldpath' to 'newpath' */
|
||||
int do_rename(struct sftp_conn *, char *, char *);
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
@ -23,6 +23,8 @@
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
#include <sys/mount.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
@ -475,6 +477,33 @@ send_attrib(u_int32_t id, const Attrib *a)
|
||||
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
|
||||
@ -490,6 +519,10 @@ process_init(void)
|
||||
/* 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);
|
||||
}
|
||||
@ -1099,6 +1132,42 @@ process_extended_posix_rename(u_int32_t id)
|
||||
xfree(newpath);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -1109,6 +1178,10 @@ process_extended(void)
|
||||
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);
|
||||
|
24
sftp.1
24
sftp.1
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: sftp.1,v 1.64 2007/05/31 19:20:16 jmc Exp $
|
||||
.\" $OpenBSD: sftp.1,v 1.65 2008/04/18 12:32:11 djm Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
|
||||
.\"
|
||||
@ -22,7 +22,7 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: May 31 2007 $
|
||||
.Dd $Mdocdate: April 18 2008 $
|
||||
.Dt SFTP 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -112,7 +112,7 @@ will abort if any of the following
|
||||
commands fail:
|
||||
.Ic get , put , rename , ln ,
|
||||
.Ic rm , mkdir , chdir , ls ,
|
||||
.Ic lchdir , chmod , chown , chgrp , lpwd
|
||||
.Ic lchdir , chmod , chown , chgrp , lpwd, df,
|
||||
and
|
||||
.Ic lmkdir .
|
||||
Termination on error can be suppressed on a command by command basis by
|
||||
@ -272,6 +272,24 @@ may contain
|
||||
characters and may match multiple files.
|
||||
.Ar own
|
||||
must be a numeric UID.
|
||||
.It Xo Ic df
|
||||
.Op Fl hi
|
||||
.Op Ar path
|
||||
.Xc
|
||||
Display usage information for the filesystem holding the current directory
|
||||
(or
|
||||
.Ar path
|
||||
if specified).
|
||||
If the
|
||||
.Fl h
|
||||
flag is specified, the capacity information will be displayed using
|
||||
"human-readable" suffixes.
|
||||
The
|
||||
.Fl i
|
||||
flag requests display of inode information in addition to capacity information.
|
||||
This command is only supported on servers that implement the
|
||||
.Dq statvfs@openssh.com
|
||||
extension.
|
||||
.It Ic exit
|
||||
Quit
|
||||
.Nm sftp .
|
||||
|
112
sftp.c
112
sftp.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sftp.c,v 1.99 2008/01/20 00:38:30 djm Exp $ */
|
||||
/* $OpenBSD: sftp.c,v 1.100 2008/04/18 12:32:11 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
@ -25,6 +25,7 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/statvfs.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
@ -42,6 +43,7 @@ typedef void EditLine;
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <util.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "xmalloc.h"
|
||||
@ -104,6 +106,7 @@ extern char *__progname;
|
||||
#define I_CHGRP 2
|
||||
#define I_CHMOD 3
|
||||
#define I_CHOWN 4
|
||||
#define I_DF 24
|
||||
#define I_GET 5
|
||||
#define I_HELP 6
|
||||
#define I_LCHDIR 7
|
||||
@ -136,6 +139,7 @@ static const struct CMD cmds[] = {
|
||||
{ "chgrp", I_CHGRP },
|
||||
{ "chmod", I_CHMOD },
|
||||
{ "chown", I_CHOWN },
|
||||
{ "df", I_DF },
|
||||
{ "dir", I_LS },
|
||||
{ "exit", I_QUIT },
|
||||
{ "get", I_GET },
|
||||
@ -200,6 +204,8 @@ help(void)
|
||||
printf("chgrp grp path Change group of file 'path' to 'grp'\n");
|
||||
printf("chmod mode path Change permissions of file 'path' to 'mode'\n");
|
||||
printf("chown own path Change owner of file 'path' to 'own'\n");
|
||||
printf("df [path] Display statistics for current directory or\n");
|
||||
printf(" filesystem containing 'path'\n");
|
||||
printf("help Display this help text\n");
|
||||
printf("get remote-path [local-path] Download file\n");
|
||||
printf("lls [ls-options [path]] Display local directory listing\n");
|
||||
@ -421,6 +427,33 @@ parse_ls_flags(char **argv, int argc, int *lflag)
|
||||
return optind;
|
||||
}
|
||||
|
||||
static int
|
||||
parse_df_flags(const char *cmd, char **argv, int argc, int *hflag, int *iflag)
|
||||
{
|
||||
extern int optind, optreset, opterr;
|
||||
int ch;
|
||||
|
||||
optind = optreset = 1;
|
||||
opterr = 0;
|
||||
|
||||
*hflag = *iflag = 0;
|
||||
while ((ch = getopt(argc, argv, "hi")) != -1) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
*hflag = 1;
|
||||
break;
|
||||
case 'i':
|
||||
*iflag = 1;
|
||||
break;
|
||||
default:
|
||||
error("%s: Invalid flag -%c", cmd, ch);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return optind;
|
||||
}
|
||||
|
||||
static int
|
||||
is_dir(char *path)
|
||||
{
|
||||
@ -797,6 +830,56 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
do_df(struct sftp_conn *conn, char *path, int hflag, int iflag)
|
||||
{
|
||||
struct statvfs st;
|
||||
char s_used[FMT_SCALED_STRSIZE];
|
||||
char s_avail[FMT_SCALED_STRSIZE];
|
||||
char s_root[FMT_SCALED_STRSIZE];
|
||||
char s_total[FMT_SCALED_STRSIZE];
|
||||
|
||||
if (do_statvfs(conn, path, &st, 1) == -1)
|
||||
return -1;
|
||||
if (iflag) {
|
||||
printf(" Inodes Used Avail "
|
||||
"(root) %%Capacity\n");
|
||||
printf("%11llu %11llu %11llu %11llu %3llu%%\n",
|
||||
(unsigned long long)st.f_files,
|
||||
(unsigned long long)(st.f_files - st.f_ffree),
|
||||
(unsigned long long)st.f_favail,
|
||||
(unsigned long long)st.f_ffree,
|
||||
(unsigned long long)(100 * (st.f_files - st.f_ffree) /
|
||||
st.f_files));
|
||||
} else if (hflag) {
|
||||
strlcpy(s_used, "error", sizeof(s_used));
|
||||
strlcpy(s_avail, "error", sizeof(s_avail));
|
||||
strlcpy(s_root, "error", sizeof(s_root));
|
||||
strlcpy(s_total, "error", sizeof(s_total));
|
||||
fmt_scaled((st.f_blocks - st.f_bfree) * st.f_frsize, s_used);
|
||||
fmt_scaled(st.f_bavail * st.f_frsize, s_avail);
|
||||
fmt_scaled(st.f_bfree * st.f_frsize, s_root);
|
||||
fmt_scaled(st.f_blocks * st.f_frsize, s_total);
|
||||
printf(" Size Used Avail (root) %%Capacity\n");
|
||||
printf("%7sB %7sB %7sB %7sB %3llu%%\n",
|
||||
s_total, s_used, s_avail, s_root,
|
||||
(unsigned long long)(100 * (st.f_blocks - st.f_bfree) /
|
||||
st.f_blocks));
|
||||
} else {
|
||||
printf(" Size Used Avail "
|
||||
"(root) %%Capacity\n");
|
||||
printf("%12llu %12llu %12llu %12llu %3llu%%\n",
|
||||
(unsigned long long)(st.f_frsize * st.f_blocks / 1024),
|
||||
(unsigned long long)(st.f_frsize *
|
||||
(st.f_blocks - st.f_bfree) / 1024),
|
||||
(unsigned long long)(st.f_frsize * st.f_bavail / 1024),
|
||||
(unsigned long long)(st.f_frsize * st.f_bfree / 1024),
|
||||
(unsigned long long)(100 * (st.f_blocks - st.f_bfree) /
|
||||
st.f_blocks));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Undo escaping of glob sequences in place. Used to undo extra escaping
|
||||
* applied in makeargv() when the string is destined for a function that
|
||||
@ -972,7 +1055,7 @@ makeargv(const char *arg, int *argcp)
|
||||
}
|
||||
|
||||
static int
|
||||
parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
|
||||
parse_args(const char **cpp, int *pflag, int *lflag, int *iflag, int *hflag,
|
||||
unsigned long *n_arg, char **path1, char **path2)
|
||||
{
|
||||
const char *cmd, *cp = *cpp;
|
||||
@ -1016,7 +1099,7 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
|
||||
}
|
||||
|
||||
/* Get arguments and parse flags */
|
||||
*lflag = *pflag = *n_arg = 0;
|
||||
*lflag = *pflag = *hflag = *n_arg = 0;
|
||||
*path1 = *path2 = NULL;
|
||||
optidx = 1;
|
||||
switch (cmdnum) {
|
||||
@ -1068,6 +1151,18 @@ parse_args(const char **cpp, int *pflag, int *lflag, int *iflag,
|
||||
if (cmdnum != I_RM)
|
||||
undo_glob_escape(*path1);
|
||||
break;
|
||||
case I_DF:
|
||||
if ((optidx = parse_df_flags(cmd, argv, argc, hflag,
|
||||
iflag)) == -1)
|
||||
return -1;
|
||||
/* Default to current directory if no path specified */
|
||||
if (argc - optidx < 1)
|
||||
*path1 = NULL;
|
||||
else {
|
||||
*path1 = xstrdup(argv[optidx]);
|
||||
undo_glob_escape(*path1);
|
||||
}
|
||||
break;
|
||||
case I_LS:
|
||||
if ((optidx = parse_ls_flags(argv, argc, lflag)) == -1)
|
||||
return(-1);
|
||||
@ -1130,7 +1225,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
||||
int err_abort)
|
||||
{
|
||||
char *path1, *path2, *tmp;
|
||||
int pflag, lflag, iflag, cmdnum, i;
|
||||
int pflag, lflag, iflag, hflag, cmdnum, i;
|
||||
unsigned long n_arg;
|
||||
Attrib a, *aa;
|
||||
char path_buf[MAXPATHLEN];
|
||||
@ -1138,7 +1233,7 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
||||
glob_t g;
|
||||
|
||||
path1 = path2 = NULL;
|
||||
cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &n_arg,
|
||||
cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &hflag, &n_arg,
|
||||
&path1, &path2);
|
||||
|
||||
if (iflag != 0)
|
||||
@ -1232,6 +1327,13 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
|
||||
path1 = make_absolute(path1, *pwd);
|
||||
err = do_globbed_ls(conn, path1, tmp, lflag);
|
||||
break;
|
||||
case I_DF:
|
||||
/* Default to current directory if no path specified */
|
||||
if (path1 == NULL)
|
||||
path1 = xstrdup(*pwd);
|
||||
path1 = make_absolute(path1, *pwd);
|
||||
err = do_df(conn, path1, hflag, iflag);
|
||||
break;
|
||||
case I_LCHDIR:
|
||||
if (chdir(path1) == -1) {
|
||||
error("Couldn't change local directory to "
|
||||
|
6
sftp.h
6
sftp.h
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: sftp.h,v 1.7 2008/02/08 23:24:07 djm Exp $ */
|
||||
/* $OpenBSD: sftp.h,v 1.8 2008/04/18 12:32:11 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
@ -79,6 +79,10 @@
|
||||
#define SSH2_FXF_TRUNC 0x00000010
|
||||
#define SSH2_FXF_EXCL 0x00000020
|
||||
|
||||
/* statvfs@openssh.com f_flag flags */
|
||||
#define SSH2_FXE_STATVFS_ST_RDONLY 0x00000001
|
||||
#define SSH2_FXE_STATVFS_ST_NOSUID 0x00000002
|
||||
|
||||
/* status messages */
|
||||
#define SSH2_FX_OK 0
|
||||
#define SSH2_FX_EOF 1
|
||||
|
Loading…
Reference in New Issue
Block a user