From 7dc4850ce85a676ede0c070db6e46e022bd852fe Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:44:42 +1100 Subject: - djm@cvs.openbsd.org 2009/08/27 17:28:52 [sftp-server.c] allow setting an explicit umask on the commandline to override whatever default the user has. bz#1229; ok dtucker@ deraadt@ markus@ --- sftp-server.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'sftp-server.c') diff --git a/sftp-server.c b/sftp-server.c index d984e6049..d144001bb 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.85 2009/04/14 16:33:42 stevesk Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.86 2009/08/27 17:28:52 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -1322,7 +1322,8 @@ sftp_server_usage(void) extern char *__progname; fprintf(stderr, - "usage: %s [-he] [-l log_level] [-f log_facility]\n", __progname); + "usage: %s [-he] [-l log_level] [-f log_facility] [-u umask]\n", + __progname); exit(1); } @@ -1334,6 +1335,8 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) ssize_t len, olen, set_size; SyslogFacility log_facility = SYSLOG_FACILITY_AUTH; char *cp, buf[4*4096]; + const char *errmsg; + mode_t mask; extern char *optarg; extern char *__progname; @@ -1341,7 +1344,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) __progname = ssh_get_progname(argv[0]); log_init(__progname, log_level, log_facility, log_stderr); - while (!skipargs && (ch = getopt(argc, argv, "f:l:che")) != -1) { + while (!skipargs && (ch = getopt(argc, argv, "f:l:u:che")) != -1) { switch (ch) { case 'c': /* @@ -1363,6 +1366,13 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) if (log_facility == SYSLOG_FACILITY_NOT_SET) error("Invalid log facility \"%s\"", optarg); break; + case 'u': + mask = (mode_t)strtonum(optarg, 0, 0777, &errmsg); + if (cp != NULL) + fatal("Invalid umask \"%s\": %s", + optarg, errmsg); + (void)umask(mask); + break; case 'h': default: sftp_server_usage(); -- cgit v1.2.3 From 30359e19ecd93a494493501a8eacb4f7d36b2e3f Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 7 Oct 2009 08:47:24 +1100 Subject: - djm@cvs.openbsd.org 2009/08/31 20:56:02 [sftp-server.c] check correct variable for error message, spotted by martynas@ --- ChangeLog | 3 +++ sftp-server.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'sftp-server.c') diff --git a/ChangeLog b/ChangeLog index 971225fa8..a57890ebd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -67,6 +67,9 @@ migration measure back in 2002 when constraints were new, but just adds risk now. bz #1612, report and patch from dkg AT fifthhorseman.net; ok markus@ + - djm@cvs.openbsd.org 2009/08/31 20:56:02 + [sftp-server.c] + check correct variable for error message, spotted by martynas@ 20091002 - (djm) [Makefile.in] Mention readconf.o in ssh-keysign's make deps. diff --git a/sftp-server.c b/sftp-server.c index d144001bb..66c0c1d5f 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.86 2009/08/27 17:28:52 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.87 2009/08/31 20:56:02 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -1368,7 +1368,7 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) break; case 'u': mask = (mode_t)strtonum(optarg, 0, 0777, &errmsg); - if (cp != NULL) + if (errmsg != NULL) fatal("Invalid umask \"%s\": %s", optarg, errmsg); (void)umask(mask); -- cgit v1.2.3 From 49b7e235455bf20227877624f8c60c34a6e78458 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 24 Oct 2009 11:41:05 +1100 Subject: - sobrado@cvs.openbsd.org 2009/10/17 12:10:39 [sftp-server.c] sort flags. --- ChangeLog | 3 +++ sftp-server.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'sftp-server.c') diff --git a/ChangeLog b/ChangeLog index 16f45c8ff..67839e275 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,9 @@ - djm@cvs.openbsd.org 2009/10/11 23:03:15 [hostfile.c] mention the host name that we are looking for in check_host_in_hostfile() + - sobrado@cvs.openbsd.org 2009/10/17 12:10:39 + [sftp-server.c] + sort flags. 20091011 - (dtucker) [configure.ac sftp-client.c] Remove the gyrations required for diff --git a/sftp-server.c b/sftp-server.c index 66c0c1d5f..20a601f99 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.87 2009/08/31 20:56:02 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.88 2009/10/17 12:10:39 sobrado Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -1322,7 +1322,7 @@ sftp_server_usage(void) extern char *__progname; fprintf(stderr, - "usage: %s [-he] [-l log_level] [-f log_facility] [-u umask]\n", + "usage: %s [-eh] [-f log_facility] [-l log_level] [-u umask]\n", __progname); exit(1); } -- cgit v1.2.3 From aaf51d2d5b76c25cc549559a200a802e92b2d8aa Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 8 Jan 2010 19:04:49 +1100 Subject: - djm@cvs.openbsd.org 2010/01/04 02:25:15 [sftp-server.c] bz#1566 don't unnecessarily dup() in and out fds for sftp-server; ok markus@ --- ChangeLog | 4 ++++ sftp-server.c | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'sftp-server.c') diff --git a/ChangeLog b/ChangeLog index 70e3c15e9..05b99b160 100644 --- a/ChangeLog +++ b/ChangeLog @@ -150,6 +150,10 @@ by quoted filenames, but the UI could still be slightly improved. In particular, it is quite slow for remote completion on large directories. bz#200; ok markus@ + - djm@cvs.openbsd.org 2010/01/04 02:25:15 + [sftp-server.c] + bz#1566 don't unnecessarily dup() in and out fds for sftp-server; + ok markus@ 20091226 - (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1 diff --git a/sftp-server.c b/sftp-server.c index 20a601f99..cf4e273f8 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.88 2009/10/17 12:10:39 sobrado Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.89 2010/01/04 02:25:15 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -1397,8 +1397,8 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) logit("session opened for local user %s from [%s]", pw->pw_name, client_addr); - in = dup(STDIN_FILENO); - out = dup(STDOUT_FILENO); + in = STDIN_FILENO; + out = STDOUT_FILENO; #ifdef HAVE_CYGWIN setmode(in, O_BINARY); -- cgit v1.2.3 From db7bf82544800c21a471a89781466bbf4ac08731 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sat, 9 Jan 2010 22:24:33 +1100 Subject: - djm@cvs.openbsd.org 2010/01/09 00:20:26 [sftp-server.c sftp-server.8] add a 'read-only' mode to sftp-server(8) that disables open in write mode and all other fs-modifying protocol methods. bz#430 ok dtucker@ --- ChangeLog | 5 +++ sftp-server.8 | 12 +++++-- sftp-server.c | 103 +++++++++++++++++++++++++++++++++++++++++----------------- 3 files changed, 88 insertions(+), 32 deletions(-) (limited to 'sftp-server.c') diff --git a/ChangeLog b/ChangeLog index 31f205f6a..647d71def 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,11 @@ - (dtucker) [roaming_client.c] Wrap inttypes.h in an ifdef. - (dtucker) [loginrec.c] Use the SUSv3 specified name for the user name when using utmpx. Patch from Ed Schouten. + - (dtucker) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/01/09 00:20:26 + [sftp-server.c sftp-server.8] + add a 'read-only' mode to sftp-server(8) that disables open in write mode + and all other fs-modifying protocol methods. bz#430 ok dtucker@ 20091208 - (dtucker) OpenBSD CVS Sync diff --git a/sftp-server.8 b/sftp-server.8 index ee73c345b..84036922c 100644 --- a/sftp-server.8 +++ b/sftp-server.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp-server.8,v 1.17 2009/08/31 21:01:29 djm Exp $ +.\" $OpenBSD: sftp-server.8,v 1.18 2010/01/09 00:20:26 djm Exp $ .\" .\" Copyright (c) 2000 Markus Friedl. 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: August 31 2009 $ +.Dd $Mdocdate: January 9 2010 $ .Dt SFTP-SERVER 8 .Os .Sh NAME @@ -30,7 +30,7 @@ .Nd SFTP server subsystem .Sh SYNOPSIS .Nm sftp-server -.Op Fl eh +.Op Fl ehR .Op Fl f Ar log_facility .Op Fl l Ar log_level .Op Fl u Ar umask @@ -81,6 +81,12 @@ performs on behalf of the client. DEBUG and DEBUG1 are equivalent. DEBUG2 and DEBUG3 each specify higher levels of debugging output. The default is ERROR. +.It Fl R +Places this instance of +.Nm +into a read-only mode. +Attempts to open files for writing, as well as other operations that change +the state of the filesystem will be denied. .It Fl u Ar umask Sets an explicit .Xr umask 2 diff --git a/sftp-server.c b/sftp-server.c index cf4e273f8..ab9391cfd 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.89 2010/01/04 02:25:15 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.90 2010/01/09 00:20:26 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -70,6 +70,9 @@ Buffer oqueue; /* Version of client */ int version; +/* Disable writes */ +int readonly; + /* portable attributes, etc. */ typedef struct Stat Stat; @@ -553,16 +556,21 @@ process_open(void) mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666; logit("open \"%s\" flags %s mode 0%o", name, string_from_portable(pflags), mode); - fd = open(name, flags, mode); - if (fd < 0) { - status = errno_to_portable(errno); - } else { - handle = handle_new(HANDLE_FILE, name, fd, NULL); - if (handle < 0) { - close(fd); + if (readonly && + ((flags & O_ACCMODE) == O_WRONLY || (flags & O_ACCMODE) == O_RDWR)) + status = SSH2_FX_PERMISSION_DENIED; + else { + fd = open(name, flags, mode); + if (fd < 0) { + status = errno_to_portable(errno); } else { - send_handle(id, handle); - status = SSH2_FX_OK; + handle = handle_new(HANDLE_FILE, name, fd, NULL); + if (handle < 0) { + close(fd); + } else { + send_handle(id, handle); + status = SSH2_FX_OK; + } } } if (status != SSH2_FX_OK) @@ -632,7 +640,7 @@ process_write(void) u_int32_t id; u_int64_t off; u_int len; - int handle, fd, ret, status = SSH2_FX_FAILURE; + int handle, fd, ret, status; char *data; id = get_int(); @@ -643,7 +651,12 @@ process_write(void) debug("request %u: write \"%s\" (handle %d) off %llu len %d", id, handle_to_name(handle), handle, (unsigned long long)off, len); fd = handle_to_fd(handle); - if (fd >= 0) { + + if (fd < 0) + status = SSH2_FX_FAILURE; + else if (readonly) + status = SSH2_FX_PERMISSION_DENIED; + else { if (lseek(fd, off, SEEK_SET) < 0) { status = errno_to_portable(errno); error("process_write: seek failed"); @@ -658,6 +671,7 @@ process_write(void) handle_update_write(handle, ret); } else { debug2("nothing at all written"); + status = SSH2_FX_FAILURE; } } } @@ -754,6 +768,10 @@ process_setstat(void) name = get_string(NULL); a = get_attrib(); debug("request %u: setstat name \"%s\"", id, name); + if (readonly) { + status = SSH2_FX_PERMISSION_DENIED; + a->flags = 0; + } if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { logit("set \"%s\" size %llu", name, (unsigned long long)a->size); @@ -802,9 +820,11 @@ process_fsetstat(void) a = get_attrib(); debug("request %u: fsetstat handle %d", id, handle); fd = handle_to_fd(handle); - if (fd < 0) { + if (fd < 0) status = SSH2_FX_FAILURE; - } else { + else if (readonly) + status = SSH2_FX_PERMISSION_DENIED; + else { char *name = handle_to_name(handle); if (a->flags & SSH2_FILEXFER_ATTR_SIZE) { @@ -952,8 +972,12 @@ process_remove(void) name = get_string(NULL); debug3("request %u: remove", id); logit("remove name \"%s\"", name); - ret = unlink(name); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + if (readonly) + status = SSH2_FX_PERMISSION_DENIED; + else { + ret = unlink(name); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + } send_status(id, status); xfree(name); } @@ -973,8 +997,12 @@ process_mkdir(void) a->perm & 07777 : 0777; debug3("request %u: mkdir", id); logit("mkdir name \"%s\" mode 0%o", name, mode); - ret = mkdir(name, mode); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + if (readonly) + status = SSH2_FX_PERMISSION_DENIED; + else { + ret = mkdir(name, mode); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + } send_status(id, status); xfree(name); } @@ -990,8 +1018,12 @@ process_rmdir(void) name = get_string(NULL); debug3("request %u: rmdir", id); logit("rmdir name \"%s\"", name); - ret = rmdir(name); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + if (readonly) + status = SSH2_FX_PERMISSION_DENIED; + else { + ret = rmdir(name); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + } send_status(id, status); xfree(name); } @@ -1036,7 +1068,9 @@ process_rename(void) debug3("request %u: rename", id); logit("rename old \"%s\" new \"%s\"", oldpath, newpath); status = SSH2_FX_FAILURE; - if (lstat(oldpath, &sb) == -1) + if (readonly) + status = SSH2_FX_PERMISSION_DENIED; + else if (lstat(oldpath, &sb) == -1) status = errno_to_portable(errno); else if (S_ISREG(sb.st_mode)) { /* Race-free rename of regular files */ @@ -1120,8 +1154,12 @@ process_symlink(void) debug3("request %u: symlink", id); logit("symlink old \"%s\" new \"%s\"", oldpath, newpath); /* this will fail if 'newpath' exists */ - ret = symlink(oldpath, newpath); - status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + if (readonly) + status = SSH2_FX_PERMISSION_DENIED; + else { + ret = symlink(oldpath, newpath); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + } send_status(id, status); xfree(oldpath); xfree(newpath); @@ -1131,15 +1169,19 @@ static void process_extended_posix_rename(u_int32_t id) { char *oldpath, *newpath; + int ret, status; oldpath = get_string(NULL); newpath = get_string(NULL); debug3("request %u: posix-rename", id); logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath); - if (rename(oldpath, newpath) == -1) - send_status(id, errno_to_portable(errno)); - else - send_status(id, SSH2_FX_OK); + if (readonly) + status = SSH2_FX_PERMISSION_DENIED; + else { + ret = rename(oldpath, newpath); + status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + } + send_status(id, status); xfree(oldpath); xfree(newpath); } @@ -1322,7 +1364,7 @@ sftp_server_usage(void) extern char *__progname; fprintf(stderr, - "usage: %s [-eh] [-f log_facility] [-l log_level] [-u umask]\n", + "usage: %s [-ehR] [-f log_facility] [-l log_level] [-u umask]\n", __progname); exit(1); } @@ -1344,8 +1386,11 @@ sftp_server_main(int argc, char **argv, struct passwd *user_pw) __progname = ssh_get_progname(argv[0]); log_init(__progname, log_level, log_facility, log_stderr); - while (!skipargs && (ch = getopt(argc, argv, "f:l:u:che")) != -1) { + while (!skipargs && (ch = getopt(argc, argv, "f:l:u:cehR")) != -1) { switch (ch) { + case 'R': + readonly = 1; + break; case 'c': /* * Ignore all arguments if we are invoked as a -- cgit v1.2.3 From 2901e2daebe3a0890209f31d05d5bb9338cbed5b Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 13 Jan 2010 22:44:06 +1100 Subject: - djm@cvs.openbsd.org 2010/01/13 01:40:16 [sftp.c sftp-server.c sftp.1 sftp-common.c sftp-common.h] support '-h' (human-readable units) for sftp's ls command, just like ls(1); ok dtucker@ --- ChangeLog | 4 ++++ sftp-common.c | 19 ++++++++++++++----- sftp-common.h | 4 ++-- sftp-server.c | 4 ++-- sftp.1 | 11 ++++++++--- sftp.c | 39 ++++++++++++++++++++++----------------- 6 files changed, 52 insertions(+), 29 deletions(-) (limited to 'sftp-server.c') diff --git a/ChangeLog b/ChangeLog index 7624812b1..d4210354e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,10 @@ [canohost.c ssh-keysign.c sshconnect2.c] Make HostBased authentication work with a ProxyCommand. bz #1569, patch from imorgan at nas nasa gov, ok djm@ + - djm@cvs.openbsd.org 2010/01/13 01:40:16 + [sftp.c sftp-server.c sftp.1 sftp-common.c sftp-common.h] + support '-h' (human-readable units) for sftp's ls command, just like + ls(1); ok dtucker@ 20100112 - (dtucker) OpenBSD CVS Sync diff --git a/sftp-common.c b/sftp-common.c index 7ebadcc53..7393fc6a9 100644 --- a/sftp-common.c +++ b/sftp-common.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-common.c,v 1.20 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: sftp-common.c,v 1.21 2010/01/13 01:40:16 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Damien Miller. All rights reserved. @@ -36,6 +36,7 @@ #include #include #include +#include #include "xmalloc.h" #include "buffer.h" @@ -184,7 +185,7 @@ fx2txt(int status) * drwxr-xr-x 5 markus markus 1024 Jan 13 18:39 .ssh */ char * -ls_file(const char *name, const struct stat *st, int remote) +ls_file(const char *name, const struct stat *st, int remote, int si_units) { int ulen, glen, sz = 0; struct passwd *pw; @@ -192,6 +193,7 @@ ls_file(const char *name, const struct stat *st, int remote) struct tm *ltime = localtime(&st->st_mtime); char *user, *group; char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1]; + char sbuf[FMT_SCALED_STRSIZE]; strmode(st->st_mode, mode); if (!remote && (pw = getpwuid(st->st_uid)) != NULL) { @@ -216,8 +218,15 @@ ls_file(const char *name, const struct stat *st, int remote) tbuf[0] = '\0'; ulen = MAX(strlen(user), 8); glen = MAX(strlen(group), 8); - snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode, - (u_int)st->st_nlink, ulen, user, glen, group, - (unsigned long long)st->st_size, tbuf, name); + if (si_units) { + fmt_scaled((long long)st->st_size, sbuf); + snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8s %s %s", mode, + (u_int)st->st_nlink, ulen, user, glen, group, + sbuf, tbuf, name); + } else { + snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode, + (u_int)st->st_nlink, ulen, user, glen, group, + (unsigned long long)st->st_size, tbuf, name); + } return xstrdup(buf); } diff --git a/sftp-common.h b/sftp-common.h index 9b5848462..9ed86c070 100644 --- a/sftp-common.h +++ b/sftp-common.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-common.h,v 1.10 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: sftp-common.h,v 1.11 2010/01/13 01:40:16 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -46,6 +46,6 @@ void stat_to_attrib(const struct stat *, Attrib *); void attrib_to_stat(const Attrib *, struct stat *); Attrib *decode_attrib(Buffer *); void encode_attrib(Buffer *, const Attrib *); -char *ls_file(const char *, const struct stat *, int); +char *ls_file(const char *, const struct stat *, int, int); const char *fx2txt(int); diff --git a/sftp-server.c b/sftp-server.c index ab9391cfd..a98ac2b6d 100644 --- a/sftp-server.c +++ b/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.90 2010/01/09 00:20:26 djm Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.91 2010/01/13 01:40:16 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -940,7 +940,7 @@ process_readdir(void) continue; stat_to_attrib(&st, &(stats[count].attrib)); stats[count].name = xstrdup(dp->d_name); - stats[count].long_name = ls_file(dp->d_name, &st, 0); + stats[count].long_name = ls_file(dp->d_name, &st, 0, 0); count++; /* send up to 100 entries in one message */ /* XXX check packet size instead */ diff --git a/sftp.1 b/sftp.1 index 3ec7a0234..f6371cf54 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.80 2010/01/09 23:04:13 dtucker Exp $ +.\" $OpenBSD: sftp.1,v 1.81 2010/01/13 01:40:16 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: January 9 2010 $ +.Dd $Mdocdate: January 13 2010 $ .Dt SFTP 1 .Os .Sh NAME @@ -393,7 +393,7 @@ to .It Ic lpwd Print local working directory. .It Xo Ic ls -.Op Fl 1aflnrSt +.Op Fl 1aflhnrSt .Op Ar path .Xc Display a remote directory listing of either @@ -421,6 +421,11 @@ The default sort order is lexicographical. .It Fl l Display additional details including permissions and ownership information. +.It Fl h +When used with a long format option, use unit suffixes: Byte, Kilobyte, +Megabyte, Gigabyte, Terabyte, Petabyte, and Exabyte in order to reduce +the number of digits to four or fewer using powers of 2 for sizes (K=1024, +M=1048576, etc.). .It Fl n Produce a long listing with user and group information presented numerically. diff --git a/sftp.c b/sftp.c index 78f8ca178..16f84987c 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.118 2010/01/09 11:13:02 dtucker Exp $ */ +/* $OpenBSD: sftp.c,v 1.119 2010/01/13 01:40:16 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -110,16 +110,17 @@ extern char *__progname; #define WHITESPACE " \t\r\n" /* ls flags */ -#define LS_LONG_VIEW 0x01 /* Full view ala ls -l */ -#define LS_SHORT_VIEW 0x02 /* Single row view ala ls -1 */ -#define LS_NUMERIC_VIEW 0x04 /* Long view with numeric uid/gid */ -#define LS_NAME_SORT 0x08 /* Sort by name (default) */ -#define LS_TIME_SORT 0x10 /* Sort by mtime */ -#define LS_SIZE_SORT 0x20 /* Sort by file size */ -#define LS_REVERSE_SORT 0x40 /* Reverse sort order */ -#define LS_SHOW_ALL 0x80 /* Don't skip filenames starting with '.' */ - -#define VIEW_FLAGS (LS_LONG_VIEW|LS_SHORT_VIEW|LS_NUMERIC_VIEW) +#define LS_LONG_VIEW 0x0001 /* Full view ala ls -l */ +#define LS_SHORT_VIEW 0x0002 /* Single row view ala ls -1 */ +#define LS_NUMERIC_VIEW 0x0004 /* Long view with numeric uid/gid */ +#define LS_NAME_SORT 0x0008 /* Sort by name (default) */ +#define LS_TIME_SORT 0x0010 /* Sort by mtime */ +#define LS_SIZE_SORT 0x0020 /* Sort by file size */ +#define LS_REVERSE_SORT 0x0040 /* Reverse sort order */ +#define LS_SHOW_ALL 0x0080 /* Don't skip filenames starting with '.' */ +#define LS_SI_UNITS 0x0100 /* Display sizes as K, M, G, etc. */ + +#define VIEW_FLAGS (LS_LONG_VIEW|LS_SHORT_VIEW|LS_NUMERIC_VIEW|LS_SI_UNITS) #define SORT_FLAGS (LS_NAME_SORT|LS_TIME_SORT|LS_SIZE_SORT) /* Commands for interactive mode */ @@ -383,7 +384,7 @@ parse_ls_flags(char **argv, int argc, int *lflag) opterr = 0; *lflag = LS_NAME_SORT; - while ((ch = getopt(argc, argv, "1Saflnrt")) != -1) { + while ((ch = getopt(argc, argv, "1Safhlnrt")) != -1) { switch (ch) { case '1': *lflag &= ~VIEW_FLAGS; @@ -399,12 +400,15 @@ parse_ls_flags(char **argv, int argc, int *lflag) case 'f': *lflag &= ~SORT_FLAGS; break; + case 'h': + *lflag |= LS_SI_UNITS; + break; case 'l': - *lflag &= ~VIEW_FLAGS; + *lflag &= ~LS_SHORT_VIEW; *lflag |= LS_LONG_VIEW; break; case 'n': - *lflag &= ~VIEW_FLAGS; + *lflag &= ~LS_SHORT_VIEW; *lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW; break; case 'r': @@ -716,13 +720,14 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) xfree(tmp); if (lflag & LS_LONG_VIEW) { - if (lflag & LS_NUMERIC_VIEW) { + if (lflag & (LS_NUMERIC_VIEW|LS_SI_UNITS)) { char *lname; struct stat sb; memset(&sb, 0, sizeof(sb)); attrib_to_stat(&d[n]->a, &sb); - lname = ls_file(fname, &sb, 1); + lname = ls_file(fname, &sb, 1, + (lflag & LS_SI_UNITS)); printf("%s\n", lname); xfree(lname); } else @@ -824,7 +829,7 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, a = do_lstat(conn, g.gl_pathv[i], 1); if (a != NULL) attrib_to_stat(a, &sb); - lname = ls_file(fname, &sb, 1); + lname = ls_file(fname, &sb, 1, (lflag & LS_SI_UNITS)); printf("%s\n", lname); xfree(lname); } else { -- cgit v1.2.3