- register int cnt, maxentry;
- register char *p, *names;
- struct dirent *entry;
- LS *stats;
- DIR *dirp;
-
- /* make this big so we don't realloc often */
-#define DEFNUM 256
- maxentry = DEFNUM;
- *s_stats = stats = (LS *)emalloc((u_int)DEFNUM * sizeof(LS));
- *s_names = names = emalloc((u_int)lp->lstat.st_size);
-
- if (!(dirp = opendir(f_specialdir ? lp->name : "."))) {
- (void)fprintf(stderr, "ls: %s: %s\n",
- lp->name, strerror(errno));
- return(0);
- }
- for (cnt = 0; entry = readdir(dirp);) {
- /* this does -A and -a */
- p = entry->d_name;
- if (p[0] == '.') {
- if (!f_listdot)
- continue;
- if (!f_listalldot && (!p[1] || p[1] == '.' && !p[2]))
- continue;
- }
- if (cnt == maxentry) {
- maxentry += DEFNUM;
- if (!(stats = (LS *)realloc((char *)stats,
- (u_int)maxentry * sizeof(LS))))
- nomem();
- }
- if (needstat && lstat(entry->d_name, &stats[cnt].lstat)) {
- (void)fprintf(stderr, "ls: %s: %s\n",
- entry->d_name, strerror(errno));
- if (errno == ENOENT)
- continue;
- exit(1);
- }
- stats[cnt].name = names;
- bcopy(entry->d_name, names, (int)entry->d_namlen);
- names += entry->d_namlen;
- *names++ = '\0';
- ++cnt;
- }
- closedir(dirp);
- return(cnt);
+ int a_info, b_info;
+
+ a_info = (*a)->fts_info;
+ if (a_info == FTS_ERR)
+ return (0);
+ b_info = (*b)->fts_info;
+ if (b_info == FTS_ERR)
+ return (0);
+
+ if (a_info == FTS_NS || b_info == FTS_NS)
+ return (namecmp(*a, *b));
+
+ if (a_info == b_info)
+ return (sortfcn(*a, *b));
+
+ if ((*a)->fts_level == FTS_ROOTLEVEL)
+ if (a_info == FTS_D)
+ return (1);
+ else if (b_info == FTS_D)
+ return (-1);
+ else
+ return (sortfcn(*a, *b));
+ else
+ return (sortfcn(*a, *b));