aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-10-28 12:37:51 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-10-28 12:37:51 +0000
commit94cf69fe3e24b2b94c363e30664672617196e628 (patch)
tree1f5aa6371eb42b7c5d5205e3acb75b11e7d12b11
parent5c7596058dedb99ab0fbe773cc7ac61a2ffe9fbf (diff)
downloadbusybox-w32-94cf69fe3e24b2b94c363e30664672617196e628.tar.gz
busybox-w32-94cf69fe3e24b2b94c363e30664672617196e628.tar.bz2
busybox-w32-94cf69fe3e24b2b94c363e30664672617196e628.zip
ls: cleanup part 2. ifdef forest is much less scary now :)
-rw-r--r--coreutils/chmod.c20
-rw-r--r--coreutils/ls.c326
2 files changed, 148 insertions, 198 deletions
diff --git a/coreutils/chmod.c b/coreutils/chmod.c
index b601504f8..4abae2d51 100644
--- a/coreutils/chmod.c
+++ b/coreutils/chmod.c
@@ -133,7 +133,7 @@ function create() {
133 ln -s ../up dir/up 133 ln -s ../up dir/up
134 ) 134 )
135} 135}
136function test() { 136function tst() {
137 (cd test1; $t1 $1) 137 (cd test1; $t1 $1)
138 (cd test2; $t2 $1) 138 (cd test2; $t2 $1)
139 (cd test1; ls -lR) >out1 139 (cd test1; ls -lR) >out1
@@ -145,13 +145,13 @@ function test() {
145t1="/tmp/busybox chmod" 145t1="/tmp/busybox chmod"
146t2="/usr/bin/chmod" 146t2="/usr/bin/chmod"
147create test1; create test2 147create test1; create test2
148test "a+w file" 148tst "a+w file"
149test "a-w dir" 149tst "a-w dir"
150test "a+w linkfile" 150tst "a+w linkfile"
151test "a-w linkdir" 151tst "a-w linkdir"
152test "-R a+w file" 152tst "-R a+w file"
153test "-R a-w dir" 153tst "-R a-w dir"
154test "-R a+w linkfile" 154tst "-R a+w linkfile"
155test "-R a-w linkdir" 155tst "-R a-w linkdir"
156test "a-r,a+x linkfile" 156tst "a-r,a+x linkfile"
157*/ 157*/
diff --git a/coreutils/ls.c b/coreutils/ls.c
index f31a49682..6b507db69 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -29,115 +29,98 @@
29 * 1. requires lstat (BSD) - how do you do it without? 29 * 1. requires lstat (BSD) - how do you do it without?
30 */ 30 */
31 31
32enum {
33 TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */
34 COLUMN_GAP = 2, /* includes the file type char */
35};
36
37/************************************************************************/
38
39#include "busybox.h" 32#include "busybox.h"
40#include <getopt.h> 33#include <getopt.h>
41 34
42/* what is the overall style of the listing */ 35enum {
43#define STYLE_COLUMNS (1U<<21) /* fill columns */ 36
44#define STYLE_LONG (2U<<21) /* one record per line, extended info */ 37TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */
45#define STYLE_SINGLE (3U<<21) /* one record per line */ 38COLUMN_GAP = 2, /* includes the file type char */
46 39
47#define STYLE_MASK STYLE_SINGLE 40/* what is the overall style of the listing */
48#define STYLE_ONE_RECORD_FLAG STYLE_LONG 41STYLE_COLUMNS = 1 << 21, /* fill columns */
42STYLE_LONG = 2 << 21, /* one record per line, extended info */
43STYLE_SINGLE = 3 << 21, /* one record per line */
44STYLE_MASK = STYLE_SINGLE,
49 45
50/* 51306 lrwxrwxrwx 1 root root 2 May 11 01:43 /bin/view -> vi* */ 46/* 51306 lrwxrwxrwx 1 root root 2 May 11 01:43 /bin/view -> vi* */
51/* what file information will be listed */ 47/* what file information will be listed */
52#define LIST_INO (1U<<0) 48LIST_INO = 1 << 0,
53#define LIST_BLOCKS (1U<<1) 49LIST_BLOCKS = 1 << 1,
54#define LIST_MODEBITS (1U<<2) 50LIST_MODEBITS = 1 << 2,
55#define LIST_NLINKS (1U<<3) 51LIST_NLINKS = 1 << 3,
56#define LIST_ID_NAME (1U<<4) 52LIST_ID_NAME = 1 << 4,
57#define LIST_ID_NUMERIC (1U<<5) 53LIST_ID_NUMERIC = 1 << 5,
58#define LIST_CONTEXT (1U<<6) 54LIST_CONTEXT = 1 << 6,
59#define LIST_SIZE (1U<<7) 55LIST_SIZE = 1 << 7,
60#define LIST_DEV (1U<<8) 56LIST_DEV = 1 << 8,
61#define LIST_DATE_TIME (1U<<9) 57LIST_DATE_TIME = 1 << 9,
62#define LIST_FULLTIME (1U<<10) 58LIST_FULLTIME = 1 << 10,
63#define LIST_FILENAME (1U<<11) 59LIST_FILENAME = 1 << 11,
64#define LIST_SYMLINK (1U<<12) 60LIST_SYMLINK = 1 << 12,
65#define LIST_FILETYPE (1U<<13) 61LIST_FILETYPE = 1 << 13,
66#define LIST_EXEC (1U<<14) 62LIST_EXEC = 1 << 14,
67 63LIST_MASK = (LIST_EXEC << 1) - 1,
68#define LIST_MASK ((LIST_EXEC << 1) - 1)
69 64
70/* what files will be displayed */ 65/* what files will be displayed */
71#define DISP_DIRNAME (1U<<15) /* 2 or more items? label directories */ 66DISP_DIRNAME = 1 << 15, /* 2 or more items? label directories */
72#define DISP_HIDDEN (1U<<16) /* show filenames starting with . */ 67DISP_HIDDEN = 1 << 16, /* show filenames starting with . */
73#define DISP_DOT (1U<<17) /* show . and .. */ 68DISP_DOT = 1 << 17, /* show . and .. */
74#define DISP_NOLIST (1U<<18) /* show directory as itself, not contents */ 69DISP_NOLIST = 1 << 18, /* show directory as itself, not contents */
75#define DISP_RECURSIVE (1U<<19) /* show directory and everything below it */ 70DISP_RECURSIVE = 1 << 19, /* show directory and everything below it */
76#define DISP_ROWS (1U<<20) /* print across rows */ 71DISP_ROWS = 1 << 20, /* print across rows */
77 72DISP_MASK = ((DISP_ROWS << 1) - 1) & ~(DISP_DIRNAME - 1),
78#define DISP_MASK (((DISP_ROWS << 1) - 1) & ~(DISP_DIRNAME - 1)) 73
79 74/* how will the files be sorted (CONFIG_FEATURE_LS_SORTFILES) */
80// CONFIG_FEATURE_LS_SORTFILES 75SORT_FORWARD = 0, /* sort in reverse order */
81/* how will the files be sorted */ 76SORT_REVERSE = 1 << 27, /* sort in reverse order */
82#define SORT_ORDER_FORWARD 0 /* sort in reverse order */ 77
83#define SORT_ORDER_REVERSE (1U<<27) /* sort in reverse order */ 78SORT_NAME = 0, /* sort by file name */
84 79SORT_SIZE = 1 << 28, /* sort by file size */
85#define SORT_NAME 0 /* sort by file name */ 80SORT_ATIME = 2 << 28, /* sort by last access time */
86#define SORT_SIZE (1U<<28) /* sort by file size */ 81SORT_CTIME = 3 << 28, /* sort by last change time */
87#define SORT_ATIME (2U<<28) /* sort by last access time */ 82SORT_MTIME = 4 << 28, /* sort by last modification time */
88#define SORT_CTIME (3U<<28) /* sort by last change time */ 83SORT_VERSION = 5 << 28, /* sort by version */
89#define SORT_MTIME (4U<<28) /* sort by last modification time */ 84SORT_EXT = 6 << 28, /* sort by file name extension */
90#define SORT_VERSION (5U<<28) /* sort by version */ 85SORT_DIR = 7 << 28, /* sort by file or directory */
91#define SORT_EXT (6U<<28) /* sort by file name extension */ 86SORT_MASK = (7 << 28) * ENABLE_FEATURE_LS_SORTFILES,
92#define SORT_DIR (7U<<28) /* sort by file or directory */
93
94#define SORT_MASK (7U<<28)
95 87
96/* which of the three times will be used */ 88/* which of the three times will be used */
97#define TIME_CHANGE ((1U<<23) * ENABLE_FEATURE_LS_TIMESTAMPS) 89TIME_CHANGE = (1 << 23) * ENABLE_FEATURE_LS_TIMESTAMPS,
98#define TIME_ACCESS ((1U<<24) * ENABLE_FEATURE_LS_TIMESTAMPS) 90TIME_ACCESS = (1 << 24) * ENABLE_FEATURE_LS_TIMESTAMPS,
99#define TIME_MASK ((3U<<23) * ENABLE_FEATURE_LS_TIMESTAMPS) 91TIME_MASK = (3 << 23) * ENABLE_FEATURE_LS_TIMESTAMPS,
100 92
101#if ENABLE_FEATURE_LS_FOLLOWLINKS 93FOLLOW_LINKS = (1 << 25) * ENABLE_FEATURE_LS_FOLLOWLINKS,
102#define FOLLOW_LINKS (1U<<25) 94
103#endif 95LS_DISP_HR = (1 << 26) * ENABLE_FEATURE_HUMAN_READABLE,
104#if ENABLE_FEATURE_HUMAN_READABLE
105#define LS_DISP_HR (1U<<26)
106#endif
107 96
108#define LIST_SHORT (LIST_FILENAME) 97LIST_SHORT = LIST_FILENAME,
109//#define LIST_ISHORT (LIST_INO | LIST_FILENAME) 98LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \
110#define LIST_LONG (LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \ 99 LIST_DATE_TIME | LIST_FILENAME | LIST_SYMLINK,
111 LIST_DATE_TIME | LIST_FILENAME | LIST_SYMLINK)
112//#define LIST_ILONG (LIST_INO | LIST_LONG)
113 100
114#define SPLIT_DIR 1 101SPLIT_DIR = 1,
115#define SPLIT_FILE 0 102SPLIT_FILE = 0,
116#define SPLIT_SUBDIR 2 103SPLIT_SUBDIR = 2,
104
105};
117 106
118#define TYPEINDEX(mode) (((mode) >> 12) & 0x0f) 107#define TYPEINDEX(mode) (((mode) >> 12) & 0x0f)
119#define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)]) 108#define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)])
120 109#define APPCHAR(mode) ("\0|\0\0/\0\0\0\0\0@\0=\0\0\0" [TYPEINDEX(mode)])
121#if defined(CONFIG_FEATURE_LS_FILETYPES) || defined(CONFIG_FEATURE_LS_COLOR) 110#define COLOR(mode) ("\000\043\043\043\042\000\043\043"\
122# define APPCHAR(mode) ("\0|\0\0/\0\0\0\0\0@\0=\0\0\0" [TYPEINDEX(mode)]) 111 "\000\000\044\000\043\000\000\040" [TYPEINDEX(mode)])
123#endif 112#define ATTR(mode) ("\00\00\01\00\01\00\01\00"\
113 "\00\00\01\00\01\00\00\01" [TYPEINDEX(mode)])
124 114
125/* colored LS support by JaWi, janwillem.janssen@lxtreme.nl */ 115/* colored LS support by JaWi, janwillem.janssen@lxtreme.nl */
126#if ENABLE_FEATURE_LS_COLOR 116#if ENABLE_FEATURE_LS_COLOR
127
128static int show_color; 117static int show_color;
129
130/* long option entry used only for --color, which has no short option 118/* long option entry used only for --color, which has no short option
131 * equivalent. */ 119 * equivalent. */
132static const struct option ls_color_opt[] = { 120static const struct option ls_color_opt[] = {
133 { "color", optional_argument, NULL, 1 }, 121 { "color", optional_argument, NULL, 1 },
134 { NULL, 0, NULL, 0 } 122 { NULL, 0, NULL, 0 }
135}; 123};
136
137#define COLOR(mode) ("\000\043\043\043\042\000\043\043"\
138 "\000\000\044\000\043\000\000\040" [TYPEINDEX(mode)])
139#define ATTR(mode) ("\00\00\01\00\01\00\01\00"\
140 "\00\00\01\00\01\00\00\01" [TYPEINDEX(mode)])
141#else 124#else
142enum { show_color = 0 }; 125enum { show_color = 0 };
143#endif 126#endif
@@ -145,13 +128,13 @@ enum { show_color = 0 };
145/* 128/*
146 * a directory entry and its stat info are stored here 129 * a directory entry and its stat info are stored here
147 */ 130 */
148struct dnode { /* the basic node */ 131struct dnode { /* the basic node */
149 char *name; /* the dir entry name */ 132 char *name; /* the dir entry name */
150 char *fullname; /* the dir entry name */ 133 char *fullname; /* the dir entry name */
151 int allocated; 134 int allocated;
152 struct stat dstat; /* the file stat info */ 135 struct stat dstat; /* the file stat info */
153 USE_SELINUX(security_context_t sid;) 136 USE_SELINUX(security_context_t sid;)
154 struct dnode *next; /* point at the next node */ 137 struct dnode *next; /* point at the next node */
155}; 138};
156typedef struct dnode dnode_t; 139typedef struct dnode dnode_t;
157 140
@@ -179,7 +162,7 @@ static struct dnode *my_stat(char *fullname, char *name)
179 struct dnode *cur; 162 struct dnode *cur;
180 USE_SELINUX(security_context_t sid = NULL;) 163 USE_SELINUX(security_context_t sid = NULL;)
181 164
182 if (ENABLE_FEATURE_LS_FOLLOWLINKS && (all_fmt & FOLLOW_LINKS)) { 165 if (all_fmt & FOLLOW_LINKS) {
183#if ENABLE_SELINUX 166#if ENABLE_SELINUX
184 if (is_selinux_enabled()) { 167 if (is_selinux_enabled()) {
185 getfilecon(fullname, &sid); 168 getfilecon(fullname, &sid);
@@ -211,7 +194,6 @@ static struct dnode *my_stat(char *fullname, char *name)
211 return cur; 194 return cur;
212} 195}
213 196
214/*----------------------------------------------------------------------*/
215#if ENABLE_FEATURE_LS_COLOR 197#if ENABLE_FEATURE_LS_COLOR
216static char fgcolor(mode_t mode) 198static char fgcolor(mode_t mode)
217{ 199{
@@ -223,7 +205,6 @@ static char fgcolor(mode_t mode)
223 return COLOR(mode); 205 return COLOR(mode);
224} 206}
225 207
226/*----------------------------------------------------------------------*/
227static char bgcolor(mode_t mode) 208static char bgcolor(mode_t mode)
228{ 209{
229 if (S_ISREG(mode) && (mode & (S_IXUSR | S_IXGRP | S_IXOTH))) 210 if (S_ISREG(mode) && (mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
@@ -232,7 +213,6 @@ static char bgcolor(mode_t mode)
232} 213}
233#endif 214#endif
234 215
235/*----------------------------------------------------------------------*/
236#if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR 216#if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR
237static char append_char(mode_t mode) 217static char append_char(mode_t mode)
238{ 218{
@@ -248,11 +228,8 @@ static char append_char(mode_t mode)
248} 228}
249#endif 229#endif
250 230
251/*----------------------------------------------------------------------*/
252
253#define countdirs(A, B) count_dirs((A), (B), 1) 231#define countdirs(A, B) count_dirs((A), (B), 1)
254#define countsubdirs(A, B) count_dirs((A), (B), 0) 232#define countsubdirs(A, B) count_dirs((A), (B), 0)
255
256static int count_dirs(struct dnode **dn, int nfiles, int notsubdirs) 233static int count_dirs(struct dnode **dn, int nfiles, int notsubdirs)
257{ 234{
258 int i, dirs; 235 int i, dirs;
@@ -282,7 +259,7 @@ static int countfiles(struct dnode **dnp)
282 if (dnp == NULL) 259 if (dnp == NULL)
283 return 0; 260 return 0;
284 nfiles = 0; 261 nfiles = 0;
285 for (cur = dnp[0]; cur->next != NULL; cur = cur->next) 262 for (cur = dnp[0]; cur->next; cur = cur->next)
286 nfiles++; 263 nfiles++;
287 nfiles++; 264 nfiles++;
288 return nfiles; 265 return nfiles;
@@ -356,7 +333,6 @@ static struct dnode **splitdnarray(struct dnode **dn, int nfiles, int which)
356 return dnp; 333 return dnp;
357} 334}
358 335
359/*----------------------------------------------------------------------*/
360#if ENABLE_FEATURE_LS_SORTFILES 336#if ENABLE_FEATURE_LS_SORTFILES
361static int sortcmp(const void *a, const void *b) 337static int sortcmp(const void *a, const void *b)
362{ 338{
@@ -365,7 +341,9 @@ static int sortcmp(const void *a, const void *b)
365 unsigned sort_opts = all_fmt & SORT_MASK; 341 unsigned sort_opts = all_fmt & SORT_MASK;
366 int dif; 342 int dif;
367 343
368 dif = 0; /* assume SORT_NAME */ 344 dif = 0; /* assume SORT_NAME */
345 // TODO: use pre-initialized function pointer
346 // instead of branch forest
369 if (sort_opts == SORT_SIZE) { 347 if (sort_opts == SORT_SIZE) {
370 dif = (int) (d2->dstat.st_size - d1->dstat.st_size); 348 dif = (int) (d2->dstat.st_size - d1->dstat.st_size);
371 } else if (sort_opts == SORT_ATIME) { 349 } else if (sort_opts == SORT_ATIME) {
@@ -386,24 +364,21 @@ static int sortcmp(const void *a, const void *b)
386 else dif = strcmp(d1->name, d2->name); 364 else dif = strcmp(d1->name, d2->name);
387 } 365 }
388 366
389 if (all_fmt & SORT_ORDER_REVERSE) { 367 if (all_fmt & SORT_REVERSE) {
390 dif = -dif; 368 dif = -dif;
391 } 369 }
392 return dif; 370 return dif;
393} 371}
394 372
395/*----------------------------------------------------------------------*/
396static void dnsort(struct dnode **dn, int size) 373static void dnsort(struct dnode **dn, int size)
397{ 374{
398 qsort(dn, size, sizeof *dn, sortcmp); 375 qsort(dn, size, sizeof(*dn), sortcmp);
399} 376}
400#else 377#else
401#define sortcmp(a, b) 0
402#define dnsort(dn, size) do {} while(0) 378#define dnsort(dn, size) do {} while(0)
403#endif 379#endif
404 380
405 381
406/*----------------------------------------------------------------------*/
407static void showfiles(struct dnode **dn, int nfiles) 382static void showfiles(struct dnode **dn, int nfiles)
408{ 383{
409 int i, ncols, nrows, row, nc; 384 int i, ncols, nrows, row, nc;
@@ -414,27 +389,25 @@ static void showfiles(struct dnode **dn, int nfiles)
414 if (dn == NULL || nfiles < 1) 389 if (dn == NULL || nfiles < 1)
415 return; 390 return;
416 391
417 if (all_fmt & STYLE_ONE_RECORD_FLAG) { 392 if (all_fmt & STYLE_LONG) {
418 ncols = 1; 393 ncols = 1;
419 } else { 394 } else {
420 /* find the longest file name- use that as the column width */ 395 /* find the longest file name, use that as the column width */
421 for (i = 0; i < nfiles; i++) { 396 for (i = 0; i < nfiles; i++) {
422 int len = strlen(dn[i]->name) + 397 int len = strlen(dn[i]->name);
423#if ENABLE_SELINUX
424 ((all_fmt & LIST_CONTEXT) ? 33 : 0) +
425#endif
426 ((all_fmt & LIST_INO) ? 8 : 0) +
427 ((all_fmt & LIST_BLOCKS) ? 5 : 0);
428 if (column_width < len) 398 if (column_width < len)
429 column_width = len; 399 column_width = len;
430 } 400 }
431 column_width += tabstops; 401 column_width += tabstops +
402 USE_SELINUX( ((all_fmt & LIST_CONTEXT) ? 33 : 0) + )
403 ((all_fmt & LIST_INO) ? 8 : 0) +
404 ((all_fmt & LIST_BLOCKS) ? 5 : 0);
432 ncols = (int) (terminal_width / column_width); 405 ncols = (int) (terminal_width / column_width);
433 } 406 }
434 407
435 if (ncols > 1) { 408 if (ncols > 1) {
436 nrows = nfiles / ncols; 409 nrows = nfiles / ncols;
437 if ((nrows * ncols) < nfiles) 410 if (nrows * ncols < nfiles)
438 nrows++; /* round up fractionals */ 411 nrows++; /* round up fractionals */
439 } else { 412 } else {
440 nrows = nfiles; 413 nrows = nfiles;
@@ -462,7 +435,7 @@ static void showfiles(struct dnode **dn, int nfiles)
462 } 435 }
463} 436}
464 437
465/*----------------------------------------------------------------------*/ 438
466static void showdirs(struct dnode **dn, int ndirs, int first) 439static void showdirs(struct dnode **dn, int ndirs, int first)
467{ 440{
468 int i, nfiles; 441 int i, nfiles;
@@ -484,7 +457,7 @@ static void showdirs(struct dnode **dn, int ndirs, int first)
484 nfiles = countfiles(subdnp); 457 nfiles = countfiles(subdnp);
485 if (nfiles > 0) { 458 if (nfiles > 0) {
486 /* list all files at this level */ 459 /* list all files at this level */
487 if (ENABLE_FEATURE_LS_SORTFILES) dnsort(subdnp, nfiles); 460 dnsort(subdnp, nfiles);
488 showfiles(subdnp, nfiles); 461 showfiles(subdnp, nfiles);
489 if (ENABLE_FEATURE_LS_RECURSIVE) { 462 if (ENABLE_FEATURE_LS_RECURSIVE) {
490 if (all_fmt & DISP_RECURSIVE) { 463 if (all_fmt & DISP_RECURSIVE) {
@@ -492,7 +465,7 @@ static void showdirs(struct dnode **dn, int ndirs, int first)
492 dnd = splitdnarray(subdnp, nfiles, SPLIT_SUBDIR); 465 dnd = splitdnarray(subdnp, nfiles, SPLIT_SUBDIR);
493 dndirs = countsubdirs(subdnp, nfiles); 466 dndirs = countsubdirs(subdnp, nfiles);
494 if (dndirs > 0) { 467 if (dndirs > 0) {
495 if (ENABLE_FEATURE_LS_SORTFILES) dnsort(dnd, dndirs); 468 dnsort(dnd, dndirs);
496 showdirs(dnd, dndirs, 0); 469 showdirs(dnd, dndirs, 0);
497 /* free the array of dnode pointers to the dirs */ 470 /* free the array of dnode pointers to the dirs */
498 free(dnd); 471 free(dnd);
@@ -505,7 +478,7 @@ static void showdirs(struct dnode **dn, int ndirs, int first)
505 } 478 }
506} 479}
507 480
508/*----------------------------------------------------------------------*/ 481
509static struct dnode **list_dir(const char *path) 482static struct dnode **list_dir(const char *path)
510{ 483{
511 struct dnode *dn, *cur, **dnp; 484 struct dnode *dn, *cur, **dnp;
@@ -532,14 +505,14 @@ static struct dnode **list_dir(const char *path)
532 entry->d_name[1] == '.' 505 entry->d_name[1] == '.'
533 && entry->d_name[2] == 0)) 506 && entry->d_name[2] == 0))
534 && !(all_fmt & DISP_DOT)) 507 && !(all_fmt & DISP_DOT))
535 continue; 508 continue;
536 if (!(all_fmt & DISP_HIDDEN)) 509 if (!(all_fmt & DISP_HIDDEN))
537 continue; 510 continue;
538 } 511 }
539 fullname = concat_path_file(path, entry->d_name); 512 fullname = concat_path_file(path, entry->d_name);
540 cur = my_stat(fullname, strrchr(fullname, '/') + 1); 513 cur = my_stat(fullname, strrchr(fullname, '/') + 1);
541 if (!cur) { 514 if (!cur) {
542 // FIXME: free(fullname); ? 515 free(fullname);
543 continue; 516 continue;
544 } 517 }
545 cur->allocated = 1; 518 cur->allocated = 1;
@@ -563,7 +536,7 @@ static struct dnode **list_dir(const char *path)
563 return dnp; 536 return dnp;
564} 537}
565 538
566/*----------------------------------------------------------------------*/ 539
567static int list_single(struct dnode *dn) 540static int list_single(struct dnode *dn)
568{ 541{
569 int i, column = 0; 542 int i, column = 0;
@@ -627,7 +600,7 @@ static int list_single(struct dnode *dn)
627 column += printf("%4d, %3d ", (int) major(dn->dstat.st_rdev), 600 column += printf("%4d, %3d ", (int) major(dn->dstat.st_rdev),
628 (int) minor(dn->dstat.st_rdev)); 601 (int) minor(dn->dstat.st_rdev));
629 } else { 602 } else {
630 if (ENABLE_FEATURE_HUMAN_READABLE && (all_fmt & LS_DISP_HR)) { 603 if (all_fmt & LS_DISP_HR) {
631 column += printf("%9s ", 604 column += printf("%9s ",
632 make_human_readable_str(dn->dstat.st_size, 1, 0)); 605 make_human_readable_str(dn->dstat.st_size, 1, 0));
633 } else { 606 } else {
@@ -661,12 +634,12 @@ static int list_single(struct dnode *dn)
661 int len = 0; 634 int len = 0;
662 635
663 if (dn->sid) { 636 if (dn->sid) {
664 /* I assume sid initilized with NULL */ 637 /* I assume sid initilized with NULL */
665 len = strlen(dn->sid)+1; 638 len = strlen(dn->sid)+1;
666 safe_strncpy(context, dn->sid, len); 639 safe_strncpy(context, dn->sid, len);
667 freecon(dn->sid); 640 freecon(dn->sid);
668 }else { 641 } else {
669 safe_strncpy(context, "unknown", 8); 642 safe_strncpy(context, "unknown", 8);
670 } 643 }
671 printf("%-32s ", context); 644 printf("%-32s ", context);
672 column += MAX(33, len); 645 column += MAX(33, len);
@@ -677,7 +650,7 @@ static int list_single(struct dnode *dn)
677 errno = 0; 650 errno = 0;
678 if (show_color && !lstat(dn->fullname, &info)) { 651 if (show_color && !lstat(dn->fullname, &info)) {
679 printf("\033[%d;%dm", bgcolor(info.st_mode), 652 printf("\033[%d;%dm", bgcolor(info.st_mode),
680 fgcolor(info.st_mode)); 653 fgcolor(info.st_mode));
681 } 654 }
682 column += printf("%s", dn->name); 655 column += printf("%s", dn->name);
683 if (show_color) { 656 if (show_color) {
@@ -687,31 +660,29 @@ static int list_single(struct dnode *dn)
687 case LIST_SYMLINK: 660 case LIST_SYMLINK:
688 if (S_ISLNK(dn->dstat.st_mode)) { 661 if (S_ISLNK(dn->dstat.st_mode)) {
689 char *lpath = xreadlink(dn->fullname); 662 char *lpath = xreadlink(dn->fullname);
690 663 if (!lpath) break;
691 if (lpath) { 664 printf(" -> ");
692 printf(" -> "); 665#if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR
693#if defined(CONFIG_FEATURE_LS_FILETYPES) || defined (CONFIG_FEATURE_LS_COLOR) 666 if (!stat(dn->fullname, &info)) {
694 if (!stat(dn->fullname, &info)) { 667 append = append_char(info.st_mode);
695 append = append_char(info.st_mode); 668 }
696 }
697#endif 669#endif
698 if (show_color) { 670 if (show_color) {
699 errno = 0; 671 errno = 0;
700 printf("\033[%d;%dm", bgcolor(info.st_mode), 672 printf("\033[%d;%dm", bgcolor(info.st_mode),
701 fgcolor(info.st_mode)); 673 fgcolor(info.st_mode));
702 }
703 column += printf("%s", lpath) + 4;
704 if (show_color) {
705 printf("\033[0m");
706 }
707 free(lpath);
708 } 674 }
675 column += printf("%s", lpath) + 4;
676 if (show_color) {
677 printf("\033[0m");
678 }
679 free(lpath);
709 } 680 }
710 break; 681 break;
711#if ENABLE_FEATURE_LS_FILETYPES 682#if ENABLE_FEATURE_LS_FILETYPES
712 case LIST_FILETYPE: 683 case LIST_FILETYPE:
713 if (append != '\0') { 684 if (append) {
714 printf("%1c", append); 685 putchar(append);
715 column++; 686 column++;
716 } 687 }
717 break; 688 break;
@@ -722,8 +693,6 @@ static int list_single(struct dnode *dn)
722 return column; 693 return column;
723} 694}
724 695
725/*----------------------------------------------------------------------*/
726
727/* "[-]Cadil1", POSIX mandated options, busybox always supports */ 696/* "[-]Cadil1", POSIX mandated options, busybox always supports */
728/* "[-]gnsx", POSIX non-mandated options, busybox always supports */ 697/* "[-]gnsx", POSIX non-mandated options, busybox always supports */
729/* "[-]Ak" GNU options, busybox always supports */ 698/* "[-]Ak" GNU options, busybox always supports */
@@ -732,7 +701,6 @@ static int list_single(struct dnode *dn)
732/* "[-]SXvThw", GNU options, busybox optionally supports */ 701/* "[-]SXvThw", GNU options, busybox optionally supports */
733/* "[-]K", SELinux mandated options, busybox optionally supports */ 702/* "[-]K", SELinux mandated options, busybox optionally supports */
734/* "[-]e", I think we made this one up */ 703/* "[-]e", I think we made this one up */
735
736static const char ls_options[] = "Cadil1gnsxAk" 704static const char ls_options[] = "Cadil1gnsxAk"
737 USE_FEATURE_LS_TIMESTAMPS("cetu") 705 USE_FEATURE_LS_TIMESTAMPS("cetu")
738 USE_FEATURE_LS_SORTFILES("SXrv") 706 USE_FEATURE_LS_SORTFILES("SXrv")
@@ -743,10 +711,12 @@ static const char ls_options[] = "Cadil1gnsxAk"
743 USE_SELINUX("K") 711 USE_SELINUX("K")
744 USE_FEATURE_AUTOWIDTH("T:w:"); 712 USE_FEATURE_AUTOWIDTH("T:w:");
745 713
746#define LIST_MASK_TRIGGER 0 714enum {
747#define STYLE_MASK_TRIGGER STYLE_MASK 715 LIST_MASK_TRIGGER = 0,
748#define SORT_MASK_TRIGGER SORT_MASK 716 STYLE_MASK_TRIGGER = STYLE_MASK,
749#define DISP_MASK_TRIGGER DISP_ROWS 717 DISP_MASK_TRIGGER = DISP_ROWS,
718 SORT_MASK_TRIGGER = SORT_MASK,
719};
750 720
751static const unsigned opt_flags[] = { 721static const unsigned opt_flags[] = {
752 LIST_SHORT | STYLE_COLUMNS, /* C */ 722 LIST_SHORT | STYLE_COLUMNS, /* C */
@@ -760,11 +730,7 @@ static const unsigned opt_flags[] = {
760 LIST_BLOCKS, /* s */ 730 LIST_BLOCKS, /* s */
761 DISP_ROWS, /* x */ 731 DISP_ROWS, /* x */
762 DISP_HIDDEN, /* A */ 732 DISP_HIDDEN, /* A */
763#if ENABLE_SELINUX 733 ENABLE_SELINUX * LIST_CONTEXT, /* k (ignored if !SELINUX) */
764 LIST_CONTEXT, /* k */
765#else
766 0, /* k - ingored */
767#endif
768#if ENABLE_FEATURE_LS_TIMESTAMPS 734#if ENABLE_FEATURE_LS_TIMESTAMPS
769 TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */ 735 TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */
770 LIST_FULLTIME, /* e */ 736 LIST_FULLTIME, /* e */
@@ -774,7 +740,7 @@ static const unsigned opt_flags[] = {
774#if ENABLE_FEATURE_LS_SORTFILES 740#if ENABLE_FEATURE_LS_SORTFILES
775 SORT_SIZE, /* S */ 741 SORT_SIZE, /* S */
776 SORT_EXT, /* X */ 742 SORT_EXT, /* X */
777 SORT_ORDER_REVERSE, /* r */ 743 SORT_REVERSE, /* r */
778 SORT_VERSION, /* v */ 744 SORT_VERSION, /* v */
779#endif 745#endif
780#if ENABLE_FEATURE_LS_FILETYPES 746#if ENABLE_FEATURE_LS_FILETYPES
@@ -800,8 +766,6 @@ static const unsigned opt_flags[] = {
800}; 766};
801 767
802 768
803/*----------------------------------------------------------------------*/
804
805int ls_main(int argc, char **argv) 769int ls_main(int argc, char **argv)
806{ 770{
807 struct dnode **dnd; 771 struct dnode **dnd;
@@ -817,16 +781,12 @@ int ls_main(int argc, char **argv)
817 int ac; 781 int ac;
818 int i; 782 int i;
819 char **av; 783 char **av;
820#if ENABLE_FEATURE_AUTOWIDTH 784 USE_FEATURE_AUTOWIDTH(char *tabstops_str = NULL;)
821 char *tabstops_str = NULL; 785 USE_FEATURE_AUTOWIDTH(char *terminal_width_str = NULL;)
822 char *terminal_width_str = NULL; 786 USE_FEATURE_LS_COLOR(char *color_opt;)
823#endif
824#if ENABLE_FEATURE_LS_COLOR
825 char *color_opt;
826#endif
827 787
828 all_fmt = LIST_SHORT | 788 all_fmt = LIST_SHORT |
829 (ENABLE_FEATURE_LS_SORTFILES * (SORT_NAME | SORT_ORDER_FORWARD)); 789 (ENABLE_FEATURE_LS_SORTFILES * (SORT_NAME | SORT_FORWARD));
830 790
831#if ENABLE_FEATURE_AUTOWIDTH 791#if ENABLE_FEATURE_AUTOWIDTH
832 /* Obtain the terminal width. */ 792 /* Obtain the terminal width. */
@@ -835,27 +795,17 @@ int ls_main(int argc, char **argv)
835 terminal_width--; 795 terminal_width--;
836#endif 796#endif
837 797
838#if ENABLE_FEATURE_LS_COLOR
839 applet_long_options = ls_color_opt;
840#endif
841
842 /* process options */ 798 /* process options */
799 USE_FEATURE_LS_COLOR(applet_long_options = ls_color_opt;)
843#if ENABLE_FEATURE_AUTOWIDTH 800#if ENABLE_FEATURE_AUTOWIDTH
844 opt = getopt32(argc, argv, ls_options, &tabstops_str, &terminal_width_str 801 opt = getopt32(argc, argv, ls_options, &tabstops_str, &terminal_width_str
845#if ENABLE_FEATURE_LS_COLOR 802 USE_FEATURE_LS_COLOR(, &color_opt));
846 , &color_opt
847#endif
848 );
849 if (tabstops_str) 803 if (tabstops_str)
850 tabstops = xatou(tabstops_str); 804 tabstops = xatou(tabstops_str);
851 if (terminal_width_str) 805 if (terminal_width_str)
852 terminal_width = xatou(terminal_width_str); 806 terminal_width = xatou(terminal_width_str);
853#else 807#else
854 opt = getopt32(argc, argv, ls_options 808 opt = getopt32(argc, argv, ls_options USE_FEATURE_LS_COLOR(, &color_opt));
855#if ENABLE_FEATURE_LS_COLOR
856 , &color_opt
857#endif
858 );
859#endif 809#endif
860 for (i = 0; opt_flags[i] != (1U<<31); i++) { 810 for (i = 0; opt_flags[i] != (1U<<31); i++) {
861 if (opt & (1 << i)) { 811 if (opt & (1 << i)) {
@@ -865,7 +815,7 @@ int ls_main(int argc, char **argv)
865 all_fmt &= ~LIST_MASK; 815 all_fmt &= ~LIST_MASK;
866 if (flags & STYLE_MASK_TRIGGER) 816 if (flags & STYLE_MASK_TRIGGER)
867 all_fmt &= ~STYLE_MASK; 817 all_fmt &= ~STYLE_MASK;
868 if (ENABLE_FEATURE_LS_SORTFILES && (flags & SORT_MASK_TRIGGER)) 818 if (flags & SORT_MASK_TRIGGER)
869 all_fmt &= ~SORT_MASK; 819 all_fmt &= ~SORT_MASK;
870 if (flags & DISP_MASK_TRIGGER) 820 if (flags & DISP_MASK_TRIGGER)
871 all_fmt &= ~DISP_MASK; 821 all_fmt &= ~DISP_MASK;
@@ -873,7 +823,7 @@ int ls_main(int argc, char **argv)
873 all_fmt &= ~TIME_MASK; 823 all_fmt &= ~TIME_MASK;
874 if (flags & LIST_CONTEXT) 824 if (flags & LIST_CONTEXT)
875 all_fmt |= STYLE_SINGLE; 825 all_fmt |= STYLE_SINGLE;
876 if (ENABLE_FEATURE_HUMAN_READABLE && opt == 'l') 826 if (LS_DISP_HR && opt == 'l')
877 all_fmt &= ~LS_DISP_HR; 827 all_fmt &= ~LS_DISP_HR;
878 all_fmt |= flags; 828 all_fmt |= flags;
879 } 829 }
@@ -959,7 +909,7 @@ int ls_main(int argc, char **argv)
959 } 909 }
960 910
961 if (all_fmt & DISP_NOLIST) { 911 if (all_fmt & DISP_NOLIST) {
962 if (ENABLE_FEATURE_LS_SORTFILES) dnsort(dnp, nfiles); 912 dnsort(dnp, nfiles);
963 if (nfiles > 0) 913 if (nfiles > 0)
964 showfiles(dnp, nfiles); 914 showfiles(dnp, nfiles);
965 } else { 915 } else {
@@ -968,13 +918,13 @@ int ls_main(int argc, char **argv)
968 dndirs = countdirs(dnp, nfiles); 918 dndirs = countdirs(dnp, nfiles);
969 dnfiles = nfiles - dndirs; 919 dnfiles = nfiles - dndirs;
970 if (dnfiles > 0) { 920 if (dnfiles > 0) {
971 if (ENABLE_FEATURE_LS_SORTFILES) dnsort(dnf, dnfiles); 921 dnsort(dnf, dnfiles);
972 showfiles(dnf, dnfiles); 922 showfiles(dnf, dnfiles);
973 if (ENABLE_FEATURE_CLEAN_UP) 923 if (ENABLE_FEATURE_CLEAN_UP)
974 free(dnf); 924 free(dnf);
975 } 925 }
976 if (dndirs > 0) { 926 if (dndirs > 0) {
977 if (ENABLE_FEATURE_LS_SORTFILES) dnsort(dnd, dndirs); 927 dnsort(dnd, dndirs);
978 showdirs(dnd, dndirs, dnfiles == 0); 928 showdirs(dnd, dndirs, dnfiles == 0);
979 if (ENABLE_FEATURE_CLEAN_UP) 929 if (ENABLE_FEATURE_CLEAN_UP)
980 free(dnd); 930 free(dnd);