diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2006-10-28 12:37:51 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2006-10-28 12:37:51 +0000 |
commit | 94cf69fe3e24b2b94c363e30664672617196e628 (patch) | |
tree | 1f5aa6371eb42b7c5d5205e3acb75b11e7d12b11 | |
parent | 5c7596058dedb99ab0fbe773cc7ac61a2ffe9fbf (diff) | |
download | busybox-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.c | 20 | ||||
-rw-r--r-- | coreutils/ls.c | 326 |
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 | } |
136 | function test() { | 136 | function 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() { | |||
145 | t1="/tmp/busybox chmod" | 145 | t1="/tmp/busybox chmod" |
146 | t2="/usr/bin/chmod" | 146 | t2="/usr/bin/chmod" |
147 | create test1; create test2 | 147 | create test1; create test2 |
148 | test "a+w file" | 148 | tst "a+w file" |
149 | test "a-w dir" | 149 | tst "a-w dir" |
150 | test "a+w linkfile" | 150 | tst "a+w linkfile" |
151 | test "a-w linkdir" | 151 | tst "a-w linkdir" |
152 | test "-R a+w file" | 152 | tst "-R a+w file" |
153 | test "-R a-w dir" | 153 | tst "-R a-w dir" |
154 | test "-R a+w linkfile" | 154 | tst "-R a+w linkfile" |
155 | test "-R a-w linkdir" | 155 | tst "-R a-w linkdir" |
156 | test "a-r,a+x linkfile" | 156 | tst "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 | ||
32 | enum { | ||
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 */ | 35 | enum { |
43 | #define STYLE_COLUMNS (1U<<21) /* fill columns */ | 36 | |
44 | #define STYLE_LONG (2U<<21) /* one record per line, extended info */ | 37 | TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */ |
45 | #define STYLE_SINGLE (3U<<21) /* one record per line */ | 38 | COLUMN_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 | 41 | STYLE_COLUMNS = 1 << 21, /* fill columns */ |
42 | STYLE_LONG = 2 << 21, /* one record per line, extended info */ | ||
43 | STYLE_SINGLE = 3 << 21, /* one record per line */ | ||
44 | STYLE_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) | 48 | LIST_INO = 1 << 0, |
53 | #define LIST_BLOCKS (1U<<1) | 49 | LIST_BLOCKS = 1 << 1, |
54 | #define LIST_MODEBITS (1U<<2) | 50 | LIST_MODEBITS = 1 << 2, |
55 | #define LIST_NLINKS (1U<<3) | 51 | LIST_NLINKS = 1 << 3, |
56 | #define LIST_ID_NAME (1U<<4) | 52 | LIST_ID_NAME = 1 << 4, |
57 | #define LIST_ID_NUMERIC (1U<<5) | 53 | LIST_ID_NUMERIC = 1 << 5, |
58 | #define LIST_CONTEXT (1U<<6) | 54 | LIST_CONTEXT = 1 << 6, |
59 | #define LIST_SIZE (1U<<7) | 55 | LIST_SIZE = 1 << 7, |
60 | #define LIST_DEV (1U<<8) | 56 | LIST_DEV = 1 << 8, |
61 | #define LIST_DATE_TIME (1U<<9) | 57 | LIST_DATE_TIME = 1 << 9, |
62 | #define LIST_FULLTIME (1U<<10) | 58 | LIST_FULLTIME = 1 << 10, |
63 | #define LIST_FILENAME (1U<<11) | 59 | LIST_FILENAME = 1 << 11, |
64 | #define LIST_SYMLINK (1U<<12) | 60 | LIST_SYMLINK = 1 << 12, |
65 | #define LIST_FILETYPE (1U<<13) | 61 | LIST_FILETYPE = 1 << 13, |
66 | #define LIST_EXEC (1U<<14) | 62 | LIST_EXEC = 1 << 14, |
67 | 63 | LIST_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 */ | 66 | DISP_DIRNAME = 1 << 15, /* 2 or more items? label directories */ |
72 | #define DISP_HIDDEN (1U<<16) /* show filenames starting with . */ | 67 | DISP_HIDDEN = 1 << 16, /* show filenames starting with . */ |
73 | #define DISP_DOT (1U<<17) /* show . and .. */ | 68 | DISP_DOT = 1 << 17, /* show . and .. */ |
74 | #define DISP_NOLIST (1U<<18) /* show directory as itself, not contents */ | 69 | DISP_NOLIST = 1 << 18, /* show directory as itself, not contents */ |
75 | #define DISP_RECURSIVE (1U<<19) /* show directory and everything below it */ | 70 | DISP_RECURSIVE = 1 << 19, /* show directory and everything below it */ |
76 | #define DISP_ROWS (1U<<20) /* print across rows */ | 71 | DISP_ROWS = 1 << 20, /* print across rows */ |
77 | 72 | DISP_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 | 75 | SORT_FORWARD = 0, /* sort in reverse order */ |
81 | /* how will the files be sorted */ | 76 | SORT_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 */ | 78 | SORT_NAME = 0, /* sort by file name */ |
84 | 79 | SORT_SIZE = 1 << 28, /* sort by file size */ | |
85 | #define SORT_NAME 0 /* sort by file name */ | 80 | SORT_ATIME = 2 << 28, /* sort by last access time */ |
86 | #define SORT_SIZE (1U<<28) /* sort by file size */ | 81 | SORT_CTIME = 3 << 28, /* sort by last change time */ |
87 | #define SORT_ATIME (2U<<28) /* sort by last access time */ | 82 | SORT_MTIME = 4 << 28, /* sort by last modification time */ |
88 | #define SORT_CTIME (3U<<28) /* sort by last change time */ | 83 | SORT_VERSION = 5 << 28, /* sort by version */ |
89 | #define SORT_MTIME (4U<<28) /* sort by last modification time */ | 84 | SORT_EXT = 6 << 28, /* sort by file name extension */ |
90 | #define SORT_VERSION (5U<<28) /* sort by version */ | 85 | SORT_DIR = 7 << 28, /* sort by file or directory */ |
91 | #define SORT_EXT (6U<<28) /* sort by file name extension */ | 86 | SORT_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) | 89 | TIME_CHANGE = (1 << 23) * ENABLE_FEATURE_LS_TIMESTAMPS, |
98 | #define TIME_ACCESS ((1U<<24) * ENABLE_FEATURE_LS_TIMESTAMPS) | 90 | TIME_ACCESS = (1 << 24) * ENABLE_FEATURE_LS_TIMESTAMPS, |
99 | #define TIME_MASK ((3U<<23) * ENABLE_FEATURE_LS_TIMESTAMPS) | 91 | TIME_MASK = (3 << 23) * ENABLE_FEATURE_LS_TIMESTAMPS, |
100 | 92 | ||
101 | #if ENABLE_FEATURE_LS_FOLLOWLINKS | 93 | FOLLOW_LINKS = (1 << 25) * ENABLE_FEATURE_LS_FOLLOWLINKS, |
102 | #define FOLLOW_LINKS (1U<<25) | 94 | |
103 | #endif | 95 | LS_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) | 97 | LIST_SHORT = LIST_FILENAME, |
109 | //#define LIST_ISHORT (LIST_INO | LIST_FILENAME) | 98 | LIST_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 | 101 | SPLIT_DIR = 1, |
115 | #define SPLIT_FILE 0 | 102 | SPLIT_FILE = 0, |
116 | #define SPLIT_SUBDIR 2 | 103 | SPLIT_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 | |||
128 | static int show_color; | 117 | static 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. */ |
132 | static const struct option ls_color_opt[] = { | 120 | static 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 |
142 | enum { show_color = 0 }; | 125 | enum { 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 | */ |
148 | struct dnode { /* the basic node */ | 131 | struct 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 | }; |
156 | typedef struct dnode dnode_t; | 139 | typedef 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 |
216 | static char fgcolor(mode_t mode) | 198 | static 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 | /*----------------------------------------------------------------------*/ | ||
227 | static char bgcolor(mode_t mode) | 208 | static 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 |
237 | static char append_char(mode_t mode) | 217 | static 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 | |||
256 | static int count_dirs(struct dnode **dn, int nfiles, int notsubdirs) | 233 | static 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 |
361 | static int sortcmp(const void *a, const void *b) | 337 | static 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 | /*----------------------------------------------------------------------*/ | ||
396 | static void dnsort(struct dnode **dn, int size) | 373 | static 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 | /*----------------------------------------------------------------------*/ | ||
407 | static void showfiles(struct dnode **dn, int nfiles) | 382 | static 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 | |
466 | static void showdirs(struct dnode **dn, int ndirs, int first) | 439 | static 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 | |
509 | static struct dnode **list_dir(const char *path) | 482 | static 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 | |
567 | static int list_single(struct dnode *dn) | 540 | static 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 | |||
736 | static const char ls_options[] = "Cadil1gnsxAk" | 704 | static 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 | 714 | enum { |
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 | ||
751 | static const unsigned opt_flags[] = { | 721 | static 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 | |||
805 | int ls_main(int argc, char **argv) | 769 | int 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); |