diff options
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/Config.src | 7 | ||||
-rw-r--r-- | coreutils/Kbuild.src | 1 | ||||
-rw-r--r-- | coreutils/date.c | 8 | ||||
-rw-r--r-- | coreutils/dd.c | 2 | ||||
-rw-r--r-- | coreutils/ls.c | 415 | ||||
-rw-r--r-- | coreutils/mv.c | 2 | ||||
-rw-r--r-- | coreutils/nice.c | 6 | ||||
-rw-r--r-- | coreutils/od.c | 4 | ||||
-rw-r--r-- | coreutils/sort.c | 4 | ||||
-rw-r--r-- | coreutils/stat.c | 7 | ||||
-rw-r--r-- | coreutils/test.c | 11 | ||||
-rw-r--r-- | coreutils/touch.c | 36 | ||||
-rw-r--r-- | coreutils/tr.c | 8 | ||||
-rw-r--r-- | coreutils/wc.c | 6 |
14 files changed, 312 insertions, 205 deletions
diff --git a/coreutils/Config.src b/coreutils/Config.src index adad4ba6d..b599f7999 100644 --- a/coreutils/Config.src +++ b/coreutils/Config.src | |||
@@ -664,13 +664,6 @@ config FEATURE_TEE_USE_BLOCK_IO | |||
664 | help | 664 | help |
665 | Enable this option for a faster tee, at expense of size. | 665 | Enable this option for a faster tee, at expense of size. |
666 | 666 | ||
667 | config TOUCH | ||
668 | bool "touch" | ||
669 | default y | ||
670 | help | ||
671 | touch is used to create or change the access and/or | ||
672 | modification timestamp of specified files. | ||
673 | |||
674 | config TRUE | 667 | config TRUE |
675 | bool "true" | 668 | bool "true" |
676 | default y | 669 | default y |
diff --git a/coreutils/Kbuild.src b/coreutils/Kbuild.src index 630b048df..4ea0fa50a 100644 --- a/coreutils/Kbuild.src +++ b/coreutils/Kbuild.src | |||
@@ -74,7 +74,6 @@ lib-$(CONFIG_SYNC) += sync.o | |||
74 | lib-$(CONFIG_TAC) += tac.o | 74 | lib-$(CONFIG_TAC) += tac.o |
75 | lib-$(CONFIG_TAIL) += tail.o | 75 | lib-$(CONFIG_TAIL) += tail.o |
76 | lib-$(CONFIG_TEE) += tee.o | 76 | lib-$(CONFIG_TEE) += tee.o |
77 | lib-$(CONFIG_TOUCH) += touch.o | ||
78 | lib-$(CONFIG_TRUE) += true.o | 77 | lib-$(CONFIG_TRUE) += true.o |
79 | lib-$(CONFIG_TTY) += tty.o | 78 | lib-$(CONFIG_TTY) += tty.o |
80 | lib-$(CONFIG_UNAME) += uname.o | 79 | lib-$(CONFIG_UNAME) += uname.o |
diff --git a/coreutils/date.c b/coreutils/date.c index eed4714f9..22d0a5327 100644 --- a/coreutils/date.c +++ b/coreutils/date.c | |||
@@ -250,6 +250,10 @@ int date_main(int argc UNUSED_PARAM, char **argv) | |||
250 | ts.tv_sec = statbuf.st_mtime; | 250 | ts.tv_sec = statbuf.st_mtime; |
251 | #if ENABLE_FEATURE_DATE_NANO | 251 | #if ENABLE_FEATURE_DATE_NANO |
252 | ts.tv_nsec = statbuf.st_mtim.tv_nsec; | 252 | ts.tv_nsec = statbuf.st_mtim.tv_nsec; |
253 | /* Some toolchains use .st_mtimensec instead of st_mtim.tv_nsec. | ||
254 | * If you need #define _SVID_SOURCE 1 to enable st_mtim.tv_nsec, | ||
255 | * drop a mail to project mailing list please | ||
256 | */ | ||
253 | #endif | 257 | #endif |
254 | } else { | 258 | } else { |
255 | #if ENABLE_FEATURE_DATE_NANO | 259 | #if ENABLE_FEATURE_DATE_NANO |
@@ -278,7 +282,9 @@ int date_main(int argc UNUSED_PARAM, char **argv) | |||
278 | } | 282 | } |
279 | 283 | ||
280 | /* Correct any day of week and day of year etc. fields */ | 284 | /* Correct any day of week and day of year etc. fields */ |
281 | tm_time.tm_isdst = -1; /* Be sure to recheck dst */ | 285 | /* Be sure to recheck dst (but not if date is time_t format) */ |
286 | if (date_str[0] != '@') | ||
287 | tm_time.tm_isdst = -1; | ||
282 | ts.tv_sec = validate_tm_time(date_str, &tm_time); | 288 | ts.tv_sec = validate_tm_time(date_str, &tm_time); |
283 | 289 | ||
284 | maybe_set_utc(opt); | 290 | maybe_set_utc(opt); |
diff --git a/coreutils/dd.c b/coreutils/dd.c index c22a39da7..da205ec69 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c | |||
@@ -24,7 +24,7 @@ static const struct suffix_mult dd_suffixes[] = { | |||
24 | { "b", 512 }, | 24 | { "b", 512 }, |
25 | { "kD", 1000 }, | 25 | { "kD", 1000 }, |
26 | { "k", 1024 }, | 26 | { "k", 1024 }, |
27 | { "K", 1024 }, /* compat with coreutils dd */ | 27 | { "K", 1024 }, /* compat with coreutils dd */ |
28 | { "MD", 1000000 }, | 28 | { "MD", 1000000 }, |
29 | { "M", 1048576 }, | 29 | { "M", 1048576 }, |
30 | { "GD", 1000000000 }, | 30 | { "GD", 1000000000 }, |
diff --git a/coreutils/ls.c b/coreutils/ls.c index 1a670201c..1afe28c8d 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
@@ -29,6 +29,71 @@ | |||
29 | * [2009-03] | 29 | * [2009-03] |
30 | * ls sorts listing now, and supports almost all options. | 30 | * ls sorts listing now, and supports almost all options. |
31 | */ | 31 | */ |
32 | |||
33 | //usage:#define ls_trivial_usage | ||
34 | //usage: "[-1AaCxd" | ||
35 | //usage: IF_FEATURE_LS_FOLLOWLINKS("LH") | ||
36 | //usage: IF_FEATURE_LS_RECURSIVE("R") | ||
37 | //usage: IF_FEATURE_LS_FILETYPES("Fp") "lins" | ||
38 | //usage: IF_FEATURE_LS_TIMESTAMPS("e") | ||
39 | //usage: IF_FEATURE_HUMAN_READABLE("h") | ||
40 | //usage: IF_FEATURE_LS_SORTFILES("rSXv") | ||
41 | //usage: IF_FEATURE_LS_TIMESTAMPS("ctu") | ||
42 | //usage: IF_SELINUX("kKZ") "]" | ||
43 | //usage: IF_FEATURE_AUTOWIDTH(" -w WIDTH") " [FILE]..." | ||
44 | //usage:#define ls_full_usage "\n\n" | ||
45 | //usage: "List directory contents\n" | ||
46 | //usage: "\nOptions:" | ||
47 | //usage: "\n -1 List in a single column" | ||
48 | //usage: "\n -A Don't list . and .." | ||
49 | //usage: "\n -a Don't hide entries starting with ." | ||
50 | //usage: "\n -C List by columns" | ||
51 | //usage: "\n -x List by lines" | ||
52 | //usage: "\n -d List directory entries instead of contents" | ||
53 | //usage: IF_FEATURE_LS_FOLLOWLINKS( | ||
54 | //usage: "\n -L Follow symlinks" | ||
55 | //usage: "\n -H Follow symlinks on command line only" | ||
56 | //usage: ) | ||
57 | //usage: IF_FEATURE_LS_RECURSIVE( | ||
58 | //usage: "\n -R Recurse" | ||
59 | //usage: ) | ||
60 | //usage: IF_FEATURE_LS_FILETYPES( | ||
61 | //usage: "\n -F Append indicator (one of */=@|) to entries" | ||
62 | //usage: "\n -p Append indicator (one of /=@|) to entries" | ||
63 | //usage: ) | ||
64 | //usage: "\n -l Long listing format" | ||
65 | //usage: "\n -i List inode numbers" | ||
66 | //usage: "\n -n List numeric UIDs and GIDs instead of names" | ||
67 | //usage: "\n -s List the size of each file, in blocks" | ||
68 | //usage: IF_FEATURE_LS_TIMESTAMPS( | ||
69 | //usage: "\n -e List full date and time" | ||
70 | //usage: ) | ||
71 | //usage: IF_FEATURE_HUMAN_READABLE( | ||
72 | //usage: "\n -h List sizes in human readable format (1K 243M 2G)" | ||
73 | //usage: ) | ||
74 | //usage: IF_FEATURE_LS_SORTFILES( | ||
75 | //usage: "\n -r Sort in reverse order" | ||
76 | //usage: "\n -S Sort by file size" | ||
77 | //usage: "\n -X Sort by extension" | ||
78 | //usage: "\n -v Sort by version" | ||
79 | //usage: ) | ||
80 | //usage: IF_FEATURE_LS_TIMESTAMPS( | ||
81 | //usage: "\n -c With -l: sort by ctime" | ||
82 | //usage: "\n -t With -l: sort by modification time" | ||
83 | //usage: "\n -u With -l: sort by access time" | ||
84 | //usage: ) | ||
85 | //usage: IF_SELINUX( | ||
86 | //usage: "\n -k List security context" | ||
87 | //usage: "\n -K List security context in long format" | ||
88 | //usage: "\n -Z List security context and permission" | ||
89 | //usage: ) | ||
90 | //usage: IF_FEATURE_AUTOWIDTH( | ||
91 | //usage: "\n -w N Assume the terminal is N columns wide" | ||
92 | //usage: ) | ||
93 | //usage: IF_FEATURE_LS_COLOR( | ||
94 | //usage: "\n --color[={always,never,auto}] Control coloring" | ||
95 | //usage: ) | ||
96 | |||
32 | #include "libbb.h" | 97 | #include "libbb.h" |
33 | #include "unicode.h" | 98 | #include "unicode.h" |
34 | 99 | ||
@@ -53,13 +118,12 @@ | |||
53 | 118 | ||
54 | enum { | 119 | enum { |
55 | TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */ | 120 | TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */ |
56 | COLUMN_GAP = 2, /* includes the file type char */ | ||
57 | 121 | ||
58 | /* what is the overall style of the listing */ | 122 | SPLIT_DIR = 1, |
59 | STYLE_COLUMNS = 1 << 21, /* fill columns */ | 123 | SPLIT_FILE = 0, |
60 | STYLE_LONG = 2 << 21, /* one record per line, extended info */ | 124 | SPLIT_SUBDIR = 2, |
61 | STYLE_SINGLE = 3 << 21, /* one record per line */ | 125 | |
62 | STYLE_MASK = STYLE_SINGLE, | 126 | /* Bits in all_fmt: */ |
63 | 127 | ||
64 | /* 51306 lrwxrwxrwx 1 root root 2 May 11 01:43 /bin/view -> vi* */ | 128 | /* 51306 lrwxrwxrwx 1 root root 2 May 11 01:43 /bin/view -> vi* */ |
65 | /* what file information will be listed */ | 129 | /* what file information will be listed */ |
@@ -71,75 +135,74 @@ LIST_ID_NAME = 1 << 4, | |||
71 | LIST_ID_NUMERIC = 1 << 5, | 135 | LIST_ID_NUMERIC = 1 << 5, |
72 | LIST_CONTEXT = 1 << 6, | 136 | LIST_CONTEXT = 1 << 6, |
73 | LIST_SIZE = 1 << 7, | 137 | LIST_SIZE = 1 << 7, |
74 | //LIST_DEV = 1 << 8, - unused, synonym to LIST_SIZE | 138 | LIST_DATE_TIME = 1 << 8, |
75 | LIST_DATE_TIME = 1 << 9, | 139 | LIST_FULLTIME = 1 << 9, |
76 | LIST_FULLTIME = 1 << 10, | 140 | LIST_SYMLINK = 1 << 10, |
77 | LIST_FILENAME = 1 << 11, | 141 | LIST_FILETYPE = 1 << 11, |
78 | LIST_SYMLINK = 1 << 12, | 142 | LIST_EXEC = 1 << 12, |
79 | LIST_FILETYPE = 1 << 13, | ||
80 | LIST_EXEC = 1 << 14, | ||
81 | LIST_MASK = (LIST_EXEC << 1) - 1, | 143 | LIST_MASK = (LIST_EXEC << 1) - 1, |
82 | 144 | ||
83 | /* what files will be displayed */ | 145 | /* what files will be displayed */ |
84 | DISP_DIRNAME = 1 << 15, /* 2 or more items? label directories */ | 146 | DISP_DIRNAME = 1 << 13, /* 2 or more items? label directories */ |
85 | DISP_HIDDEN = 1 << 16, /* show filenames starting with . */ | 147 | DISP_HIDDEN = 1 << 14, /* show filenames starting with . */ |
86 | DISP_DOT = 1 << 17, /* show . and .. */ | 148 | DISP_DOT = 1 << 15, /* show . and .. */ |
87 | DISP_NOLIST = 1 << 18, /* show directory as itself, not contents */ | 149 | DISP_NOLIST = 1 << 16, /* show directory as itself, not contents */ |
88 | DISP_RECURSIVE = 1 << 19, /* show directory and everything below it */ | 150 | DISP_RECURSIVE = 1 << 17, /* show directory and everything below it */ |
89 | DISP_ROWS = 1 << 20, /* print across rows */ | 151 | DISP_ROWS = 1 << 18, /* print across rows */ |
90 | DISP_MASK = ((DISP_ROWS << 1) - 1) & ~(DISP_DIRNAME - 1), | 152 | DISP_MASK = ((DISP_ROWS << 1) - 1) & ~(DISP_DIRNAME - 1), |
91 | 153 | ||
92 | /* how will the files be sorted (CONFIG_FEATURE_LS_SORTFILES) */ | 154 | /* what is the overall style of the listing */ |
93 | SORT_FORWARD = 0, /* sort in reverse order */ | 155 | STYLE_COLUMNAR = 1 << 19, /* many records per line */ |
94 | SORT_REVERSE = 1 << 27, /* sort in reverse order */ | 156 | STYLE_LONG = 2 << 19, /* one record per line, extended info */ |
95 | 157 | STYLE_SINGLE = 3 << 19, /* one record per line */ | |
96 | SORT_NAME = 0, /* sort by file name */ | 158 | STYLE_MASK = STYLE_SINGLE, |
97 | SORT_SIZE = 1 << 28, /* sort by file size */ | ||
98 | SORT_ATIME = 2 << 28, /* sort by last access time */ | ||
99 | SORT_CTIME = 3 << 28, /* sort by last change time */ | ||
100 | SORT_MTIME = 4 << 28, /* sort by last modification time */ | ||
101 | SORT_VERSION = 5 << 28, /* sort by version */ | ||
102 | SORT_EXT = 6 << 28, /* sort by file name extension */ | ||
103 | SORT_DIR = 7 << 28, /* sort by file or directory */ | ||
104 | SORT_MASK = (7 << 28) * ENABLE_FEATURE_LS_SORTFILES, | ||
105 | 159 | ||
106 | /* which of the three times will be used */ | 160 | /* which of the three times will be used */ |
107 | TIME_CHANGE = (1 << 23) * ENABLE_FEATURE_LS_TIMESTAMPS, | 161 | TIME_CHANGE = (1 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS, |
108 | TIME_ACCESS = (1 << 24) * ENABLE_FEATURE_LS_TIMESTAMPS, | 162 | TIME_ACCESS = (1 << 22) * ENABLE_FEATURE_LS_TIMESTAMPS, |
109 | TIME_MASK = (3 << 23) * ENABLE_FEATURE_LS_TIMESTAMPS, | 163 | TIME_MASK = (3 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS, |
110 | 164 | ||
111 | FOLLOW_LINKS = (1 << 25) * ENABLE_FEATURE_LS_FOLLOWLINKS, | 165 | /* how will the files be sorted (CONFIG_FEATURE_LS_SORTFILES) */ |
166 | SORT_REVERSE = 1 << 23, | ||
112 | 167 | ||
113 | LS_DISP_HR = (1 << 26) * ENABLE_FEATURE_HUMAN_READABLE, | 168 | SORT_NAME = 0, /* sort by file name */ |
169 | SORT_SIZE = 1 << 24, /* sort by file size */ | ||
170 | SORT_ATIME = 2 << 24, /* sort by last access time */ | ||
171 | SORT_CTIME = 3 << 24, /* sort by last change time */ | ||
172 | SORT_MTIME = 4 << 24, /* sort by last modification time */ | ||
173 | SORT_VERSION = 5 << 24, /* sort by version */ | ||
174 | SORT_EXT = 6 << 24, /* sort by file name extension */ | ||
175 | SORT_DIR = 7 << 24, /* sort by file or directory */ | ||
176 | SORT_MASK = (7 << 24) * ENABLE_FEATURE_LS_SORTFILES, | ||
114 | 177 | ||
115 | LIST_SHORT = LIST_FILENAME, | ||
116 | LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \ | 178 | LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \ |
117 | LIST_DATE_TIME | LIST_FILENAME | LIST_SYMLINK, | 179 | LIST_DATE_TIME | LIST_SYMLINK, |
118 | |||
119 | SPLIT_DIR = 1, | ||
120 | SPLIT_FILE = 0, | ||
121 | SPLIT_SUBDIR = 2, | ||
122 | }; | 180 | }; |
123 | 181 | ||
124 | /* "[-]Cadil1", POSIX mandated options, busybox always supports */ | 182 | /* -Cadil1 Std options, busybox always supports */ |
125 | /* "[-]gnsx", POSIX non-mandated options, busybox always supports */ | 183 | /* -gnsxA Std options, busybox always supports */ |
126 | /* "[-]Q" GNU option? busybox always supports */ | 184 | /* -Q GNU option, busybox always supports */ |
127 | /* "[-]Ak" GNU options, busybox always supports */ | 185 | /* -k SELinux option, busybox always supports (ignores if !SELinux) */ |
128 | /* "[-]FLRctur", POSIX mandated options, busybox optionally supports */ | 186 | /* Std has -k which means "show sizes in kbytes" */ |
129 | /* "[-]p", POSIX non-mandated options, busybox optionally supports */ | 187 | /* -FLHRctur Std options, busybox optionally supports */ |
130 | /* "[-]SXvThw", GNU options, busybox optionally supports */ | 188 | /* -p Std option, busybox optionally supports */ |
131 | /* "[-]K", SELinux mandated options, busybox optionally supports */ | 189 | /* Not fully compatible - we show not only '/' but other chars too */ |
132 | /* "[-]e", I think we made this one up */ | 190 | /* -SXvhTw GNU options, busybox optionally supports */ |
191 | /* -T TABWIDTH is ignored (we don't use tabs on output) */ | ||
192 | /* -K SELinux mandated options, busybox optionally supports */ | ||
193 | /* -e I think we made this one up (looks similar to GNU --full-time) */ | ||
194 | /* Std opts we do not support: */ | ||
195 | /* -H Follow the links on command line only */ | ||
133 | static const char ls_options[] ALIGN1 = | 196 | static const char ls_options[] ALIGN1 = |
134 | "Cadil1gnsxQAk" /* 13 opts, total 13 */ | 197 | "Cadil1gnsxQAk" /* 13 opts, total 13 */ |
135 | IF_FEATURE_LS_TIMESTAMPS("cetu") /* 4, 17 */ | 198 | IF_FEATURE_LS_TIMESTAMPS("cetu") /* 4, 17 */ |
136 | IF_FEATURE_LS_SORTFILES("SXrv") /* 4, 21 */ | 199 | IF_FEATURE_LS_SORTFILES("SXrv") /* 4, 21 */ |
137 | IF_FEATURE_LS_FILETYPES("Fp") /* 2, 23 */ | 200 | IF_FEATURE_LS_FILETYPES("Fp") /* 2, 23 */ |
138 | IF_FEATURE_LS_FOLLOWLINKS("L") /* 1, 24 */ | 201 | IF_FEATURE_LS_RECURSIVE("R") /* 1, 24 */ |
139 | IF_FEATURE_LS_RECURSIVE("R") /* 1, 25 */ | 202 | IF_SELINUX("KZ") /* 2, 26 */ |
140 | IF_FEATURE_HUMAN_READABLE("h") /* 1, 26 */ | 203 | IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 28 */ |
141 | IF_SELINUX("KZ") /* 2, 28 */ | 204 | IF_FEATURE_HUMAN_READABLE("h") /* 1, 29 */ |
142 | IF_FEATURE_AUTOWIDTH("T:w:") /* 2, 30 */ | 205 | IF_FEATURE_AUTOWIDTH("T:w:") /* 2, 31 */ |
143 | ; | 206 | ; |
144 | enum { | 207 | enum { |
145 | //OPT_C = (1 << 0), | 208 | //OPT_C = (1 << 0), |
@@ -155,75 +218,88 @@ enum { | |||
155 | OPT_Q = (1 << 10), | 218 | OPT_Q = (1 << 10), |
156 | //OPT_A = (1 << 11), | 219 | //OPT_A = (1 << 11), |
157 | //OPT_k = (1 << 12), | 220 | //OPT_k = (1 << 12), |
158 | OPTBIT_color = 13 | ||
159 | + 4 * ENABLE_FEATURE_LS_TIMESTAMPS | ||
160 | + 4 * ENABLE_FEATURE_LS_SORTFILES | ||
161 | + 2 * ENABLE_FEATURE_LS_FILETYPES | ||
162 | + 1 * ENABLE_FEATURE_LS_FOLLOWLINKS | ||
163 | + 1 * ENABLE_FEATURE_LS_RECURSIVE | ||
164 | + 1 * ENABLE_FEATURE_HUMAN_READABLE | ||
165 | + 2 * ENABLE_SELINUX | ||
166 | + 2 * ENABLE_FEATURE_AUTOWIDTH, | ||
167 | OPT_color = 1 << OPTBIT_color, | ||
168 | }; | ||
169 | 221 | ||
170 | enum { | 222 | OPTBIT_c = 13, |
171 | LIST_MASK_TRIGGER = 0, | 223 | OPTBIT_e, |
172 | STYLE_MASK_TRIGGER = STYLE_MASK, | 224 | OPTBIT_t, |
173 | DISP_MASK_TRIGGER = DISP_ROWS, | 225 | OPTBIT_u, |
174 | SORT_MASK_TRIGGER = SORT_MASK, | 226 | OPTBIT_S = OPTBIT_c + 4 * ENABLE_FEATURE_LS_TIMESTAMPS, |
227 | OPTBIT_X, /* 18 */ | ||
228 | OPTBIT_r, | ||
229 | OPTBIT_v, | ||
230 | OPTBIT_F = OPTBIT_S + 4 * ENABLE_FEATURE_LS_SORTFILES, | ||
231 | OPTBIT_p, /* 22 */ | ||
232 | OPTBIT_R = OPTBIT_F + 2 * ENABLE_FEATURE_LS_FILETYPES, | ||
233 | OPTBIT_K = OPTBIT_R + 1 * ENABLE_FEATURE_LS_RECURSIVE, | ||
234 | OPTBIT_Z, /* 25 */ | ||
235 | OPTBIT_L = OPTBIT_K + 2 * ENABLE_SELINUX, | ||
236 | OPTBIT_H, /* 27 */ | ||
237 | OPTBIT_h = OPTBIT_L + 1 * ENABLE_FEATURE_LS_FOLLOWLINKS, | ||
238 | OPTBIT_T = OPTBIT_h + 2 * ENABLE_FEATURE_HUMAN_READABLE, | ||
239 | OPTBIT_w, /* 30 */ | ||
240 | OPTBIT_color = OPTBIT_T + 2 * ENABLE_FEATURE_AUTOWIDTH, | ||
241 | |||
242 | OPT_c = (1 << OPTBIT_c) * ENABLE_FEATURE_LS_TIMESTAMPS, | ||
243 | OPT_e = (1 << OPTBIT_e) * ENABLE_FEATURE_LS_TIMESTAMPS, | ||
244 | OPT_t = (1 << OPTBIT_t) * ENABLE_FEATURE_LS_TIMESTAMPS, | ||
245 | OPT_u = (1 << OPTBIT_u) * ENABLE_FEATURE_LS_TIMESTAMPS, | ||
246 | OPT_S = (1 << OPTBIT_S) * ENABLE_FEATURE_LS_SORTFILES, | ||
247 | OPT_X = (1 << OPTBIT_X) * ENABLE_FEATURE_LS_SORTFILES, | ||
248 | OPT_r = (1 << OPTBIT_r) * ENABLE_FEATURE_LS_SORTFILES, | ||
249 | OPT_v = (1 << OPTBIT_v) * ENABLE_FEATURE_LS_SORTFILES, | ||
250 | OPT_F = (1 << OPTBIT_F) * ENABLE_FEATURE_LS_FILETYPES, | ||
251 | OPT_p = (1 << OPTBIT_p) * ENABLE_FEATURE_LS_FILETYPES, | ||
252 | OPT_R = (1 << OPTBIT_R) * ENABLE_FEATURE_LS_RECURSIVE, | ||
253 | OPT_K = (1 << OPTBIT_K) * ENABLE_SELINUX, | ||
254 | OPT_Z = (1 << OPTBIT_Z) * ENABLE_SELINUX, | ||
255 | OPT_L = (1 << OPTBIT_L) * ENABLE_FEATURE_LS_FOLLOWLINKS, | ||
256 | OPT_H = (1 << OPTBIT_H) * ENABLE_FEATURE_LS_FOLLOWLINKS, | ||
257 | OPT_h = (1 << OPTBIT_h) * ENABLE_FEATURE_HUMAN_READABLE, | ||
258 | OPT_T = (1 << OPTBIT_T) * ENABLE_FEATURE_AUTOWIDTH, | ||
259 | OPT_w = (1 << OPTBIT_w) * ENABLE_FEATURE_AUTOWIDTH, | ||
260 | OPT_color = (1 << OPTBIT_color) * ENABLE_FEATURE_LS_COLOR, | ||
175 | }; | 261 | }; |
176 | 262 | ||
177 | /* TODO: simple toggles may be stored as OPT_xxx bits instead */ | 263 | /* TODO: simple toggles may be stored as OPT_xxx bits instead */ |
178 | static const unsigned opt_flags[] = { | 264 | static const uint32_t opt_flags[] = { |
179 | LIST_SHORT | STYLE_COLUMNS, /* C */ | 265 | STYLE_COLUMNAR, /* C */ |
180 | DISP_HIDDEN | DISP_DOT, /* a */ | 266 | DISP_HIDDEN | DISP_DOT, /* a */ |
181 | DISP_NOLIST, /* d */ | 267 | DISP_NOLIST, /* d */ |
182 | LIST_INO, /* i */ | 268 | LIST_INO, /* i */ |
183 | LIST_LONG | STYLE_LONG, /* l - remember LS_DISP_HR in mask! */ | 269 | LIST_LONG | STYLE_LONG, /* l */ |
184 | LIST_SHORT | STYLE_SINGLE, /* 1 */ | 270 | STYLE_SINGLE, /* 1 */ |
185 | 0, /* g (don't show group) - handled via OPT_g */ | 271 | 0, /* g (don't show owner) - handled via OPT_g */ |
186 | LIST_ID_NUMERIC, /* n */ | 272 | LIST_ID_NUMERIC, /* n */ |
187 | LIST_BLOCKS, /* s */ | 273 | LIST_BLOCKS, /* s */ |
188 | DISP_ROWS, /* x */ | 274 | DISP_ROWS | STYLE_COLUMNAR, /* x */ |
189 | 0, /* Q (quote filename) - handled via OPT_Q */ | 275 | 0, /* Q (quote filename) - handled via OPT_Q */ |
190 | DISP_HIDDEN, /* A */ | 276 | DISP_HIDDEN, /* A */ |
191 | ENABLE_SELINUX * LIST_CONTEXT, /* k (ignored if !SELINUX) */ | 277 | ENABLE_SELINUX * LIST_CONTEXT, /* k (ignored if !SELINUX) */ |
192 | #if ENABLE_FEATURE_LS_TIMESTAMPS | 278 | #if ENABLE_FEATURE_LS_TIMESTAMPS |
193 | TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */ | 279 | TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */ |
194 | LIST_FULLTIME, /* e */ | 280 | LIST_FULLTIME, /* e */ |
195 | ENABLE_FEATURE_LS_SORTFILES * SORT_MTIME, /* t */ | 281 | ENABLE_FEATURE_LS_SORTFILES * SORT_MTIME, /* t */ |
196 | TIME_ACCESS | (ENABLE_FEATURE_LS_SORTFILES * SORT_ATIME), /* u */ | 282 | TIME_ACCESS | (ENABLE_FEATURE_LS_SORTFILES * SORT_ATIME), /* u */ |
197 | #endif | 283 | #endif |
198 | #if ENABLE_FEATURE_LS_SORTFILES | 284 | #if ENABLE_FEATURE_LS_SORTFILES |
199 | SORT_SIZE, /* S */ | 285 | SORT_SIZE, /* S */ |
200 | SORT_EXT, /* X */ | 286 | SORT_EXT, /* X */ |
201 | SORT_REVERSE, /* r */ | 287 | SORT_REVERSE, /* r */ |
202 | SORT_VERSION, /* v */ | 288 | SORT_VERSION, /* v */ |
203 | #endif | 289 | #endif |
204 | #if ENABLE_FEATURE_LS_FILETYPES | 290 | #if ENABLE_FEATURE_LS_FILETYPES |
205 | LIST_FILETYPE | LIST_EXEC, /* F */ | 291 | LIST_FILETYPE | LIST_EXEC, /* F */ |
206 | LIST_FILETYPE, /* p */ | 292 | LIST_FILETYPE, /* p */ |
207 | #endif | ||
208 | #if ENABLE_FEATURE_LS_FOLLOWLINKS | ||
209 | FOLLOW_LINKS, /* L */ | ||
210 | #endif | 293 | #endif |
211 | #if ENABLE_FEATURE_LS_RECURSIVE | 294 | #if ENABLE_FEATURE_LS_RECURSIVE |
212 | DISP_RECURSIVE, /* R */ | 295 | DISP_RECURSIVE, /* R */ |
213 | #endif | ||
214 | #if ENABLE_FEATURE_HUMAN_READABLE | ||
215 | LS_DISP_HR, /* h */ | ||
216 | #endif | 296 | #endif |
217 | #if ENABLE_SELINUX | 297 | #if ENABLE_SELINUX |
218 | LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME, /* K */ | 298 | LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME, /* K */ |
219 | #endif | ||
220 | #if ENABLE_SELINUX | ||
221 | LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT, /* Z */ | 299 | LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT, /* Z */ |
222 | #endif | 300 | #endif |
223 | (1U<<31) | 301 | (1U << 31) |
224 | /* options after Z are not processed through opt_flags: | 302 | /* options after Z are not processed through opt_flags */ |
225 | * T, w - ignored | ||
226 | */ | ||
227 | }; | 303 | }; |
228 | 304 | ||
229 | 305 | ||
@@ -246,7 +322,6 @@ struct globals { | |||
246 | smallint exit_code; | 322 | smallint exit_code; |
247 | unsigned all_fmt; | 323 | unsigned all_fmt; |
248 | #if ENABLE_FEATURE_AUTOWIDTH | 324 | #if ENABLE_FEATURE_AUTOWIDTH |
249 | unsigned tabstops; // = COLUMN_GAP; | ||
250 | unsigned terminal_width; // = TERMINAL_WIDTH; | 325 | unsigned terminal_width; // = TERMINAL_WIDTH; |
251 | #endif | 326 | #endif |
252 | #if ENABLE_FEATURE_LS_TIMESTAMPS | 327 | #if ENABLE_FEATURE_LS_TIMESTAMPS |
@@ -263,11 +338,9 @@ enum { show_color = 0 }; | |||
263 | #define exit_code (G.exit_code ) | 338 | #define exit_code (G.exit_code ) |
264 | #define all_fmt (G.all_fmt ) | 339 | #define all_fmt (G.all_fmt ) |
265 | #if ENABLE_FEATURE_AUTOWIDTH | 340 | #if ENABLE_FEATURE_AUTOWIDTH |
266 | # define tabstops (G.tabstops ) | ||
267 | # define terminal_width (G.terminal_width) | 341 | # define terminal_width (G.terminal_width) |
268 | #else | 342 | #else |
269 | enum { | 343 | enum { |
270 | tabstops = COLUMN_GAP, | ||
271 | terminal_width = TERMINAL_WIDTH, | 344 | terminal_width = TERMINAL_WIDTH, |
272 | }; | 345 | }; |
273 | #endif | 346 | #endif |
@@ -275,7 +348,6 @@ enum { | |||
275 | #define INIT_G() do { \ | 348 | #define INIT_G() do { \ |
276 | /* we have to zero it out because of NOEXEC */ \ | 349 | /* we have to zero it out because of NOEXEC */ \ |
277 | memset(&G, 0, sizeof(G)); \ | 350 | memset(&G, 0, sizeof(G)); \ |
278 | IF_FEATURE_AUTOWIDTH(tabstops = COLUMN_GAP;) \ | ||
279 | IF_FEATURE_AUTOWIDTH(terminal_width = TERMINAL_WIDTH;) \ | 351 | IF_FEATURE_AUTOWIDTH(terminal_width = TERMINAL_WIDTH;) \ |
280 | IF_FEATURE_LS_TIMESTAMPS(time(¤t_time_t);) \ | 352 | IF_FEATURE_LS_TIMESTAMPS(time(¤t_time_t);) \ |
281 | } while (0) | 353 | } while (0) |
@@ -287,7 +359,7 @@ static struct dnode *my_stat(const char *fullname, const char *name, int force_f | |||
287 | struct dnode *cur; | 359 | struct dnode *cur; |
288 | IF_SELINUX(security_context_t sid = NULL;) | 360 | IF_SELINUX(security_context_t sid = NULL;) |
289 | 361 | ||
290 | if ((all_fmt & FOLLOW_LINKS) || force_follow) { | 362 | if ((option_mask32 & OPT_L) || force_follow) { |
291 | #if ENABLE_SELINUX | 363 | #if ENABLE_SELINUX |
292 | if (is_selinux_enabled()) { | 364 | if (is_selinux_enabled()) { |
293 | getfilecon(fullname, &sid); | 365 | getfilecon(fullname, &sid); |
@@ -547,7 +619,7 @@ static unsigned calc_name_len(const char *name) | |||
547 | 619 | ||
548 | 620 | ||
549 | /* Return the number of used columns. | 621 | /* Return the number of used columns. |
550 | * Note that only STYLE_COLUMNS uses return value. | 622 | * Note that only STYLE_COLUMNAR uses return value. |
551 | * STYLE_SINGLE and STYLE_LONG don't care. | 623 | * STYLE_SINGLE and STYLE_LONG don't care. |
552 | * coreutils 7.2 also supports: | 624 | * coreutils 7.2 also supports: |
553 | * ls -b (--escape) = octal escapes (although it doesn't look like working) | 625 | * ls -b (--escape) = octal escapes (although it doesn't look like working) |
@@ -581,7 +653,7 @@ static unsigned print_name(const char *name) | |||
581 | } | 653 | } |
582 | 654 | ||
583 | /* Return the number of used columns. | 655 | /* Return the number of used columns. |
584 | * Note that only STYLE_COLUMNS uses return value, | 656 | * Note that only STYLE_COLUMNAR uses return value, |
585 | * STYLE_SINGLE and STYLE_LONG don't care. | 657 | * STYLE_SINGLE and STYLE_LONG don't care. |
586 | */ | 658 | */ |
587 | static NOINLINE unsigned list_single(const struct dnode *dn) | 659 | static NOINLINE unsigned list_single(const struct dnode *dn) |
@@ -625,7 +697,7 @@ static NOINLINE unsigned list_single(const struct dnode *dn) | |||
625 | if (all_fmt & LIST_ID_NAME) { | 697 | if (all_fmt & LIST_ID_NAME) { |
626 | if (option_mask32 & OPT_g) { | 698 | if (option_mask32 & OPT_g) { |
627 | column += printf("%-8.8s ", | 699 | column += printf("%-8.8s ", |
628 | get_cached_username(dn->dstat.st_uid)); | 700 | get_cached_groupname(dn->dstat.st_gid)); |
629 | } else { | 701 | } else { |
630 | column += printf("%-8.8s %-8.8s ", | 702 | column += printf("%-8.8s %-8.8s ", |
631 | get_cached_username(dn->dstat.st_uid), | 703 | get_cached_username(dn->dstat.st_uid), |
@@ -635,19 +707,19 @@ static NOINLINE unsigned list_single(const struct dnode *dn) | |||
635 | #endif | 707 | #endif |
636 | if (all_fmt & LIST_ID_NUMERIC) { | 708 | if (all_fmt & LIST_ID_NUMERIC) { |
637 | if (option_mask32 & OPT_g) | 709 | if (option_mask32 & OPT_g) |
638 | column += printf("%-8u ", (int) dn->dstat.st_uid); | 710 | column += printf("%-8u ", (int) dn->dstat.st_gid); |
639 | else | 711 | else |
640 | column += printf("%-8u %-8u ", | 712 | column += printf("%-8u %-8u ", |
641 | (int) dn->dstat.st_uid, | 713 | (int) dn->dstat.st_uid, |
642 | (int) dn->dstat.st_gid); | 714 | (int) dn->dstat.st_gid); |
643 | } | 715 | } |
644 | if (all_fmt & (LIST_SIZE /*|LIST_DEV*/ )) { | 716 | if (all_fmt & LIST_SIZE) { |
645 | if (S_ISBLK(dn->dstat.st_mode) || S_ISCHR(dn->dstat.st_mode)) { | 717 | if (S_ISBLK(dn->dstat.st_mode) || S_ISCHR(dn->dstat.st_mode)) { |
646 | column += printf("%4u, %3u ", | 718 | column += printf("%4u, %3u ", |
647 | (int) major(dn->dstat.st_rdev), | 719 | (int) major(dn->dstat.st_rdev), |
648 | (int) minor(dn->dstat.st_rdev)); | 720 | (int) minor(dn->dstat.st_rdev)); |
649 | } else { | 721 | } else { |
650 | if (all_fmt & LS_DISP_HR) { | 722 | if (option_mask32 & OPT_h) { |
651 | column += printf("%"HUMAN_READABLE_MAX_WIDTH_STR"s ", | 723 | column += printf("%"HUMAN_READABLE_MAX_WIDTH_STR"s ", |
652 | /* print st_size, show one fractional, use suffixes */ | 724 | /* print st_size, show one fractional, use suffixes */ |
653 | make_human_readable_str(dn->dstat.st_size, 1, 0) | 725 | make_human_readable_str(dn->dstat.st_size, 1, 0) |
@@ -689,20 +761,20 @@ static NOINLINE unsigned list_single(const struct dnode *dn) | |||
689 | freecon(dn->sid); | 761 | freecon(dn->sid); |
690 | } | 762 | } |
691 | #endif | 763 | #endif |
692 | if (all_fmt & LIST_FILENAME) { | 764 | |
693 | #if ENABLE_FEATURE_LS_COLOR | 765 | #if ENABLE_FEATURE_LS_COLOR |
694 | if (show_color) { | 766 | if (show_color) { |
695 | info.st_mode = 0; /* for fgcolor() */ | 767 | info.st_mode = 0; /* for fgcolor() */ |
696 | lstat(dn->fullname, &info); | 768 | lstat(dn->fullname, &info); |
697 | printf("\033[%u;%um", bold(info.st_mode), | 769 | printf("\033[%u;%um", bold(info.st_mode), |
698 | fgcolor(info.st_mode)); | 770 | fgcolor(info.st_mode)); |
699 | } | 771 | } |
700 | #endif | 772 | #endif |
701 | column += print_name(dn->name); | 773 | column += print_name(dn->name); |
702 | if (show_color) { | 774 | if (show_color) { |
703 | printf("\033[0m"); | 775 | printf("\033[0m"); |
704 | } | ||
705 | } | 776 | } |
777 | |||
706 | if (all_fmt & LIST_SYMLINK) { | 778 | if (all_fmt & LIST_SYMLINK) { |
707 | if (S_ISLNK(dn->dstat.st_mode) && lpath) { | 779 | if (S_ISLNK(dn->dstat.st_mode) && lpath) { |
708 | printf(" -> "); | 780 | printf(" -> "); |
@@ -742,9 +814,9 @@ static NOINLINE unsigned list_single(const struct dnode *dn) | |||
742 | static void showfiles(struct dnode **dn, unsigned nfiles) | 814 | static void showfiles(struct dnode **dn, unsigned nfiles) |
743 | { | 815 | { |
744 | unsigned i, ncols, nrows, row, nc; | 816 | unsigned i, ncols, nrows, row, nc; |
745 | unsigned column = 0; | 817 | unsigned column; |
746 | unsigned nexttab = 0; | 818 | unsigned nexttab; |
747 | unsigned column_width = 0; /* used only by STYLE_COLUMNS */ | 819 | unsigned column_width = 0; /* used only by STYLE_COLUMNAR */ |
748 | 820 | ||
749 | if (all_fmt & STYLE_LONG) { /* STYLE_LONG or STYLE_SINGLE */ | 821 | if (all_fmt & STYLE_LONG) { /* STYLE_LONG or STYLE_SINGLE */ |
750 | ncols = 1; | 822 | ncols = 1; |
@@ -755,7 +827,7 @@ static void showfiles(struct dnode **dn, unsigned nfiles) | |||
755 | if (column_width < len) | 827 | if (column_width < len) |
756 | column_width = len; | 828 | column_width = len; |
757 | } | 829 | } |
758 | column_width += tabstops + | 830 | column_width += 1 + |
759 | IF_SELINUX( ((all_fmt & LIST_CONTEXT) ? 33 : 0) + ) | 831 | IF_SELINUX( ((all_fmt & LIST_CONTEXT) ? 33 : 0) + ) |
760 | ((all_fmt & LIST_INO) ? 8 : 0) + | 832 | ((all_fmt & LIST_INO) ? 8 : 0) + |
761 | ((all_fmt & LIST_BLOCKS) ? 5 : 0); | 833 | ((all_fmt & LIST_BLOCKS) ? 5 : 0); |
@@ -771,6 +843,8 @@ static void showfiles(struct dnode **dn, unsigned nfiles) | |||
771 | ncols = 1; | 843 | ncols = 1; |
772 | } | 844 | } |
773 | 845 | ||
846 | column = 0; | ||
847 | nexttab = 0; | ||
774 | for (row = 0; row < nrows; row++) { | 848 | for (row = 0; row < nrows; row++) { |
775 | for (nc = 0; nc < ncols; nc++) { | 849 | for (nc = 0; nc < ncols; nc++) { |
776 | /* reach into the array based on the column and row */ | 850 | /* reach into the array based on the column and row */ |
@@ -781,8 +855,8 @@ static void showfiles(struct dnode **dn, unsigned nfiles) | |||
781 | if (i < nfiles) { | 855 | if (i < nfiles) { |
782 | if (column > 0) { | 856 | if (column > 0) { |
783 | nexttab -= column; | 857 | nexttab -= column; |
784 | printf("%*s", nexttab, ""); | 858 | printf("%*s ", nexttab, ""); |
785 | column += nexttab; | 859 | column += nexttab + 1; |
786 | } | 860 | } |
787 | nexttab = column + column_width; | 861 | nexttab = column + column_width; |
788 | column += list_single(dn[i]); | 862 | column += list_single(dn[i]); |
@@ -835,12 +909,6 @@ static void showdirs(struct dnode **dn, int first) | |||
835 | struct dnode **subdnp; | 909 | struct dnode **subdnp; |
836 | struct dnode **dnd; | 910 | struct dnode **dnd; |
837 | 911 | ||
838 | /* Never happens: | ||
839 | if (dn == NULL || ndirs < 1) { | ||
840 | return; | ||
841 | } | ||
842 | */ | ||
843 | |||
844 | for (; *dn; dn++) { | 912 | for (; *dn; dn++) { |
845 | if (all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) { | 913 | if (all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) { |
846 | if (!first) | 914 | if (!first) |
@@ -981,8 +1049,7 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
981 | 1049 | ||
982 | init_unicode(); | 1050 | init_unicode(); |
983 | 1051 | ||
984 | all_fmt = LIST_SHORT | | 1052 | all_fmt = ENABLE_FEATURE_LS_SORTFILES * SORT_NAME; |
985 | (ENABLE_FEATURE_LS_SORTFILES * (SORT_NAME | SORT_FORWARD)); | ||
986 | 1053 | ||
987 | #if ENABLE_FEATURE_AUTOWIDTH | 1054 | #if ENABLE_FEATURE_AUTOWIDTH |
988 | /* obtain the terminal width */ | 1055 | /* obtain the terminal width */ |
@@ -993,32 +1060,38 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
993 | 1060 | ||
994 | /* process options */ | 1061 | /* process options */ |
995 | IF_FEATURE_LS_COLOR(applet_long_options = ls_longopts;) | 1062 | IF_FEATURE_LS_COLOR(applet_long_options = ls_longopts;) |
996 | #if ENABLE_FEATURE_AUTOWIDTH | 1063 | opt_complementary = |
997 | opt_complementary = "T+:w+"; /* -T N, -w N */ | 1064 | /* -e implies -l */ |
998 | opt = getopt32(argv, ls_options, &tabstops, &terminal_width | 1065 | "el" |
999 | IF_FEATURE_LS_COLOR(, &color_opt)); | 1066 | /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html: |
1000 | #else | 1067 | * in some pairs of opts, only last one takes effect: |
1001 | opt = getopt32(argv, ls_options IF_FEATURE_LS_COLOR(, &color_opt)); | 1068 | */ |
1002 | #endif | 1069 | IF_FEATURE_LS_TIMESTAMPS(IF_FEATURE_LS_SORTFILES(":t-S:S-t")) /* time/size */ |
1003 | for (i = 0; opt_flags[i] != (1U<<31); i++) { | 1070 | // ":m-l:l-m" - we don't have -m |
1071 | IF_FEATURE_LS_FOLLOWLINKS(":H-L:L-H") | ||
1072 | ":C-xl:x-Cl:l-xC" /* bycols/bylines/long */ | ||
1073 | ":C-1:1-C" /* bycols/oneline */ | ||
1074 | ":x-1:1-x" /* bylines/oneline (not in SuS, but in GNU coreutils 8.4) */ | ||
1075 | ":c-u:u-c" /* mtime/atime */ | ||
1076 | /* -w NUM: */ | ||
1077 | IF_FEATURE_AUTOWIDTH(":w+"); | ||
1078 | opt = getopt32(argv, ls_options | ||
1079 | IF_FEATURE_AUTOWIDTH(, NULL, &terminal_width) | ||
1080 | IF_FEATURE_LS_COLOR(, &color_opt) | ||
1081 | ); | ||
1082 | for (i = 0; opt_flags[i] != (1U << 31); i++) { | ||
1004 | if (opt & (1 << i)) { | 1083 | if (opt & (1 << i)) { |
1005 | unsigned flags = opt_flags[i]; | 1084 | uint32_t flags = opt_flags[i]; |
1006 | 1085 | ||
1007 | if (flags & LIST_MASK_TRIGGER) | 1086 | if (flags & STYLE_MASK) |
1008 | all_fmt &= ~LIST_MASK; | ||
1009 | if (flags & STYLE_MASK_TRIGGER) | ||
1010 | all_fmt &= ~STYLE_MASK; | 1087 | all_fmt &= ~STYLE_MASK; |
1011 | if (flags & SORT_MASK_TRIGGER) | 1088 | if (flags & SORT_MASK) |
1012 | all_fmt &= ~SORT_MASK; | 1089 | all_fmt &= ~SORT_MASK; |
1013 | if (flags & DISP_MASK_TRIGGER) | ||
1014 | all_fmt &= ~DISP_MASK; | ||
1015 | if (flags & TIME_MASK) | 1090 | if (flags & TIME_MASK) |
1016 | all_fmt &= ~TIME_MASK; | 1091 | all_fmt &= ~TIME_MASK; |
1092 | |||
1017 | if (flags & LIST_CONTEXT) | 1093 | if (flags & LIST_CONTEXT) |
1018 | all_fmt |= STYLE_SINGLE; | 1094 | all_fmt |= STYLE_SINGLE; |
1019 | /* huh?? opt cannot be 'l' */ | ||
1020 | //if (LS_DISP_HR && opt == 'l') | ||
1021 | // all_fmt &= ~LS_DISP_HR; | ||
1022 | all_fmt |= flags; | 1095 | all_fmt |= flags; |
1023 | } | 1096 | } |
1024 | } | 1097 | } |
@@ -1058,14 +1131,14 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1058 | all_fmt = (all_fmt & ~SORT_MASK) | SORT_ATIME; | 1131 | all_fmt = (all_fmt & ~SORT_MASK) | SORT_ATIME; |
1059 | } | 1132 | } |
1060 | if ((all_fmt & STYLE_MASK) != STYLE_LONG) /* only for long list */ | 1133 | if ((all_fmt & STYLE_MASK) != STYLE_LONG) /* only for long list */ |
1061 | all_fmt &= ~(LIST_ID_NUMERIC|LIST_FULLTIME|LIST_ID_NAME|LIST_ID_NUMERIC); | 1134 | all_fmt &= ~(LIST_ID_NUMERIC|LIST_ID_NAME|LIST_FULLTIME); |
1062 | if (ENABLE_FEATURE_LS_USERNAME) | 1135 | if (ENABLE_FEATURE_LS_USERNAME) |
1063 | if ((all_fmt & STYLE_MASK) == STYLE_LONG && (all_fmt & LIST_ID_NUMERIC)) | 1136 | if ((all_fmt & STYLE_MASK) == STYLE_LONG && (all_fmt & LIST_ID_NUMERIC)) |
1064 | all_fmt &= ~LIST_ID_NAME; /* don't list names if numeric uid */ | 1137 | all_fmt &= ~LIST_ID_NAME; /* don't list names if numeric uid */ |
1065 | 1138 | ||
1066 | /* choose a display format */ | 1139 | /* choose a display format if one was not already specified by an option */ |
1067 | if (!(all_fmt & STYLE_MASK)) | 1140 | if (!(all_fmt & STYLE_MASK)) |
1068 | all_fmt |= (isatty(STDOUT_FILENO) ? STYLE_COLUMNS : STYLE_SINGLE); | 1141 | all_fmt |= (isatty(STDOUT_FILENO) ? STYLE_COLUMNAR : STYLE_SINGLE); |
1069 | 1142 | ||
1070 | argv += optind; | 1143 | argv += optind; |
1071 | if (!argv[0]) | 1144 | if (!argv[0]) |
@@ -1078,8 +1151,12 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1078 | dn = NULL; | 1151 | dn = NULL; |
1079 | nfiles = 0; | 1152 | nfiles = 0; |
1080 | do { | 1153 | do { |
1081 | /* NB: follow links on command line unless -l or -s */ | 1154 | cur = my_stat(*argv, *argv, |
1082 | cur = my_stat(*argv, *argv, !(all_fmt & (STYLE_LONG|LIST_BLOCKS))); | 1155 | /* follow links on command line unless -l, -s or -F: */ |
1156 | !((all_fmt & (STYLE_LONG|LIST_BLOCKS)) || (option_mask32 & OPT_F)) | ||
1157 | /* ... or if -H: */ | ||
1158 | || (option_mask32 & OPT_H) | ||
1159 | ); | ||
1083 | argv++; | 1160 | argv++; |
1084 | if (!cur) | 1161 | if (!cur) |
1085 | continue; | 1162 | continue; |
diff --git a/coreutils/mv.c b/coreutils/mv.c index 245639bd0..399f391b2 100644 --- a/coreutils/mv.c +++ b/coreutils/mv.c | |||
@@ -92,7 +92,7 @@ int mv_main(int argc, char **argv) | |||
92 | || (flags & OPT_FILEUTILS_INTERACTIVE)) | 92 | || (flags & OPT_FILEUTILS_INTERACTIVE)) |
93 | ) { | 93 | ) { |
94 | if (fprintf(stderr, "mv: overwrite '%s'? ", dest) < 0) { | 94 | if (fprintf(stderr, "mv: overwrite '%s'? ", dest) < 0) { |
95 | goto RET_1; /* Ouch! fprintf failed! */ | 95 | goto RET_1; /* Ouch! fprintf failed! */ |
96 | } | 96 | } |
97 | if (!bb_ask_confirmation()) { | 97 | if (!bb_ask_confirmation()) { |
98 | goto RET_0; | 98 | goto RET_0; |
diff --git a/coreutils/nice.c b/coreutils/nice.c index 6b8fce24d..35d6bf3d9 100644 --- a/coreutils/nice.c +++ b/coreutils/nice.c | |||
@@ -17,12 +17,12 @@ int nice_main(int argc, char **argv) | |||
17 | 17 | ||
18 | old_priority = getpriority(PRIO_PROCESS, 0); | 18 | old_priority = getpriority(PRIO_PROCESS, 0); |
19 | 19 | ||
20 | if (!*++argv) { /* No args, so (GNU) output current nice value. */ | 20 | if (!*++argv) { /* No args, so (GNU) output current nice value. */ |
21 | printf("%d\n", old_priority); | 21 | printf("%d\n", old_priority); |
22 | fflush_stdout_and_exit(EXIT_SUCCESS); | 22 | fflush_stdout_and_exit(EXIT_SUCCESS); |
23 | } | 23 | } |
24 | 24 | ||
25 | adjustment = 10; /* Set default adjustment. */ | 25 | adjustment = 10; /* Set default adjustment. */ |
26 | 26 | ||
27 | if (argv[0][0] == '-') { | 27 | if (argv[0][0] == '-') { |
28 | if (argv[0][1] == 'n') { /* -n */ | 28 | if (argv[0][1] == 'n') { /* -n */ |
@@ -32,7 +32,7 @@ int nice_main(int argc, char **argv) | |||
32 | } else { /* -NNN (NNN may be negative) == -n NNN */ | 32 | } else { /* -NNN (NNN may be negative) == -n NNN */ |
33 | argv[0] += 1; argv--; argc++; | 33 | argv[0] += 1; argv--; argc++; |
34 | } | 34 | } |
35 | if (argc < 4) { /* Missing priority and/or utility! */ | 35 | if (argc < 4) { /* Missing priority and/or utility! */ |
36 | bb_show_usage(); | 36 | bb_show_usage(); |
37 | } | 37 | } |
38 | adjustment = xatoi_range(argv[1], INT_MIN/2, INT_MAX/2); | 38 | adjustment = xatoi_range(argv[1], INT_MIN/2, INT_MAX/2); |
diff --git a/coreutils/od.c b/coreutils/od.c index dcd693446..e62711671 100644 --- a/coreutils/od.c +++ b/coreutils/od.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Based on code from util-linux v 2.11l | 4 | * Based on code from util-linux v 2.11l |
5 | * | 5 | * |
6 | * Copyright (c) 1990 | 6 | * Copyright (c) 1990 |
7 | * The Regents of the University of California. All rights reserved. | 7 | * The Regents of the University of California. All rights reserved. |
8 | * | 8 | * |
9 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | 9 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
10 | * | 10 | * |
@@ -174,7 +174,7 @@ int od_main(int argc, char **argv) | |||
174 | bb_dump_add(dumper, "\" \""); | 174 | bb_dump_add(dumper, "\" \""); |
175 | } | 175 | } |
176 | bb_dump_add(dumper, add_strings[(int)od_o2si[(p - od_opts)]]); | 176 | bb_dump_add(dumper, add_strings[(int)od_o2si[(p - od_opts)]]); |
177 | } else { /* P, p, s, w, or other unhandled */ | 177 | } else { /* P, p, s, w, or other unhandled */ |
178 | bb_show_usage(); | 178 | bb_show_usage(); |
179 | } | 179 | } |
180 | } | 180 | } |
diff --git a/coreutils/sort.c b/coreutils/sort.c index eccc2d437..3562464d1 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c | |||
@@ -52,8 +52,8 @@ enum { | |||
52 | static char key_separator; | 52 | static char key_separator; |
53 | 53 | ||
54 | static struct sort_key { | 54 | static struct sort_key { |
55 | struct sort_key *next_key; /* linked list */ | 55 | struct sort_key *next_key; /* linked list */ |
56 | unsigned range[4]; /* start word, start char, end word, end char */ | 56 | unsigned range[4]; /* start word, start char, end word, end char */ |
57 | unsigned flags; | 57 | unsigned flags; |
58 | } *key_list; | 58 | } *key_list; |
59 | 59 | ||
diff --git a/coreutils/stat.c b/coreutils/stat.c index b4e6f10fd..7351f5956 100644 --- a/coreutils/stat.c +++ b/coreutils/stat.c | |||
@@ -630,10 +630,9 @@ static bool do_stat(const char *filename, const char *format) | |||
630 | # if ENABLE_SELINUX | 630 | # if ENABLE_SELINUX |
631 | printf(" S_Context: %lc\n", *scontext); | 631 | printf(" S_Context: %lc\n", *scontext); |
632 | # endif | 632 | # endif |
633 | printf("Access: %s\n" "Modify: %s\n" "Change: %s\n", | 633 | printf("Access: %s\n", human_time(statbuf.st_atime)); |
634 | human_time(statbuf.st_atime), | 634 | printf("Modify: %s\n", human_time(statbuf.st_mtime)); |
635 | human_time(statbuf.st_mtime), | 635 | printf("Change: %s\n", human_time(statbuf.st_ctime)); |
636 | human_time(statbuf.st_ctime)); | ||
637 | } | 636 | } |
638 | #endif /* FEATURE_STAT_FORMAT */ | 637 | #endif /* FEATURE_STAT_FORMAT */ |
639 | return 1; | 638 | return 1; |
diff --git a/coreutils/test.c b/coreutils/test.c index 1952337b3..3e9ab7c65 100644 --- a/coreutils/test.c +++ b/coreutils/test.c | |||
@@ -49,9 +49,9 @@ | |||
49 | * state. */ | 49 | * state. */ |
50 | 50 | ||
51 | /* test(1) accepts the following grammar: | 51 | /* test(1) accepts the following grammar: |
52 | oexpr ::= aexpr | aexpr "-o" oexpr ; | 52 | oexpr ::= aexpr | aexpr "-o" oexpr ; |
53 | aexpr ::= nexpr | nexpr "-a" aexpr ; | 53 | aexpr ::= nexpr | nexpr "-a" aexpr ; |
54 | nexpr ::= primary | "!" primary | 54 | nexpr ::= primary | "!" primary |
55 | primary ::= unary-operator operand | 55 | primary ::= unary-operator operand |
56 | | operand binary-operator operand | 56 | | operand binary-operator operand |
57 | | operand | 57 | | operand |
@@ -901,7 +901,10 @@ int test_main(int argc, char **argv) | |||
901 | res = !oexpr(check_operator(*args)); | 901 | res = !oexpr(check_operator(*args)); |
902 | 902 | ||
903 | if (*args != NULL && *++args != NULL) { | 903 | if (*args != NULL && *++args != NULL) { |
904 | /* TODO: example when this happens? */ | 904 | /* Examples: |
905 | * test 3 -lt 5 6 | ||
906 | * test -t 1 2 | ||
907 | */ | ||
905 | bb_error_msg("%s: unknown operand", *args); | 908 | bb_error_msg("%s: unknown operand", *args); |
906 | res = 2; | 909 | res = 2; |
907 | } | 910 | } |
diff --git a/coreutils/touch.c b/coreutils/touch.c index afff36b4d..6c2b948e6 100644 --- a/coreutils/touch.c +++ b/coreutils/touch.c | |||
@@ -19,6 +19,35 @@ | |||
19 | 19 | ||
20 | #include "libbb.h" | 20 | #include "libbb.h" |
21 | 21 | ||
22 | //config:config TOUCH | ||
23 | //config: bool "touch" | ||
24 | //config: default y | ||
25 | //config: help | ||
26 | //config: touch is used to create or change the access and/or | ||
27 | //config: modification timestamp of specified files. | ||
28 | |||
29 | //applet:IF_TOUCH(APPLET_NOFORK(touch, touch, _BB_DIR_BIN, _BB_SUID_DROP, touch)) | ||
30 | |||
31 | //kbuild:lib-$(CONFIG_TOUCH) += touch.o | ||
32 | |||
33 | //usage:#define touch_trivial_usage | ||
34 | //usage: "[-c]" IF_DESKTOP(" [-d DATE] [-r FILE]") " FILE [FILE]..." | ||
35 | //usage:#define touch_full_usage "\n\n" | ||
36 | //usage: "Update the last-modified date on the given FILE[s]\n" | ||
37 | //usage: "\nOptions:" | ||
38 | //usage: "\n -c Don't create files" | ||
39 | //usage: IF_DESKTOP( | ||
40 | //usage: "\n -d DT Date/time to use" | ||
41 | //usage: "\n -r FILE Use FILE's date/time" | ||
42 | //usage: ) | ||
43 | //usage: | ||
44 | //usage:#define touch_example_usage | ||
45 | //usage: "$ ls -l /tmp/foo\n" | ||
46 | //usage: "/bin/ls: /tmp/foo: No such file or directory\n" | ||
47 | //usage: "$ touch /tmp/foo\n" | ||
48 | //usage: "$ ls -l /tmp/foo\n" | ||
49 | //usage: "-rw-rw-r-- 1 andersen andersen 0 Apr 15 01:11 /tmp/foo\n" | ||
50 | |||
22 | /* This is a NOFORK applet. Be very careful! */ | 51 | /* This is a NOFORK applet. Be very careful! */ |
23 | 52 | ||
24 | /* coreutils implements: | 53 | /* coreutils implements: |
@@ -91,9 +120,10 @@ int touch_main(int argc UNUSED_PARAM, char **argv) | |||
91 | struct tm tm_time; | 120 | struct tm tm_time; |
92 | time_t t; | 121 | time_t t; |
93 | 122 | ||
94 | //time(&t); | 123 | //memset(&tm_time, 0, sizeof(tm_time)); |
95 | //localtime_r(&t, &tm_time); | 124 | /* Better than memset: makes "HH:MM" dates meaningful */ |
96 | memset(&tm_time, 0, sizeof(tm_time)); | 125 | time(&t); |
126 | localtime_r(&t, &tm_time); | ||
97 | parse_datestr(date_str, &tm_time); | 127 | parse_datestr(date_str, &tm_time); |
98 | 128 | ||
99 | /* Correct any day of week and day of year etc. fields */ | 129 | /* Correct any day of week and day of year etc. fields */ |
diff --git a/coreutils/tr.c b/coreutils/tr.c index d6bc7d20a..21d77ef95 100644 --- a/coreutils/tr.c +++ b/coreutils/tr.c | |||
@@ -203,7 +203,7 @@ static unsigned expand(const char *arg, char **buffer_p) | |||
203 | buffer[pos++] = *arg; /* copy CHAR */ | 203 | buffer[pos++] = *arg; /* copy CHAR */ |
204 | if (!arg[0] || arg[1] != '=' || arg[2] != ']') | 204 | if (!arg[0] || arg[1] != '=' || arg[2] != ']') |
205 | bb_show_usage(); | 205 | bb_show_usage(); |
206 | arg += 3; /* skip CHAR=] */ | 206 | arg += 3; /* skip CHAR=] */ |
207 | continue; | 207 | continue; |
208 | } | 208 | } |
209 | /* The rest of "[xyz..." cases is treated as normal | 209 | /* The rest of "[xyz..." cases is treated as normal |
@@ -258,9 +258,9 @@ int tr_main(int argc UNUSED_PARAM, char **argv) | |||
258 | char *invec = vector + ASCII; | 258 | char *invec = vector + ASCII; |
259 | char *outvec = vector + ASCII * 2; | 259 | char *outvec = vector + ASCII * 2; |
260 | 260 | ||
261 | #define TR_OPT_complement (3 << 0) | 261 | #define TR_OPT_complement (3 << 0) |
262 | #define TR_OPT_delete (1 << 2) | 262 | #define TR_OPT_delete (1 << 2) |
263 | #define TR_OPT_squeeze_reps (1 << 3) | 263 | #define TR_OPT_squeeze_reps (1 << 3) |
264 | 264 | ||
265 | for (i = 0; i < ASCII; i++) { | 265 | for (i = 0; i < ASCII; i++) { |
266 | vector[i] = i; | 266 | vector[i] = i; |
diff --git a/coreutils/wc.c b/coreutils/wc.c index ecadae59b..fe3f274f8 100644 --- a/coreutils/wc.c +++ b/coreutils/wc.c | |||
@@ -153,7 +153,7 @@ int wc_main(int argc UNUSED_PARAM, char **argv) | |||
153 | bb_simple_perror_msg(arg); | 153 | bb_simple_perror_msg(arg); |
154 | status = EXIT_FAILURE; | 154 | status = EXIT_FAILURE; |
155 | } | 155 | } |
156 | goto DO_EOF; /* Treat an EOF as '\r'. */ | 156 | goto DO_EOF; /* Treat an EOF as '\r'. */ |
157 | } | 157 | } |
158 | 158 | ||
159 | /* Cater for -c and -m */ | 159 | /* Cater for -c and -m */ |
@@ -179,7 +179,7 @@ int wc_main(int argc UNUSED_PARAM, char **argv) | |||
179 | */ | 179 | */ |
180 | if (c == '\t') { | 180 | if (c == '\t') { |
181 | linepos = (linepos | 7) + 1; | 181 | linepos = (linepos | 7) + 1; |
182 | } else { /* '\n', '\r', '\f', or '\v' */ | 182 | } else { /* '\n', '\r', '\f', or '\v' */ |
183 | DO_EOF: | 183 | DO_EOF: |
184 | if (linepos > counts[WC_LENGTH]) { | 184 | if (linepos > counts[WC_LENGTH]) { |
185 | counts[WC_LENGTH] = linepos; | 185 | counts[WC_LENGTH] = linepos; |
@@ -230,7 +230,7 @@ int wc_main(int argc UNUSED_PARAM, char **argv) | |||
230 | * effect of trashing the totals array after outputting it, but that's | 230 | * effect of trashing the totals array after outputting it, but that's |
231 | * irrelavent since we no longer need it. */ | 231 | * irrelavent since we no longer need it. */ |
232 | if (num_files > 1) { | 232 | if (num_files > 1) { |
233 | num_files = 0; /* Make sure we don't get here again. */ | 233 | num_files = 0; /* Make sure we don't get here again. */ |
234 | arg = "total"; | 234 | arg = "total"; |
235 | pcounts = totals; | 235 | pcounts = totals; |
236 | --argv; | 236 | --argv; |