aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-05-13 17:28:46 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-05-13 17:28:46 +0200
commit4029e21b37a18bea86dd438d4a9138789ecdce6c (patch)
tree4e23c08d7fab2bb2a62959c313b0cc081f09a0f3 /coreutils
parent2a81639534bcfd075dee12eacc6c45e657e4488e (diff)
downloadbusybox-w32-4029e21b37a18bea86dd438d4a9138789ecdce6c.tar.gz
busybox-w32-4029e21b37a18bea86dd438d4a9138789ecdce6c.tar.bz2
busybox-w32-4029e21b37a18bea86dd438d4a9138789ecdce6c.zip
ls: reorder and rename functions. No code changes
function old new delta display_single - 931 +931 scan_and_display_dirs_recur - 497 +497 display_files - 422 +422 showfiles 422 - -422 showdirs 497 - -497 list_single 931 - -931 ------------------------------------------------------------------------------ (add/remove: 3/3 grow/shrink: 0/0 up/down: 1850/-1850) Total: 0 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/ls.c478
1 files changed, 240 insertions, 238 deletions
diff --git a/coreutils/ls.c b/coreutils/ls.c
index 52c2c4db7..907955077 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -326,7 +326,7 @@ struct dnode {
326// (such as nanosecond-resolution timespamps) 326// (such as nanosecond-resolution timespamps)
327// and padding, which we also don't want to store. 327// and padding, which we also don't want to store.
328// We also can pre-parse dev_t dn_rdev (in glibc, it's huge). 328// We also can pre-parse dev_t dn_rdev (in glibc, it's huge).
329// On 32-bit uclibc: dnode size went from 112 to 84 bytes 329// On 32-bit uclibc: dnode size went from 112 to 84 bytes.
330// 330//
331 /* Same names as in struct stat, but with dn_ instead of st_ pfx: */ 331 /* Same names as in struct stat, but with dn_ instead of st_ pfx: */
332 mode_t dn_mode; /* obtained with lstat OR stat, depending on -L etc */ 332 mode_t dn_mode; /* obtained with lstat OR stat, depending on -L etc */
@@ -376,61 +376,8 @@ struct globals {
376} while (0) 376} while (0)
377 377
378 378
379static struct dnode *my_stat(const char *fullname, const char *name, int force_follow) 379/*** Output code ***/
380{
381 struct stat statbuf;
382 struct dnode *cur;
383 380
384 cur = xzalloc(sizeof(*cur));
385 cur->fullname = fullname;
386 cur->name = name;
387
388 if ((option_mask32 & OPT_L) || force_follow) {
389#if ENABLE_SELINUX
390 if (is_selinux_enabled()) {
391 getfilecon(fullname, &cur->sid);
392 }
393#endif
394 if (stat(fullname, &statbuf)) {
395 bb_simple_perror_msg(fullname);
396 G.exit_code = EXIT_FAILURE;
397 free(cur);
398 return NULL;
399 }
400 cur->dn_mode_stat = statbuf.st_mode;
401 } else {
402#if ENABLE_SELINUX
403 if (is_selinux_enabled()) {
404 lgetfilecon(fullname, &cur->sid);
405 }
406#endif
407 if (lstat(fullname, &statbuf)) {
408 bb_simple_perror_msg(fullname);
409 G.exit_code = EXIT_FAILURE;
410 free(cur);
411 return NULL;
412 }
413 cur->dn_mode_lstat = statbuf.st_mode;
414 }
415
416 /* cur->dstat = statbuf: */
417 cur->dn_mode = statbuf.st_mode ;
418 cur->dn_size = statbuf.st_size ;
419#if ENABLE_FEATURE_LS_TIMESTAMPS || ENABLE_FEATURE_LS_SORTFILES
420 cur->dn_atime = statbuf.st_atime ;
421 cur->dn_mtime = statbuf.st_mtime ;
422 cur->dn_ctime = statbuf.st_ctime ;
423#endif
424 cur->dn_ino = statbuf.st_ino ;
425 cur->dn_blocks = statbuf.st_blocks;
426 cur->dn_nlink = statbuf.st_nlink ;
427 cur->dn_uid = statbuf.st_uid ;
428 cur->dn_gid = statbuf.st_gid ;
429 cur->dn_rdev_maj = major(statbuf.st_rdev);
430 cur->dn_rdev_min = minor(statbuf.st_rdev);
431
432 return cur;
433}
434 381
435/* FYI type values: 1:fifo 2:char 4:dir 6:blk 8:file 10:link 12:socket 382/* FYI type values: 1:fifo 2:char 4:dir 6:blk 8:file 10:link 12:socket
436 * (various wacky OSes: 13:Sun door 14:BSD whiteout 5:XENIX named file 383 * (various wacky OSes: 13:Sun door 14:BSD whiteout 5:XENIX named file
@@ -493,155 +440,6 @@ static char append_char(mode_t mode)
493} 440}
494#endif 441#endif
495 442
496static unsigned count_dirs(struct dnode **dn, int which)
497{
498 unsigned dirs, all;
499
500 if (!dn)
501 return 0;
502
503 dirs = all = 0;
504 for (; *dn; dn++) {
505 const char *name;
506
507 all++;
508 if (!S_ISDIR((*dn)->dn_mode))
509 continue;
510
511 name = (*dn)->name;
512 if (which != SPLIT_SUBDIR /* if not requested to skip . / .. */
513 /* or if it's not . or .. */
514 || name[0] != '.'
515 || (name[1] && (name[1] != '.' || name[2]))
516 ) {
517 dirs++;
518 }
519 }
520 return which != SPLIT_FILE ? dirs : all - dirs;
521}
522
523/* get memory to hold an array of pointers */
524static struct dnode **dnalloc(unsigned num)
525{
526 if (num < 1)
527 return NULL;
528
529 num++; /* so that we have terminating NULL */
530 return xzalloc(num * sizeof(struct dnode *));
531}
532
533#if ENABLE_FEATURE_LS_RECURSIVE
534static void dfree(struct dnode **dnp)
535{
536 unsigned i;
537
538 if (dnp == NULL)
539 return;
540
541 for (i = 0; dnp[i]; i++) {
542 struct dnode *cur = dnp[i];
543 if (cur->fname_allocated)
544 free((char*)cur->fullname);
545 free(cur);
546 }
547 free(dnp);
548}
549#else
550#define dfree(...) ((void)0)
551#endif
552
553/* Returns NULL-terminated malloced vector of pointers (or NULL) */
554static struct dnode **splitdnarray(struct dnode **dn, int which)
555{
556 unsigned dncnt, d;
557 struct dnode **dnp;
558
559 if (dn == NULL)
560 return NULL;
561
562 /* count how many dirs or files there are */
563 dncnt = count_dirs(dn, which);
564
565 /* allocate a file array and a dir array */
566 dnp = dnalloc(dncnt);
567
568 /* copy the entrys into the file or dir array */
569 for (d = 0; *dn; dn++) {
570 if (S_ISDIR((*dn)->dn_mode)) {
571 const char *name;
572
573 if (which == SPLIT_FILE)
574 continue;
575
576 name = (*dn)->name;
577 if ((which & SPLIT_DIR) /* any dir... */
578 /* ... or not . or .. */
579 || name[0] != '.'
580 || (name[1] && (name[1] != '.' || name[2]))
581 ) {
582 dnp[d++] = *dn;
583 }
584 } else
585 if (which == SPLIT_FILE) {
586 dnp[d++] = *dn;
587 }
588 }
589 return dnp;
590}
591
592#if ENABLE_FEATURE_LS_SORTFILES
593static int sortcmp(const void *a, const void *b)
594{
595 struct dnode *d1 = *(struct dnode **)a;
596 struct dnode *d2 = *(struct dnode **)b;
597 unsigned sort_opts = G.all_fmt & SORT_MASK;
598 off_t dif;
599
600 dif = 0; /* assume SORT_NAME */
601 // TODO: use pre-initialized function pointer
602 // instead of branch forest
603 if (sort_opts == SORT_SIZE) {
604 dif = (d2->dn_size - d1->dn_size);
605 } else if (sort_opts == SORT_ATIME) {
606 dif = (d2->dn_atime - d1->dn_atime);
607 } else if (sort_opts == SORT_CTIME) {
608 dif = (d2->dn_ctime - d1->dn_ctime);
609 } else if (sort_opts == SORT_MTIME) {
610 dif = (d2->dn_mtime - d1->dn_mtime);
611 } else if (sort_opts == SORT_DIR) {
612 dif = S_ISDIR(d2->dn_mode) - S_ISDIR(d1->dn_mode);
613 /* } else if (sort_opts == SORT_VERSION) { */
614 /* } else if (sort_opts == SORT_EXT) { */
615 }
616 if (dif == 0) {
617 /* sort by name, or tie_breaker for other sorts */
618 if (ENABLE_LOCALE_SUPPORT)
619 dif = strcoll(d1->name, d2->name);
620 else
621 dif = strcmp(d1->name, d2->name);
622 }
623
624 /* Make dif fit into an int */
625 if (sizeof(dif) > sizeof(int)) {
626 enum { BITS_TO_SHIFT = 8 * (sizeof(dif) - sizeof(int)) };
627 /* shift leaving only "int" worth of bits */
628 if (dif != 0) {
629 dif = 1 | (int)((uoff_t)dif >> BITS_TO_SHIFT);
630 }
631 }
632
633 return (G.all_fmt & SORT_REVERSE) ? -(int)dif : (int)dif;
634}
635
636static void dnsort(struct dnode **dn, int size)
637{
638 qsort(dn, size, sizeof(*dn), sortcmp);
639}
640#else
641#define dnsort(dn, size) ((void)0)
642#endif
643
644
645static unsigned calc_name_len(const char *name) 443static unsigned calc_name_len(const char *name)
646{ 444{
647 unsigned len; 445 unsigned len;
@@ -664,7 +462,6 @@ static unsigned calc_name_len(const char *name)
664 return len; 462 return len;
665} 463}
666 464
667
668/* Return the number of used columns. 465/* Return the number of used columns.
669 * Note that only STYLE_COLUMNAR uses return value. 466 * Note that only STYLE_COLUMNAR uses return value.
670 * STYLE_SINGLE and STYLE_LONG don't care. 467 * STYLE_SINGLE and STYLE_LONG don't care.
@@ -703,7 +500,7 @@ static unsigned print_name(const char *name)
703 * Note that only STYLE_COLUMNAR uses return value, 500 * Note that only STYLE_COLUMNAR uses return value,
704 * STYLE_SINGLE and STYLE_LONG don't care. 501 * STYLE_SINGLE and STYLE_LONG don't care.
705 */ 502 */
706static NOINLINE unsigned list_single(const struct dnode *dn) 503static NOINLINE unsigned display_single(const struct dnode *dn)
707{ 504{
708 unsigned column = 0; 505 unsigned column = 0;
709 char *lpath; 506 char *lpath;
@@ -854,7 +651,7 @@ static NOINLINE unsigned list_single(const struct dnode *dn)
854 return column; 651 return column;
855} 652}
856 653
857static void showfiles(struct dnode **dn, unsigned nfiles) 654static void display_files(struct dnode **dn, unsigned nfiles)
858{ 655{
859 unsigned i, ncols, nrows, row, nc; 656 unsigned i, ncols, nrows, row, nc;
860 unsigned column; 657 unsigned column;
@@ -902,7 +699,7 @@ static void showfiles(struct dnode **dn, unsigned nfiles)
902 column += nexttab + 1; 699 column += nexttab + 1;
903 } 700 }
904 nexttab = column + column_width; 701 nexttab = column + column_width;
905 column += list_single(dn[i]); 702 column += display_single(dn[i]);
906 } 703 }
907 } 704 }
908 putchar('\n'); 705 putchar('\n');
@@ -911,38 +708,214 @@ static void showfiles(struct dnode **dn, unsigned nfiles)
911} 708}
912 709
913 710
914#if ENABLE_DESKTOP 711/*** Dir scanning code ***/
915/* http://www.opengroup.org/onlinepubs/9699919799/utilities/ls.html 712
916 * If any of the -l, -n, -s options is specified, each list 713static struct dnode *my_stat(const char *fullname, const char *name, int force_follow)
917 * of files within the directory shall be preceded by a
918 * status line indicating the number of file system blocks
919 * occupied by files in the directory in 512-byte units if
920 * the -k option is not specified, or 1024-byte units if the
921 * -k option is specified, rounded up to the next integral
922 * number of units.
923 */
924/* by Jorgen Overgaard (jorgen AT antistaten.se) */
925static off_t calculate_blocks(struct dnode **dn)
926{ 714{
927 uoff_t blocks = 1; 715 struct stat statbuf;
928 if (dn) { 716 struct dnode *cur;
929 while (*dn) { 717
930 /* st_blocks is in 512 byte blocks */ 718 cur = xzalloc(sizeof(*cur));
931 blocks += (*dn)->dn_blocks; 719 cur->fullname = fullname;
932 dn++; 720 cur->name = name;
721
722 if ((option_mask32 & OPT_L) || force_follow) {
723#if ENABLE_SELINUX
724 if (is_selinux_enabled()) {
725 getfilecon(fullname, &cur->sid);
726 }
727#endif
728 if (stat(fullname, &statbuf)) {
729 bb_simple_perror_msg(fullname);
730 G.exit_code = EXIT_FAILURE;
731 free(cur);
732 return NULL;
733 }
734 cur->dn_mode_stat = statbuf.st_mode;
735 } else {
736#if ENABLE_SELINUX
737 if (is_selinux_enabled()) {
738 lgetfilecon(fullname, &cur->sid);
739 }
740#endif
741 if (lstat(fullname, &statbuf)) {
742 bb_simple_perror_msg(fullname);
743 G.exit_code = EXIT_FAILURE;
744 free(cur);
745 return NULL;
933 } 746 }
747 cur->dn_mode_lstat = statbuf.st_mode;
934 } 748 }
935 749
936 /* Even though standard says use 512 byte blocks, coreutils use 1k */ 750 /* cur->dstat = statbuf: */
937 /* Actually, we round up by calculating (blocks + 1) / 2, 751 cur->dn_mode = statbuf.st_mode ;
938 * "+ 1" was done when we initialized blocks to 1 */ 752 cur->dn_size = statbuf.st_size ;
939 return blocks >> 1; 753#if ENABLE_FEATURE_LS_TIMESTAMPS || ENABLE_FEATURE_LS_SORTFILES
754 cur->dn_atime = statbuf.st_atime ;
755 cur->dn_mtime = statbuf.st_mtime ;
756 cur->dn_ctime = statbuf.st_ctime ;
757#endif
758 cur->dn_ino = statbuf.st_ino ;
759 cur->dn_blocks = statbuf.st_blocks;
760 cur->dn_nlink = statbuf.st_nlink ;
761 cur->dn_uid = statbuf.st_uid ;
762 cur->dn_gid = statbuf.st_gid ;
763 cur->dn_rdev_maj = major(statbuf.st_rdev);
764 cur->dn_rdev_min = minor(statbuf.st_rdev);
765
766 return cur;
940} 767}
768
769static unsigned count_dirs(struct dnode **dn, int which)
770{
771 unsigned dirs, all;
772
773 if (!dn)
774 return 0;
775
776 dirs = all = 0;
777 for (; *dn; dn++) {
778 const char *name;
779
780 all++;
781 if (!S_ISDIR((*dn)->dn_mode))
782 continue;
783
784 name = (*dn)->name;
785 if (which != SPLIT_SUBDIR /* if not requested to skip . / .. */
786 /* or if it's not . or .. */
787 || name[0] != '.'
788 || (name[1] && (name[1] != '.' || name[2]))
789 ) {
790 dirs++;
791 }
792 }
793 return which != SPLIT_FILE ? dirs : all - dirs;
794}
795
796/* get memory to hold an array of pointers */
797static struct dnode **dnalloc(unsigned num)
798{
799 if (num < 1)
800 return NULL;
801
802 num++; /* so that we have terminating NULL */
803 return xzalloc(num * sizeof(struct dnode *));
804}
805
806#if ENABLE_FEATURE_LS_RECURSIVE
807static void dfree(struct dnode **dnp)
808{
809 unsigned i;
810
811 if (dnp == NULL)
812 return;
813
814 for (i = 0; dnp[i]; i++) {
815 struct dnode *cur = dnp[i];
816 if (cur->fname_allocated)
817 free((char*)cur->fullname);
818 free(cur);
819 }
820 free(dnp);
821}
822#else
823#define dfree(...) ((void)0)
941#endif 824#endif
942 825
826/* Returns NULL-terminated malloced vector of pointers (or NULL) */
827static struct dnode **splitdnarray(struct dnode **dn, int which)
828{
829 unsigned dncnt, d;
830 struct dnode **dnp;
831
832 if (dn == NULL)
833 return NULL;
834
835 /* count how many dirs or files there are */
836 dncnt = count_dirs(dn, which);
837
838 /* allocate a file array and a dir array */
839 dnp = dnalloc(dncnt);
840
841 /* copy the entrys into the file or dir array */
842 for (d = 0; *dn; dn++) {
843 if (S_ISDIR((*dn)->dn_mode)) {
844 const char *name;
845
846 if (which == SPLIT_FILE)
847 continue;
848
849 name = (*dn)->name;
850 if ((which & SPLIT_DIR) /* any dir... */
851 /* ... or not . or .. */
852 || name[0] != '.'
853 || (name[1] && (name[1] != '.' || name[2]))
854 ) {
855 dnp[d++] = *dn;
856 }
857 } else
858 if (which == SPLIT_FILE) {
859 dnp[d++] = *dn;
860 }
861 }
862 return dnp;
863}
864
865#if ENABLE_FEATURE_LS_SORTFILES
866static int sortcmp(const void *a, const void *b)
867{
868 struct dnode *d1 = *(struct dnode **)a;
869 struct dnode *d2 = *(struct dnode **)b;
870 unsigned sort_opts = G.all_fmt & SORT_MASK;
871 off_t dif;
872
873 dif = 0; /* assume SORT_NAME */
874 // TODO: use pre-initialized function pointer
875 // instead of branch forest
876 if (sort_opts == SORT_SIZE) {
877 dif = (d2->dn_size - d1->dn_size);
878 } else if (sort_opts == SORT_ATIME) {
879 dif = (d2->dn_atime - d1->dn_atime);
880 } else if (sort_opts == SORT_CTIME) {
881 dif = (d2->dn_ctime - d1->dn_ctime);
882 } else if (sort_opts == SORT_MTIME) {
883 dif = (d2->dn_mtime - d1->dn_mtime);
884 } else if (sort_opts == SORT_DIR) {
885 dif = S_ISDIR(d2->dn_mode) - S_ISDIR(d1->dn_mode);
886 /* } else if (sort_opts == SORT_VERSION) { */
887 /* } else if (sort_opts == SORT_EXT) { */
888 }
889 if (dif == 0) {
890 /* sort by name, or tie_breaker for other sorts */
891 if (ENABLE_LOCALE_SUPPORT)
892 dif = strcoll(d1->name, d2->name);
893 else
894 dif = strcmp(d1->name, d2->name);
895 }
896
897 /* Make dif fit into an int */
898 if (sizeof(dif) > sizeof(int)) {
899 enum { BITS_TO_SHIFT = 8 * (sizeof(dif) - sizeof(int)) };
900 /* shift leaving only "int" worth of bits */
901 if (dif != 0) {
902 dif = 1 | (int)((uoff_t)dif >> BITS_TO_SHIFT);
903 }
904 }
905
906 return (G.all_fmt & SORT_REVERSE) ? -(int)dif : (int)dif;
907}
908
909static void dnsort(struct dnode **dn, int size)
910{
911 qsort(dn, size, sizeof(*dn), sortcmp);
912}
913#else
914#define dnsort(dn, size) ((void)0)
915#endif
943 916
944/* Returns NULL-terminated malloced vector of pointers (or NULL) */ 917/* Returns NULL-terminated malloced vector of pointers (or NULL) */
945static struct dnode **list_dir(const char *path, unsigned *nfiles_p) 918static struct dnode **scan_one_dir(const char *path, unsigned *nfiles_p)
946{ 919{
947 struct dnode *dn, *cur, **dnp; 920 struct dnode *dn, *cur, **dnp;
948 struct dirent *entry; 921 struct dirent *entry;
@@ -1001,8 +974,36 @@ static struct dnode **list_dir(const char *path, unsigned *nfiles_p)
1001 return dnp; 974 return dnp;
1002} 975}
1003 976
977#if ENABLE_DESKTOP
978/* http://www.opengroup.org/onlinepubs/9699919799/utilities/ls.html
979 * If any of the -l, -n, -s options is specified, each list
980 * of files within the directory shall be preceded by a
981 * status line indicating the number of file system blocks
982 * occupied by files in the directory in 512-byte units if
983 * the -k option is not specified, or 1024-byte units if the
984 * -k option is specified, rounded up to the next integral
985 * number of units.
986 */
987/* by Jorgen Overgaard (jorgen AT antistaten.se) */
988static off_t calculate_blocks(struct dnode **dn)
989{
990 uoff_t blocks = 1;
991 if (dn) {
992 while (*dn) {
993 /* st_blocks is in 512 byte blocks */
994 blocks += (*dn)->dn_blocks;
995 dn++;
996 }
997 }
998
999 /* Even though standard says use 512 byte blocks, coreutils use 1k */
1000 /* Actually, we round up by calculating (blocks + 1) / 2,
1001 * "+ 1" was done when we initialized blocks to 1 */
1002 return blocks >> 1;
1003}
1004#endif
1004 1005
1005static void showdirs(struct dnode **dn, int first) 1006static void scan_and_display_dirs_recur(struct dnode **dn, int first)
1006{ 1007{
1007 unsigned nfiles; 1008 unsigned nfiles;
1008 struct dnode **subdnp; 1009 struct dnode **subdnp;
@@ -1014,7 +1015,7 @@ static void showdirs(struct dnode **dn, int first)
1014 first = 0; 1015 first = 0;
1015 printf("%s:\n", (*dn)->fullname); 1016 printf("%s:\n", (*dn)->fullname);
1016 } 1017 }
1017 subdnp = list_dir((*dn)->fullname, &nfiles); 1018 subdnp = scan_one_dir((*dn)->fullname, &nfiles);
1018#if ENABLE_DESKTOP 1019#if ENABLE_DESKTOP
1019 if ((G.all_fmt & STYLE_MASK) == STYLE_LONG) 1020 if ((G.all_fmt & STYLE_MASK) == STYLE_LONG)
1020 printf("total %"OFF_FMT"u\n", calculate_blocks(subdnp)); 1021 printf("total %"OFF_FMT"u\n", calculate_blocks(subdnp));
@@ -1022,7 +1023,8 @@ static void showdirs(struct dnode **dn, int first)
1022 if (nfiles > 0) { 1023 if (nfiles > 0) {
1023 /* list all files at this level */ 1024 /* list all files at this level */
1024 dnsort(subdnp, nfiles); 1025 dnsort(subdnp, nfiles);
1025 showfiles(subdnp, nfiles); 1026 display_files(subdnp, nfiles);
1027
1026 if (ENABLE_FEATURE_LS_RECURSIVE 1028 if (ENABLE_FEATURE_LS_RECURSIVE
1027 && (G.all_fmt & DISP_RECURSIVE) 1029 && (G.all_fmt & DISP_RECURSIVE)
1028 ) { 1030 ) {
@@ -1033,7 +1035,7 @@ static void showdirs(struct dnode **dn, int first)
1033 dndirs = count_dirs(subdnp, SPLIT_SUBDIR); 1035 dndirs = count_dirs(subdnp, SPLIT_SUBDIR);
1034 if (dndirs > 0) { 1036 if (dndirs > 0) {
1035 dnsort(dnd, dndirs); 1037 dnsort(dnd, dndirs);
1036 showdirs(dnd, 0); 1038 scan_and_display_dirs_recur(dnd, 0);
1037 /* free the array of dnode pointers to the dirs */ 1039 /* free the array of dnode pointers to the dirs */
1038 free(dnd); 1040 free(dnd);
1039 } 1041 }
@@ -1215,7 +1217,7 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
1215 1217
1216 if (G.all_fmt & DISP_NOLIST) { 1218 if (G.all_fmt & DISP_NOLIST) {
1217 dnsort(dnp, nfiles); 1219 dnsort(dnp, nfiles);
1218 showfiles(dnp, nfiles); 1220 display_files(dnp, nfiles);
1219 } else { 1221 } else {
1220 dnd = splitdnarray(dnp, SPLIT_DIR); 1222 dnd = splitdnarray(dnp, SPLIT_DIR);
1221 dnf = splitdnarray(dnp, SPLIT_FILE); 1223 dnf = splitdnarray(dnp, SPLIT_FILE);
@@ -1223,13 +1225,13 @@ int ls_main(int argc UNUSED_PARAM, char **argv)
1223 dnfiles = nfiles - dndirs; 1225 dnfiles = nfiles - dndirs;
1224 if (dnfiles > 0) { 1226 if (dnfiles > 0) {
1225 dnsort(dnf, dnfiles); 1227 dnsort(dnf, dnfiles);
1226 showfiles(dnf, dnfiles); 1228 display_files(dnf, dnfiles);
1227 if (ENABLE_FEATURE_CLEAN_UP) 1229 if (ENABLE_FEATURE_CLEAN_UP)
1228 free(dnf); 1230 free(dnf);
1229 } 1231 }
1230 if (dndirs > 0) { 1232 if (dndirs > 0) {
1231 dnsort(dnd, dndirs); 1233 dnsort(dnd, dndirs);
1232 showdirs(dnd, dnfiles == 0); 1234 scan_and_display_dirs_recur(dnd, dnfiles == 0);
1233 if (ENABLE_FEATURE_CLEAN_UP) 1235 if (ENABLE_FEATURE_CLEAN_UP)
1234 free(dnd); 1236 free(dnd);
1235 } 1237 }