View | Details | Raw Unified | Return to bug 2694
Collapse All | Expand All

(-)a/sftp.c (-2 / +46 lines)
Lines 86-91 volatile sig_atomic_t interrupted = 0; Link Here
86
86
87
/* I wish qsort() took a separate ctx for the comparison function...*/
87
/* I wish qsort() took a separate ctx for the comparison function...*/
88
int sort_flag;
88
int sort_flag;
89
glob_t *sort_glob;
89
90
90
/* Context used for commandline completion */
91
/* Context used for commandline completion */
91
struct complete_ctx {
92
struct complete_ctx {
Lines 857-862 do_ls_dir(struct sftp_conn *conn, const char *path, Link Here
857
	return (0);
858
	return (0);
858
}
859
}
859
860
861
static int
862
sglob_comp(const void *aa, const void *bb)
863
{
864
	u_int a = *(const u_int *)aa;
865
	u_int b = *(const u_int *)bb;
866
	const char *ap = sort_glob->gl_pathv[a];
867
	const char *bp = sort_glob->gl_pathv[b];
868
	const struct stat *as = sort_glob->gl_statv[a];
869
	const struct stat *bs = sort_glob->gl_statv[b];
870
	int rmul = sort_flag & LS_REVERSE_SORT ? -1 : 1;
871
872
#define NCMP(a,b) (a == b ? 0 : (a < b ? 1 : -1))
873
	if (sort_flag & LS_NAME_SORT)
874
		return (rmul * strcmp(ap, bp));
875
	else if (sort_flag & LS_TIME_SORT)
876
		return (rmul * timespeccmp(&as->st_mtim, &bs->st_mtim, <));
877
	else if (sort_flag & LS_SIZE_SORT)
878
		return (rmul * NCMP(as->st_size, bs->st_size));
879
880
	fatal("Unknown ls sort type");
881
}
882
860
/* sftp ls.1 replacement which handles path globs */
883
/* sftp ls.1 replacement which handles path globs */
861
static int
884
static int
862
do_globbed_ls(struct sftp_conn *conn, const char *path,
885
do_globbed_ls(struct sftp_conn *conn, const char *path,
Lines 866-872 do_globbed_ls(struct sftp_conn *conn, const char *path, Link Here
866
	glob_t g;
889
	glob_t g;
867
	int err, r;
890
	int err, r;
868
	struct winsize ws;
891
	struct winsize ws;
869
	u_int i, c = 1, colspace = 0, columns = 1, m = 0, width = 80;
892
	u_int i, j, nentries, *indices = NULL, c = 1;
893
	u_int colspace = 0, columns = 1, m = 0, width = 80;
870
894
871
	memset(&g, 0, sizeof(g));
895
	memset(&g, 0, sizeof(g));
872
896
Lines 911-917 do_globbed_ls(struct sftp_conn *conn, const char *path, Link Here
911
		colspace = width / columns;
935
		colspace = width / columns;
912
	}
936
	}
913
937
914
	for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
938
	/*
939
	 * Sorting: rather than mess with the contents of glob_t, prepare
940
	 * an array of indices into it and sort that. For the usual
941
	 * unsorted case, the indices are just the identity 1=1, 2=2, etc.
942
	 */
943
	for (nentries = 0; g.gl_pathv[nentries] != NULL; nentries++)
944
		;	/* count entries */
945
	indices = calloc(nentries, sizeof(*indices));
946
	for (i = 0; i < nentries; i++)
947
		indices[i] = i;
948
949
	if (lflag & SORT_FLAGS) {
950
		sort_glob = &g;
951
		sort_flag = lflag & (SORT_FLAGS|LS_REVERSE_SORT);
952
		qsort(indices, nentries, sizeof(*indices), sglob_comp);
953
		sort_glob = NULL;
954
	}
955
956
	for (j = 0; j < nentries && !interrupted; j++) {
957
		i = indices[j];
915
		fname = path_strip(g.gl_pathv[i], strip_path);
958
		fname = path_strip(g.gl_pathv[i], strip_path);
916
		if (lflag & LS_LONG_VIEW) {
959
		if (lflag & LS_LONG_VIEW) {
917
			if (g.gl_statv[i] == NULL) {
960
			if (g.gl_statv[i] == NULL) {
Lines 939-944 do_globbed_ls(struct sftp_conn *conn, const char *path, Link Here
939
 out:
982
 out:
940
	if (g.gl_pathc)
983
	if (g.gl_pathc)
941
		globfree(&g);
984
		globfree(&g);
985
	free(indices);
942
986
943
	return 0;
987
	return 0;
944
}
988
}

Return to bug 2694