diff options
author | Ron Yorston <rmy@pobox.com> | 2021-06-28 07:46:32 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2021-06-28 07:46:32 +0100 |
commit | e1ad66c0b8fd58a7158d40771175a7dab224202d (patch) | |
tree | 959d687eee9637151ad5798322586174de331141 /coreutils | |
parent | 0fdf99bee07b6c38795eb5415b5e337ab82cfba8 (diff) | |
parent | 5dbbd0a6f52befe6bc57baf97d39168e595197f1 (diff) | |
download | busybox-w32-e1ad66c0b8fd58a7158d40771175a7dab224202d.tar.gz busybox-w32-e1ad66c0b8fd58a7158d40771175a7dab224202d.tar.bz2 busybox-w32-e1ad66c0b8fd58a7158d40771175a7dab224202d.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'coreutils')
-rw-r--r-- | coreutils/chgrp.c | 8 | ||||
-rw-r--r-- | coreutils/chmod.c | 7 | ||||
-rw-r--r-- | coreutils/chown.c | 10 | ||||
-rw-r--r-- | coreutils/cksum.c | 54 | ||||
-rw-r--r-- | coreutils/cp.c | 199 | ||||
-rw-r--r-- | coreutils/cut.c | 1 | ||||
-rw-r--r-- | coreutils/df.c | 45 | ||||
-rw-r--r-- | coreutils/du.c | 33 | ||||
-rw-r--r-- | coreutils/echo.c | 6 | ||||
-rw-r--r-- | coreutils/env.c | 19 | ||||
-rw-r--r-- | coreutils/expr.c | 4 | ||||
-rw-r--r-- | coreutils/id.c | 2 | ||||
-rw-r--r-- | coreutils/mv.c | 76 | ||||
-rw-r--r-- | coreutils/nproc.c | 4 | ||||
-rw-r--r-- | coreutils/shred.c | 33 | ||||
-rw-r--r-- | coreutils/sort.c | 2 | ||||
-rw-r--r-- | coreutils/touch.c | 2 | ||||
-rw-r--r-- | coreutils/tty.c | 2 | ||||
-rw-r--r-- | coreutils/uname.c | 4 | ||||
-rw-r--r-- | coreutils/uniq.c | 24 | ||||
-rw-r--r-- | coreutils/uudecode.c | 10 | ||||
-rw-r--r-- | coreutils/who.c | 2 | ||||
-rw-r--r-- | coreutils/yes.c | 2 |
23 files changed, 327 insertions, 222 deletions
diff --git a/coreutils/chgrp.c b/coreutils/chgrp.c index 0c2060981..e6ac316e5 100644 --- a/coreutils/chgrp.c +++ b/coreutils/chgrp.c | |||
@@ -23,13 +23,17 @@ | |||
23 | //usage:#define chgrp_trivial_usage | 23 | //usage:#define chgrp_trivial_usage |
24 | //usage: "[-Rh"IF_DESKTOP("LHPcvf")"]... GROUP FILE..." | 24 | //usage: "[-Rh"IF_DESKTOP("LHPcvf")"]... GROUP FILE..." |
25 | //usage:#define chgrp_full_usage "\n\n" | 25 | //usage:#define chgrp_full_usage "\n\n" |
26 | //usage: "Change the group membership of FILEs to GROUP\n" | 26 | //usage: "Change the group membership of FILEs to GROUP" |
27 | //usage: "\n -R Recurse" | 27 | //usage: "\n" |
28 | //usage: "\n -h Affect symlinks instead of symlink targets" | 28 | //usage: "\n -h Affect symlinks instead of symlink targets" |
29 | //usage: IF_DESKTOP( | 29 | //usage: IF_DESKTOP( |
30 | //usage: "\n -L Traverse all symlinks to directories" | 30 | //usage: "\n -L Traverse all symlinks to directories" |
31 | //usage: "\n -H Traverse symlinks on command line only" | 31 | //usage: "\n -H Traverse symlinks on command line only" |
32 | //usage: "\n -P Don't traverse symlinks (default)" | 32 | //usage: "\n -P Don't traverse symlinks (default)" |
33 | //usage: ) | ||
34 | //next 4 options are the same for chmod/chown/chgrp: | ||
35 | //usage: "\n -R Recurse" | ||
36 | //usage: IF_DESKTOP( | ||
33 | //usage: "\n -c List changed files" | 37 | //usage: "\n -c List changed files" |
34 | //usage: "\n -v Verbose" | 38 | //usage: "\n -v Verbose" |
35 | //usage: "\n -f Hide errors" | 39 | //usage: "\n -f Hide errors" |
diff --git a/coreutils/chmod.c b/coreutils/chmod.c index d2988c490..e260adab2 100644 --- a/coreutils/chmod.c +++ b/coreutils/chmod.c | |||
@@ -26,12 +26,13 @@ | |||
26 | //usage:#define chmod_trivial_usage | 26 | //usage:#define chmod_trivial_usage |
27 | //usage: "[-R"IF_DESKTOP("cvf")"] MODE[,MODE]... FILE..." | 27 | //usage: "[-R"IF_DESKTOP("cvf")"] MODE[,MODE]... FILE..." |
28 | //usage:#define chmod_full_usage "\n\n" | 28 | //usage:#define chmod_full_usage "\n\n" |
29 | //usage: "Each MODE is one or more of the letters ugoa, one of the\n" | 29 | //usage: "MODE is octal number (bit pattern sstrwxrwxrwx) or [ugoa]{+|-|=}[rwxXst]" |
30 | //usage: "symbols +-= and one or more of the letters rwxst\n" | 30 | //usage: "\n" |
31 | //next 4 options are the same for chmod/chown/chgrp: | ||
31 | //usage: "\n -R Recurse" | 32 | //usage: "\n -R Recurse" |
32 | //usage: IF_DESKTOP( | 33 | //usage: IF_DESKTOP( |
33 | //usage: "\n -c List changed files" | 34 | //usage: "\n -c List changed files" |
34 | //usage: "\n -v List all files" | 35 | //usage: "\n -v Verbose" |
35 | //usage: "\n -f Hide errors" | 36 | //usage: "\n -f Hide errors" |
36 | //usage: ) | 37 | //usage: ) |
37 | //usage: | 38 | //usage: |
diff --git a/coreutils/chown.c b/coreutils/chown.c index 170507147..528a2a05a 100644 --- a/coreutils/chown.c +++ b/coreutils/chown.c | |||
@@ -28,15 +28,19 @@ | |||
28 | //usage:#define chown_trivial_usage | 28 | //usage:#define chown_trivial_usage |
29 | //usage: "[-Rh"IF_DESKTOP("LHPcvf")"]... USER[:[GRP]] FILE..." | 29 | //usage: "[-Rh"IF_DESKTOP("LHPcvf")"]... USER[:[GRP]] FILE..." |
30 | //usage:#define chown_full_usage "\n\n" | 30 | //usage:#define chown_full_usage "\n\n" |
31 | //usage: "Change the owner and/or group of FILEs to USER and/or GRP\n" | 31 | //usage: "Change the owner and/or group of FILEs to USER and/or GRP" |
32 | //usage: "\n -R Recurse" | 32 | //usage: "\n" |
33 | //usage: "\n -h Affect symlinks instead of symlink targets" | 33 | //usage: "\n -h Affect symlinks instead of symlink targets" |
34 | //usage: IF_DESKTOP( | 34 | //usage: IF_DESKTOP( |
35 | //usage: "\n -L Traverse all symlinks to directories" | 35 | //usage: "\n -L Traverse all symlinks to directories" |
36 | //usage: "\n -H Traverse symlinks on command line only" | 36 | //usage: "\n -H Traverse symlinks on command line only" |
37 | //usage: "\n -P Don't traverse symlinks (default)" | 37 | //usage: "\n -P Don't traverse symlinks (default)" |
38 | //usage: ) | ||
39 | //next 4 options are the same for chmod/chown/chgrp: | ||
40 | //usage: "\n -R Recurse" | ||
41 | //usage: IF_DESKTOP( | ||
38 | //usage: "\n -c List changed files" | 42 | //usage: "\n -c List changed files" |
39 | //usage: "\n -v List all files" | 43 | //usage: "\n -v Verbose" |
40 | //usage: "\n -f Hide errors" | 44 | //usage: "\n -f Hide errors" |
41 | //usage: ) | 45 | //usage: ) |
42 | //usage: | 46 | //usage: |
diff --git a/coreutils/cksum.c b/coreutils/cksum.c index 633322bc7..83b7e3238 100644 --- a/coreutils/cksum.c +++ b/coreutils/cksum.c | |||
@@ -9,32 +9,40 @@ | |||
9 | //config:config CKSUM | 9 | //config:config CKSUM |
10 | //config: bool "cksum (4.1 kb)" | 10 | //config: bool "cksum (4.1 kb)" |
11 | //config: default y | 11 | //config: default y |
12 | //config: help | 12 | //config: |
13 | //config: cksum is used to calculate the CRC32 checksum of a file. | 13 | //config:config CRC32 |
14 | //config: bool "crc32 (4.1 kb)" | ||
15 | //config: default y | ||
14 | 16 | ||
17 | // APPLET_NOEXEC:name main location suid_type help | ||
15 | //applet:IF_CKSUM(APPLET_NOEXEC(cksum, cksum, BB_DIR_USR_BIN, BB_SUID_DROP, cksum)) | 18 | //applet:IF_CKSUM(APPLET_NOEXEC(cksum, cksum, BB_DIR_USR_BIN, BB_SUID_DROP, cksum)) |
19 | //applet:IF_CRC32(APPLET_NOEXEC(crc32, cksum, BB_DIR_USR_BIN, BB_SUID_DROP, cksum)) | ||
16 | /* bb_common_bufsiz1 usage here is safe wrt NOEXEC: not expecting it to be zeroed. */ | 20 | /* bb_common_bufsiz1 usage here is safe wrt NOEXEC: not expecting it to be zeroed. */ |
17 | 21 | ||
18 | //kbuild:lib-$(CONFIG_CKSUM) += cksum.o | 22 | //kbuild:lib-$(CONFIG_CKSUM) += cksum.o |
23 | //kbuild:lib-$(CONFIG_CRC32) += cksum.o | ||
19 | 24 | ||
20 | //usage:#define cksum_trivial_usage | 25 | //usage:#define cksum_trivial_usage |
21 | //usage: "FILE..." | 26 | //usage: "FILE..." |
22 | //usage:#define cksum_full_usage "\n\n" | 27 | //usage:#define cksum_full_usage "\n\n" |
23 | //usage: "Calculate the CRC32 checksums of FILEs" | 28 | //usage: "Calculate CRC32 checksum of FILEs" |
24 | 29 | ||
25 | #include "libbb.h" | 30 | #include "libbb.h" |
26 | #include "common_bufsiz.h" | 31 | #include "common_bufsiz.h" |
27 | 32 | ||
28 | /* This is a NOEXEC applet. Be very careful! */ | 33 | /* This is a NOEXEC applet. Be very careful! */ |
29 | 34 | ||
35 | #define IS_CKSUM (ENABLE_CKSUM && (!ENABLE_CRC32 || applet_name[1] == 'k')) | ||
36 | #define IS_CRC32 (ENABLE_CRC32 && (!ENABLE_CKSUM || applet_name[1] == 'r')) | ||
37 | |||
30 | int cksum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 38 | int cksum_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
31 | int cksum_main(int argc UNUSED_PARAM, char **argv) | 39 | int cksum_main(int argc UNUSED_PARAM, char **argv) |
32 | { | 40 | { |
33 | uint32_t *crc32_table = crc32_filltable(NULL, 1); | 41 | uint32_t *crc32_table = crc32_filltable(NULL, IS_CKSUM); |
34 | int exit_code = EXIT_SUCCESS; | 42 | int exit_code = EXIT_SUCCESS; |
35 | 43 | ||
36 | #if ENABLE_DESKTOP | 44 | #if ENABLE_DESKTOP |
37 | getopt32(argv, ""); /* coreutils 6.9 compat */ | 45 | getopt32(argv, ""); /* cksum coreutils 6.9 compat */ |
38 | argv += optind; | 46 | argv += optind; |
39 | #else | 47 | #else |
40 | argv++; | 48 | argv++; |
@@ -43,41 +51,55 @@ int cksum_main(int argc UNUSED_PARAM, char **argv) | |||
43 | setup_common_bufsiz(); | 51 | setup_common_bufsiz(); |
44 | do { | 52 | do { |
45 | uint32_t crc; | 53 | uint32_t crc; |
46 | off_t filesize; | 54 | IF_CKSUM(off_t filesize;) |
47 | int fd = open_or_warn_stdin(*argv ? *argv : bb_msg_standard_input); | 55 | const char *fname = *argv ? *argv : bb_msg_standard_input; |
56 | int fd = open_or_warn_stdin(fname); | ||
48 | 57 | ||
49 | if (fd < 0) { | 58 | if (fd < 0) { |
50 | exit_code = EXIT_FAILURE; | 59 | exit_code = EXIT_FAILURE; |
51 | continue; | 60 | continue; |
52 | } | 61 | } |
53 | 62 | ||
54 | crc = 0; | 63 | crc = IS_CKSUM ? 0 : 0xffffffff; |
55 | filesize = 0; | 64 | IF_CKSUM(filesize = 0;) |
56 | #define read_buf bb_common_bufsiz1 | 65 | #define read_buf bb_common_bufsiz1 |
57 | for (;;) { | 66 | for (;;) { |
58 | uoff_t t; | ||
59 | int bytes_read = safe_read(fd, read_buf, COMMON_BUFSIZE); | 67 | int bytes_read = safe_read(fd, read_buf, COMMON_BUFSIZE); |
68 | if (bytes_read < 0) | ||
69 | bb_simple_perror_msg_and_die(fname); | ||
60 | if (bytes_read > 0) { | 70 | if (bytes_read > 0) { |
61 | filesize += bytes_read; | 71 | IF_CKSUM(filesize += bytes_read;) |
62 | } else { | 72 | } else { |
63 | /* Checksum filesize bytes, LSB first, and exit */ | 73 | IF_CKSUM(uoff_t t;) |
74 | |||
64 | close(fd); | 75 | close(fd); |
76 | if (IS_CRC32) | ||
77 | break; | ||
78 | #if ENABLE_CKSUM | ||
65 | fd = -1; /* break flag */ | 79 | fd = -1; /* break flag */ |
80 | /* Checksum filesize bytes, LSB first */ | ||
66 | t = filesize; | 81 | t = filesize; |
67 | bytes_read = 0; | 82 | /*bytes_read = 0; - already is */ |
68 | while (t != 0) { | 83 | while (t != 0) { |
69 | read_buf[bytes_read++] = (uint8_t)t; | 84 | read_buf[bytes_read++] = (uint8_t)t; |
70 | t >>= 8; | 85 | t >>= 8; |
71 | } | 86 | } |
87 | #endif | ||
72 | } | 88 | } |
73 | crc = crc32_block_endian1(crc, read_buf, bytes_read, crc32_table); | 89 | crc = (IS_CKSUM ? crc32_block_endian1 : crc32_block_endian0)(crc, read_buf, bytes_read, crc32_table); |
74 | if (fd < 0) | 90 | if (ENABLE_CKSUM && fd < 0) |
75 | break; | 91 | break; |
76 | } | 92 | } |
77 | 93 | ||
78 | crc = ~crc; | 94 | crc = ~crc; |
79 | printf((*argv ? "%u %"OFF_FMT"u %s\n" : "%u %"OFF_FMT"u\n"), | 95 | #if ENABLE_CKSUM |
96 | if (IS_CKSUM) | ||
97 | printf((*argv ? "%u %"OFF_FMT"u %s\n" : "%u %"OFF_FMT"u\n"), | ||
80 | (unsigned)crc, filesize, *argv); | 98 | (unsigned)crc, filesize, *argv); |
99 | else | ||
100 | #endif | ||
101 | printf((*argv ? "%08x %s\n" : "%08x\n"), | ||
102 | (unsigned)crc, *argv); | ||
81 | } while (*argv && *++argv); | 103 | } while (*argv && *++argv); |
82 | 104 | ||
83 | fflush_stdout_and_exit(exit_code); | 105 | fflush_stdout_and_exit(exit_code); |
diff --git a/coreutils/cp.c b/coreutils/cp.c index f92ba6886..50ca1ccea 100644 --- a/coreutils/cp.c +++ b/coreutils/cp.c | |||
@@ -37,8 +37,55 @@ | |||
37 | 37 | ||
38 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/cp.html */ | 38 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/cp.html */ |
39 | 39 | ||
40 | // Options of cp from GNU coreutils 6.10: | ||
41 | // -a, --archive | ||
42 | // -f, --force | ||
43 | // -i, --interactive | ||
44 | // -l, --link | ||
45 | // -L, --dereference | ||
46 | // -P, --no-dereference | ||
47 | // -R, -r, --recursive | ||
48 | // -s, --symbolic-link | ||
49 | // -v, --verbose | ||
50 | // -H follow command-line symbolic links in SOURCE | ||
51 | // -d same as --no-dereference --preserve=links | ||
52 | // -p same as --preserve=mode,ownership,timestamps | ||
53 | // -c same as --preserve=context | ||
54 | // -u, --update | ||
55 | // copy only when the SOURCE file is newer than the destination | ||
56 | // file or when the destination file is missing | ||
57 | // --remove-destination | ||
58 | // remove each existing destination file before attempting to open | ||
59 | // --parents | ||
60 | // use full source file name under DIRECTORY | ||
61 | // -T, --no-target-directory | ||
62 | // treat DEST as a normal file | ||
63 | // NOT SUPPORTED IN BBOX: | ||
64 | // --backup[=CONTROL] | ||
65 | // make a backup of each existing destination file | ||
66 | // -b like --backup but does not accept an argument | ||
67 | // --copy-contents | ||
68 | // copy contents of special files when recursive | ||
69 | // --preserve[=ATTR_LIST] | ||
70 | // preserve attributes (default: mode,ownership,timestamps), | ||
71 | // if possible additional attributes: security context,links,all | ||
72 | // --no-preserve=ATTR_LIST | ||
73 | // --sparse=WHEN | ||
74 | // control creation of sparse files | ||
75 | // --strip-trailing-slashes | ||
76 | // remove any trailing slashes from each SOURCE argument | ||
77 | // -S, --suffix=SUFFIX | ||
78 | // override the usual backup suffix | ||
79 | // -t, --target-directory=DIRECTORY | ||
80 | // copy all SOURCE arguments into DIRECTORY | ||
81 | // -x, --one-file-system | ||
82 | // stay on this file system | ||
83 | // -Z, --context=CONTEXT | ||
84 | // (SELinux) set SELinux security context of copy to CONTEXT | ||
85 | |||
40 | //usage:#define cp_trivial_usage | 86 | //usage:#define cp_trivial_usage |
41 | //usage: "[-arPLHpfilsTu] SOURCE... DEST" | 87 | //usage: "[-arPLHpfinlsTu] SOURCE DEST\n" |
88 | //usage: "or: cp [-arPLHpfinlsu] SOURCE... { -t DIRECTORY | DIRECTORY }" | ||
42 | //usage:#define cp_full_usage "\n\n" | 89 | //usage:#define cp_full_usage "\n\n" |
43 | //usage: "Copy SOURCEs to DEST\n" | 90 | //usage: "Copy SOURCEs to DEST\n" |
44 | //usage: "\n -a Same as -dpR" | 91 | //usage: "\n -a Same as -dpR" |
@@ -52,8 +99,10 @@ | |||
52 | //usage: "\n -p Preserve file attributes if possible" | 99 | //usage: "\n -p Preserve file attributes if possible" |
53 | //usage: "\n -f Overwrite" | 100 | //usage: "\n -f Overwrite" |
54 | //usage: "\n -i Prompt before overwrite" | 101 | //usage: "\n -i Prompt before overwrite" |
102 | //usage: "\n -n Don't overwrite" | ||
55 | //usage: "\n -l,-s Create (sym)links" | 103 | //usage: "\n -l,-s Create (sym)links" |
56 | //usage: "\n -T Treat DEST as a normal file" | 104 | //usage: "\n -T Refuse to copy if DEST is a directory" |
105 | //usage: "\n -t DIR Copy all SOURCEs into DIR" | ||
57 | //usage: "\n -u Copy only newer files" | 106 | //usage: "\n -u Copy only newer files" |
58 | 107 | ||
59 | #include "libbb.h" | 108 | #include "libbb.h" |
@@ -73,14 +122,12 @@ int cp_main(int argc, char **argv) | |||
73 | int flags; | 122 | int flags; |
74 | int status; | 123 | int status; |
75 | enum { | 124 | enum { |
76 | FILEUTILS_CP_OPTNUM = sizeof(FILEUTILS_CP_OPTSTR)-1, | ||
77 | #if ENABLE_FEATURE_CP_LONG_OPTIONS | 125 | #if ENABLE_FEATURE_CP_LONG_OPTIONS |
78 | /*OPT_rmdest = FILEUTILS_RMDEST = 1 << FILEUTILS_CP_OPTNUM */ | 126 | /*OPT_rmdest = FILEUTILS_RMDEST = 1 << FILEUTILS_CP_OPTBITS */ |
79 | OPT_parents = 1 << (FILEUTILS_CP_OPTNUM+1), | 127 | OPT_parents = 1 << (FILEUTILS_CP_OPTBITS+1), |
80 | OPT_reflink = 1 << (FILEUTILS_CP_OPTNUM+2), | 128 | OPT_reflink = 1 << (FILEUTILS_CP_OPTBITS+2), |
81 | #endif | 129 | #endif |
82 | }; | 130 | }; |
83 | |||
84 | #if ENABLE_FEATURE_CP_LONG_OPTIONS | 131 | #if ENABLE_FEATURE_CP_LONG_OPTIONS |
85 | # if ENABLE_FEATURE_CP_REFLINK | 132 | # if ENABLE_FEATURE_CP_REFLINK |
86 | char *reflink = NULL; | 133 | char *reflink = NULL; |
@@ -88,28 +135,34 @@ int cp_main(int argc, char **argv) | |||
88 | flags = getopt32long(argv, "^" | 135 | flags = getopt32long(argv, "^" |
89 | FILEUTILS_CP_OPTSTR | 136 | FILEUTILS_CP_OPTSTR |
90 | "\0" | 137 | "\0" |
91 | // Need at least two arguments | 138 | // Need at least one argument. (Usually two+, but -t DIR can have only one) |
92 | // Soft- and hardlinking doesn't mix | 139 | // Soft- and hardlinking doesn't mix |
93 | // -P and -d are the same (-P is POSIX, -d is GNU) | 140 | // -P and -d are the same (-P is POSIX, -d is GNU) |
94 | // -r and -R are the same | 141 | // -r and -R are the same |
95 | // -R (and therefore -r) turns on -d (coreutils does this) | 142 | // -R (and therefore -r) turns on -d (coreutils does this) |
96 | // -a = -pdR | 143 | // -a = -pdR |
97 | "-2:l--s:s--l:Pd:rRd:Rd:apdR", | 144 | // -i overrides -n and vice versa (last wins) |
145 | "-1:l--s:s--l:Pd:rRd:Rd:apdR:i-n:n-i", | ||
98 | "archive\0" No_argument "a" | 146 | "archive\0" No_argument "a" |
99 | "force\0" No_argument "f" | 147 | "force\0" No_argument "f" |
100 | "interactive\0" No_argument "i" | 148 | "interactive\0" No_argument "i" |
149 | "no-clobber\0" No_argument "n" | ||
101 | "link\0" No_argument "l" | 150 | "link\0" No_argument "l" |
102 | "dereference\0" No_argument "L" | 151 | "dereference\0" No_argument "L" |
103 | "no-dereference\0" No_argument "P" | 152 | "no-dereference\0" No_argument "P" |
104 | "recursive\0" No_argument "R" | 153 | "recursive\0" No_argument "R" |
105 | "symbolic-link\0" No_argument "s" | 154 | "symbolic-link\0" No_argument "s" |
106 | "no-target-directory\0" No_argument "T" | 155 | "no-target-directory\0" No_argument "T" |
156 | "target-directory\0" Required_argument "t" | ||
107 | "verbose\0" No_argument "v" | 157 | "verbose\0" No_argument "v" |
108 | "update\0" No_argument "u" | 158 | "update\0" No_argument "u" |
109 | "remove-destination\0" No_argument "\xff" | 159 | "remove-destination\0" No_argument "\xff" |
110 | "parents\0" No_argument "\xfe" | 160 | "parents\0" No_argument "\xfe" |
111 | # if ENABLE_FEATURE_CP_REFLINK | 161 | # if ENABLE_FEATURE_CP_REFLINK |
112 | "reflink\0" Optional_argument "\xfd" | 162 | "reflink\0" Optional_argument "\xfd" |
163 | # endif | ||
164 | , &last | ||
165 | # if ENABLE_FEATURE_CP_REFLINK | ||
113 | , &reflink | 166 | , &reflink |
114 | # endif | 167 | # endif |
115 | ); | 168 | ); |
@@ -128,55 +181,10 @@ int cp_main(int argc, char **argv) | |||
128 | flags = getopt32(argv, "^" | 181 | flags = getopt32(argv, "^" |
129 | FILEUTILS_CP_OPTSTR | 182 | FILEUTILS_CP_OPTSTR |
130 | "\0" | 183 | "\0" |
131 | "-2:l--s:s--l:Pd:rRd:Rd:apdR" | 184 | "-1:l--s:s--l:Pd:rRd:Rd:apdR" |
185 | , &last | ||
132 | ); | 186 | ); |
133 | #endif | 187 | #endif |
134 | /* Options of cp from GNU coreutils 6.10: | ||
135 | * -a, --archive | ||
136 | * -f, --force | ||
137 | * -i, --interactive | ||
138 | * -l, --link | ||
139 | * -L, --dereference | ||
140 | * -P, --no-dereference | ||
141 | * -R, -r, --recursive | ||
142 | * -s, --symbolic-link | ||
143 | * -v, --verbose | ||
144 | * -H follow command-line symbolic links in SOURCE | ||
145 | * -d same as --no-dereference --preserve=links | ||
146 | * -p same as --preserve=mode,ownership,timestamps | ||
147 | * -c same as --preserve=context | ||
148 | * -u, --update | ||
149 | * copy only when the SOURCE file is newer than the destination | ||
150 | * file or when the destination file is missing | ||
151 | * --remove-destination | ||
152 | * remove each existing destination file before attempting to open | ||
153 | * --parents | ||
154 | * use full source file name under DIRECTORY | ||
155 | * -T, --no-target-directory | ||
156 | * treat DEST as a normal file | ||
157 | * NOT SUPPORTED IN BBOX: | ||
158 | * --backup[=CONTROL] | ||
159 | * make a backup of each existing destination file | ||
160 | * -b like --backup but does not accept an argument | ||
161 | * --copy-contents | ||
162 | * copy contents of special files when recursive | ||
163 | * --preserve[=ATTR_LIST] | ||
164 | * preserve attributes (default: mode,ownership,timestamps), | ||
165 | * if possible additional attributes: security context,links,all | ||
166 | * --no-preserve=ATTR_LIST | ||
167 | * --sparse=WHEN | ||
168 | * control creation of sparse files | ||
169 | * --strip-trailing-slashes | ||
170 | * remove any trailing slashes from each SOURCE argument | ||
171 | * -S, --suffix=SUFFIX | ||
172 | * override the usual backup suffix | ||
173 | * -t, --target-directory=DIRECTORY | ||
174 | * copy all SOURCE arguments into DIRECTORY | ||
175 | * -x, --one-file-system | ||
176 | * stay on this file system | ||
177 | * -Z, --context=CONTEXT | ||
178 | * (SELinux) set SELinux security context of copy to CONTEXT | ||
179 | */ | ||
180 | argc -= optind; | 188 | argc -= optind; |
181 | argv += optind; | 189 | argv += optind; |
182 | /* Reverse this bit. If there is -d, bit is not set: */ | 190 | /* Reverse this bit. If there is -d, bit is not set: */ |
@@ -195,49 +203,56 @@ int cp_main(int argc, char **argv) | |||
195 | #endif | 203 | #endif |
196 | 204 | ||
197 | status = EXIT_SUCCESS; | 205 | status = EXIT_SUCCESS; |
198 | last = argv[argc - 1]; | 206 | if (!(flags & FILEUTILS_TARGET_DIR)) { |
199 | /* If there are only two arguments and... */ | 207 | last = argv[argc - 1]; |
200 | if (argc == 2) { | 208 | if (argc < 2) |
201 | s_flags = cp_mv_stat2(*argv, &source_stat, | 209 | bb_show_usage(); |
202 | (flags & FILEUTILS_DEREFERENCE) ? stat : lstat); | 210 | if (argc != 2) { |
203 | if (s_flags < 0) | 211 | if (flags & FILEUTILS_NO_TARGET_DIR) |
204 | return EXIT_FAILURE; | 212 | bb_show_usage(); |
205 | d_flags = cp_mv_stat(last, &dest_stat); | 213 | /* "cp A B C... DIR" - target must be dir */ |
206 | if (d_flags < 0) | 214 | } else /* argc == 2 */ { |
207 | return EXIT_FAILURE; | 215 | /* "cp A B" - only case where target can be not a dir */ |
216 | s_flags = cp_mv_stat2(*argv, &source_stat, | ||
217 | (flags & FILEUTILS_DEREFERENCE) ? stat : lstat); | ||
218 | if (s_flags < 0) /* error other than ENOENT */ | ||
219 | return EXIT_FAILURE; | ||
220 | d_flags = cp_mv_stat(last, &dest_stat); | ||
221 | if (d_flags < 0) /* error other than ENOENT */ | ||
222 | return EXIT_FAILURE; | ||
208 | 223 | ||
209 | if (flags & FILEUTILS_NO_TARGET_DIR) { /* -T */ | 224 | if (flags & FILEUTILS_NO_TARGET_DIR) { /* -T */ |
210 | if (!(s_flags & 2) && (d_flags & 2)) | 225 | if (!(s_flags & 2) && (d_flags & 2)) |
211 | /* cp -T NOTDIR DIR */ | 226 | /* cp -T NOTDIR DIR */ |
212 | bb_error_msg_and_die("'%s' is a directory", last); | 227 | bb_error_msg_and_die("'%s' is a directory", last); |
213 | } | 228 | } |
214 | 229 | ||
215 | #if ENABLE_FEATURE_CP_LONG_OPTIONS | 230 | #if ENABLE_FEATURE_CP_LONG_OPTIONS |
216 | //bb_error_msg("flags:%x FILEUTILS_RMDEST:%x OPT_parents:%x", | 231 | //bb_error_msg("flags:%x FILEUTILS_RMDEST:%x OPT_parents:%x", |
217 | // flags, FILEUTILS_RMDEST, OPT_parents); | 232 | // flags, FILEUTILS_RMDEST, OPT_parents); |
218 | if (flags & OPT_parents) { | 233 | if (flags & OPT_parents) { |
219 | if (!(d_flags & 2)) { | 234 | if (!(d_flags & 2)) { |
220 | bb_simple_error_msg_and_die("with --parents, the destination must be a directory"); | 235 | bb_simple_error_msg_and_die("with --parents, the destination must be a directory"); |
236 | } | ||
237 | } | ||
238 | if (flags & FILEUTILS_RMDEST) { | ||
239 | flags |= FILEUTILS_FORCE; | ||
221 | } | 240 | } |
222 | } | ||
223 | if (flags & FILEUTILS_RMDEST) { | ||
224 | flags |= FILEUTILS_FORCE; | ||
225 | } | ||
226 | #endif | 241 | #endif |
227 | 242 | ||
228 | /* ...if neither is a directory... */ | 243 | /* ...if neither is a directory... */ |
229 | if (!((s_flags | d_flags) & 2) | 244 | if (!((s_flags | d_flags) & 2) |
230 | /* ...or: recursing, the 1st is a directory, and the 2nd doesn't exist... */ | 245 | /* ...or: recursing, the 1st is a directory, and the 2nd doesn't exist... */ |
231 | || ((flags & FILEUTILS_RECUR) && (s_flags & 2) && !d_flags) | 246 | || ((flags & FILEUTILS_RECUR) && (s_flags & 2) && !d_flags) |
232 | || (flags & FILEUTILS_NO_TARGET_DIR) | 247 | || (flags & FILEUTILS_NO_TARGET_DIR) |
233 | ) { | 248 | ) { |
234 | /* Do a simple copy */ | 249 | /* Do a simple copy */ |
235 | dest = last; | 250 | dest = last; |
236 | goto DO_COPY; /* NB: argc==2 -> *++argv==last */ | 251 | goto DO_COPY; /* NB: argc==2 -> *++argv==last */ |
252 | } | ||
237 | } | 253 | } |
238 | } else if (flags & FILEUTILS_NO_TARGET_DIR) { | ||
239 | bb_simple_error_msg_and_die("too many arguments"); | ||
240 | } | 254 | } |
255 | /* else: last is DIR from "-t DIR" */ | ||
241 | 256 | ||
242 | while (1) { | 257 | while (1) { |
243 | #if ENABLE_FEATURE_CP_LONG_OPTIONS | 258 | #if ENABLE_FEATURE_CP_LONG_OPTIONS |
@@ -259,7 +274,7 @@ int cp_main(int argc, char **argv) | |||
259 | if (copy_file(*argv, dest, flags) < 0) { | 274 | if (copy_file(*argv, dest, flags) < 0) { |
260 | status = EXIT_FAILURE; | 275 | status = EXIT_FAILURE; |
261 | } | 276 | } |
262 | if (*++argv == last) { | 277 | if (!*++argv || *argv == last) { |
263 | /* possibly leaking dest... */ | 278 | /* possibly leaking dest... */ |
264 | break; | 279 | break; |
265 | } | 280 | } |
diff --git a/coreutils/cut.c b/coreutils/cut.c index 5897d82b6..cc3c32576 100644 --- a/coreutils/cut.c +++ b/coreutils/cut.c | |||
@@ -29,6 +29,7 @@ | |||
29 | //usage: "\n -s Output only lines containing delimiter" | 29 | //usage: "\n -s Output only lines containing delimiter" |
30 | //usage: "\n -f LIST Print only these fields" | 30 | //usage: "\n -f LIST Print only these fields" |
31 | //usage: "\n -n Ignored" | 31 | //usage: "\n -n Ignored" |
32 | //(manpage:-n with -b: don't split multibyte characters) | ||
32 | //usage: | 33 | //usage: |
33 | //usage:#define cut_example_usage | 34 | //usage:#define cut_example_usage |
34 | //usage: "$ echo \"Hello world\" | cut -f 1 -d ' '\n" | 35 | //usage: "$ echo \"Hello world\" | cut -f 1 -d ' '\n" |
diff --git a/coreutils/df.c b/coreutils/df.c index debb86867..e8d4bc8f2 100644 --- a/coreutils/df.c +++ b/coreutils/df.c | |||
@@ -45,7 +45,7 @@ | |||
45 | //usage: IF_FEATURE_HUMAN_READABLE("mh") | 45 | //usage: IF_FEATURE_HUMAN_READABLE("mh") |
46 | //usage: "T" | 46 | //usage: "T" |
47 | //usage: IF_FEATURE_DF_FANCY("ai] [-B SIZE") | 47 | //usage: IF_FEATURE_DF_FANCY("ai] [-B SIZE") |
48 | //usage: "] [FILESYSTEM]..." | 48 | //usage: "] [-t TYPE] [FILESYSTEM]..." |
49 | //usage:#define df_full_usage "\n\n" | 49 | //usage:#define df_full_usage "\n\n" |
50 | //usage: "Print filesystem usage statistics\n" | 50 | //usage: "Print filesystem usage statistics\n" |
51 | //usage: "\n -P POSIX output format" | 51 | //usage: "\n -P POSIX output format" |
@@ -55,6 +55,7 @@ | |||
55 | //usage: "\n -h Human readable (e.g. 1K 243M 2G)" | 55 | //usage: "\n -h Human readable (e.g. 1K 243M 2G)" |
56 | //usage: ) | 56 | //usage: ) |
57 | //usage: "\n -T Print filesystem type" | 57 | //usage: "\n -T Print filesystem type" |
58 | //usage: "\n -t TYPE Print only mounts of this type" | ||
58 | //usage: IF_FEATURE_DF_FANCY( | 59 | //usage: IF_FEATURE_DF_FANCY( |
59 | //usage: "\n -a Show all filesystems" | 60 | //usage: "\n -a Show all filesystems" |
60 | //usage: "\n -i Inodes" | 61 | //usage: "\n -i Inodes" |
@@ -97,24 +98,31 @@ int df_main(int argc UNUSED_PARAM, char **argv) | |||
97 | FILE *mount_table; | 98 | FILE *mount_table; |
98 | struct mntent *mount_entry; | 99 | struct mntent *mount_entry; |
99 | struct statvfs s; | 100 | struct statvfs s; |
100 | |||
101 | enum { | 101 | enum { |
102 | OPT_KILO = (1 << 0), | 102 | OPT_KILO = (1 << 0), |
103 | OPT_POSIX = (1 << 1), | 103 | OPT_POSIX = (1 << 1), |
104 | OPT_FSTYPE = (1 << 2), | 104 | OPT_FSTYPE = (1 << 2), |
105 | OPT_ALL = (1 << 3) * ENABLE_FEATURE_DF_FANCY, | 105 | OPT_t = (1 << 3), |
106 | OPT_INODE = (1 << 4) * ENABLE_FEATURE_DF_FANCY, | 106 | OPT_ALL = (1 << 4) * ENABLE_FEATURE_DF_FANCY, |
107 | OPT_BSIZE = (1 << 5) * ENABLE_FEATURE_DF_FANCY, | 107 | OPT_INODE = (1 << 5) * ENABLE_FEATURE_DF_FANCY, |
108 | OPT_HUMAN = (1 << (3 + 3*ENABLE_FEATURE_DF_FANCY)) * ENABLE_FEATURE_HUMAN_READABLE, | 108 | OPT_BSIZE = (1 << 6) * ENABLE_FEATURE_DF_FANCY, |
109 | OPT_MEGA = (1 << (4 + 3*ENABLE_FEATURE_DF_FANCY)) * ENABLE_FEATURE_HUMAN_READABLE, | 109 | OPT_HUMAN = (1 << (4 + 3*ENABLE_FEATURE_DF_FANCY)) * ENABLE_FEATURE_HUMAN_READABLE, |
110 | OPT_MEGA = (1 << (5 + 3*ENABLE_FEATURE_DF_FANCY)) * ENABLE_FEATURE_HUMAN_READABLE, | ||
110 | }; | 111 | }; |
111 | const char *disp_units_hdr = NULL; | 112 | const char *disp_units_hdr = NULL; |
112 | char *chp; | 113 | char *chp, *opt_t; |
113 | 114 | ||
114 | init_unicode(); | 115 | init_unicode(); |
115 | 116 | ||
117 | /* From the manpage of df from coreutils-6.10: | ||
118 | * Disk space is shown in 1K blocks by default, unless the environment | ||
119 | * variable POSIXLY_CORRECT is set, in which case 512-byte blocks are used. | ||
120 | */ | ||
121 | if (getenv("POSIXLY_CORRECT")) /* TODO - a new libbb function? */ | ||
122 | df_disp_hr = 512; | ||
123 | |||
116 | opt = getopt32(argv, "^" | 124 | opt = getopt32(argv, "^" |
117 | "kPT" | 125 | "kPTt:" |
118 | IF_FEATURE_DF_FANCY("aiB:") | 126 | IF_FEATURE_DF_FANCY("aiB:") |
119 | IF_FEATURE_HUMAN_READABLE("hm") | 127 | IF_FEATURE_HUMAN_READABLE("hm") |
120 | "\0" | 128 | "\0" |
@@ -123,6 +131,7 @@ int df_main(int argc UNUSED_PARAM, char **argv) | |||
123 | #elif ENABLE_FEATURE_HUMAN_READABLE | 131 | #elif ENABLE_FEATURE_HUMAN_READABLE |
124 | "k-m:m-k" | 132 | "k-m:m-k" |
125 | #endif | 133 | #endif |
134 | , &opt_t | ||
126 | IF_FEATURE_DF_FANCY(, &chp) | 135 | IF_FEATURE_DF_FANCY(, &chp) |
127 | ); | 136 | ); |
128 | if (opt & OPT_MEGA) | 137 | if (opt & OPT_MEGA) |
@@ -142,13 +151,6 @@ int df_main(int argc UNUSED_PARAM, char **argv) | |||
142 | got_it: ; | 151 | got_it: ; |
143 | } | 152 | } |
144 | 153 | ||
145 | /* From the manpage of df from coreutils-6.10: | ||
146 | * Disk space is shown in 1K blocks by default, unless the environment | ||
147 | * variable POSIXLY_CORRECT is set, in which case 512-byte blocks are used. | ||
148 | */ | ||
149 | if (getenv("POSIXLY_CORRECT")) /* TODO - a new libbb function? */ | ||
150 | df_disp_hr = 512; | ||
151 | |||
152 | if (opt & OPT_HUMAN) { | 154 | if (opt & OPT_HUMAN) { |
153 | df_disp_hr = 0; | 155 | df_disp_hr = 0; |
154 | disp_units_hdr = " Size"; | 156 | disp_units_hdr = " Size"; |
@@ -214,6 +216,11 @@ int df_main(int argc UNUSED_PARAM, char **argv) | |||
214 | mount_point = mount_entry->mnt_dir; | 216 | mount_point = mount_entry->mnt_dir; |
215 | fs_type = mount_entry->mnt_type; | 217 | fs_type = mount_entry->mnt_type; |
216 | 218 | ||
219 | if (opt & OPT_t) { | ||
220 | if (strcmp(fs_type, opt_t) != 0) | ||
221 | continue; | ||
222 | } | ||
223 | |||
217 | if (statvfs(mount_point, &s) != 0) { | 224 | if (statvfs(mount_point, &s) != 0) { |
218 | bb_simple_perror_msg(mount_point); | 225 | bb_simple_perror_msg(mount_point); |
219 | goto set_error; | 226 | goto set_error; |
diff --git a/coreutils/du.c b/coreutils/du.c index 247a08c95..092647468 100644 --- a/coreutils/du.c +++ b/coreutils/du.c | |||
@@ -42,6 +42,7 @@ | |||
42 | //usage:#define du_full_usage "\n\n" | 42 | //usage:#define du_full_usage "\n\n" |
43 | //usage: "Summarize disk space used for FILEs (or directories)\n" | 43 | //usage: "Summarize disk space used for FILEs (or directories)\n" |
44 | //usage: "\n -a Show file sizes too" | 44 | //usage: "\n -a Show file sizes too" |
45 | //usage: "\n -b Apparent size (including holes)" | ||
45 | //usage: "\n -L Follow all symlinks" | 46 | //usage: "\n -L Follow all symlinks" |
46 | //usage: "\n -H Follow symlinks on command line" | 47 | //usage: "\n -H Follow symlinks on command line" |
47 | //usage: "\n -d N Limit output to directories (and files with -a) of depth < N" | 48 | //usage: "\n -d N Limit output to directories (and files with -a) of depth < N" |
@@ -84,8 +85,9 @@ enum { | |||
84 | OPT_d_maxdepth = (1 << 6), | 85 | OPT_d_maxdepth = (1 << 6), |
85 | OPT_l_hardlinks = (1 << 7), | 86 | OPT_l_hardlinks = (1 << 7), |
86 | OPT_c_total = (1 << 8), | 87 | OPT_c_total = (1 << 8), |
87 | OPT_h_for_humans = (1 << 9), | 88 | OPT_b = (1 << 9), |
88 | OPT_m_mbytes = (1 << 10), | 89 | OPT_h_for_humans = (1 << 10), |
90 | OPT_m_mbytes = (1 << 11), | ||
89 | }; | 91 | }; |
90 | 92 | ||
91 | struct globals { | 93 | struct globals { |
@@ -109,7 +111,7 @@ static void print(unsigned long long size, const char *filename) | |||
109 | /* TODO - May not want to defer error checking here. */ | 111 | /* TODO - May not want to defer error checking here. */ |
110 | #if ENABLE_FEATURE_HUMAN_READABLE | 112 | #if ENABLE_FEATURE_HUMAN_READABLE |
111 | # if ENABLE_DESKTOP | 113 | # if ENABLE_DESKTOP |
112 | /* ~30 bytes of code for extra comtat: | 114 | /* ~30 bytes of code for extra compat: |
113 | * coreutils' du rounds sizes up: | 115 | * coreutils' du rounds sizes up: |
114 | * for example, 1025k file is shown as "2" by du -m. | 116 | * for example, 1025k file is shown as "2" by du -m. |
115 | * We round to nearest if human-readable [too hard to fix], | 117 | * We round to nearest if human-readable [too hard to fix], |
@@ -124,12 +126,16 @@ static void print(unsigned long long size, const char *filename) | |||
124 | * If G.disp_unit == 0, show one fractional | 126 | * If G.disp_unit == 0, show one fractional |
125 | * and use suffixes | 127 | * and use suffixes |
126 | */ | 128 | */ |
127 | make_human_readable_str(size, 512, G.disp_unit), | 129 | make_human_readable_str(size, (option_mask32 & OPT_b) ? 1 : 512, G.disp_unit), |
128 | filename); | 130 | filename); |
129 | #else | 131 | #else |
130 | if (G.disp_k) { | 132 | if (G.disp_k) { |
131 | size++; | 133 | if (!(option_mask32 & OPT_b)) { |
132 | size >>= 1; | 134 | size++; |
135 | size >>= 1; | ||
136 | } else { | ||
137 | size >>= 10; | ||
138 | } | ||
133 | } | 139 | } |
134 | printf("%"LL_FMT"u\t%s\n", size, filename); | 140 | printf("%"LL_FMT"u\t%s\n", size, filename); |
135 | #endif | 141 | #endif |
@@ -155,7 +161,7 @@ static unsigned long long du(const char *filename) | |||
155 | } | 161 | } |
156 | } | 162 | } |
157 | 163 | ||
158 | sum = statbuf.st_blocks; | 164 | sum = ((option_mask32 & OPT_b) ? statbuf.st_size : statbuf.st_blocks); |
159 | 165 | ||
160 | if (S_ISLNK(statbuf.st_mode)) { | 166 | if (S_ISLNK(statbuf.st_mode)) { |
161 | if (G.slink_depth > G.du_depth) { /* -H or -L */ | 167 | if (G.slink_depth > G.du_depth) { /* -H or -L */ |
@@ -164,7 +170,7 @@ static unsigned long long du(const char *filename) | |||
164 | G.status = EXIT_FAILURE; | 170 | G.status = EXIT_FAILURE; |
165 | return 0; | 171 | return 0; |
166 | } | 172 | } |
167 | sum = statbuf.st_blocks; | 173 | sum = ((option_mask32 & OPT_b) ? statbuf.st_size : statbuf.st_blocks); |
168 | if (G.slink_depth == 1) { | 174 | if (G.slink_depth == 1) { |
169 | /* Convert -H to -L */ | 175 | /* Convert -H to -L */ |
170 | G.slink_depth = INT_MAX; | 176 | G.slink_depth = INT_MAX; |
@@ -241,11 +247,14 @@ int du_main(int argc UNUSED_PARAM, char **argv) | |||
241 | */ | 247 | */ |
242 | #if ENABLE_FEATURE_HUMAN_READABLE | 248 | #if ENABLE_FEATURE_HUMAN_READABLE |
243 | opt = getopt32(argv, "^" | 249 | opt = getopt32(argv, "^" |
244 | "aHkLsxd:+lchm" | 250 | "aHkLsxd:+lcbhm" |
245 | "\0" "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s", | 251 | "\0" "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s", |
246 | &G.max_print_depth | 252 | &G.max_print_depth |
247 | ); | 253 | ); |
248 | argv += optind; | 254 | argv += optind; |
255 | if (opt & OPT_b) { | ||
256 | G.disp_unit = 1; | ||
257 | } | ||
249 | if (opt & OPT_h_for_humans) { | 258 | if (opt & OPT_h_for_humans) { |
250 | G.disp_unit = 0; | 259 | G.disp_unit = 0; |
251 | } | 260 | } |
@@ -257,16 +266,16 @@ int du_main(int argc UNUSED_PARAM, char **argv) | |||
257 | } | 266 | } |
258 | #else | 267 | #else |
259 | opt = getopt32(argv, "^" | 268 | opt = getopt32(argv, "^" |
260 | "aHkLsxd:+lc" | 269 | "aHkLsxd:+lcb" |
261 | "\0" "H-L:L-H:s-d:d-s", | 270 | "\0" "H-L:L-H:s-d:d-s", |
262 | &G.max_print_depth | 271 | &G.max_print_depth |
263 | ); | 272 | ); |
264 | argv += optind; | 273 | argv += optind; |
265 | #if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K | 274 | # if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K |
266 | if (opt & OPT_k_kbytes) { | 275 | if (opt & OPT_k_kbytes) { |
267 | G.disp_k = 1; | 276 | G.disp_k = 1; |
268 | } | 277 | } |
269 | #endif | 278 | # endif |
270 | #endif | 279 | #endif |
271 | if (opt & OPT_H_follow_links) { | 280 | if (opt & OPT_H_follow_links) { |
272 | G.slink_depth = 1; | 281 | G.slink_depth = 1; |
diff --git a/coreutils/echo.c b/coreutils/echo.c index aab177cee..82f0358b6 100644 --- a/coreutils/echo.c +++ b/coreutils/echo.c | |||
@@ -43,10 +43,10 @@ | |||
43 | //usage:#define echo_trivial_usage | 43 | //usage:#define echo_trivial_usage |
44 | //usage: IF_FEATURE_FANCY_ECHO("[-neE] ") "[ARG]..." | 44 | //usage: IF_FEATURE_FANCY_ECHO("[-neE] ") "[ARG]..." |
45 | //usage:#define echo_full_usage "\n\n" | 45 | //usage:#define echo_full_usage "\n\n" |
46 | //usage: "Print the specified ARGs to stdout" | 46 | //usage: "Print ARGs to stdout" |
47 | //usage: IF_FEATURE_FANCY_ECHO( "\n" | 47 | //usage: IF_FEATURE_FANCY_ECHO( "\n" |
48 | //usage: "\n -n Suppress trailing newline" | 48 | //usage: "\n -n No trailing newline" |
49 | //usage: "\n -e Interpret backslash escapes (i.e., \\t=tab)" | 49 | //usage: "\n -e Interpret backslash escapes (\\t=tab etc)" |
50 | //usage: "\n -E Don't interpret backslash escapes (default)" | 50 | //usage: "\n -E Don't interpret backslash escapes (default)" |
51 | //usage: ) | 51 | //usage: ) |
52 | //usage: | 52 | //usage: |
diff --git a/coreutils/env.c b/coreutils/env.c index c37c0c2df..a0ea4dd27 100644 --- a/coreutils/env.c +++ b/coreutils/env.c | |||
@@ -39,12 +39,15 @@ | |||
39 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/env.html */ | 39 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/env.html */ |
40 | 40 | ||
41 | //usage:#define env_trivial_usage | 41 | //usage:#define env_trivial_usage |
42 | //usage: "[-iu] [-] [name=value]... [PROG ARGS]" | 42 | //usage: "[-i0] [-u NAME]... [-] [NAME=VALUE]... [PROG ARGS]" |
43 | // The "-" can occur only once (unlike, say, -i): it terminates option processing, | ||
44 | // so if it is followed by another "-" arg (or any option-looking arg), | ||
45 | // that arg will be taken as PROG (or even as NAME=VALUE, example: "-z=QWE"). | ||
43 | //usage:#define env_full_usage "\n\n" | 46 | //usage:#define env_full_usage "\n\n" |
44 | //usage: "Print the current environment or run PROG after setting up\n" | 47 | //usage: "Print current environment or run PROG after setting up environment\n" |
45 | //usage: "the specified environment\n" | 48 | //usage: "\n -, -i Start with empty environment" |
46 | //usage: "\n -, -i Start with an empty environment" | 49 | //usage: "\n -0 NUL terminated output" |
47 | //usage: "\n -u Remove variable from the environment" | 50 | //usage: "\n -u NAME Remove variable from environment" |
48 | 51 | ||
49 | #include "libbb.h" | 52 | #include "libbb.h" |
50 | 53 | ||
@@ -54,8 +57,9 @@ int env_main(int argc UNUSED_PARAM, char **argv) | |||
54 | unsigned opts; | 57 | unsigned opts; |
55 | llist_t *unset_env = NULL; | 58 | llist_t *unset_env = NULL; |
56 | 59 | ||
57 | opts = getopt32long(argv, "+iu:*", | 60 | opts = getopt32long(argv, "+i0u:*", |
58 | "ignore-environment\0" No_argument "i" | 61 | "ignore-environment\0" No_argument "i" |
62 | "null\0" No_argument "0" | ||
59 | "unset\0" Required_argument "u" | 63 | "unset\0" Required_argument "u" |
60 | , &unset_env | 64 | , &unset_env |
61 | ); | 65 | ); |
@@ -90,8 +94,9 @@ int env_main(int argc UNUSED_PARAM, char **argv) | |||
90 | 94 | ||
91 | if (environ) { /* clearenv() may set environ == NULL! */ | 95 | if (environ) { /* clearenv() may set environ == NULL! */ |
92 | char **ep; | 96 | char **ep; |
97 | opts = (opts & 2) ? 0 : '\n'; | ||
93 | for (ep = environ; *ep; ep++) { | 98 | for (ep = environ; *ep; ep++) { |
94 | puts(*ep); | 99 | printf("%s%c", *ep, opts); |
95 | } | 100 | } |
96 | } | 101 | } |
97 | 102 | ||
diff --git a/coreutils/expr.c b/coreutils/expr.c index c11505d13..b896acd44 100644 --- a/coreutils/expr.c +++ b/coreutils/expr.c | |||
@@ -45,7 +45,7 @@ | |||
45 | //usage:#define expr_trivial_usage | 45 | //usage:#define expr_trivial_usage |
46 | //usage: "EXPRESSION" | 46 | //usage: "EXPRESSION" |
47 | //usage:#define expr_full_usage "\n\n" | 47 | //usage:#define expr_full_usage "\n\n" |
48 | //usage: "Print the value of EXPRESSION to stdout\n" | 48 | //usage: "Print the value of EXPRESSION\n" |
49 | //usage: "\n" | 49 | //usage: "\n" |
50 | //usage: "EXPRESSION may be:\n" | 50 | //usage: "EXPRESSION may be:\n" |
51 | //usage: " ARG1 | ARG2 ARG1 if it is neither null nor 0, otherwise ARG2\n" | 51 | //usage: " ARG1 | ARG2 ARG1 if it is neither null nor 0, otherwise ARG2\n" |
@@ -63,7 +63,7 @@ | |||
63 | //usage: " ARG1 % ARG2\n" | 63 | //usage: " ARG1 % ARG2\n" |
64 | //usage: " STRING : REGEXP Anchored pattern match of REGEXP in STRING\n" | 64 | //usage: " STRING : REGEXP Anchored pattern match of REGEXP in STRING\n" |
65 | //usage: " match STRING REGEXP Same as STRING : REGEXP\n" | 65 | //usage: " match STRING REGEXP Same as STRING : REGEXP\n" |
66 | //usage: " substr STRING POS LENGTH Substring of STRING, POS counted from 1\n" | 66 | //usage: " substr STRING POS LEN Substring of STRING, POS counts from 1\n" |
67 | //usage: " index STRING CHARS Index in STRING where any CHARS is found, or 0\n" | 67 | //usage: " index STRING CHARS Index in STRING where any CHARS is found, or 0\n" |
68 | //usage: " length STRING Length of STRING\n" | 68 | //usage: " length STRING Length of STRING\n" |
69 | //usage: " quote TOKEN Interpret TOKEN as a string, even if\n" | 69 | //usage: " quote TOKEN Interpret TOKEN as a string, even if\n" |
diff --git a/coreutils/id.c b/coreutils/id.c index f453a87ae..18bda3c55 100644 --- a/coreutils/id.c +++ b/coreutils/id.c | |||
@@ -52,7 +52,7 @@ | |||
52 | //usage:#define groups_trivial_usage | 52 | //usage:#define groups_trivial_usage |
53 | //usage: "[USER]" | 53 | //usage: "[USER]" |
54 | //usage:#define groups_full_usage "\n\n" | 54 | //usage:#define groups_full_usage "\n\n" |
55 | //usage: "Print the group memberships of USER or for the current process" | 55 | //usage: "Print the groups USER is in" |
56 | //usage: | 56 | //usage: |
57 | //usage:#define groups_example_usage | 57 | //usage:#define groups_example_usage |
58 | //usage: "$ groups\n" | 58 | //usage: "$ groups\n" |
diff --git a/coreutils/mv.c b/coreutils/mv.c index f5ed9fcfc..fd2422683 100644 --- a/coreutils/mv.c +++ b/coreutils/mv.c | |||
@@ -23,13 +23,15 @@ | |||
23 | //kbuild:lib-$(CONFIG_MV) += mv.o | 23 | //kbuild:lib-$(CONFIG_MV) += mv.o |
24 | 24 | ||
25 | //usage:#define mv_trivial_usage | 25 | //usage:#define mv_trivial_usage |
26 | //usage: "[-fin] SOURCE DEST\n" | 26 | //usage: "[-finT] SOURCE DEST\n" |
27 | //usage: "or: mv [-fin] SOURCE... DIRECTORY" | 27 | //usage: "or: mv [-fin] SOURCE... { -t DIRECTORY | DIRECTORY }" |
28 | //usage:#define mv_full_usage "\n\n" | 28 | //usage:#define mv_full_usage "\n\n" |
29 | //usage: "Rename SOURCE to DEST, or move SOURCEs to DIRECTORY\n" | 29 | //usage: "Rename SOURCE to DEST, or move SOURCEs to DIRECTORY\n" |
30 | //usage: "\n -f Don't prompt before overwriting" | 30 | //usage: "\n -f Don't prompt before overwriting" |
31 | //usage: "\n -i Interactive, prompt before overwrite" | 31 | //usage: "\n -i Interactive, prompt before overwrite" |
32 | //usage: "\n -n Don't overwrite an existing file" | 32 | //usage: "\n -n Don't overwrite an existing file" |
33 | //usage: "\n -T Refuse to move if DEST is a directory" | ||
34 | //usage: "\n -t DIR Move all SOURCEs into DIR" | ||
33 | //usage: | 35 | //usage: |
34 | //usage:#define mv_example_usage | 36 | //usage:#define mv_example_usage |
35 | //usage: "$ mv /tmp/foo /bin/bar\n" | 37 | //usage: "$ mv /tmp/foo /bin/bar\n" |
@@ -40,7 +42,7 @@ | |||
40 | int mv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 42 | int mv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
41 | int mv_main(int argc, char **argv) | 43 | int mv_main(int argc, char **argv) |
42 | { | 44 | { |
43 | struct stat dest_stat; | 45 | struct stat statbuf; |
44 | const char *last; | 46 | const char *last; |
45 | const char *dest; | 47 | const char *dest; |
46 | unsigned flags; | 48 | unsigned flags; |
@@ -51,41 +53,66 @@ int mv_main(int argc, char **argv) | |||
51 | #define OPT_FORCE (1 << 0) | 53 | #define OPT_FORCE (1 << 0) |
52 | #define OPT_INTERACTIVE (1 << 1) | 54 | #define OPT_INTERACTIVE (1 << 1) |
53 | #define OPT_NOCLOBBER (1 << 2) | 55 | #define OPT_NOCLOBBER (1 << 2) |
54 | #define OPT_VERBOSE ((1 << 3) * ENABLE_FEATURE_VERBOSE) | 56 | #define OPT_DESTNOTDIR (1 << 3) |
55 | /* Need at least two arguments. | 57 | #define OPT_DESTDIR (1 << 4) |
56 | * If more than one of -f, -i, -n is specified , only the final one | 58 | #define OPT_VERBOSE ((1 << 5) * ENABLE_FEATURE_VERBOSE) |
57 | * takes effect (it unsets previous options). | ||
58 | */ | ||
59 | flags = getopt32long(argv, "^" | 59 | flags = getopt32long(argv, "^" |
60 | "finv" | 60 | "finTt:v" |
61 | "\0" | 61 | "\0" |
62 | "-2:f-in:i-fn:n-fi", | 62 | /* At least one argument. (Usually two+, but -t DIR can have only one) */ |
63 | "-1" | ||
64 | /* only the final one of -f, -i, -n takes effect */ | ||
65 | ":f-in:i-fn:n-fi" | ||
66 | /* -t and -T don't mix */ | ||
67 | ":t--T:T--t", | ||
63 | "interactive\0" No_argument "i" | 68 | "interactive\0" No_argument "i" |
64 | "force\0" No_argument "f" | 69 | "force\0" No_argument "f" |
65 | "no-clobber\0" No_argument "n" | 70 | "no-clobber\0" No_argument "n" |
71 | "no-target-directory\0" No_argument "T" | ||
72 | "target-directory\0" Required_argument "t" | ||
66 | IF_FEATURE_VERBOSE( | 73 | IF_FEATURE_VERBOSE( |
67 | "verbose\0" No_argument "v" | 74 | "verbose\0" No_argument "v", |
75 | &last | ||
68 | ) | 76 | ) |
69 | ); | 77 | ); |
70 | argc -= optind; | 78 | argc -= optind; |
71 | argv += optind; | 79 | argv += optind; |
72 | last = argv[argc - 1]; | ||
73 | 80 | ||
74 | if (argc == 2) { | 81 | if (!(flags & OPT_DESTDIR)) { |
75 | dest_exists = cp_mv_stat(last, &dest_stat); | 82 | last = argv[argc - 1]; |
76 | if (dest_exists < 0) { | 83 | if (argc < 2) |
77 | return EXIT_FAILURE; | 84 | bb_show_usage(); |
78 | } | 85 | if (argc != 2) { |
79 | 86 | if (flags & OPT_DESTNOTDIR) | |
80 | if (!(dest_exists & 2)) { /* last is not a directory */ | 87 | bb_show_usage(); |
81 | dest = last; | 88 | /* "mv A B C... DIR" - target must be dir */ |
82 | goto DO_MOVE; | 89 | } else /* argc == 2 */ { |
90 | /* "mv A B" - only case where target can be not a dir */ | ||
91 | dest_exists = cp_mv_stat(last, &statbuf); | ||
92 | if (dest_exists < 0) { /* error other than ENOENT */ | ||
93 | return EXIT_FAILURE; | ||
94 | } | ||
95 | if (!(dest_exists & 2)) { | ||
96 | /* last is not a directory */ | ||
97 | dest = last; | ||
98 | goto DO_MOVE; | ||
99 | } | ||
100 | /* last is a directory */ | ||
101 | if (flags & OPT_DESTNOTDIR) { | ||
102 | if (stat(argv[0], &statbuf) == 0 && !S_ISDIR(statbuf.st_mode)) | ||
103 | bb_error_msg_and_die("'%s' is a directory", last); | ||
104 | /* "mv -T DIR1 DIR2" is allowed (renames a dir) */ | ||
105 | dest = last; | ||
106 | goto DO_MOVE; | ||
107 | } | ||
108 | /* else: fall through into "do { move SRC to DIR/SRC } while" loop */ | ||
83 | } | 109 | } |
84 | } | 110 | } |
111 | /* else: last is DIR from "-t DIR" */ | ||
85 | 112 | ||
86 | do { | 113 | do { |
87 | dest = concat_path_file(last, bb_get_last_path_component_strip(*argv)); | 114 | dest = concat_path_file(last, bb_get_last_path_component_strip(*argv)); |
88 | dest_exists = cp_mv_stat(dest, &dest_stat); | 115 | dest_exists = cp_mv_stat(dest, &statbuf); |
89 | if (dest_exists < 0) { | 116 | if (dest_exists < 0) { |
90 | goto RET_1; | 117 | goto RET_1; |
91 | } | 118 | } |
@@ -108,11 +135,10 @@ int mv_main(int argc, char **argv) | |||
108 | } | 135 | } |
109 | 136 | ||
110 | if (rename(*argv, dest) < 0) { | 137 | if (rename(*argv, dest) < 0) { |
111 | struct stat source_stat; | ||
112 | int source_exists; | 138 | int source_exists; |
113 | 139 | ||
114 | if (errno != EXDEV | 140 | if (errno != EXDEV |
115 | || (source_exists = cp_mv_stat2(*argv, &source_stat, lstat)) < 1 | 141 | || (source_exists = cp_mv_stat2(*argv, &statbuf, lstat)) < 1 |
116 | ) { | 142 | ) { |
117 | bb_perror_msg("can't rename '%s'", *argv); | 143 | bb_perror_msg("can't rename '%s'", *argv); |
118 | } else { | 144 | } else { |
@@ -159,7 +185,7 @@ int mv_main(int argc, char **argv) | |||
159 | if (dest != last) { | 185 | if (dest != last) { |
160 | free((void *) dest); | 186 | free((void *) dest); |
161 | } | 187 | } |
162 | } while (*++argv != last); | 188 | } while (*++argv && *argv != last); |
163 | 189 | ||
164 | return status; | 190 | return status; |
165 | } | 191 | } |
diff --git a/coreutils/nproc.c b/coreutils/nproc.c index 7025765c5..b345255a7 100644 --- a/coreutils/nproc.c +++ b/coreutils/nproc.c | |||
@@ -14,7 +14,7 @@ | |||
14 | //kbuild:lib-$(CONFIG_NPROC) += nproc.o | 14 | //kbuild:lib-$(CONFIG_NPROC) += nproc.o |
15 | 15 | ||
16 | //usage:#define nproc_trivial_usage | 16 | //usage:#define nproc_trivial_usage |
17 | //usage: ""IF_LONG_OPTS("--all --ignore=N") | 17 | //usage: ""IF_LONG_OPTS("[--all] [--ignore=N]") |
18 | //usage:#define nproc_full_usage "\n\n" | 18 | //usage:#define nproc_full_usage "\n\n" |
19 | //usage: "Print number of available CPUs" | 19 | //usage: "Print number of available CPUs" |
20 | //usage: IF_LONG_OPTS( | 20 | //usage: IF_LONG_OPTS( |
@@ -49,7 +49,7 @@ int nproc_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
49 | if (cpuid && isdigit(cpuid[strlen(cpuid) - 1])) | 49 | if (cpuid && isdigit(cpuid[strlen(cpuid) - 1])) |
50 | count++; | 50 | count++; |
51 | } | 51 | } |
52 | closedir(cpusd); | 52 | IF_FEATURE_CLEAN_UP(closedir(cpusd);) |
53 | } | 53 | } |
54 | } else | 54 | } else |
55 | #endif | 55 | #endif |
diff --git a/coreutils/shred.c b/coreutils/shred.c index 0b11b9491..794d7b815 100644 --- a/coreutils/shred.c +++ b/coreutils/shred.c | |||
@@ -15,14 +15,15 @@ | |||
15 | //kbuild:lib-$(CONFIG_SHRED) += shred.o | 15 | //kbuild:lib-$(CONFIG_SHRED) += shred.o |
16 | 16 | ||
17 | //usage:#define shred_trivial_usage | 17 | //usage:#define shred_trivial_usage |
18 | //usage: "FILE..." | 18 | //usage: "[-fuz] [-n N] [-s SIZE] FILE..." |
19 | //usage:#define shred_full_usage "\n\n" | 19 | //usage:#define shred_full_usage "\n\n" |
20 | //usage: "Overwrite/delete FILEs\n" | 20 | //usage: "Overwrite/delete FILEs\n" |
21 | //usage: "\n -f Chmod to ensure writability" | 21 | //usage: "\n -f Chmod to ensure writability" |
22 | //usage: "\n -s SIZE Size to write" | ||
22 | //usage: "\n -n N Overwrite N times (default 3)" | 23 | //usage: "\n -n N Overwrite N times (default 3)" |
23 | //usage: "\n -z Final overwrite with zeros" | 24 | //usage: "\n -z Final overwrite with zeros" |
24 | //usage: "\n -u Remove file" | 25 | //usage: "\n -u Remove file" |
25 | //-x and -v are accepted but have no effect | 26 | //-x (exact: don't round up to 4k) and -v (verbose) are accepted but have no effect |
26 | 27 | ||
27 | /* shred (GNU coreutils) 8.25: | 28 | /* shred (GNU coreutils) 8.25: |
28 | -f, --force change permissions to allow writing if necessary | 29 | -f, --force change permissions to allow writing if necessary |
@@ -41,6 +42,7 @@ | |||
41 | int shred_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 42 | int shred_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
42 | int shred_main(int argc UNUSED_PARAM, char **argv) | 43 | int shred_main(int argc UNUSED_PARAM, char **argv) |
43 | { | 44 | { |
45 | char *opt_s; | ||
44 | int rand_fd = rand_fd; /* for compiler */ | 46 | int rand_fd = rand_fd; /* for compiler */ |
45 | int zero_fd; | 47 | int zero_fd; |
46 | unsigned num_iter = 3; | 48 | unsigned num_iter = 3; |
@@ -52,18 +54,16 @@ int shred_main(int argc UNUSED_PARAM, char **argv) | |||
52 | OPT_n = (1 << 3), | 54 | OPT_n = (1 << 3), |
53 | OPT_v = (1 << 4), | 55 | OPT_v = (1 << 4), |
54 | OPT_x = (1 << 5), | 56 | OPT_x = (1 << 5), |
57 | OPT_s = (1 << 6), | ||
55 | }; | 58 | }; |
56 | 59 | ||
57 | opt = getopt32(argv, "fuzn:+vx", &num_iter); | 60 | opt = getopt32(argv, "^" "fuzn:+vxs:" "\0" "-1"/*min 1 arg*/, &num_iter, &opt_s); |
58 | argv += optind; | 61 | argv += optind; |
59 | 62 | ||
60 | zero_fd = MINGW_SPECIAL(xopen)("/dev/zero", O_RDONLY); | 63 | zero_fd = MINGW_SPECIAL(xopen)("/dev/zero", O_RDONLY); |
61 | if (num_iter != 0) | 64 | if (num_iter != 0) |
62 | rand_fd = MINGW_SPECIAL(xopen)("/dev/urandom", O_RDONLY); | 65 | rand_fd = MINGW_SPECIAL(xopen)("/dev/urandom", O_RDONLY); |
63 | 66 | ||
64 | if (!*argv) | ||
65 | bb_show_usage(); | ||
66 | |||
67 | for (;;) { | 67 | for (;;) { |
68 | struct stat sb; | 68 | struct stat sb; |
69 | const char *fname; | 69 | const char *fname; |
@@ -85,6 +85,11 @@ int shred_main(int argc UNUSED_PARAM, char **argv) | |||
85 | if (fstat(fd, &sb) == 0 && sb.st_size > 0) { | 85 | if (fstat(fd, &sb) == 0 && sb.st_size > 0) { |
86 | off_t size = sb.st_size; | 86 | off_t size = sb.st_size; |
87 | 87 | ||
88 | if (opt & OPT_s) { | ||
89 | size = BB_STRTOOFF(opt_s, NULL, 0); /* accepts oct/hex */ | ||
90 | if (errno || size < 0) bb_show_usage(); | ||
91 | } | ||
92 | |||
88 | for (i = 0; i < num_iter; i++) { | 93 | for (i = 0; i < num_iter; i++) { |
89 | bb_copyfd_size(rand_fd, fd, size); | 94 | bb_copyfd_size(rand_fd, fd, size); |
90 | fdatasync(fd); | 95 | fdatasync(fd); |
@@ -94,18 +99,18 @@ int shred_main(int argc UNUSED_PARAM, char **argv) | |||
94 | bb_copyfd_size(zero_fd, fd, size); | 99 | bb_copyfd_size(zero_fd, fd, size); |
95 | fdatasync(fd); | 100 | fdatasync(fd); |
96 | } | 101 | } |
97 | if (opt & OPT_u) { | 102 | } |
98 | ftruncate(fd, 0); | 103 | if (opt & OPT_u) { |
104 | ftruncate(fd, 0); | ||
99 | #if ENABLE_PLATFORM_MINGW32 | 105 | #if ENABLE_PLATFORM_MINGW32 |
100 | xclose(fd); | 106 | xclose(fd); |
101 | #endif | 107 | #endif |
102 | xunlink(fname); | 108 | xunlink(fname); |
103 | } | 109 | } |
104 | #if ENABLE_PLATFORM_MINGW32 | 110 | #if ENABLE_PLATFORM_MINGW32 |
105 | else | 111 | else |
106 | #endif | 112 | #endif |
107 | xclose(fd); | 113 | xclose(fd); |
108 | } | ||
109 | } | 114 | } |
110 | 115 | ||
111 | return EXIT_SUCCESS; | 116 | return EXIT_SUCCESS; |
diff --git a/coreutils/sort.c b/coreutils/sort.c index 6c4e3038c..32a06e40a 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c | |||
@@ -67,7 +67,7 @@ | |||
67 | //usage: "\n -r Reverse sort order" | 67 | //usage: "\n -r Reverse sort order" |
68 | //usage: "\n -s Stable (don't sort ties alphabetically)" | 68 | //usage: "\n -s Stable (don't sort ties alphabetically)" |
69 | //usage: "\n -u Suppress duplicate lines" | 69 | //usage: "\n -u Suppress duplicate lines" |
70 | //usage: "\n -z Lines are terminated by NUL, not newline" | 70 | //usage: "\n -z NUL terminated input and output" |
71 | ///////: "\n -m Ignored for GNU compatibility" | 71 | ///////: "\n -m Ignored for GNU compatibility" |
72 | ///////: "\n -S BUFSZ Ignored for GNU compatibility" | 72 | ///////: "\n -S BUFSZ Ignored for GNU compatibility" |
73 | ///////: "\n -T TMPDIR Ignored for GNU compatibility" | 73 | ///////: "\n -T TMPDIR Ignored for GNU compatibility" |
diff --git a/coreutils/touch.c b/coreutils/touch.c index 2b225dd16..ec12eb7cf 100644 --- a/coreutils/touch.c +++ b/coreutils/touch.c | |||
@@ -31,7 +31,7 @@ | |||
31 | //kbuild:lib-$(CONFIG_TOUCH) += touch.o | 31 | //kbuild:lib-$(CONFIG_TOUCH) += touch.o |
32 | 32 | ||
33 | //usage:#define touch_trivial_usage | 33 | //usage:#define touch_trivial_usage |
34 | //usage: "[-c" IF_FEATURE_TOUCH_SUSV3("am") "]" | 34 | //usage: "[-ch" IF_FEATURE_TOUCH_SUSV3("am") "]" |
35 | //usage: IF_FEATURE_TOUCH_SUSV3(" [-d DATE] [-t DATE] [-r FILE]") | 35 | //usage: IF_FEATURE_TOUCH_SUSV3(" [-d DATE] [-t DATE] [-r FILE]") |
36 | //usage: " FILE..." | 36 | //usage: " FILE..." |
37 | //usage:#define touch_full_usage "\n\n" | 37 | //usage:#define touch_full_usage "\n\n" |
diff --git a/coreutils/tty.c b/coreutils/tty.c index ff6f2bb3b..e448c27ec 100644 --- a/coreutils/tty.c +++ b/coreutils/tty.c | |||
@@ -21,7 +21,7 @@ | |||
21 | /* http://www.opengroup.org/onlinepubs/9699919799/utilities/tty.html */ | 21 | /* http://www.opengroup.org/onlinepubs/9699919799/utilities/tty.html */ |
22 | 22 | ||
23 | //usage:#define tty_trivial_usage | 23 | //usage:#define tty_trivial_usage |
24 | //usage: "" | 24 | //usage: "" IF_INCLUDE_SUSv2("[-s]") |
25 | //usage:#define tty_full_usage "\n\n" | 25 | //usage:#define tty_full_usage "\n\n" |
26 | //usage: "Print file name of stdin's terminal" | 26 | //usage: "Print file name of stdin's terminal" |
27 | //usage: IF_INCLUDE_SUSv2( "\n" | 27 | //usage: IF_INCLUDE_SUSv2( "\n" |
diff --git a/coreutils/uname.c b/coreutils/uname.c index 2a1602b4c..da785ab4c 100644 --- a/coreutils/uname.c +++ b/coreutils/uname.c | |||
@@ -79,13 +79,13 @@ | |||
79 | //usage:#define uname_full_usage "\n\n" | 79 | //usage:#define uname_full_usage "\n\n" |
80 | //usage: "Print system information\n" | 80 | //usage: "Print system information\n" |
81 | //usage: "\n -a Print all" | 81 | //usage: "\n -a Print all" |
82 | //usage: "\n -m The machine (hardware) type" | 82 | //usage: "\n -m Machine (hardware) type" |
83 | //usage: "\n -n Hostname" | 83 | //usage: "\n -n Hostname" |
84 | //usage: "\n -r Kernel release" | 84 | //usage: "\n -r Kernel release" |
85 | //usage: "\n -s Kernel name (default)" | 85 | //usage: "\n -s Kernel name (default)" |
86 | //usage: "\n -p Processor type" | 86 | //usage: "\n -p Processor type" |
87 | //usage: "\n -v Kernel version" | 87 | //usage: "\n -v Kernel version" |
88 | //usage: "\n -i The hardware platform" | 88 | //usage: "\n -i Hardware platform" |
89 | //usage: "\n -o OS name" | 89 | //usage: "\n -o OS name" |
90 | //usage: | 90 | //usage: |
91 | //usage:#define uname_example_usage | 91 | //usage:#define uname_example_usage |
diff --git a/coreutils/uniq.c b/coreutils/uniq.c index e1594286f..a3058ac07 100644 --- a/coreutils/uniq.c +++ b/coreutils/uniq.c | |||
@@ -20,13 +20,14 @@ | |||
20 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/uniq.html */ | 20 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/uniq.html */ |
21 | 21 | ||
22 | //usage:#define uniq_trivial_usage | 22 | //usage:#define uniq_trivial_usage |
23 | //usage: "[-cdui] [-f,s,w N] [INPUT [OUTPUT]]" | 23 | //usage: "[-cduiz] [-f,s,w N] [FILE [OUTFILE]]" |
24 | //usage:#define uniq_full_usage "\n\n" | 24 | //usage:#define uniq_full_usage "\n\n" |
25 | //usage: "Discard duplicate lines\n" | 25 | //usage: "Discard duplicate lines\n" |
26 | //usage: "\n -c Prefix lines by the number of occurrences" | 26 | //usage: "\n -c Prefix lines by the number of occurrences" |
27 | //usage: "\n -d Only print duplicate lines" | 27 | //usage: "\n -d Only print duplicate lines" |
28 | //usage: "\n -u Only print unique lines" | 28 | //usage: "\n -u Only print unique lines" |
29 | //usage: "\n -i Ignore case" | 29 | //usage: "\n -i Ignore case" |
30 | //usage: "\n -z NUL terminated output" | ||
30 | //usage: "\n -f N Skip first N fields" | 31 | //usage: "\n -f N Skip first N fields" |
31 | //usage: "\n -s N Skip first N chars (after any skipped fields)" | 32 | //usage: "\n -s N Skip first N chars (after any skipped fields)" |
32 | //usage: "\n -w N Compare N characters in line" | 33 | //usage: "\n -w N Compare N characters in line" |
@@ -45,23 +46,25 @@ int uniq_main(int argc UNUSED_PARAM, char **argv) | |||
45 | const char *input_filename; | 46 | const char *input_filename; |
46 | unsigned skip_fields, skip_chars, max_chars; | 47 | unsigned skip_fields, skip_chars, max_chars; |
47 | unsigned opt; | 48 | unsigned opt; |
49 | char eol; | ||
48 | char *cur_line; | 50 | char *cur_line; |
49 | const char *cur_compare; | 51 | const char *cur_compare; |
50 | 52 | ||
51 | enum { | 53 | enum { |
52 | OPT_c = 0x1, | 54 | OPT_c = 1 << 0, |
53 | OPT_d = 0x2, /* print only dups */ | 55 | OPT_d = 1 << 1, /* print only dups */ |
54 | OPT_u = 0x4, /* print only uniq */ | 56 | OPT_u = 1 << 2, /* print only uniq */ |
55 | OPT_f = 0x8, | 57 | OPT_f = 1 << 3, |
56 | OPT_s = 0x10, | 58 | OPT_s = 1 << 4, |
57 | OPT_w = 0x20, | 59 | OPT_w = 1 << 5, |
58 | OPT_i = 0x40, | 60 | OPT_i = 1 << 6, |
61 | OPT_z = 1 << 7, | ||
59 | }; | 62 | }; |
60 | 63 | ||
61 | skip_fields = skip_chars = 0; | 64 | skip_fields = skip_chars = 0; |
62 | max_chars = INT_MAX; | 65 | max_chars = INT_MAX; |
63 | 66 | ||
64 | opt = getopt32(argv, "cduf:+s:+w:+i", &skip_fields, &skip_chars, &max_chars); | 67 | opt = getopt32(argv, "cduf:+s:+w:+iz", &skip_fields, &skip_chars, &max_chars); |
65 | argv += optind; | 68 | argv += optind; |
66 | 69 | ||
67 | input_filename = argv[0]; | 70 | input_filename = argv[0]; |
@@ -86,6 +89,7 @@ int uniq_main(int argc UNUSED_PARAM, char **argv) | |||
86 | } | 89 | } |
87 | 90 | ||
88 | cur_compare = cur_line = NULL; /* prime the pump */ | 91 | cur_compare = cur_line = NULL; /* prime the pump */ |
92 | eol = (opt & OPT_z) ? 0 : '\n'; | ||
89 | 93 | ||
90 | do { | 94 | do { |
91 | unsigned i; | 95 | unsigned i; |
@@ -127,7 +131,7 @@ int uniq_main(int argc UNUSED_PARAM, char **argv) | |||
127 | /* %7lu matches GNU coreutils 6.9 */ | 131 | /* %7lu matches GNU coreutils 6.9 */ |
128 | printf("%7lu ", dups + 1); | 132 | printf("%7lu ", dups + 1); |
129 | } | 133 | } |
130 | puts(old_line); | 134 | printf("%s%c", old_line, eol); |
131 | } | 135 | } |
132 | free(old_line); | 136 | free(old_line); |
133 | } | 137 | } |
diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c index 02b037276..a607977e9 100644 --- a/coreutils/uudecode.c +++ b/coreutils/uudecode.c | |||
@@ -183,7 +183,7 @@ int uudecode_main(int argc UNUSED_PARAM, char **argv) | |||
183 | //usage:#define base32_trivial_usage | 183 | //usage:#define base32_trivial_usage |
184 | //usage: "[-d] [-w COL] [FILE]" | 184 | //usage: "[-d] [-w COL] [FILE]" |
185 | //usage:#define base32_full_usage "\n\n" | 185 | //usage:#define base32_full_usage "\n\n" |
186 | //usage: "Base32 encode or decode FILE to standard output" | 186 | //usage: "Base32 encode or decode FILE to standard output\n" |
187 | //usage: "\n -d Decode data" | 187 | //usage: "\n -d Decode data" |
188 | //usage: "\n -w COL Wrap lines at COL (default 76, 0 disables)" | 188 | //usage: "\n -w COL Wrap lines at COL (default 76, 0 disables)" |
189 | ////usage: "\n -i When decoding, ignore non-alphabet characters" | 189 | ////usage: "\n -i When decoding, ignore non-alphabet characters" |
@@ -191,10 +191,12 @@ int uudecode_main(int argc UNUSED_PARAM, char **argv) | |||
191 | //usage:#define base64_trivial_usage | 191 | //usage:#define base64_trivial_usage |
192 | //usage: "[-d] [-w COL] [FILE]" | 192 | //usage: "[-d] [-w COL] [FILE]" |
193 | //usage:#define base64_full_usage "\n\n" | 193 | //usage:#define base64_full_usage "\n\n" |
194 | //usage: "Base64 encode or decode FILE to standard output" | 194 | //usage: "Base64 encode or decode FILE to standard output\n" |
195 | //usage: "\n -d Decode data" | 195 | //usage: "\n -d Decode data" |
196 | //usage: "\n -w COL Wrap lines at COL (default 76, 0 disables)" | 196 | //usage: "\n -w COL Wrap lines at COL (default 76, 0 disables)" |
197 | ////usage: "\n -i When decoding, ignore non-alphabet characters" | 197 | ///////: "\n -i When decoding, ignore non-alphabet characters" |
198 | // -i is accepted but has no effect: currently, decode_base32/64() functions | ||
199 | // (called via read_base64()) skip invalid chars unconditionally. | ||
198 | 200 | ||
199 | // APPLET_ODDNAME:name main location suid_type help | 201 | // APPLET_ODDNAME:name main location suid_type help |
200 | //applet:IF_BASE32(APPLET_ODDNAME(base32, baseNUM, BB_DIR_BIN, BB_SUID_DROP, base32)) | 202 | //applet:IF_BASE32(APPLET_ODDNAME(base32, baseNUM, BB_DIR_BIN, BB_SUID_DROP, base32)) |
@@ -272,7 +274,7 @@ int baseNUM_main(int argc UNUSED_PARAM, char **argv) | |||
272 | unsigned opts; | 274 | unsigned opts; |
273 | unsigned col = 76; | 275 | unsigned col = 76; |
274 | 276 | ||
275 | opts = getopt32(argv, "^" "dw:+" "\0" "?1"/* 1 arg max*/, &col); | 277 | opts = getopt32(argv, "^" "diw:+" "\0" "?1"/* 1 arg max*/, &col); |
276 | argv += optind; | 278 | argv += optind; |
277 | 279 | ||
278 | if (!argv[0]) | 280 | if (!argv[0]) |
diff --git a/coreutils/who.c b/coreutils/who.c index be9c3ccca..3725d77f5 100644 --- a/coreutils/who.c +++ b/coreutils/who.c | |||
@@ -78,7 +78,7 @@ | |||
78 | // root pts/1 Mon13 3:24m 1:01 0.01s w | 78 | // root pts/1 Mon13 3:24m 1:01 0.01s w |
79 | 79 | ||
80 | //usage:#define who_trivial_usage | 80 | //usage:#define who_trivial_usage |
81 | //usage: "[-a]" | 81 | //usage: "[-aH]" |
82 | //usage:#define who_full_usage "\n\n" | 82 | //usage:#define who_full_usage "\n\n" |
83 | //usage: "Show who is logged on\n" | 83 | //usage: "Show who is logged on\n" |
84 | //usage: "\n -a Show all" | 84 | //usage: "\n -a Show all" |
diff --git a/coreutils/yes.c b/coreutils/yes.c index 38ffff46c..64dfa500c 100644 --- a/coreutils/yes.c +++ b/coreutils/yes.c | |||
@@ -27,7 +27,7 @@ | |||
27 | //usage:#define yes_trivial_usage | 27 | //usage:#define yes_trivial_usage |
28 | //usage: "[STRING]" | 28 | //usage: "[STRING]" |
29 | //usage:#define yes_full_usage "\n\n" | 29 | //usage:#define yes_full_usage "\n\n" |
30 | //usage: "Repeatedly output a line with STRING, or 'y'" | 30 | //usage: "Repeatedly print a line with STRING, or 'y'" |
31 | 31 | ||
32 | #include "libbb.h" | 32 | #include "libbb.h" |
33 | 33 | ||