aboutsummaryrefslogtreecommitdiff
path: root/coreutils/ls.c
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils/ls.c')
-rw-r--r--coreutils/ls.c112
1 files changed, 27 insertions, 85 deletions
diff --git a/coreutils/ls.c b/coreutils/ls.c
index 47acec603..4a20b3396 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -36,32 +36,18 @@ enum {
36 36
37/************************************************************************/ 37/************************************************************************/
38 38
39#include <sys/types.h> 39#include "busybox.h"
40#include <sys/stat.h>
41#include <stdio.h>
42#include <unistd.h> 40#include <unistd.h>
43#include <dirent.h>
44#include <errno.h> 41#include <errno.h>
45#include <stdio.h>
46#include <string.h> 42#include <string.h>
47#include <stdlib.h>
48#include <fcntl.h> 43#include <fcntl.h>
49#include <signal.h> 44#include <signal.h>
50#include <termios.h>
51#include <getopt.h> /* struct option */ 45#include <getopt.h> /* struct option */
52#include <sys/ioctl.h> 46#include <sys/ioctl.h>
53#include <sys/sysmacros.h> /* major() and minor() */ 47#include <sys/sysmacros.h> /* major() and minor() */
54#include "busybox.h"
55#ifdef CONFIG_SELINUX
56#include <selinux/selinux.h> /* for is_selinux_enabled() */
57#endif
58
59#ifdef CONFIG_FEATURE_LS_TIMESTAMPS
60#include <time.h> 48#include <time.h>
61#endif
62 49
63/* what is the overall style of the listing */ 50/* what is the overall style of the listing */
64#define STYLE_AUTO (0)
65#define STYLE_COLUMNS (1U<<21) /* fill columns */ 51#define STYLE_COLUMNS (1U<<21) /* fill columns */
66#define STYLE_LONG (2U<<21) /* one record per line, extended info */ 52#define STYLE_LONG (2U<<21) /* one record per line, extended info */
67#define STYLE_SINGLE (3U<<21) /* one record per line */ 53#define STYLE_SINGLE (3U<<21) /* one record per line */
@@ -99,7 +85,7 @@ enum {
99 85
100#define DISP_MASK (((DISP_ROWS << 1) - 1) & ~(DISP_DIRNAME - 1)) 86#define DISP_MASK (((DISP_ROWS << 1) - 1) & ~(DISP_DIRNAME - 1))
101 87
102#ifdef CONFIG_FEATURE_LS_SORTFILES 88// CONFIG_FEATURE_LS_SORTFILES
103/* how will the files be sorted */ 89/* how will the files be sorted */
104#define SORT_ORDER_FORWARD 0 /* sort in reverse order */ 90#define SORT_ORDER_FORWARD 0 /* sort in reverse order */
105#define SORT_ORDER_REVERSE (1U<<27) /* sort in reverse order */ 91#define SORT_ORDER_REVERSE (1U<<27) /* sort in reverse order */
@@ -114,7 +100,6 @@ enum {
114#define SORT_DIR (7U<<28) /* sort by file or directory */ 100#define SORT_DIR (7U<<28) /* sort by file or directory */
115 101
116#define SORT_MASK (7U<<28) 102#define SORT_MASK (7U<<28)
117#endif
118 103
119#ifdef CONFIG_FEATURE_LS_TIMESTAMPS 104#ifdef CONFIG_FEATURE_LS_TIMESTAMPS
120/* which of the three times will be used */ 105/* which of the three times will be used */
@@ -416,11 +401,8 @@ static int sortcmp(const void *a, const void *b)
416 401
417 if (dif == 0) { 402 if (dif == 0) {
418 /* sort by name- may be a tie_breaker for time or size cmp */ 403 /* sort by name- may be a tie_breaker for time or size cmp */
419#ifdef CONFIG_LOCALE_SUPPORT 404 if (ENABLE_LOCALE_SUPPORT) dif = strcoll(d1->name, d2->name);
420 dif = strcoll(d1->name, d2->name); 405 else dif = strcmp(d1->name, d2->name);
421#else
422 dif = strcmp(d1->name, d2->name);
423#endif
424 } 406 }
425 407
426 if (all_fmt & SORT_ORDER_REVERSE) { 408 if (all_fmt & SORT_ORDER_REVERSE) {
@@ -434,8 +416,12 @@ static void dnsort(struct dnode **dn, int size)
434{ 416{
435 qsort(dn, size, sizeof *dn, sortcmp); 417 qsort(dn, size, sizeof *dn, sortcmp);
436} 418}
419#else
420#define sortcmp(a, b) 0
421#define dnsort(dn, size)
437#endif 422#endif
438 423
424
439/*----------------------------------------------------------------------*/ 425/*----------------------------------------------------------------------*/
440static void showfiles(struct dnode **dn, int nfiles) 426static void showfiles(struct dnode **dn, int nfiles)
441{ 427{
@@ -502,11 +488,8 @@ static void showdirs(struct dnode **dn, int ndirs, int first)
502{ 488{
503 int i, nfiles; 489 int i, nfiles;
504 struct dnode **subdnp; 490 struct dnode **subdnp;
505
506#ifdef CONFIG_FEATURE_LS_RECURSIVE
507 int dndirs; 491 int dndirs;
508 struct dnode **dnd; 492 struct dnode **dnd;
509#endif
510 493
511 if (dn == NULL || ndirs < 1) 494 if (dn == NULL || ndirs < 1)
512 return; 495 return;
@@ -522,9 +505,7 @@ static void showdirs(struct dnode **dn, int ndirs, int first)
522 nfiles = countfiles(subdnp); 505 nfiles = countfiles(subdnp);
523 if (nfiles > 0) { 506 if (nfiles > 0) {
524 /* list all files at this level */ 507 /* list all files at this level */
525#ifdef CONFIG_FEATURE_LS_SORTFILES 508 if (ENABLE_FEATURE_LS_SORTFILES) dnsort(subdnp, nfiles);
526 dnsort(subdnp, nfiles);
527#endif
528 showfiles(subdnp, nfiles); 509 showfiles(subdnp, nfiles);
529#ifdef CONFIG_FEATURE_LS_RECURSIVE 510#ifdef CONFIG_FEATURE_LS_RECURSIVE
530 if (all_fmt & DISP_RECURSIVE) { 511 if (all_fmt & DISP_RECURSIVE) {
@@ -532,9 +513,7 @@ static void showdirs(struct dnode **dn, int ndirs, int first)
532 dnd = splitdnarray(subdnp, nfiles, SPLIT_SUBDIR); 513 dnd = splitdnarray(subdnp, nfiles, SPLIT_SUBDIR);
533 dndirs = countsubdirs(subdnp, nfiles); 514 dndirs = countsubdirs(subdnp, nfiles);
534 if (dndirs > 0) { 515 if (dndirs > 0) {
535#ifdef CONFIG_FEATURE_LS_SORTFILES 516 if (ENABLE_FEATURE_LS_SORTFILES) dnsort(dnd, dndirs);
536 dnsort(dnd, dndirs);
537#endif
538 showdirs(dnd, dndirs, 0); 517 showdirs(dnd, dndirs, 0);
539 free(dnd); /* free the array of dnode pointers to the dirs */ 518 free(dnd); /* free the array of dnode pointers to the dirs */
540 } 519 }
@@ -796,12 +775,6 @@ static int list_single(struct dnode *dn)
796# define LS_STR_TIMESTAMPS "" 775# define LS_STR_TIMESTAMPS ""
797#endif 776#endif
798 777
799#ifdef CONFIG_FEATURE_LS_SORTFILES
800# define LS_STR_SORTFILES "SXrv"
801#else
802# define LS_STR_SORTFILES ""
803#endif
804
805#ifdef CONFIG_FEATURE_LS_FILETYPES 778#ifdef CONFIG_FEATURE_LS_FILETYPES
806# define LS_STR_FILETYPES "Fp" 779# define LS_STR_FILETYPES "Fp"
807#else 780#else
@@ -840,7 +813,7 @@ static int list_single(struct dnode *dn)
840 813
841static const char ls_options[]="Cadil1gnsxAk" \ 814static const char ls_options[]="Cadil1gnsxAk" \
842 LS_STR_TIMESTAMPS \ 815 LS_STR_TIMESTAMPS \
843 LS_STR_SORTFILES \ 816 USE_FEATURE_LS_SORTFILES("SXrv") \
844 LS_STR_FILETYPES \ 817 LS_STR_FILETYPES \
845 LS_STR_FOLLOW_LINKS \ 818 LS_STR_FOLLOW_LINKS \
846 LS_STR_RECURSIVE \ 819 LS_STR_RECURSIVE \
@@ -872,22 +845,10 @@ static const unsigned opt_flags[] = {
872 0, /* k - ingored */ 845 0, /* k - ingored */
873#endif 846#endif
874#ifdef CONFIG_FEATURE_LS_TIMESTAMPS 847#ifdef CONFIG_FEATURE_LS_TIMESTAMPS
875# ifdef CONFIG_FEATURE_LS_SORTFILES 848 TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */
876 TIME_CHANGE | SORT_CTIME, /* c */
877# else
878 TIME_CHANGE, /* c */
879# endif
880 LIST_FULLTIME, /* e */ 849 LIST_FULLTIME, /* e */
881# ifdef CONFIG_FEATURE_LS_SORTFILES 850 ENABLE_FEATURE_LS_SORTFILES * SORT_MTIME, /* t */
882 SORT_MTIME, /* t */ 851 TIME_ACCESS | (ENABLE_FEATURE_LS_SORTFILES * SORT_ATIME), /* u */
883# else
884 0, /* t - ignored -- is this correct? */
885# endif
886# ifdef CONFIG_FEATURE_LS_SORTFILES
887 TIME_ACCESS | SORT_ATIME, /* u */
888# else
889 TIME_ACCESS, /* u */
890# endif
891#endif 852#endif
892#ifdef CONFIG_FEATURE_LS_SORTFILES 853#ifdef CONFIG_FEATURE_LS_SORTFILES
893 SORT_SIZE, /* S */ 854 SORT_SIZE, /* S */
@@ -943,14 +904,8 @@ int ls_main(int argc, char **argv)
943 char *color_opt; 904 char *color_opt;
944#endif 905#endif
945 906
946 all_fmt = LIST_SHORT | STYLE_AUTO 907 all_fmt = LIST_SHORT | (ENABLE_FEATURE_LS_TIMESTAMPS * TIME_MOD) |
947#ifdef CONFIG_FEATURE_LS_TIMESTAMPS 908 (ENABLE_FEATURE_LS_SORTFILES * (SORT_NAME | SORT_ORDER_FORWARD));
948 | TIME_MOD
949#endif
950#ifdef CONFIG_FEATURE_LS_SORTFILES
951 | SORT_NAME | SORT_ORDER_FORWARD
952#endif
953 ;
954 909
955#ifdef CONFIG_FEATURE_AUTOWIDTH 910#ifdef CONFIG_FEATURE_AUTOWIDTH
956 /* Obtain the terminal width. */ 911 /* Obtain the terminal width. */
@@ -993,11 +948,9 @@ int ls_main(int argc, char **argv)
993 if (flags & STYLE_MASK_TRIGGER) { 948 if (flags & STYLE_MASK_TRIGGER) {
994 all_fmt &= ~STYLE_MASK; 949 all_fmt &= ~STYLE_MASK;
995 } 950 }
996#ifdef CONFIG_FEATURE_LS_SORTFILES 951 if (ENABLE_FEATURE_LS_SORTFILES && (flags & SORT_MASK_TRIGGER)) {
997 if (flags & SORT_MASK_TRIGGER) {
998 all_fmt &= ~SORT_MASK; 952 all_fmt &= ~SORT_MASK;
999 } 953 }
1000#endif
1001 if (flags & DISP_MASK_TRIGGER) { 954 if (flags & DISP_MASK_TRIGGER) {
1002 all_fmt &= ~DISP_MASK; 955 all_fmt &= ~DISP_MASK;
1003 } 956 }
@@ -1049,12 +1002,12 @@ int ls_main(int argc, char **argv)
1049 if (all_fmt & DISP_NOLIST) 1002 if (all_fmt & DISP_NOLIST)
1050 all_fmt &= ~DISP_RECURSIVE; /* no recurse if listing only dir */ 1003 all_fmt &= ~DISP_RECURSIVE; /* no recurse if listing only dir */
1051#endif 1004#endif
1052#if defined (CONFIG_FEATURE_LS_TIMESTAMPS) && defined (CONFIG_FEATURE_LS_SORTFILES) 1005 if (ENABLE_FEATURE_LS_TIMESTAMPS && ENABLE_FEATURE_LS_SORTFILES) {
1053 if (all_fmt & TIME_CHANGE) 1006 if (all_fmt & TIME_CHANGE)
1054 all_fmt = (all_fmt & ~SORT_MASK) | SORT_CTIME; 1007 all_fmt = (all_fmt & ~SORT_MASK) | SORT_CTIME;
1055 if (all_fmt & TIME_ACCESS) 1008 if (all_fmt & TIME_ACCESS)
1056 all_fmt = (all_fmt & ~SORT_MASK) | SORT_ATIME; 1009 all_fmt = (all_fmt & ~SORT_MASK) | SORT_ATIME;
1057#endif 1010 }
1058 if ((all_fmt & STYLE_MASK) != STYLE_LONG) /* only for long list */ 1011 if ((all_fmt & STYLE_MASK) != STYLE_LONG) /* only for long list */
1059 all_fmt &= ~(LIST_ID_NUMERIC|LIST_FULLTIME|LIST_ID_NAME|LIST_ID_NUMERIC); 1012 all_fmt &= ~(LIST_ID_NUMERIC|LIST_FULLTIME|LIST_ID_NAME|LIST_ID_NUMERIC);
1060#ifdef CONFIG_FEATURE_LS_USERNAME 1013#ifdef CONFIG_FEATURE_LS_USERNAME
@@ -1063,13 +1016,8 @@ int ls_main(int argc, char **argv)
1063#endif 1016#endif
1064 1017
1065 /* choose a display format */ 1018 /* choose a display format */
1066 if ((all_fmt & STYLE_MASK) == STYLE_AUTO) 1019 if (!(all_fmt & STYLE_MASK))
1067#if STYLE_AUTO != 0
1068 all_fmt = (all_fmt & ~STYLE_MASK)
1069 | (isatty(STDOUT_FILENO) ? STYLE_COLUMNS : STYLE_SINGLE);
1070#else
1071 all_fmt |= (isatty(STDOUT_FILENO) ? STYLE_COLUMNS : STYLE_SINGLE); 1020 all_fmt |= (isatty(STDOUT_FILENO) ? STYLE_COLUMNS : STYLE_SINGLE);
1072#endif
1073 1021
1074 /* 1022 /*
1075 * when there are no cmd line args we have to supply a default "." arg. 1023 * when there are no cmd line args we have to supply a default "." arg.
@@ -1114,9 +1062,7 @@ int ls_main(int argc, char **argv)
1114 } 1062 }
1115 1063
1116 if (all_fmt & DISP_NOLIST) { 1064 if (all_fmt & DISP_NOLIST) {
1117#ifdef CONFIG_FEATURE_LS_SORTFILES 1065 if (ENABLE_FEATURE_LS_SORTFILES) dnsort(dnp, nfiles);
1118 dnsort(dnp, nfiles);
1119#endif
1120 if (nfiles > 0) 1066 if (nfiles > 0)
1121 showfiles(dnp, nfiles); 1067 showfiles(dnp, nfiles);
1122 } else { 1068 } else {
@@ -1125,17 +1071,13 @@ int ls_main(int argc, char **argv)
1125 dndirs = countdirs(dnp, nfiles); 1071 dndirs = countdirs(dnp, nfiles);
1126 dnfiles = nfiles - dndirs; 1072 dnfiles = nfiles - dndirs;
1127 if (dnfiles > 0) { 1073 if (dnfiles > 0) {
1128#ifdef CONFIG_FEATURE_LS_SORTFILES 1074 if (ENABLE_FEATURE_LS_SORTFILES) dnsort(dnf, dnfiles);
1129 dnsort(dnf, dnfiles);
1130#endif
1131 showfiles(dnf, dnfiles); 1075 showfiles(dnf, dnfiles);
1132 if (ENABLE_FEATURE_CLEAN_UP) 1076 if (ENABLE_FEATURE_CLEAN_UP)
1133 free(dnf); 1077 free(dnf);
1134 } 1078 }
1135 if (dndirs > 0) { 1079 if (dndirs > 0) {
1136#ifdef CONFIG_FEATURE_LS_SORTFILES 1080 if (ENABLE_FEATURE_LS_SORTFILES) dnsort(dnd, dndirs);
1137 dnsort(dnd, dndirs);
1138#endif
1139 showdirs(dnd, dndirs, dnfiles == 0); 1081 showdirs(dnd, dndirs, dnfiles == 0);
1140 if (ENABLE_FEATURE_CLEAN_UP) 1082 if (ENABLE_FEATURE_CLEAN_UP)
1141 free(dnd); 1083 free(dnd);