From 19c8f2b310d06b1cf213186a96abce09bf676061 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Thu, 15 May 2003 13:49:21 +1000 Subject: [PATCH] - mouring@cvs.openbsd.org 2003/05/15 03:43:59 [sftp-int.c] Teach ls how to display multiple column display and allow users to return to single column format via 'ls -1'. OK @djm --- ChangeLog | 6 ++++- sftp-int.c | 79 +++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 69 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index 89ef50273..ca7125bf8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -31,6 +31,10 @@ - mouring@cvs.openbsd.org 2003/05/15 03:39:07 [sftp-int.c] Make put/get (globed and nonglobed) code more consistant. OK djm@ + - mouring@cvs.openbsd.org 2003/05/15 03:43:59 + [sftp-int.c] + Teach ls how to display multiple column display and allow users + to return to single column format via 'ls -1'. OK @djm - (djm) Always parse UsePAM - (djm) Configure glue for DNS support (code doesn't work in portable yet) - (djm) Import getrrsetbyname() function from OpenBSD libc (for DNS support) @@ -1511,4 +1515,4 @@ save auth method before monitor_reset_key_state(); bugzilla bug #284; ok provos@ -$Id: ChangeLog,v 1.2713 2003/05/15 03:48:59 djm Exp $ +$Id: ChangeLog,v 1.2714 2003/05/15 03:49:21 djm Exp $ diff --git a/sftp-int.c b/sftp-int.c index 25879baf1..f2d3f9468 100644 --- a/sftp-int.c +++ b/sftp-int.c @@ -25,7 +25,7 @@ /* XXX: recursive operations */ #include "includes.h" -RCSID("$OpenBSD: sftp-int.c,v 1.59 2003/05/15 03:39:07 mouring Exp $"); +RCSID("$OpenBSD: sftp-int.c,v 1.60 2003/05/15 03:43:59 mouring Exp $"); #include "buffer.h" #include "xmalloc.h" @@ -53,6 +53,10 @@ int showprogress = 1; /* Seperators for interactive commands */ #define WHITESPACE " \t\r\n" +/* Define what type of ls view (0 - multi-column) */ +#define LONG_VIEW 1 /* Full view ala ls -l */ +#define SHORT_VIEW 2 /* Single row view ala ls -1 */ + /* Commands for interactive mode */ #define I_CHDIR 1 #define I_CHGRP 2 @@ -307,7 +311,10 @@ parse_ls_flags(const char **cpp, int *lflag) for(; strchr(WHITESPACE, *cp) == NULL; cp++) { switch (*cp) { case 'l': - *lflag = 1; + *lflag = LONG_VIEW; + break; + case '1': + *lflag = SHORT_VIEW; break; default: error("Invalid flag -%c", *cp); @@ -558,15 +565,26 @@ sdirent_comp(const void *aa, const void *bb) static int do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) { - int n; + int n, c = 1, colspace = 0, columns = 1; SFTP_DIRENT **d; if ((n = do_readdir(conn, path, &d)) != 0) return (n); - /* Count entries for sort */ - for (n = 0; d[n] != NULL; n++) - ; + if (!(lflag & SHORT_VIEW)) { + int m = 0, width = 80; + struct winsize ws; + + /* Count entries for sort and find longest filename */ + for (n = 0; d[n] != NULL; n++) + m = MAX(m, strlen(d[n]->filename)); + + if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) + width = ws.ws_col; + + columns = width / (m + 2); + colspace = width / columns; + } qsort(d, n, sizeof(*d), sdirent_comp); @@ -577,7 +595,7 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) fname = path_strip(tmp, strip_path); xfree(tmp); - if (lflag) { + if (lflag & LONG_VIEW) { char *lname; struct stat sb; @@ -587,13 +605,20 @@ do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag) printf("%s\n", lname); xfree(lname); } else { - /* XXX - multicolumn display would be nice here */ - printf("%s\n", fname); + printf("%-*s", colspace, fname); + if (c >= columns) { + printf("\n"); + c = 1; + } else + c++; } xfree(fname); } + if (!(lflag & LONG_VIEW) && (c != 1)) + printf("\n"); + free_sftp_dirents(d); return (0); } @@ -604,9 +629,8 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, int lflag) { glob_t g; - int i; + int i, c = 1, colspace = 0, columns = 1; Attrib *a; - struct stat sb; memset(&g, 0, sizeof(g)); @@ -633,12 +657,30 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, } } + if (!(lflag & SHORT_VIEW)) { + int m = 0, width = 80; + struct winsize ws; + + /* Count entries for sort and find longest filename */ + for (i = 0; g.gl_pathv[i]; i++) + m = MAX(m, strlen(g.gl_pathv[i])); + + if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) + width = ws.ws_col; + + columns = width / (m + 2); + colspace = width / columns; + } + for (i = 0; g.gl_pathv[i]; i++) { - char *fname, *lname; + char *fname; fname = path_strip(g.gl_pathv[i], strip_path); - if (lflag) { + if (lflag & LONG_VIEW) { + char *lname; + struct stat sb; + /* * XXX: this is slow - 1 roundtrip per path * A solution to this is to fork glob() and @@ -654,12 +696,19 @@ do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, printf("%s\n", lname); xfree(lname); } else { - /* XXX - multicolumn display would be nice here */ - printf("%s\n", fname); + printf("%-*s", colspace, fname); + if (c >= columns) { + printf("\n"); + c = 1; + } else + c++; } xfree(fname); } + if (!(lflag & LONG_VIEW) && (c != 1)) + printf("\n"); + if (g.gl_pathc) globfree(&g);