aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2011-01-04 19:40:30 +0700
committerNguyễn Thái Ngọc Duy <pclouds@gmail.com>2011-01-04 19:40:30 +0700
commit3b5c308768d76298bb964814ecc34de47bcac0b4 (patch)
tree795340e9d8f5e5bf9e8d895641099af343eec2a0 /coreutils
parent2b9a0e715ec459198f486653023d963b79291da7 (diff)
parent5fe2f863b9cee5ab0e7ac873538bce48846dbad8 (diff)
downloadbusybox-w32-3b5c308768d76298bb964814ecc34de47bcac0b4.tar.gz
busybox-w32-3b5c308768d76298bb964814ecc34de47bcac0b4.tar.bz2
busybox-w32-3b5c308768d76298bb964814ecc34de47bcac0b4.zip
Merge commit '06f719fd79fe15ce6fd5431bc58fcb22851de24d^'
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/cksum.c2
-rw-r--r--coreutils/date.c106
-rw-r--r--coreutils/dos2unix.c2
-rw-r--r--coreutils/fold.c2
-rw-r--r--coreutils/head.c2
-rw-r--r--coreutils/id.c2
-rw-r--r--coreutils/md5_sha1_sum.c8
-rw-r--r--coreutils/mkfifo.c2
-rw-r--r--coreutils/mknod.c2
-rw-r--r--coreutils/printenv.c2
-rw-r--r--coreutils/seq.c3
-rw-r--r--coreutils/sleep.c21
-rw-r--r--coreutils/sort.c2
-rw-r--r--coreutils/tee.c2
-rw-r--r--coreutils/uniq.c4
-rw-r--r--coreutils/uudecode.c73
-rw-r--r--coreutils/wc.c79
17 files changed, 174 insertions, 140 deletions
diff --git a/coreutils/cksum.c b/coreutils/cksum.c
index 8e7800ee9..7bf383e2d 100644
--- a/coreutils/cksum.c
+++ b/coreutils/cksum.c
@@ -8,6 +8,8 @@
8 */ 8 */
9#include "libbb.h" 9#include "libbb.h"
10 10
11/* This is a NOEXEC applet. Be very careful! */
12
11int cksum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 13int cksum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
12int cksum_main(int argc UNUSED_PARAM, char **argv) 14int cksum_main(int argc UNUSED_PARAM, char **argv)
13{ 15{
diff --git a/coreutils/date.c b/coreutils/date.c
index 881dcc429..eed4714f9 100644
--- a/coreutils/date.c
+++ b/coreutils/date.c
@@ -19,38 +19,7 @@
19/* Input parsing code is always bulky - used heavy duty libc stuff as 19/* Input parsing code is always bulky - used heavy duty libc stuff as
20 much as possible, missed out a lot of bounds checking */ 20 much as possible, missed out a lot of bounds checking */
21 21
22/* Default input handling to save surprising some people */ 22//applet:IF_DATE(APPLET(date, _BB_DIR_BIN, _BB_SUID_DROP))
23
24/* GNU coreutils 6.9 man page:
25 * date [OPTION]... [+FORMAT]
26 * date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
27 * -d, --date=STRING
28 * display time described by STRING, not `now'
29 * -f, --file=DATEFILE
30 * like --date once for each line of DATEFILE
31 * -r, --reference=FILE
32 * display the last modification time of FILE
33 * -R, --rfc-2822
34 * output date and time in RFC 2822 format.
35 * Example: Mon, 07 Aug 2006 12:34:56 -0600
36 * --rfc-3339=TIMESPEC
37 * output date and time in RFC 3339 format.
38 * TIMESPEC='date', 'seconds', or 'ns'
39 * Date and time components are separated by a single space:
40 * 2006-08-07 12:34:56-06:00
41 * -s, --set=STRING
42 * set time described by STRING
43 * -u, --utc, --universal
44 * print or set Coordinated Universal Time
45 *
46 * Busybox:
47 * long options are not supported
48 * -f is not supported
49 * -I seems to roughly match --rfc-3339, but -I has _optional_ param
50 * (thus "-I seconds" doesn't work, only "-Iseconds"),
51 * and does not support -Ins
52 * -D FMT is a bbox extension for _input_ conversion of -d DATE
53 */
54 23
55//kbuild:lib-$(CONFIG_DATE) += date.o 24//kbuild:lib-$(CONFIG_DATE) += date.o
56 25
@@ -69,6 +38,7 @@
69//config: Enable option (-I) to output an ISO-8601 compliant 38//config: Enable option (-I) to output an ISO-8601 compliant
70//config: date/time string. 39//config: date/time string.
71//config: 40//config:
41//config:# defaults to "no": stat's nanosecond field is a bit non-portable
72//config:config FEATURE_DATE_NANO 42//config:config FEATURE_DATE_NANO
73//config: bool "Support %[num]N nanosecond format specifier" 43//config: bool "Support %[num]N nanosecond format specifier"
74//config: default n 44//config: default n
@@ -92,6 +62,78 @@
92//config: the same format. With it on, 'date DATE' additionally supports 62//config: the same format. With it on, 'date DATE' additionally supports
93//config: MMDDhhmm[[YY]YY][.ss] format. 63//config: MMDDhhmm[[YY]YY][.ss] format.
94 64
65/* GNU coreutils 6.9 man page:
66 * date [OPTION]... [+FORMAT]
67 * date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
68 * -d, --date=STRING
69 * display time described by STRING, not `now'
70 * -f, --file=DATEFILE
71 * like --date once for each line of DATEFILE
72 * -r, --reference=FILE
73 * display the last modification time of FILE
74 * -R, --rfc-2822
75 * output date and time in RFC 2822 format.
76 * Example: Mon, 07 Aug 2006 12:34:56 -0600
77 * --rfc-3339=TIMESPEC
78 * output date and time in RFC 3339 format.
79 * TIMESPEC='date', 'seconds', or 'ns'
80 * Date and time components are separated by a single space:
81 * 2006-08-07 12:34:56-06:00
82 * -s, --set=STRING
83 * set time described by STRING
84 * -u, --utc, --universal
85 * print or set Coordinated Universal Time
86 *
87 * Busybox:
88 * long options are not supported
89 * -f is not supported
90 * -I seems to roughly match --rfc-3339, but -I has _optional_ param
91 * (thus "-I seconds" doesn't work, only "-Iseconds"),
92 * and does not support -Ins
93 * -D FMT is a bbox extension for _input_ conversion of -d DATE
94 */
95
96//usage:#define date_trivial_usage
97//usage: "[OPTIONS] [+FMT] [TIME]"
98//usage:#define date_full_usage "\n\n"
99//usage: "Display time (using +FMT), or set time\n"
100//usage: "\nOptions:"
101//usage: IF_NOT_LONG_OPTS(
102//usage: "\n [-s] TIME Set time to TIME"
103//usage: "\n -u Work in UTC (don't convert to local time)"
104//usage: "\n -R Output RFC-2822 compliant date string"
105//usage: ) IF_LONG_OPTS(
106//usage: "\n [-s,--set] TIME Set time to TIME"
107//usage: "\n -u,--utc Work in UTC (don't convert to local time)"
108//usage: "\n -R,--rfc-2822 Output RFC-2822 compliant date string"
109//usage: )
110//usage: IF_FEATURE_DATE_ISOFMT(
111//usage: "\n -I[SPEC] Output ISO-8601 compliant date string"
112//usage: "\n SPEC='date' (default) for date only,"
113//usage: "\n 'hours', 'minutes', or 'seconds' for date and"
114//usage: "\n time to the indicated precision"
115//usage: )
116//usage: IF_NOT_LONG_OPTS(
117//usage: "\n -r FILE Display last modification time of FILE"
118//usage: "\n -d TIME Display TIME, not 'now'"
119//usage: ) IF_LONG_OPTS(
120//usage: "\n -r,--reference FILE Display last modification time of FILE"
121//usage: "\n -d,--date TIME Display TIME, not 'now'"
122//usage: )
123//usage: IF_FEATURE_DATE_ISOFMT(
124//usage: "\n -D FMT Use FMT for -d TIME conversion"
125//usage: )
126//usage: "\n"
127//usage: "\nRecognized TIME formats:"
128//usage: "\n hh:mm[:ss]"
129//usage: "\n [YYYY.]MM.DD-hh:mm[:ss]"
130//usage: "\n YYYY-MM-DD hh:mm[:ss]"
131//usage: "\n [[[[[YY]YY]MM]DD]hh]mm[.ss]"
132//usage:
133//usage:#define date_example_usage
134//usage: "$ date\n"
135//usage: "Wed Apr 12 18:52:41 MDT 2000\n"
136
95#include "libbb.h" 137#include "libbb.h"
96#if ENABLE_FEATURE_DATE_NANO 138#if ENABLE_FEATURE_DATE_NANO
97# include <sys/syscall.h> 139# include <sys/syscall.h>
diff --git a/coreutils/dos2unix.c b/coreutils/dos2unix.c
index ef1ea4328..8aa1d93b5 100644
--- a/coreutils/dos2unix.c
+++ b/coreutils/dos2unix.c
@@ -14,6 +14,8 @@
14 14
15#include "libbb.h" 15#include "libbb.h"
16 16
17/* This is a NOEXEC applet. Be very careful! */
18
17enum { 19enum {
18 CT_UNIX2DOS = 1, 20 CT_UNIX2DOS = 1,
19 CT_DOS2UNIX 21 CT_DOS2UNIX
diff --git a/coreutils/fold.c b/coreutils/fold.c
index 54f1aa2ac..4a6429ad7 100644
--- a/coreutils/fold.c
+++ b/coreutils/fold.c
@@ -12,6 +12,8 @@
12#include "libbb.h" 12#include "libbb.h"
13#include "unicode.h" 13#include "unicode.h"
14 14
15/* This is a NOEXEC applet. Be very careful! */
16
15/* Must match getopt32 call */ 17/* Must match getopt32 call */
16#define FLAG_COUNT_BYTES 1 18#define FLAG_COUNT_BYTES 1
17#define FLAG_BREAK_SPACES 2 19#define FLAG_BREAK_SPACES 2
diff --git a/coreutils/head.c b/coreutils/head.c
index 0845b4375..669aae819 100644
--- a/coreutils/head.c
+++ b/coreutils/head.c
@@ -13,6 +13,8 @@
13 13
14#include "libbb.h" 14#include "libbb.h"
15 15
16/* This is a NOEXEC applet. Be very careful! */
17
16static const char head_opts[] ALIGN1 = 18static const char head_opts[] ALIGN1 =
17 "n:" 19 "n:"
18#if ENABLE_FEATURE_FANCY_HEAD 20#if ENABLE_FEATURE_FANCY_HEAD
diff --git a/coreutils/id.c b/coreutils/id.c
index 56286f4d4..ed1dc862e 100644
--- a/coreutils/id.c
+++ b/coreutils/id.c
@@ -17,6 +17,8 @@
17 17
18#include "libbb.h" 18#include "libbb.h"
19 19
20/* This is a NOEXEC applet. Be very careful! */
21
20#if !ENABLE_USE_BB_PWD_GRP 22#if !ENABLE_USE_BB_PWD_GRP
21#if defined(__UCLIBC_MAJOR__) && (__UCLIBC_MAJOR__ == 0) 23#if defined(__UCLIBC_MAJOR__) && (__UCLIBC_MAJOR__ == 0)
22#if (__UCLIBC_MINOR__ < 9) || (__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ < 30) 24#if (__UCLIBC_MINOR__ < 9) || (__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ < 30)
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c
index 646f8bd10..e79210c0d 100644
--- a/coreutils/md5_sha1_sum.c
+++ b/coreutils/md5_sha1_sum.c
@@ -8,6 +8,8 @@
8 8
9#include "libbb.h" 9#include "libbb.h"
10 10
11/* This is a NOEXEC applet. Be very careful! */
12
11typedef enum { 13typedef enum {
12 /* 4th letter of applet_name is... */ 14 /* 4th letter of applet_name is... */
13 HASH_MD5 = 's', /* "md5>s<um" */ 15 HASH_MD5 = 's', /* "md5>s<um" */
@@ -41,7 +43,7 @@ static uint8_t *hash_file(const char *filename /*, hash_algo_t hash_algo*/)
41 } context; 43 } context;
42 uint8_t *hash_value = NULL; 44 uint8_t *hash_value = NULL;
43 RESERVE_CONFIG_UBUFFER(in_buf, 4096); 45 RESERVE_CONFIG_UBUFFER(in_buf, 4096);
44 void FAST_FUNC (*update)(const void*, size_t, void*); 46 void FAST_FUNC (*update)(void*, const void*, size_t);
45 void FAST_FUNC (*final)(void*, void*); 47 void FAST_FUNC (*final)(void*, void*);
46 hash_algo_t hash_algo = applet_name[3]; 48 hash_algo_t hash_algo = applet_name[3];
47 49
@@ -76,11 +78,11 @@ static uint8_t *hash_file(const char *filename /*, hash_algo_t hash_algo*/)
76 } 78 }
77 79
78 while (0 < (count = safe_read(src_fd, in_buf, 4096))) { 80 while (0 < (count = safe_read(src_fd, in_buf, 4096))) {
79 update(in_buf, count, &context); 81 update(&context, in_buf, count);
80 } 82 }
81 83
82 if (count == 0) { 84 if (count == 0) {
83 final(in_buf, &context); 85 final(&context, in_buf);
84 hash_value = hash_bin_to_hex(in_buf, hash_len); 86 hash_value = hash_bin_to_hex(in_buf, hash_len);
85 } 87 }
86 88
diff --git a/coreutils/mkfifo.c b/coreutils/mkfifo.c
index 41aedd099..4388ccaa3 100644
--- a/coreutils/mkfifo.c
+++ b/coreutils/mkfifo.c
@@ -13,6 +13,8 @@
13#include "libbb.h" 13#include "libbb.h"
14#include "libcoreutils/coreutils.h" 14#include "libcoreutils/coreutils.h"
15 15
16/* This is a NOEXEC applet. Be very careful! */
17
16int mkfifo_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 18int mkfifo_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
17int mkfifo_main(int argc UNUSED_PARAM, char **argv) 19int mkfifo_main(int argc UNUSED_PARAM, char **argv)
18{ 20{
diff --git a/coreutils/mknod.c b/coreutils/mknod.c
index 0e5542dde..14d91b5df 100644
--- a/coreutils/mknod.c
+++ b/coreutils/mknod.c
@@ -14,6 +14,8 @@
14#include "libbb.h" 14#include "libbb.h"
15#include "libcoreutils/coreutils.h" 15#include "libcoreutils/coreutils.h"
16 16
17/* This is a NOEXEC applet. Be very careful! */
18
17static const char modes_chars[] ALIGN1 = { 'p', 'c', 'u', 'b', 0, 1, 1, 2 }; 19static const char modes_chars[] ALIGN1 = { 'p', 'c', 'u', 'b', 0, 1, 1, 2 };
18static const mode_t modes_cubp[] = { S_IFIFO, S_IFCHR, S_IFBLK }; 20static const mode_t modes_cubp[] = { S_IFIFO, S_IFCHR, S_IFBLK };
19 21
diff --git a/coreutils/printenv.c b/coreutils/printenv.c
index d38f8fb5f..33be5c096 100644
--- a/coreutils/printenv.c
+++ b/coreutils/printenv.c
@@ -10,6 +10,8 @@
10 10
11#include "libbb.h" 11#include "libbb.h"
12 12
13/* This is a NOFORK applet. Be very careful! */
14
13int printenv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 15int printenv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
14int printenv_main(int argc UNUSED_PARAM, char **argv) 16int printenv_main(int argc UNUSED_PARAM, char **argv)
15{ 17{
diff --git a/coreutils/seq.c b/coreutils/seq.c
index 8be25360f..22bf3ec9d 100644
--- a/coreutils/seq.c
+++ b/coreutils/seq.c
@@ -86,7 +86,8 @@ int seq_main(int argc, char **argv)
86 v = first; 86 v = first;
87 n = 0; 87 n = 0;
88 while (increment >= 0 ? v <= last : v >= last) { 88 while (increment >= 0 ? v <= last : v >= last) {
89 printf("%s%0*.*f", sep, width, frac_part, v); 89 if (printf("%s%0*.*f", sep, width, frac_part, v) < 0)
90 break; /* I/O error, bail out (yes, this really happens) */
90 sep = opt_s; 91 sep = opt_s;
91 /* v += increment; - would accumulate floating point errors */ 92 /* v += increment; - would accumulate floating point errors */
92 n++; 93 n++;
diff --git a/coreutils/sleep.c b/coreutils/sleep.c
index b983df47e..433f9d6ee 100644
--- a/coreutils/sleep.c
+++ b/coreutils/sleep.c
@@ -20,7 +20,7 @@
20 20
21#include "libbb.h" 21#include "libbb.h"
22 22
23/* This is a NOFORK applet. Be very careful! */ 23/* Do not make this applet NOFORK. It breaks ^C-ing of pauses in shells */
24 24
25 25
26#if ENABLE_FEATURE_FANCY_SLEEP || ENABLE_FEATURE_FLOAT_SLEEP 26#if ENABLE_FEATURE_FANCY_SLEEP || ENABLE_FEATURE_FLOAT_SLEEP
@@ -49,6 +49,10 @@ int sleep_main(int argc UNUSED_PARAM, char **argv)
49 49
50#if ENABLE_FEATURE_FLOAT_SLEEP 50#if ENABLE_FEATURE_FLOAT_SLEEP
51 51
52# if ENABLE_LOCALE_SUPPORT
53 /* undo busybox.c setlocale */
54 setlocale(LC_NUMERIC, "C");
55# endif
52 duration = 0; 56 duration = 0;
53 do { 57 do {
54 char *arg = *argv; 58 char *arg = *argv;
@@ -62,14 +66,15 @@ int sleep_main(int argc UNUSED_PARAM, char **argv)
62 d = strtod(arg, &pp); 66 d = strtod(arg, &pp);
63 if (errno || *pp) 67 if (errno || *pp)
64 bb_show_usage(); 68 bb_show_usage();
65 arg[len] = sv; 69 arg += len;
66 len--; 70 *arg-- = sv;
67 sv = arg[len]; 71 sv = *arg;
68 arg[len] = '1'; 72 *arg = '1';
69 duration += d * xatoul_sfx(&arg[len], sfx); 73 duration += d * xatoul_sfx(arg, sfx);
70 arg[len] = sv; 74 *arg = sv;
71 } else 75 } else {
72 duration += xatoul_sfx(arg, sfx); 76 duration += xatoul_sfx(arg, sfx);
77 }
73 } while (*++argv); 78 } while (*++argv);
74 79
75 ts.tv_sec = MAXINT(typeof(ts.tv_sec)); 80 ts.tv_sec = MAXINT(typeof(ts.tv_sec));
diff --git a/coreutils/sort.c b/coreutils/sort.c
index 4407b7105..eccc2d437 100644
--- a/coreutils/sort.c
+++ b/coreutils/sort.c
@@ -412,7 +412,7 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
412#if ENABLE_FEATURE_SORT_BIG 412#if ENABLE_FEATURE_SORT_BIG
413 /* Open output file _after_ we read all input ones */ 413 /* Open output file _after_ we read all input ones */
414 if (option_mask32 & FLAG_o) 414 if (option_mask32 & FLAG_o)
415 xmove_fd(xopen3(str_o, O_WRONLY, 0666), STDOUT_FILENO); 415 xmove_fd(xopen(str_o, O_WRONLY|O_CREAT|O_TRUNC), STDOUT_FILENO);
416#endif 416#endif
417 flag = (option_mask32 & FLAG_z) ? '\0' : '\n'; 417 flag = (option_mask32 & FLAG_z) ? '\0' : '\n';
418 for (i = 0; i < linecount; i++) 418 for (i = 0; i < linecount; i++)
diff --git a/coreutils/tee.c b/coreutils/tee.c
index 2e1e367f2..e66e885ec 100644
--- a/coreutils/tee.c
+++ b/coreutils/tee.c
@@ -42,7 +42,7 @@ int tee_main(int argc, char **argv)
42 * that doesn't consume all its input. Good idea... */ 42 * that doesn't consume all its input. Good idea... */
43 signal(SIGPIPE, SIG_IGN); 43 signal(SIGPIPE, SIG_IGN);
44 44
45 /* Allocate an array of FILE *'s, with one extra for a sentinal. */ 45 /* Allocate an array of FILE *'s, with one extra for a sentinel. */
46 fp = files = xzalloc(sizeof(FILE *) * (argc + 2)); 46 fp = files = xzalloc(sizeof(FILE *) * (argc + 2));
47 np = names = argv - 1; 47 np = names = argv - 1;
48 48
diff --git a/coreutils/uniq.c b/coreutils/uniq.c
index f0364b9a1..358de7894 100644
--- a/coreutils/uniq.c
+++ b/coreutils/uniq.c
@@ -52,8 +52,8 @@ int uniq_main(int argc UNUSED_PARAM, char **argv)
52 if (output[0] != '-' || output[1]) { 52 if (output[0] != '-' || output[1]) {
53 // Won't work with "uniq - FILE" and closed stdin: 53 // Won't work with "uniq - FILE" and closed stdin:
54 //close(STDOUT_FILENO); 54 //close(STDOUT_FILENO);
55 //xopen3(output, O_WRONLY | O_CREAT | O_TRUNC, 0666); 55 //xopen(output, O_WRONLY | O_CREAT | O_TRUNC);
56 xmove_fd(xopen3(output, O_WRONLY | O_CREAT | O_TRUNC, 0666), STDOUT_FILENO); 56 xmove_fd(xopen(output, O_WRONLY | O_CREAT | O_TRUNC), STDOUT_FILENO);
57 } 57 }
58 } 58 }
59 } 59 }
diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c
index 0da9b0988..0c4311f24 100644
--- a/coreutils/uudecode.c
+++ b/coreutils/uudecode.c
@@ -13,7 +13,7 @@
13#include "libbb.h" 13#include "libbb.h"
14 14
15#if ENABLE_UUDECODE 15#if ENABLE_UUDECODE
16static void read_stduu(FILE *src_stream, FILE *dst_stream) 16static void FAST_FUNC read_stduu(FILE *src_stream, FILE *dst_stream, int flags UNUSED_PARAM)
17{ 17{
18 char *line; 18 char *line;
19 19
@@ -75,71 +75,6 @@ static void read_stduu(FILE *src_stream, FILE *dst_stream)
75} 75}
76#endif 76#endif
77 77
78static void read_base64(FILE *src_stream, FILE *dst_stream)
79{
80 int term_count = 0;
81
82 while (1) {
83 unsigned char translated[4];
84 int count = 0;
85
86 /* Process one group of 4 chars */
87 while (count < 4) {
88 char *table_ptr;
89 int ch;
90
91 /* Get next _valid_ character.
92 * bb_uuenc_tbl_base64[] contains this string:
93 * 0 1 2 3 4 5 6
94 * 012345678901234567890123456789012345678901234567890123456789012345
95 * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n"
96 */
97 do {
98 ch = fgetc(src_stream);
99 if (ch == EOF) {
100 if (ENABLE_BASE64
101 && (!ENABLE_UUDECODE || applet_name[0] == 'b')
102 && count == 0
103 ) {
104 return;
105 }
106 bb_error_msg_and_die("short file");
107 }
108 table_ptr = strchr(bb_uuenc_tbl_base64, ch);
109 } while (!table_ptr);
110
111 /* Convert encoded character to decimal */
112 ch = table_ptr - bb_uuenc_tbl_base64;
113
114 if (ch == 65 /* '\n' */) {
115 /* Terminating "====" line? */
116 if (term_count == 4)
117 return; /* yes */
118 term_count = 0;
119 continue;
120 }
121 /* ch is 64 is char was '=', otherwise 0..63 */
122 translated[count] = ch & 63; /* 64 -> 0 */
123 if (ch == 64) {
124 term_count++;
125 break;
126 }
127 count++;
128 }
129
130 /* Merge 6 bit chars to 8 bit.
131 * count can be < 4 when we decode the tail:
132 * "eQ==" -> "y", not "y NUL NUL"
133 */
134 if (count > 1)
135 fputc(translated[0] << 2 | translated[1] >> 4, dst_stream);
136 if (count > 2)
137 fputc(translated[1] << 4 | translated[2] >> 2, dst_stream);
138 if (count > 3)
139 fputc(translated[2] << 6 | translated[3], dst_stream);
140 } /* while (1) */
141}
142
143#if ENABLE_UUDECODE 78#if ENABLE_UUDECODE
144int uudecode_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 79int uudecode_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
145int uudecode_main(int argc UNUSED_PARAM, char **argv) 80int uudecode_main(int argc UNUSED_PARAM, char **argv)
@@ -158,7 +93,7 @@ int uudecode_main(int argc UNUSED_PARAM, char **argv)
158 93
159 /* Search for the start of the encoding */ 94 /* Search for the start of the encoding */
160 while ((line = xmalloc_fgetline(src_stream)) != NULL) { 95 while ((line = xmalloc_fgetline(src_stream)) != NULL) {
161 void (*decode_fn_ptr)(FILE *src, FILE *dst); 96 void FAST_FUNC (*decode_fn_ptr)(FILE *src, FILE *dst, int flags);
162 char *line_ptr; 97 char *line_ptr;
163 FILE *dst_stream; 98 FILE *dst_stream;
164 int mode; 99 int mode;
@@ -189,7 +124,7 @@ int uudecode_main(int argc UNUSED_PARAM, char **argv)
189 fchmod(fileno(dst_stream), mode & (S_IRWXU | S_IRWXG | S_IRWXO)); 124 fchmod(fileno(dst_stream), mode & (S_IRWXU | S_IRWXG | S_IRWXO));
190 } 125 }
191 free(line); 126 free(line);
192 decode_fn_ptr(src_stream, dst_stream); 127 decode_fn_ptr(src_stream, dst_stream, /*flags:*/ BASE64_FLAG_UU_STOP + BASE64_FLAG_NO_STOP_CHAR);
193 /* fclose_if_not_stdin(src_stream); - redundant */ 128 /* fclose_if_not_stdin(src_stream); - redundant */
194 return EXIT_SUCCESS; 129 return EXIT_SUCCESS;
195 } 130 }
@@ -231,7 +166,7 @@ int base64_main(int argc UNUSED_PARAM, char **argv)
231 *--argv = (char*)"-"; 166 *--argv = (char*)"-";
232 src_stream = xfopen_stdin(argv[0]); 167 src_stream = xfopen_stdin(argv[0]);
233 if (opts) { 168 if (opts) {
234 read_base64(src_stream, stdout); 169 read_base64(src_stream, stdout, /*flags:*/ (char)EOF);
235 } else { 170 } else {
236 enum { 171 enum {
237 SRC_BUF_SIZE = 76/4*3, /* This *MUST* be a multiple of 3 */ 172 SRC_BUF_SIZE = 76/4*3, /* This *MUST* be a multiple of 3 */
diff --git a/coreutils/wc.c b/coreutils/wc.c
index 4f14374c3..ecadae59b 100644
--- a/coreutils/wc.c
+++ b/coreutils/wc.c
@@ -7,7 +7,7 @@
7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
8 */ 8 */
9 9
10/* BB_AUDIT SUSv3 _NOT_ compliant -- option -m is not currently supported. */ 10/* BB_AUDIT SUSv3 compliant. */
11/* http://www.opengroup.org/onlinepubs/007904975/utilities/wc.html */ 11/* http://www.opengroup.org/onlinepubs/007904975/utilities/wc.html */
12 12
13/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) 13/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
@@ -19,10 +19,6 @@
19 * 3) no checking of ferror on EOF returns 19 * 3) no checking of ferror on EOF returns
20 * 4) isprint() wasn't considered when word counting. 20 * 4) isprint() wasn't considered when word counting.
21 * 21 *
22 * TODO:
23 *
24 * When locale support is enabled, count multibyte chars in the '-m' case.
25 *
26 * NOTES: 22 * NOTES:
27 * 23 *
28 * The previous busybox wc attempted an optimization using stat for the 24 * The previous busybox wc attempted an optimization using stat for the
@@ -40,8 +36,8 @@
40 * 36 *
41 * for which 'wc -c' should output '0'. 37 * for which 'wc -c' should output '0'.
42 */ 38 */
43
44#include "libbb.h" 39#include "libbb.h"
40#include "unicode.h"
45 41
46#if !ENABLE_LOCALE_SUPPORT 42#if !ENABLE_LOCALE_SUPPORT
47# undef isprint 43# undef isprint
@@ -58,11 +54,39 @@
58# define COUNT_FMT "u" 54# define COUNT_FMT "u"
59#endif 55#endif
60 56
57/* We support -m even when UNICODE_SUPPORT is off,
58 * we just don't advertise it in help text,
59 * since it is the same as -c in this case.
60 */
61
62//usage:#define wc_trivial_usage
63//usage: "[-c"IF_UNICODE_SUPPORT("m")"lwL] [FILE]..."
64//usage:
65//usage:#define wc_full_usage "\n\n"
66//usage: "Count lines, words, and bytes for each FILE (or stdin)\n"
67//usage: "\nOptions:"
68//usage: "\n -c Count bytes"
69//usage: IF_UNICODE_SUPPORT(
70//usage: "\n -m Count characters"
71//usage: )
72//usage: "\n -l Count newlines"
73//usage: "\n -w Count words"
74//usage: "\n -L Print longest line length"
75//usage:
76//usage:#define wc_example_usage
77//usage: "$ wc /etc/passwd\n"
78//usage: " 31 46 1365 /etc/passwd\n"
79
80/* Order is important if we want to be compatible with
81 * column order in "wc -cmlwL" output:
82 */
61enum { 83enum {
62 WC_LINES = 0, 84 WC_LINES = 0,
63 WC_WORDS = 1, 85 WC_WORDS = 1,
64 WC_CHARS = 2, 86 WC_UNICHARS = 2,
65 WC_LENGTH = 3 87 WC_CHARS = 3,
88 WC_LENGTH = 4,
89 NUM_WCS = 5,
66}; 90};
67 91
68int wc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 92int wc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
@@ -72,13 +96,15 @@ int wc_main(int argc UNUSED_PARAM, char **argv)
72 const char *start_fmt = " %9"COUNT_FMT + 1; 96 const char *start_fmt = " %9"COUNT_FMT + 1;
73 const char *fname_fmt = " %s\n"; 97 const char *fname_fmt = " %s\n";
74 COUNT_T *pcounts; 98 COUNT_T *pcounts;
75 COUNT_T counts[4]; 99 COUNT_T counts[NUM_WCS];
76 COUNT_T totals[4]; 100 COUNT_T totals[NUM_WCS];
77 int num_files; 101 int num_files;
78 smallint status = EXIT_SUCCESS; 102 smallint status = EXIT_SUCCESS;
79 unsigned print_type; 103 unsigned print_type;
80 104
81 print_type = getopt32(argv, "lwcL"); 105 init_unicode();
106
107 print_type = getopt32(argv, "lwcmL");
82 108
83 if (print_type == 0) { 109 if (print_type == 0) {
84 print_type = (1 << WC_LINES) | (1 << WC_WORDS) | (1 << WC_CHARS); 110 print_type = (1 << WC_LINES) | (1 << WC_WORDS) | (1 << WC_CHARS);
@@ -99,7 +125,7 @@ int wc_main(int argc UNUSED_PARAM, char **argv)
99 pcounts = counts; 125 pcounts = counts;
100 126
101 num_files = 0; 127 num_files = 0;
102 while ((arg = *argv++) != 0) { 128 while ((arg = *argv++) != NULL) {
103 FILE *fp; 129 FILE *fp;
104 const char *s; 130 const char *s;
105 unsigned u; 131 unsigned u;
@@ -117,21 +143,28 @@ int wc_main(int argc UNUSED_PARAM, char **argv)
117 linepos = 0; 143 linepos = 0;
118 in_word = 0; 144 in_word = 0;
119 145
120 do { 146 while (1) {
121 int c; 147 int c;
122 /* Our -w doesn't match GNU wc exactly... oh well */ 148 /* Our -w doesn't match GNU wc exactly... oh well */
123 149
124 ++counts[WC_CHARS];
125 c = getc(fp); 150 c = getc(fp);
126 if (c == EOF) { 151 if (c == EOF) {
127 if (ferror(fp)) { 152 if (ferror(fp)) {
128 bb_simple_perror_msg(arg); 153 bb_simple_perror_msg(arg);
129 status = EXIT_FAILURE; 154 status = EXIT_FAILURE;
130 } 155 }
131 --counts[WC_CHARS];
132 goto DO_EOF; /* Treat an EOF as '\r'. */ 156 goto DO_EOF; /* Treat an EOF as '\r'. */
133 } 157 }
134 if (isprint_asciionly(c)) { 158
159 /* Cater for -c and -m */
160 ++counts[WC_CHARS];
161 if (unicode_status != UNICODE_ON /* every byte is a new char */
162 || (c & 0xc0) != 0x80 /* it isn't a 2nd+ byte of a Unicode char */
163 ) {
164 ++counts[WC_UNICHARS];
165 }
166
167 if (isprint_asciionly(c)) { /* FIXME: not unicode-aware */
135 ++linepos; 168 ++linepos;
136 if (!isspace(c)) { 169 if (!isspace(c)) {
137 in_word = 1; 170 in_word = 1;
@@ -167,18 +200,18 @@ int wc_main(int argc UNUSED_PARAM, char **argv)
167 if (c == EOF) { 200 if (c == EOF) {
168 break; 201 break;
169 } 202 }
170 } while (1); 203 }
204
205 fclose_if_not_stdin(fp);
171 206
172 if (totals[WC_LENGTH] < counts[WC_LENGTH]) { 207 if (totals[WC_LENGTH] < counts[WC_LENGTH]) {
173 totals[WC_LENGTH] = counts[WC_LENGTH]; 208 totals[WC_LENGTH] = counts[WC_LENGTH];
174 } 209 }
175 totals[WC_LENGTH] -= counts[WC_LENGTH]; 210 totals[WC_LENGTH] -= counts[WC_LENGTH];
176 211
177 fclose_if_not_stdin(fp);
178
179 OUTPUT: 212 OUTPUT:
180 /* coreutils wc tries hard to print pretty columns 213 /* coreutils wc tries hard to print pretty columns
181 * (saves results for all files, find max col len etc...) 214 * (saves results for all files, finds max col len etc...)
182 * we won't try that hard, it will bloat us too much */ 215 * we won't try that hard, it will bloat us too much */
183 s = start_fmt; 216 s = start_fmt;
184 u = 0; 217 u = 0;
@@ -188,7 +221,7 @@ int wc_main(int argc UNUSED_PARAM, char **argv)
188 s = " %9"COUNT_FMT; /* Ok... restore the leading space. */ 221 s = " %9"COUNT_FMT; /* Ok... restore the leading space. */
189 } 222 }
190 totals[u] += pcounts[u]; 223 totals[u] += pcounts[u];
191 } while (++u < 4); 224 } while (++u < NUM_WCS);
192 printf(fname_fmt, arg); 225 printf(fname_fmt, arg);
193 } 226 }
194 227