summaryrefslogtreecommitdiff
path: root/sftp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sftp.c')
-rw-r--r--sftp.c58
1 files changed, 54 insertions, 4 deletions
diff --git a/sftp.c b/sftp.c
index 76add3908..67110f738 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp.c,v 1.178 2017/02/15 01:46:47 djm Exp $ */ 1/* $OpenBSD: sftp.c,v 1.180 2017/06/10 06:33:34 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -106,6 +106,7 @@ volatile sig_atomic_t interrupted = 0;
106 106
107/* I wish qsort() took a separate ctx for the comparison function...*/ 107/* I wish qsort() took a separate ctx for the comparison function...*/
108int sort_flag; 108int sort_flag;
109glob_t *sort_glob;
109 110
110/* Context used for commandline completion */ 111/* Context used for commandline completion */
111struct complete_ctx { 112struct complete_ctx {
@@ -879,6 +880,34 @@ do_ls_dir(struct sftp_conn *conn, const char *path,
879 return (0); 880 return (0);
880} 881}
881 882
883static int
884sglob_comp(const void *aa, const void *bb)
885{
886 u_int a = *(const u_int *)aa;
887 u_int b = *(const u_int *)bb;
888 const char *ap = sort_glob->gl_pathv[a];
889 const char *bp = sort_glob->gl_pathv[b];
890 const struct stat *as = sort_glob->gl_statv[a];
891 const struct stat *bs = sort_glob->gl_statv[b];
892 int rmul = sort_flag & LS_REVERSE_SORT ? -1 : 1;
893
894#define NCMP(a,b) (a == b ? 0 : (a < b ? 1 : -1))
895 if (sort_flag & LS_NAME_SORT)
896 return (rmul * strcmp(ap, bp));
897 else if (sort_flag & LS_TIME_SORT) {
898#if defined(HAVE_STRUCT_STAT_ST_MTIM)
899 return (rmul * timespeccmp(&as->st_mtim, &bs->st_mtim, <));
900#elif defined(HAVE_STRUCT_STAT_ST_MTIME)
901 return (rmul * NCMP(as->st_mtime, bs->st_mtime));
902#else
903 return rmul * 1;
904#endif
905 } else if (sort_flag & LS_SIZE_SORT)
906 return (rmul * NCMP(as->st_size, bs->st_size));
907
908 fatal("Unknown ls sort type");
909}
910
882/* sftp ls.1 replacement which handles path globs */ 911/* sftp ls.1 replacement which handles path globs */
883static int 912static int
884do_globbed_ls(struct sftp_conn *conn, const char *path, 913do_globbed_ls(struct sftp_conn *conn, const char *path,
@@ -888,7 +917,8 @@ do_globbed_ls(struct sftp_conn *conn, const char *path,
888 glob_t g; 917 glob_t g;
889 int err, r; 918 int err, r;
890 struct winsize ws; 919 struct winsize ws;
891 u_int i, c = 1, colspace = 0, columns = 1, m = 0, width = 80; 920 u_int i, j, nentries, *indices = NULL, c = 1;
921 u_int colspace = 0, columns = 1, m = 0, width = 80;
892 922
893 memset(&g, 0, sizeof(g)); 923 memset(&g, 0, sizeof(g));
894 924
@@ -933,7 +963,26 @@ do_globbed_ls(struct sftp_conn *conn, const char *path,
933 colspace = width / columns; 963 colspace = width / columns;
934 } 964 }
935 965
936 for (i = 0; g.gl_pathv[i] && !interrupted; i++) { 966 /*
967 * Sorting: rather than mess with the contents of glob_t, prepare
968 * an array of indices into it and sort that. For the usual
969 * unsorted case, the indices are just the identity 1=1, 2=2, etc.
970 */
971 for (nentries = 0; g.gl_pathv[nentries] != NULL; nentries++)
972 ; /* count entries */
973 indices = calloc(nentries, sizeof(*indices));
974 for (i = 0; i < nentries; i++)
975 indices[i] = i;
976
977 if (lflag & SORT_FLAGS) {
978 sort_glob = &g;
979 sort_flag = lflag & (SORT_FLAGS|LS_REVERSE_SORT);
980 qsort(indices, nentries, sizeof(*indices), sglob_comp);
981 sort_glob = NULL;
982 }
983
984 for (j = 0; j < nentries && !interrupted; j++) {
985 i = indices[j];
937 fname = path_strip(g.gl_pathv[i], strip_path); 986 fname = path_strip(g.gl_pathv[i], strip_path);
938 if (lflag & LS_LONG_VIEW) { 987 if (lflag & LS_LONG_VIEW) {
939 if (g.gl_statv[i] == NULL) { 988 if (g.gl_statv[i] == NULL) {
@@ -961,6 +1010,7 @@ do_globbed_ls(struct sftp_conn *conn, const char *path,
961 out: 1010 out:
962 if (g.gl_pathc) 1011 if (g.gl_pathc)
963 globfree(&g); 1012 globfree(&g);
1013 free(indices);
964 1014
965 return 0; 1015 return 0;
966} 1016}
@@ -2246,7 +2296,7 @@ usage(void)
2246 extern char *__progname; 2296 extern char *__progname;
2247 2297
2248 fprintf(stderr, 2298 fprintf(stderr,
2249 "usage: %s [-1246aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n" 2299 "usage: %s [-46aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n"
2250 " [-D sftp_server_path] [-F ssh_config] " 2300 " [-D sftp_server_path] [-F ssh_config] "
2251 "[-i identity_file] [-l limit]\n" 2301 "[-i identity_file] [-l limit]\n"
2252 " [-o ssh_option] [-P port] [-R num_requests] " 2302 " [-o ssh_option] [-P port] [-R num_requests] "