version 1.179, 2017/05/02 08:54:19 |
version 1.180, 2017/06/10 06:33:34 |
|
|
|
|
/* I wish qsort() took a separate ctx for the comparison function...*/ |
/* I wish qsort() took a separate ctx for the comparison function...*/ |
int sort_flag; |
int sort_flag; |
|
glob_t *sort_glob; |
|
|
/* Context used for commandline completion */ |
/* Context used for commandline completion */ |
struct complete_ctx { |
struct complete_ctx { |
|
|
return (0); |
return (0); |
} |
} |
|
|
|
static int |
|
sglob_comp(const void *aa, const void *bb) |
|
{ |
|
u_int a = *(const u_int *)aa; |
|
u_int b = *(const u_int *)bb; |
|
const char *ap = sort_glob->gl_pathv[a]; |
|
const char *bp = sort_glob->gl_pathv[b]; |
|
const struct stat *as = sort_glob->gl_statv[a]; |
|
const struct stat *bs = sort_glob->gl_statv[b]; |
|
int rmul = sort_flag & LS_REVERSE_SORT ? -1 : 1; |
|
|
|
#define NCMP(a,b) (a == b ? 0 : (a < b ? 1 : -1)) |
|
if (sort_flag & LS_NAME_SORT) |
|
return (rmul * strcmp(ap, bp)); |
|
else if (sort_flag & LS_TIME_SORT) |
|
return (rmul * timespeccmp(&as->st_mtim, &bs->st_mtim, <)); |
|
else if (sort_flag & LS_SIZE_SORT) |
|
return (rmul * NCMP(as->st_size, bs->st_size)); |
|
|
|
fatal("Unknown ls sort type"); |
|
} |
|
|
/* sftp ls.1 replacement which handles path globs */ |
/* sftp ls.1 replacement which handles path globs */ |
static int |
static int |
do_globbed_ls(struct sftp_conn *conn, const char *path, |
do_globbed_ls(struct sftp_conn *conn, const char *path, |
|
|
glob_t g; |
glob_t g; |
int err, r; |
int err, r; |
struct winsize ws; |
struct winsize ws; |
u_int i, c = 1, colspace = 0, columns = 1, m = 0, width = 80; |
u_int i, j, nentries, *indices = NULL, c = 1; |
|
u_int colspace = 0, columns = 1, m = 0, width = 80; |
|
|
memset(&g, 0, sizeof(g)); |
memset(&g, 0, sizeof(g)); |
|
|
|
|
colspace = width / columns; |
colspace = width / columns; |
} |
} |
|
|
for (i = 0; g.gl_pathv[i] && !interrupted; i++) { |
/* |
|
* Sorting: rather than mess with the contents of glob_t, prepare |
|
* an array of indices into it and sort that. For the usual |
|
* unsorted case, the indices are just the identity 1=1, 2=2, etc. |
|
*/ |
|
for (nentries = 0; g.gl_pathv[nentries] != NULL; nentries++) |
|
; /* count entries */ |
|
indices = calloc(nentries, sizeof(*indices)); |
|
for (i = 0; i < nentries; i++) |
|
indices[i] = i; |
|
|
|
if (lflag & SORT_FLAGS) { |
|
sort_glob = &g; |
|
sort_flag = lflag & (SORT_FLAGS|LS_REVERSE_SORT); |
|
qsort(indices, nentries, sizeof(*indices), sglob_comp); |
|
sort_glob = NULL; |
|
} |
|
|
|
for (j = 0; j < nentries && !interrupted; j++) { |
|
i = indices[j]; |
fname = path_strip(g.gl_pathv[i], strip_path); |
fname = path_strip(g.gl_pathv[i], strip_path); |
if (lflag & LS_LONG_VIEW) { |
if (lflag & LS_LONG_VIEW) { |
if (g.gl_statv[i] == NULL) { |
if (g.gl_statv[i] == NULL) { |
|
|
out: |
out: |
if (g.gl_pathc) |
if (g.gl_pathc) |
globfree(&g); |
globfree(&g); |
|
free(indices); |
|
|
return 0; |
return 0; |
} |
} |