aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2013-02-07 14:25:54 +0000
committerRon Yorston <rmy@pobox.com>2013-02-07 14:25:54 +0000
commitb604585914e032b28bef3e337a978e56a9069cda (patch)
treeb2ee0a3fb38d10397c602d0fe215ea3bbbf334c0
parent0eda07c7ff8cf1fc11bc1bda5383f884d7adf031 (diff)
parentba76b7a40b929878833731f76306b1c977cc8650 (diff)
downloadbusybox-w32-b604585914e032b28bef3e337a978e56a9069cda.tar.gz
busybox-w32-b604585914e032b28bef3e337a978e56a9069cda.tar.bz2
busybox-w32-b604585914e032b28bef3e337a978e56a9069cda.zip
Merge branch 'busybox' into merge
-rw-r--r--Config.in15
-rw-r--r--Makefile2
-rw-r--r--archival/cpio.c30
-rw-r--r--archival/dpkg.c6
-rw-r--r--archival/gzip.c16
-rw-r--r--archival/libarchive/decompress_gunzip.c4
-rw-r--r--archival/libarchive/decompress_uncompress.c4
-rw-r--r--archival/libarchive/lzo1x_9x.c12
-rw-r--r--archival/libarchive/lzo1x_c.c2
-rw-r--r--archival/libarchive/lzo1x_d.c2
-rw-r--r--archival/lzop.c10
-rw-r--r--archival/tar.c14
-rw-r--r--archival/unzip.c19
-rw-r--r--console-tools/loadfont.c2
-rw-r--r--console-tools/setlogcons.c7
-rw-r--r--coreutils/Config.src12
-rw-r--r--coreutils/Kbuild.src1
-rw-r--r--coreutils/cal.c15
-rw-r--r--coreutils/chown.c4
-rw-r--r--coreutils/cut.c2
-rw-r--r--coreutils/df.c8
-rw-r--r--coreutils/du.c4
-rw-r--r--coreutils/id.c2
-rw-r--r--coreutils/ls.c4
-rw-r--r--coreutils/md5_sha1_sum.c19
-rw-r--r--coreutils/mknod.c2
-rw-r--r--coreutils/od_bloaty.c4
-rw-r--r--coreutils/sort.c2
-rw-r--r--coreutils/stat.c58
-rw-r--r--coreutils/stty.c2
-rw-r--r--coreutils/sum.c4
-rw-r--r--coreutils/test.c2
-rw-r--r--e2fsprogs/fsck.c4
-rw-r--r--editors/awk.c2
-rw-r--r--editors/diff.c2
-rw-r--r--editors/sed.c2
-rw-r--r--editors/vi.c40
-rw-r--r--findutils/find.c4
-rw-r--r--findutils/grep.c39
-rw-r--r--include/applets.src.h1
-rw-r--r--include/bb_archive.h6
-rw-r--r--include/grp_.h24
-rw-r--r--include/libbb.h11
-rw-r--r--include/platform.h5
-rw-r--r--include/pwd_.h24
-rw-r--r--include/shadow_.h14
-rw-r--r--init/init.c2
-rw-r--r--libbb/Config.src10
-rw-r--r--libbb/appletlib.c20
-rw-r--r--libbb/hash_md5_sha.c294
-rw-r--r--libbb/inet_common.c4
-rw-r--r--libbb/loop.c6
-rw-r--r--libbb/procps.c2
-rw-r--r--libbb/selinux_common.c2
-rw-r--r--libbb/xatonum_template.c2
-rw-r--r--libpwdgrp/pwd_grp.c14
-rw-r--r--miscutils/crond.c2
-rw-r--r--miscutils/dc.c20
-rw-r--r--miscutils/devfsd.c56
-rw-r--r--miscutils/fbsplash.c2
-rw-r--r--miscutils/flashcp.c26
-rw-r--r--miscutils/hdparm.c6
-rw-r--r--miscutils/last.c4
-rw-r--r--miscutils/last_fancy.c16
-rw-r--r--miscutils/less.c6
-rw-r--r--miscutils/rx.c4
-rw-r--r--miscutils/time.c2
-rw-r--r--miscutils/watchdog.c3
-rw-r--r--modutils/depmod.c6
-rw-r--r--modutils/rmmod.c2
-rw-r--r--networking/arp.c53
-rw-r--r--networking/brctl.c8
-rw-r--r--networking/ether-wake.c14
-rw-r--r--networking/httpd.c6
-rw-r--r--networking/httpd_ssi.c2
-rw-r--r--networking/ifconfig.c169
-rw-r--r--networking/ifenslave.c4
-rw-r--r--networking/ifplugd.c2
-rw-r--r--networking/inetd.c6
-rw-r--r--networking/interface.c31
-rw-r--r--networking/libiproute/ipaddress.c10
-rw-r--r--networking/libiproute/iprule.c14
-rw-r--r--networking/libiproute/iptunnel.c2
-rw-r--r--networking/nc.c2
-rw-r--r--networking/netstat.c2
-rw-r--r--networking/ntpd.c16
-rw-r--r--networking/ntpd_simple.c2
-rw-r--r--networking/ping.c2
-rw-r--r--networking/route.c20
-rw-r--r--networking/tc.c5
-rw-r--r--networking/traceroute.c7
-rw-r--r--networking/udhcp/d6_dhcpc.c28
-rw-r--r--networking/udhcp/dhcpc.c2
-rw-r--r--networking/udhcp/dhcpc.h6
-rw-r--r--networking/udhcp/dhcpd.h6
-rw-r--r--procps/nmeter.c2
-rw-r--r--procps/powertop.c4
-rw-r--r--procps/ps.c33
-rw-r--r--procps/sysctl.c2
-rw-r--r--procps/top.c4
-rw-r--r--runit/runsv.c2
-rw-r--r--runit/svlogd.c4
-rw-r--r--selinux/chcon.c20
-rw-r--r--selinux/runcon.c10
-rw-r--r--selinux/sestatus.c2
-rw-r--r--selinux/setfiles.c19
-rw-r--r--shell/ash.c17
-rw-r--r--shell/hush.c6
-rw-r--r--shell/math.c2
-rw-r--r--sysklogd/Config.src16
-rw-r--r--sysklogd/klogd.c10
-rw-r--r--sysklogd/syslogd.c82
-rw-r--r--testsuite/du/du-k-works4
-rwxr-xr-xtestsuite/grep.tests12
-rwxr-xr-xtestsuite/mdev.tests22
-rwxr-xr-xtestsuite/mkfs.minix.tests2
-rwxr-xr-xtestsuite/sha3sum.tests3
-rw-r--r--util-linux/Config.src10
-rw-r--r--util-linux/acpid.c2
-rw-r--r--util-linux/dmesg.c13
-rw-r--r--util-linux/fdformat.c2
-rw-r--r--util-linux/fdisk.c2
-rw-r--r--util-linux/fdisk_osf.c5
-rw-r--r--util-linux/flock.c2
-rw-r--r--util-linux/fsck_minix.c67
-rw-r--r--util-linux/getopt.c61
-rw-r--r--util-linux/ipcrm.c6
-rw-r--r--util-linux/ipcs.c256
-rw-r--r--util-linux/lspci.c6
-rw-r--r--util-linux/mdev.c25
-rw-r--r--util-linux/mount.c102
-rw-r--r--util-linux/readprofile.c16
-rw-r--r--util-linux/volume_id/hfs.c27
-rw-r--r--util-linux/volume_id/linux_raid.c6
-rw-r--r--util-linux/volume_id/nilfs.c2
-rw-r--r--util-linux/volume_id/ntfs.c4
-rw-r--r--util-linux/volume_id/squashfs.c49
-rw-r--r--util-linux/volume_id/udf.c2
-rw-r--r--util-linux/volume_id/unused_msdos.c2
-rw-r--r--util-linux/volume_id/unused_silicon_raid.c2
-rw-r--r--util-linux/volume_id/util.c25
-rw-r--r--util-linux/volume_id/volume_id.c3
-rw-r--r--util-linux/volume_id/volume_id_internal.h15
143 files changed, 1508 insertions, 880 deletions
diff --git a/Config.in b/Config.in
index def0c2c32..8999e1699 100644
--- a/Config.in
+++ b/Config.in
@@ -333,7 +333,18 @@ config FEATURE_PIDFILE
333 default y 333 default y
334 help 334 help
335 This option makes some applets (e.g. crond, syslogd, inetd) write 335 This option makes some applets (e.g. crond, syslogd, inetd) write
336 a pidfile in /var/run. Some applications rely on them. 336 a pidfile at the configured PID_FILE_PATH. It has no effect
337 on applets which require pidfiles to run.
338
339config PID_FILE_PATH
340 string "Path to directory for pidfile"
341 default "/var/run"
342 depends on FEATURE_PIDFILE
343 help
344 This is the default path where pidfiles are created. Applets which
345 allow you to set the pidfile path on the command line will override
346 this value. The option has no effect on applets that require you to
347 specify a pidfile path.
337 348
338config FEATURE_SUID 349config FEATURE_SUID
339 bool "Support for SUID/SGID handling" 350 bool "Support for SUID/SGID handling"
@@ -344,7 +355,7 @@ config FEATURE_SUID
344 root-level operations even when run by ordinary users 355 root-level operations even when run by ordinary users
345 (for example, mounting of user mounts in fstab needs this). 356 (for example, mounting of user mounts in fstab needs this).
346 357
347 Busybox will automatically drop priviledges for applets 358 Busybox will automatically drop privileges for applets
348 that don't need root access. 359 that don't need root access.
349 360
350 If you are really paranoid and don't want to do this, build two 361 If you are really paranoid and don't want to do this, build two
diff --git a/Makefile b/Makefile
index 22740d983..cecf6c02d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
1VERSION = 1 1VERSION = 1
2PATCHLEVEL = 21 2PATCHLEVEL = 22
3SUBLEVEL = 0 3SUBLEVEL = 0
4EXTRAVERSION = .git 4EXTRAVERSION = .git
5NAME = Unnamed 5NAME = Unnamed
diff --git a/archival/cpio.c b/archival/cpio.c
index 98cc18fa0..699c6dbb7 100644
--- a/archival/cpio.c
+++ b/archival/cpio.c
@@ -253,24 +253,24 @@ static NOINLINE int cpio_o(void)
253 } 253 }
254 254
255 bytes += printf("070701" 255 bytes += printf("070701"
256 "%08X%08X%08X%08X%08X%08X%08X" 256 "%08X%08X%08X%08X%08X%08X%08X"
257 "%08X%08X%08X%08X" /* GNU cpio uses uppercase hex */ 257 "%08X%08X%08X%08X" /* GNU cpio uses uppercase hex */
258 /* strlen+1: */ "%08X" 258 /* strlen+1: */ "%08X"
259 /* chksum: */ "00000000" /* (only for "070702" files) */ 259 /* chksum: */ "00000000" /* (only for "070702" files) */
260 /* name,NUL: */ "%s%c", 260 /* name,NUL: */ "%s%c",
261 (unsigned)(uint32_t) st.st_ino, 261 (unsigned)(uint32_t) st.st_ino,
262 (unsigned)(uint32_t) st.st_mode, 262 (unsigned)(uint32_t) st.st_mode,
263 (unsigned)(uint32_t) st.st_uid, 263 (unsigned)(uint32_t) st.st_uid,
264 (unsigned)(uint32_t) st.st_gid, 264 (unsigned)(uint32_t) st.st_gid,
265 (unsigned)(uint32_t) st.st_nlink, 265 (unsigned)(uint32_t) st.st_nlink,
266 (unsigned)(uint32_t) st.st_mtime, 266 (unsigned)(uint32_t) st.st_mtime,
267 (unsigned)(uint32_t) st.st_size, 267 (unsigned)(uint32_t) st.st_size,
268 (unsigned)(uint32_t) major(st.st_dev), 268 (unsigned)(uint32_t) major(st.st_dev),
269 (unsigned)(uint32_t) minor(st.st_dev), 269 (unsigned)(uint32_t) minor(st.st_dev),
270 (unsigned)(uint32_t) major(st.st_rdev), 270 (unsigned)(uint32_t) major(st.st_rdev),
271 (unsigned)(uint32_t) minor(st.st_rdev), 271 (unsigned)(uint32_t) minor(st.st_rdev),
272 (unsigned)(strlen(name) + 1), 272 (unsigned)(strlen(name) + 1),
273 name, '\0'); 273 name, '\0');
274 bytes = cpio_pad4(bytes); 274 bytes = cpio_pad4(bytes);
275 275
276 if (st.st_size) { 276 if (st.st_size) {
diff --git a/archival/dpkg.c b/archival/dpkg.c
index dae8a9747..ed86f3355 100644
--- a/archival/dpkg.c
+++ b/archival/dpkg.c
@@ -1026,8 +1026,8 @@ static int check_deps(deb_file_t **deb_file, int deb_start /*, int dep_max_count
1026 if (package_edge->type == EDGE_CONFLICTS) { 1026 if (package_edge->type == EDGE_CONFLICTS) {
1027 const unsigned package_num = 1027 const unsigned package_num =
1028 search_package_hashtable(package_edge->name, 1028 search_package_hashtable(package_edge->name,
1029 package_edge->version, 1029 package_edge->version,
1030 package_edge->operator); 1030 package_edge->operator);
1031 int result = 0; 1031 int result = 0;
1032 if (package_hashtable[package_num] != NULL) { 1032 if (package_hashtable[package_num] != NULL) {
1033 status_num = search_status_hashtable(name_hashtable[package_hashtable[package_num]->name]); 1033 status_num = search_status_hashtable(name_hashtable[package_hashtable[package_num]->name]);
@@ -1114,7 +1114,7 @@ static int check_deps(deb_file_t **deb_file, int deb_start /*, int dep_max_count
1114 */ 1114 */
1115 if (root_of_alternatives && package_edge->type != root_of_alternatives->type - 1) 1115 if (root_of_alternatives && package_edge->type != root_of_alternatives->type - 1)
1116 bb_error_msg_and_die("fatal error, package dependencies corrupt: %d != %d - 1", 1116 bb_error_msg_and_die("fatal error, package dependencies corrupt: %d != %d - 1",
1117 package_edge->type, root_of_alternatives->type); 1117 package_edge->type, root_of_alternatives->type);
1118 1118
1119 if (package_hashtable[package_num] != NULL) 1119 if (package_hashtable[package_num] != NULL)
1120 result = !package_satisfies_dependency(package_num, package_edge->type); 1120 result = !package_satisfies_dependency(package_num, package_edge->type);
diff --git a/archival/gzip.c b/archival/gzip.c
index 80db4f969..31ccab3cd 100644
--- a/archival/gzip.c
+++ b/archival/gzip.c
@@ -1179,7 +1179,7 @@ static void gen_codes(ct_data * tree, int max_code)
1179 * must be all ones. 1179 * must be all ones.
1180 */ 1180 */
1181 Assert(code + G2.bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, 1181 Assert(code + G2.bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1,
1182 "inconsistent bit counts"); 1182 "inconsistent bit counts");
1183 Tracev((stderr, "\ngen_codes: max_code %d ", max_code)); 1183 Tracev((stderr, "\ngen_codes: max_code %d ", max_code));
1184 1184
1185 for (n = 0; n <= max_code; n++) { 1185 for (n = 0; n <= max_code; n++) {
@@ -1527,9 +1527,9 @@ static int ct_tally(int dist, int lc)
1527 } 1527 }
1528 out_length >>= 3; 1528 out_length >>= 3;
1529 Trace((stderr, 1529 Trace((stderr,
1530 "\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", 1530 "\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ",
1531 G2.last_lit, G2.last_dist, in_length, out_length, 1531 G2.last_lit, G2.last_dist, in_length, out_length,
1532 100L - out_length * 100L / in_length)); 1532 100L - out_length * 100L / in_length));
1533 if (G2.last_dist < G2.last_lit / 2 && out_length < in_length / 2) 1533 if (G2.last_dist < G2.last_lit / 2 && out_length < in_length / 2)
1534 return 1; 1534 return 1;
1535 } 1535 }
@@ -1621,9 +1621,9 @@ static ulg flush_block(char *buf, ulg stored_len, int eof)
1621 static_lenb = (G2.static_len + 3 + 7) >> 3; 1621 static_lenb = (G2.static_len + 3 + 7) >> 3;
1622 1622
1623 Trace((stderr, 1623 Trace((stderr,
1624 "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", 1624 "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ",
1625 opt_lenb, G2.opt_len, static_lenb, G2.static_len, stored_len, 1625 opt_lenb, G2.opt_len, static_lenb, G2.static_len, stored_len,
1626 G2.last_lit, G2.last_dist)); 1626 G2.last_lit, G2.last_dist));
1627 1627
1628 if (static_lenb <= opt_lenb) 1628 if (static_lenb <= opt_lenb)
1629 opt_lenb = static_lenb; 1629 opt_lenb = static_lenb;
@@ -1661,7 +1661,7 @@ static ulg flush_block(char *buf, ulg stored_len, int eof)
1661 } else { 1661 } else {
1662 send_bits((DYN_TREES << 1) + eof, 3); 1662 send_bits((DYN_TREES << 1) + eof, 3);
1663 send_all_trees(G2.l_desc.max_code + 1, G2.d_desc.max_code + 1, 1663 send_all_trees(G2.l_desc.max_code + 1, G2.d_desc.max_code + 1,
1664 max_blindex + 1); 1664 max_blindex + 1);
1665 compress_block((ct_data *) G2.dyn_ltree, (ct_data *) G2.dyn_dtree); 1665 compress_block((ct_data *) G2.dyn_ltree, (ct_data *) G2.dyn_dtree);
1666 G2.compressed_len += 3 + G2.opt_len; 1666 G2.compressed_len += 3 + G2.opt_len;
1667 } 1667 }
diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c
index 2d5ab3eb3..4e6b138c3 100644
--- a/archival/libarchive/decompress_gunzip.c
+++ b/archival/libarchive/decompress_gunzip.c
@@ -293,8 +293,8 @@ static unsigned fill_bitbuffer(STATE_PARAM unsigned bitbuffer, unsigned *current
293 * m: maximum lookup bits, returns actual 293 * m: maximum lookup bits, returns actual
294 */ 294 */
295static int huft_build(const unsigned *b, const unsigned n, 295static int huft_build(const unsigned *b, const unsigned n,
296 const unsigned s, const unsigned short *d, 296 const unsigned s, const unsigned short *d,
297 const unsigned char *e, huft_t **t, unsigned *m) 297 const unsigned char *e, huft_t **t, unsigned *m)
298{ 298{
299 unsigned a; /* counter for codes of length k */ 299 unsigned a; /* counter for codes of length k */
300 unsigned c[BMAX + 1]; /* bit length count table */ 300 unsigned c[BMAX + 1]; /* bit length count table */
diff --git a/archival/libarchive/decompress_uncompress.c b/archival/libarchive/decompress_uncompress.c
index 3826a65ea..53c27080f 100644
--- a/archival/libarchive/decompress_uncompress.c
+++ b/archival/libarchive/decompress_uncompress.c
@@ -235,8 +235,8 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd)
235 p = &inbuf[posbits >> 3]; 235 p = &inbuf[posbits >> 3];
236 bb_error_msg 236 bb_error_msg
237 ("insize:%d posbits:%d inbuf:%02X %02X %02X %02X %02X (%d)", 237 ("insize:%d posbits:%d inbuf:%02X %02X %02X %02X %02X (%d)",
238 insize, posbits, p[-1], p[0], p[1], p[2], p[3], 238 insize, posbits, p[-1], p[0], p[1], p[2], p[3],
239 (posbits & 07)); 239 (posbits & 07));
240*/ 240*/
241 bb_error_msg("corrupted data"); 241 bb_error_msg("corrupted data");
242 goto err; 242 goto err;
diff --git a/archival/libarchive/lzo1x_9x.c b/archival/libarchive/lzo1x_9x.c
index 483205155..897132987 100644
--- a/archival/libarchive/lzo1x_9x.c
+++ b/archival/libarchive/lzo1x_9x.c
@@ -644,7 +644,7 @@ static int len_of_coded_match(unsigned m_len, unsigned m_off, unsigned lit)
644 644
645 645
646static int min_gain(unsigned ahead, unsigned lit1, 646static int min_gain(unsigned ahead, unsigned lit1,
647 unsigned lit2, int l1, int l2, int l3) 647 unsigned lit2, int l1, int l2, int l3)
648{ 648{
649 int lazy_match_min_gain = 0; 649 int lazy_match_min_gain = 0;
650 650
@@ -673,7 +673,7 @@ static int min_gain(unsigned ahead, unsigned lit1,
673#if defined(SWD_BEST_OFF) 673#if defined(SWD_BEST_OFF)
674 674
675static void better_match(const lzo_swd_p swd, 675static void better_match(const lzo_swd_p swd,
676 unsigned *m_len, unsigned *m_off) 676 unsigned *m_len, unsigned *m_off)
677{ 677{
678 if (*m_len <= M2_MIN_LEN) 678 if (*m_len <= M2_MIN_LEN)
679 return; 679 return;
@@ -914,8 +914,8 @@ int lzo1x_999_compress_level(const uint8_t *in, unsigned in_len,
914 914
915 compression_level -= 7; 915 compression_level -= 7;
916 return lzo1x_999_compress_internal(in, in_len, out, out_len, wrkmem, 916 return lzo1x_999_compress_internal(in, in_len, out, out_len, wrkmem,
917 c[compression_level].good_length, 917 c[compression_level].good_length,
918 c[compression_level].max_lazy, 918 c[compression_level].max_lazy,
919 c[compression_level].max_chain, 919 c[compression_level].max_chain,
920 c[compression_level].use_best_off); 920 c[compression_level].use_best_off);
921} 921}
diff --git a/archival/libarchive/lzo1x_c.c b/archival/libarchive/lzo1x_c.c
index cc86f74b1..8c77072ab 100644
--- a/archival/libarchive/lzo1x_c.c
+++ b/archival/libarchive/lzo1x_c.c
@@ -15,7 +15,7 @@
15 15
16 The LZO library is distributed in the hope that it will be useful, 16 The LZO library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details. 19 GNU General Public License for more details.
20 20
21 You should have received a copy of the GNU General Public License 21 You should have received a copy of the GNU General Public License
diff --git a/archival/libarchive/lzo1x_d.c b/archival/libarchive/lzo1x_d.c
index 348a85510..9bc1270da 100644
--- a/archival/libarchive/lzo1x_d.c
+++ b/archival/libarchive/lzo1x_d.c
@@ -15,7 +15,7 @@
15 15
16 The LZO library is distributed in the hope that it will be useful, 16 The LZO library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details. 19 GNU General Public License for more details.
20 20
21 You should have received a copy of the GNU General Public License 21 You should have received a copy of the GNU General Public License
diff --git a/archival/lzop.c b/archival/lzop.c
index fbe08417d..56003d421 100644
--- a/archival/lzop.c
+++ b/archival/lzop.c
@@ -14,7 +14,7 @@
14 14
15 This program is distributed in the hope that it will be useful, 15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details. 18 GNU General Public License for more details.
19 19
20 You should have received a copy of the GNU General Public License 20 You should have received a copy of the GNU General Public License
@@ -116,7 +116,7 @@ static NOINLINE int lzo1x_optimize(uint8_t *in, unsigned in_len,
116 unsigned nl; 116 unsigned nl;
117 unsigned long o_m1_a = 0, o_m1_b = 0, o_m2 = 0, o_m3_a = 0, o_m3_b = 0; 117 unsigned long o_m1_a = 0, o_m1_b = 0, o_m2 = 0, o_m3_a = 0, o_m3_b = 0;
118 118
119// LZO_UNUSED(wrkmem); 119// LZO_UNUSED(wrkmem);
120 120
121 *out_len = 0; 121 *out_len = 0;
122 122
@@ -346,11 +346,11 @@ static NOINLINE int lzo1x_optimize(uint8_t *in, unsigned in_len,
346 return LZO_E_EOF_NOT_FOUND; 346 return LZO_E_EOF_NOT_FOUND;
347 347
348 eof_found: 348 eof_found:
349// LZO_UNUSED(o_m1_a); LZO_UNUSED(o_m1_b); LZO_UNUSED(o_m2); 349// LZO_UNUSED(o_m1_a); LZO_UNUSED(o_m1_b); LZO_UNUSED(o_m2);
350// LZO_UNUSED(o_m3_a); LZO_UNUSED(o_m3_b); 350// LZO_UNUSED(o_m3_a); LZO_UNUSED(o_m3_b);
351 *out_len = pd(op, out); 351 *out_len = pd(op, out);
352 return (ip == ip_end ? LZO_E_OK : 352 return (ip == ip_end ? LZO_E_OK :
353 (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); 353 (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
354} 354}
355 355
356/**********************************************************************/ 356/**********************************************************************/
diff --git a/archival/tar.c b/archival/tar.c
index e27950b6c..648d1256d 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -333,13 +333,13 @@ static int writeTarHeader(struct TarBallInfo *tbInfo,
333 && (filesize <= 0x3fffffffffffffffffffffffLL) 333 && (filesize <= 0x3fffffffffffffffffffffffLL)
334#endif 334#endif
335 ) { 335 ) {
336 /* GNU tar uses "base-256 encoding" for very large numbers. 336 /* GNU tar uses "base-256 encoding" for very large numbers.
337 * Encoding is binary, with highest bit always set as a marker 337 * Encoding is binary, with highest bit always set as a marker
338 * and sign in next-highest bit: 338 * and sign in next-highest bit:
339 * 80 00 .. 00 - zero 339 * 80 00 .. 00 - zero
340 * bf ff .. ff - largest positive number 340 * bf ff .. ff - largest positive number
341 * ff ff .. ff - minus 1 341 * ff ff .. ff - minus 1
342 * c0 00 .. 00 - smallest negative number 342 * c0 00 .. 00 - smallest negative number
343 */ 343 */
344 char *p8 = header.size + sizeof(header.size); 344 char *p8 = header.size + sizeof(header.size);
345 do { 345 do {
diff --git a/archival/unzip.c b/archival/unzip.c
index 046027cc6..e4c824850 100644
--- a/archival/unzip.c
+++ b/archival/unzip.c
@@ -267,6 +267,14 @@ static void unzip_extract(zip_header_t *zip_header, int dst_fd)
267 } 267 }
268} 268}
269 269
270static void my_fgets80(char *buf80)
271{
272 fflush_all();
273 if (!fgets(buf80, 80, stdin)) {
274 bb_perror_msg_and_die("can't read standard input");
275 }
276}
277
270int unzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 278int unzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
271int unzip_main(int argc, char **argv) 279int unzip_main(int argc, char **argv)
272{ 280{
@@ -291,7 +299,7 @@ int unzip_main(int argc, char **argv)
291 llist_t *zreject = NULL; 299 llist_t *zreject = NULL;
292 char *base_dir = NULL; 300 char *base_dir = NULL;
293 int i, opt; 301 int i, opt;
294 char key_buf[80]; 302 char key_buf[80]; /* must match size used by my_fgets80 */
295 struct stat stat_buf; 303 struct stat stat_buf;
296 304
297/* -q, -l and -v: UnZip 5.52 of 28 February 2005, by Info-ZIP: 305/* -q, -l and -v: UnZip 5.52 of 28 February 2005, by Info-ZIP:
@@ -624,10 +632,7 @@ int unzip_main(int argc, char **argv)
624 i = 'y'; 632 i = 'y';
625 } else { 633 } else {
626 printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn); 634 printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn);
627 fflush_all(); 635 my_fgets80(key_buf);
628 if (!fgets(key_buf, sizeof(key_buf), stdin)) {
629 bb_perror_msg_and_die("can't read input");
630 }
631 i = key_buf[0]; 636 i = key_buf[0];
632 } 637 }
633 } else { /* File is not regular file */ 638 } else { /* File is not regular file */
@@ -668,9 +673,7 @@ int unzip_main(int argc, char **argv)
668 case 'r': 673 case 'r':
669 /* Prompt for new name */ 674 /* Prompt for new name */
670 printf("new name: "); 675 printf("new name: ");
671 if (!fgets(key_buf, sizeof(key_buf), stdin)) { 676 my_fgets80(key_buf);
672 bb_perror_msg_and_die("can't read input");
673 }
674 free(dst_fn); 677 free(dst_fn);
675 dst_fn = xstrdup(key_buf); 678 dst_fn = xstrdup(key_buf);
676 chomp(dst_fn); 679 chomp(dst_fn);
diff --git a/console-tools/loadfont.c b/console-tools/loadfont.c
index 9e887f256..032506d6d 100644
--- a/console-tools/loadfont.c
+++ b/console-tools/loadfont.c
@@ -229,7 +229,7 @@ static void do_loadtable(int fd, unsigned char *inbuf, int tailsz, int fontsize,
229 } 229 }
230 230
231 /* Note: after PIO_UNIMAPCLR and before PIO_UNIMAP 231 /* Note: after PIO_UNIMAPCLR and before PIO_UNIMAP
232 this printf did not work on many kernels */ 232 * this printf did not work on many kernels */
233 233
234 advice.advised_hashsize = 0; 234 advice.advised_hashsize = 0;
235 advice.advised_hashstep = 0; 235 advice.advised_hashstep = 0;
diff --git a/console-tools/setlogcons.c b/console-tools/setlogcons.c
index 83a895407..c76a5a42b 100644
--- a/console-tools/setlogcons.c
+++ b/console-tools/setlogcons.c
@@ -22,9 +22,10 @@ int setlogcons_main(int argc UNUSED_PARAM, char **argv)
22 struct { 22 struct {
23 char fn; 23 char fn;
24 char subarg; 24 char subarg;
25 } arg = { 11, /* redirect kernel messages */ 25 } arg = {
26 0 /* to specified console (current as default) */ 26 11, /* redirect kernel messages */
27 }; 27 0 /* to specified console (current as default) */
28 };
28 29
29 if (argv[1]) 30 if (argv[1])
30 arg.subarg = xatou_range(argv[1], 0, 63); 31 arg.subarg = xatou_range(argv[1], 0, 63);
diff --git a/coreutils/Config.src b/coreutils/Config.src
index 2ca71521f..8e43c38e1 100644
--- a/coreutils/Config.src
+++ b/coreutils/Config.src
@@ -517,6 +517,12 @@ config SHA512SUM
517 help 517 help
518 Compute and check SHA512 message digest 518 Compute and check SHA512 message digest
519 519
520config SHA3SUM
521 bool "sha3sum"
522 default y
523 help
524 Compute and check SHA3 (512-bit) message digest
525
520config SLEEP 526config SLEEP
521 bool "sleep" 527 bool "sleep"
522 default y 528 default y
@@ -777,13 +783,13 @@ config FEATURE_HUMAN_READABLE
777 help 783 help
778 Allow df, du, and ls to have human readable output. 784 Allow df, du, and ls to have human readable output.
779 785
780comment "Common options for md5sum, sha1sum, sha256sum, sha512sum" 786comment "Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum"
781 depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM 787 depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM
782 788
783config FEATURE_MD5_SHA1_SUM_CHECK 789config FEATURE_MD5_SHA1_SUM_CHECK
784 bool "Enable -c, -s and -w options" 790 bool "Enable -c, -s and -w options"
785 default y 791 default y
786 depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM 792 depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM
787 help 793 help
788 Enabling the -c options allows files to be checked 794 Enabling the -c options allows files to be checked
789 against pre-calculated hash values. 795 against pre-calculated hash values.
diff --git a/coreutils/Kbuild.src b/coreutils/Kbuild.src
index d6453f014..b715b9c47 100644
--- a/coreutils/Kbuild.src
+++ b/coreutils/Kbuild.src
@@ -62,6 +62,7 @@ lib-$(CONFIG_SEQ) += seq.o
62lib-$(CONFIG_SHA1SUM) += md5_sha1_sum.o 62lib-$(CONFIG_SHA1SUM) += md5_sha1_sum.o
63lib-$(CONFIG_SHA256SUM) += md5_sha1_sum.o 63lib-$(CONFIG_SHA256SUM) += md5_sha1_sum.o
64lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o 64lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o
65lib-$(CONFIG_SHA3SUM) += md5_sha1_sum.o
65lib-$(CONFIG_SLEEP) += sleep.o 66lib-$(CONFIG_SLEEP) += sleep.o
66lib-$(CONFIG_SPLIT) += split.o 67lib-$(CONFIG_SPLIT) += split.o
67lib-$(CONFIG_SORT) += sort.o 68lib-$(CONFIG_SORT) += sort.o
diff --git a/coreutils/cal.c b/coreutils/cal.c
index b470ad968..0d388aa1c 100644
--- a/coreutils/cal.c
+++ b/coreutils/cal.c
@@ -43,7 +43,7 @@ static const unsigned char days_in_month[] ALIGN1 = {
43}; 43};
44 44
45static const unsigned char sep1752[] ALIGN1 = { 45static const unsigned char sep1752[] ALIGN1 = {
46 1, 2, 14, 15, 16, 46 1, 2, 14, 15, 16,
47 17, 18, 19, 20, 21, 22, 23, 47 17, 18, 19, 20, 21, 22, 23,
48 24, 25, 26, 27, 28, 29, 30 48 24, 25, 26, 27, 28, 29, 30
49}; 49};
@@ -167,8 +167,8 @@ int cal_main(int argc UNUSED_PARAM, char **argv)
167 day_array(month, year, dp); 167 day_array(month, year, dp);
168 len = sprintf(lineout, "%s %d", month_names[month - 1], year); 168 len = sprintf(lineout, "%s %d", month_names[month - 1], year);
169 printf("%*s%s\n%s\n", 169 printf("%*s%s\n%s\n",
170 ((7*julian + WEEK_LEN) - len) / 2, "", 170 ((7*julian + WEEK_LEN) - len) / 2, "",
171 lineout, day_headings); 171 lineout, day_headings);
172 for (row = 0; row < 6; row++) { 172 for (row = 0; row < 6; row++) {
173 build_row(lineout, dp)[0] = '\0'; 173 build_row(lineout, dp)[0] = '\0';
174 dp += 7; 174 dp += 7;
@@ -181,10 +181,11 @@ int cal_main(int argc UNUSED_PARAM, char **argv)
181 181
182 sprintf(lineout, "%u", year); 182 sprintf(lineout, "%u", year);
183 center(lineout, 183 center(lineout,
184 (WEEK_LEN * 3 + HEAD_SEP * 2) 184 (WEEK_LEN * 3 + HEAD_SEP * 2)
185 + julian * (J_WEEK_LEN * 2 + HEAD_SEP 185 + julian * (J_WEEK_LEN * 2 + HEAD_SEP
186 - (WEEK_LEN * 3 + HEAD_SEP * 2)), 186 - (WEEK_LEN * 3 + HEAD_SEP * 2)),
187 0); 187 0
188 );
188 puts("\n"); /* two \n's */ 189 puts("\n"); /* two \n's */
189 for (i = 0; i < 12; i++) { 190 for (i = 0; i < 12; i++) {
190 day_array(i + 1, year, days[i]); 191 day_array(i + 1, year, days[i]);
diff --git a/coreutils/chown.c b/coreutils/chown.c
index bb166d8fe..1a9127622 100644
--- a/coreutils/chown.c
+++ b/coreutils/chown.c
@@ -126,8 +126,8 @@ int chown_main(int argc UNUSED_PARAM, char **argv)
126 /* This matches coreutils behavior (almost - see below) */ 126 /* This matches coreutils behavior (almost - see below) */
127 param.chown_func = chown; 127 param.chown_func = chown;
128 if (OPT_NODEREF 128 if (OPT_NODEREF
129 /* || (OPT_RECURSE && !OPT_TRAVERSE_TOP): */ 129 /* || (OPT_RECURSE && !OPT_TRAVERSE_TOP): */
130 IF_DESKTOP( || (opt & (BIT_RECURSE|BIT_TRAVERSE_TOP)) == BIT_RECURSE) 130 IF_DESKTOP( || (opt & (BIT_RECURSE|BIT_TRAVERSE_TOP)) == BIT_RECURSE)
131 ) { 131 ) {
132 param.chown_func = lchown; 132 param.chown_func = lchown;
133 } 133 }
diff --git a/coreutils/cut.c b/coreutils/cut.c
index 2c27b704f..84449c775 100644
--- a/coreutils/cut.c
+++ b/coreutils/cut.c
@@ -212,7 +212,7 @@ int cut_main(int argc UNUSED_PARAM, char **argv)
212 if (opt & CUT_OPT_SUPPRESS_FLGS) { 212 if (opt & CUT_OPT_SUPPRESS_FLGS) {
213 bb_error_msg_and_die 213 bb_error_msg_and_die
214 ("suppressing non-delimited lines makes sense%s", 214 ("suppressing non-delimited lines makes sense%s",
215 _op_on_field); 215 _op_on_field);
216 } 216 }
217 if (delim != '\t') { 217 if (delim != '\t') {
218 bb_error_msg_and_die 218 bb_error_msg_and_die
diff --git a/coreutils/df.c b/coreutils/df.c
index 63dbd61bd..5e9a8670f 100644
--- a/coreutils/df.c
+++ b/coreutils/df.c
@@ -110,9 +110,9 @@ int df_main(int argc UNUSED_PARAM, char **argv)
110 df_disp_hr = xatoul_range(chp, 1, ULONG_MAX); /* disallow 0 */ 110 df_disp_hr = xatoul_range(chp, 1, ULONG_MAX); /* disallow 0 */
111 111
112 /* From the manpage of df from coreutils-6.10: 112 /* From the manpage of df from coreutils-6.10:
113 Disk space is shown in 1K blocks by default, unless the environment 113 * Disk space is shown in 1K blocks by default, unless the environment
114 variable POSIXLY_CORRECT is set, in which case 512-byte blocks are used. 114 * variable POSIXLY_CORRECT is set, in which case 512-byte blocks are used.
115 */ 115 */
116 if (getenv("POSIXLY_CORRECT")) /* TODO - a new libbb function? */ 116 if (getenv("POSIXLY_CORRECT")) /* TODO - a new libbb function? */
117 df_disp_hr = 512; 117 df_disp_hr = 512;
118 118
@@ -221,7 +221,7 @@ int df_main(int argc UNUSED_PARAM, char **argv)
221 } 221 }
222#else 222#else
223 if (printf("\n%-20s" + 1, device) > 20 && !(opt & OPT_POSIX)) 223 if (printf("\n%-20s" + 1, device) > 20 && !(opt & OPT_POSIX))
224 printf("\n%-20s", ""); 224 printf("\n%-20s", "");
225#endif 225#endif
226 226
227#if ENABLE_FEATURE_HUMAN_READABLE 227#if ENABLE_FEATURE_HUMAN_READABLE
diff --git a/coreutils/du.c b/coreutils/du.c
index 04e78f982..05f114cc5 100644
--- a/coreutils/du.c
+++ b/coreutils/du.c
@@ -89,6 +89,10 @@ struct globals {
89#define INIT_G() do { } while (0) 89#define INIT_G() do { } while (0)
90 90
91 91
92/* FIXME? coreutils' du rounds sizes up:
93 * for example, 1025k file is shown as "2" by du -m.
94 * We round to nearest.
95 */
92static void print(unsigned long long size, const char *filename) 96static void print(unsigned long long size, const char *filename)
93{ 97{
94 /* TODO - May not want to defer error checking here. */ 98 /* TODO - May not want to defer error checking here. */
diff --git a/coreutils/id.c b/coreutils/id.c
index 399d25e34..1f20b755e 100644
--- a/coreutils/id.c
+++ b/coreutils/id.c
@@ -174,7 +174,7 @@ int id_main(int argc UNUSED_PARAM, char **argv)
174 /* Don't allow -n -r -nr -ug -rug -nug -rnug -uZ -gZ -GZ*/ 174 /* Don't allow -n -r -nr -ug -rug -nug -rnug -uZ -gZ -GZ*/
175 /* Don't allow more than one username */ 175 /* Don't allow more than one username */
176 opt_complementary = "?1:u--g:g--u:G--u:u--G:g--G:G--g:r?ugG:n?ugG" 176 opt_complementary = "?1:u--g:g--u:G--u:u--G:g--G:G--g:r?ugG:n?ugG"
177 IF_SELINUX(":u--Z:Z--u:g--Z:Z--g:G--Z:Z--G"); 177 IF_SELINUX(":u--Z:Z--u:g--Z:Z--g:G--Z:Z--G");
178 opt = getopt32(argv, "rnugG" IF_SELINUX("Z")); 178 opt = getopt32(argv, "rnugG" IF_SELINUX("Z"));
179 } 179 }
180 180
diff --git a/coreutils/ls.c b/coreutils/ls.c
index 4fe291d17..2c5fda96a 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -260,7 +260,7 @@ enum {
260 260
261/* TODO: simple toggles may be stored as OPT_xxx bits instead */ 261/* TODO: simple toggles may be stored as OPT_xxx bits instead */
262static const uint32_t opt_flags[] = { 262static const uint32_t opt_flags[] = {
263 STYLE_COLUMNAR, /* C */ 263 STYLE_COLUMNAR, /* C */
264 DISP_HIDDEN | DISP_DOT, /* a */ 264 DISP_HIDDEN | DISP_DOT, /* a */
265 DISP_NOLIST, /* d */ 265 DISP_NOLIST, /* d */
266 LIST_INO, /* i */ 266 LIST_INO, /* i */
@@ -720,7 +720,7 @@ static struct dnode *my_stat(const char *fullname, const char *name, int force_f
720 if ((option_mask32 & OPT_L) || force_follow) { 720 if ((option_mask32 & OPT_L) || force_follow) {
721#if ENABLE_SELINUX 721#if ENABLE_SELINUX
722 if (is_selinux_enabled()) { 722 if (is_selinux_enabled()) {
723 getfilecon(fullname, &cur->sid); 723 getfilecon(fullname, &cur->sid);
724 } 724 }
725#endif 725#endif
726 if (stat(fullname, &statbuf)) { 726 if (stat(fullname, &statbuf)) {
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c
index 2cb6dd43c..92a4d4462 100644
--- a/coreutils/md5_sha1_sum.c
+++ b/coreutils/md5_sha1_sum.c
@@ -55,6 +55,16 @@
55//usage: "\n -s Don't output anything, status code shows success" 55//usage: "\n -s Don't output anything, status code shows success"
56//usage: "\n -w Warn about improperly formatted checksum lines" 56//usage: "\n -w Warn about improperly formatted checksum lines"
57//usage: ) 57//usage: )
58//usage:
59//usage:#define sha3sum_trivial_usage
60//usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..."
61//usage:#define sha3sum_full_usage "\n\n"
62//usage: "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA3-512 checksums"
63//usage: IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n"
64//usage: "\n -c Check sums against list in FILEs"
65//usage: "\n -s Don't output anything, status code shows success"
66//usage: "\n -w Warn about improperly formatted checksum lines"
67//usage: )
58 68
59#include "libbb.h" 69#include "libbb.h"
60 70
@@ -65,6 +75,7 @@ enum {
65 HASH_MD5 = 's', /* "md5>s<um" */ 75 HASH_MD5 = 's', /* "md5>s<um" */
66 HASH_SHA1 = '1', 76 HASH_SHA1 = '1',
67 HASH_SHA256 = '2', 77 HASH_SHA256 = '2',
78 HASH_SHA3 = '3',
68 HASH_SHA512 = '5', 79 HASH_SHA512 = '5',
69}; 80};
70 81
@@ -86,6 +97,7 @@ static uint8_t *hash_file(const char *filename)
86{ 97{
87 int src_fd, hash_len, count; 98 int src_fd, hash_len, count;
88 union _ctx_ { 99 union _ctx_ {
100 sha3_ctx_t sha3;
89 sha512_ctx_t sha512; 101 sha512_ctx_t sha512;
90 sha256_ctx_t sha256; 102 sha256_ctx_t sha256;
91 sha1_ctx_t sha1; 103 sha1_ctx_t sha1;
@@ -124,6 +136,11 @@ static uint8_t *hash_file(const char *filename)
124 update = (void*)sha512_hash; 136 update = (void*)sha512_hash;
125 final = (void*)sha512_end; 137 final = (void*)sha512_end;
126 hash_len = 64; 138 hash_len = 64;
139 } else if (ENABLE_SHA3SUM && hash_algo == HASH_SHA3) {
140 sha3_begin(&context.sha3);
141 update = (void*)sha3_hash;
142 final = (void*)sha3_end;
143 hash_len = 64;
127 } else { 144 } else {
128 xfunc_die(); /* can't reach this */ 145 xfunc_die(); /* can't reach this */
129 } 146 }
@@ -223,7 +240,7 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv)
223 } 240 }
224 if (count_failed && !(flags & FLAG_SILENT)) { 241 if (count_failed && !(flags & FLAG_SILENT)) {
225 bb_error_msg("WARNING: %d of %d computed checksums did NOT match", 242 bb_error_msg("WARNING: %d of %d computed checksums did NOT match",
226 count_failed, count_total); 243 count_failed, count_total);
227 } 244 }
228 fclose_if_not_stdin(pre_computed_stream); 245 fclose_if_not_stdin(pre_computed_stream);
229 } else { 246 } else {
diff --git a/coreutils/mknod.c b/coreutils/mknod.c
index 32d3659ac..aa0450481 100644
--- a/coreutils/mknod.c
+++ b/coreutils/mknod.c
@@ -59,7 +59,7 @@ int mknod_main(int argc, char **argv)
59 /* Autodetect what the system supports; these macros should 59 /* Autodetect what the system supports; these macros should
60 * optimize out to two constants. */ 60 * optimize out to two constants. */
61 dev = makedev(xatoul_range(argv[2], 0, major(UINT_MAX)), 61 dev = makedev(xatoul_range(argv[2], 0, major(UINT_MAX)),
62 xatoul_range(argv[3], 0, minor(UINT_MAX))); 62 xatoul_range(argv[3], 0, minor(UINT_MAX)));
63 } 63 }
64 } 64 }
65 65
diff --git a/coreutils/od_bloaty.c b/coreutils/od_bloaty.c
index 7a6f22b03..ee4f72ca1 100644
--- a/coreutils/od_bloaty.c
+++ b/coreutils/od_bloaty.c
@@ -1028,12 +1028,12 @@ dump(off_t current_offset, off_t end_offset)
1028 l_c_m = get_lcm(); 1028 l_c_m = get_lcm();
1029 1029
1030 /* Make bytes_to_write the smallest multiple of l_c_m that 1030 /* Make bytes_to_write the smallest multiple of l_c_m that
1031 is at least as large as n_bytes_read. */ 1031 is at least as large as n_bytes_read. */
1032 bytes_to_write = l_c_m * ((n_bytes_read + l_c_m - 1) / l_c_m); 1032 bytes_to_write = l_c_m * ((n_bytes_read + l_c_m - 1) / l_c_m);
1033 1033
1034 memset(block[idx] + n_bytes_read, 0, bytes_to_write - n_bytes_read); 1034 memset(block[idx] + n_bytes_read, 0, bytes_to_write - n_bytes_read);
1035 write_block(current_offset, bytes_to_write, 1035 write_block(current_offset, bytes_to_write,
1036 block[idx ^ 1], block[idx]); 1036 block[idx ^ 1], block[idx]);
1037 current_offset += n_bytes_read; 1037 current_offset += n_bytes_read;
1038 } 1038 }
1039 1039
diff --git a/coreutils/sort.c b/coreutils/sort.c
index 1df07285c..a1625fc9c 100644
--- a/coreutils/sort.c
+++ b/coreutils/sort.c
@@ -219,7 +219,7 @@ static int compare_keys(const void *xarg, const void *yarg)
219 y = get_key(*(char **)yarg, key, flags); 219 y = get_key(*(char **)yarg, key, flags);
220#else 220#else
221 /* This curly bracket serves no purpose but to match the nesting 221 /* This curly bracket serves no purpose but to match the nesting
222 level of the for () loop we're not using */ 222 * level of the for () loop we're not using */
223 { 223 {
224 x = *(char **)xarg; 224 x = *(char **)xarg;
225 y = *(char **)yarg; 225 y = *(char **)yarg;
diff --git a/coreutils/stat.c b/coreutils/stat.c
index 259481750..69a8a1a36 100644
--- a/coreutils/stat.c
+++ b/coreutils/stat.c
@@ -611,37 +611,43 @@ static bool do_stat(const char *filename, const char *format)
611# else 611# else
612 if (option_mask32 & OPT_TERSE) { 612 if (option_mask32 & OPT_TERSE) {
613 format = (option_mask32 & OPT_SELINUX ? 613 format = (option_mask32 & OPT_SELINUX ?
614 "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n": 614 "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n"
615 "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"); 615 :
616 "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"
617 );
616 } else { 618 } else {
617 if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) { 619 if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) {
618 format = (option_mask32 & OPT_SELINUX ? 620 format = (option_mask32 & OPT_SELINUX ?
619 " File: %N\n" 621 " File: %N\n"
620 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" 622 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
621 "Device: %Dh/%dd\tInode: %-10i Links: %-5h" 623 "Device: %Dh/%dd\tInode: %-10i Links: %-5h"
622 " Device type: %t,%T\n" 624 " Device type: %t,%T\n"
623 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" 625 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
624 " S_Context: %C\n" 626 " S_Context: %C\n"
625 "Access: %x\n" "Modify: %y\n" "Change: %z\n": 627 "Access: %x\n" "Modify: %y\n" "Change: %z\n"
626 " File: %N\n" 628 :
627 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" 629 " File: %N\n"
628 "Device: %Dh/%dd\tInode: %-10i Links: %-5h" 630 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
629 " Device type: %t,%T\n" 631 "Device: %Dh/%dd\tInode: %-10i Links: %-5h"
630 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" 632 " Device type: %t,%T\n"
631 "Access: %x\n" "Modify: %y\n" "Change: %z\n"); 633 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
634 "Access: %x\n" "Modify: %y\n" "Change: %z\n"
635 );
632 } else { 636 } else {
633 format = (option_mask32 & OPT_SELINUX ? 637 format = (option_mask32 & OPT_SELINUX ?
634 " File: %N\n" 638 " File: %N\n"
635 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" 639 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
636 "Device: %Dh/%dd\tInode: %-10i Links: %h\n" 640 "Device: %Dh/%dd\tInode: %-10i Links: %h\n"
637 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" 641 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
638 "S_Context: %C\n" 642 "S_Context: %C\n"
639 "Access: %x\n" "Modify: %y\n" "Change: %z\n": 643 "Access: %x\n" "Modify: %y\n" "Change: %z\n"
640 " File: %N\n" 644 :
641 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" 645 " File: %N\n"
642 "Device: %Dh/%dd\tInode: %-10i Links: %h\n" 646 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
643 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" 647 "Device: %Dh/%dd\tInode: %-10i Links: %h\n"
644 "Access: %x\n" "Modify: %y\n" "Change: %z\n"); 648 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
649 "Access: %x\n" "Modify: %y\n" "Change: %z\n"
650 );
645 } 651 }
646 } 652 }
647# endif 653# endif
diff --git a/coreutils/stty.c b/coreutils/stty.c
index 0668cf7be..96754dd84 100644
--- a/coreutils/stty.c
+++ b/coreutils/stty.c
@@ -1056,7 +1056,7 @@ static void do_display(const struct termios *mode, int all)
1056 } 1056 }
1057#endif 1057#endif
1058 wrapf("%s = %s;", nth_string(control_name, i), 1058 wrapf("%s = %s;", nth_string(control_name, i),
1059 visible(mode->c_cc[control_info[i].offset])); 1059 visible(mode->c_cc[control_info[i].offset]));
1060 } 1060 }
1061#if VEOF == VMIN 1061#if VEOF == VMIN
1062 if ((mode->c_lflag & ICANON) == 0) 1062 if ((mode->c_lflag & ICANON) == 0)
diff --git a/coreutils/sum.c b/coreutils/sum.c
index 95110a6da..75f6ef60a 100644
--- a/coreutils/sum.c
+++ b/coreutils/sum.c
@@ -94,8 +94,8 @@ int sum_main(int argc UNUSED_PARAM, char **argv)
94 n = sum_file("-", type); 94 n = sum_file("-", type);
95 } else { 95 } else {
96 /* Need to print the name if either 96 /* Need to print the name if either
97 - more than one file given 97 * - more than one file given
98 - doing sysv */ 98 * - doing sysv */
99 type += (argv[1] || type == SUM_SYSV); 99 type += (argv[1] || type == SUM_SYSV);
100 n = 1; 100 n = 1;
101 do { 101 do {
diff --git a/coreutils/test.c b/coreutils/test.c
index 80f540c22..d8af4dcf3 100644
--- a/coreutils/test.c
+++ b/coreutils/test.c
@@ -610,7 +610,7 @@ static int test_eaccess(char *path, int mode)
610 return 0; 610 return 0;
611 611
612 /* Root can execute any file that has any one of the execute 612 /* Root can execute any file that has any one of the execute
613 bits set. */ 613 * bits set. */
614 if (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) 614 if (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
615 return 0; 615 return 0;
616 } 616 }
diff --git a/e2fsprogs/fsck.c b/e2fsprogs/fsck.c
index 4b2f774f5..d32f396e9 100644
--- a/e2fsprogs/fsck.c
+++ b/e2fsprogs/fsck.c
@@ -478,7 +478,7 @@ static int wait_one(int flags)
478 instance_list = inst->next; 478 instance_list = inst->next;
479 if (verbose > 1) 479 if (verbose > 1)
480 printf("Finished with %s (exit status %d)\n", 480 printf("Finished with %s (exit status %d)\n",
481 inst->device, status); 481 inst->device, status);
482 num_running--; 482 num_running--;
483 free_instance(inst); 483 free_instance(inst);
484 484
@@ -844,7 +844,7 @@ static int check_all(void)
844 if (verbose > 1) 844 if (verbose > 1)
845 printf("--waiting-- (pass %d)\n", passno); 845 printf("--waiting-- (pass %d)\n", passno);
846 status |= wait_many(pass_done ? FLAG_WAIT_ALL : 846 status |= wait_many(pass_done ? FLAG_WAIT_ALL :
847 FLAG_WAIT_ATLEAST_ONE); 847 FLAG_WAIT_ATLEAST_ONE);
848 if (pass_done) { 848 if (pass_done) {
849 if (verbose > 1) 849 if (verbose > 1)
850 puts("----------------------------------"); 850 puts("----------------------------------");
diff --git a/editors/awk.c b/editors/awk.c
index 42f6ef866..3224788c0 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -155,7 +155,7 @@ typedef struct tsplitter_s {
155 155
156/* simple token classes */ 156/* simple token classes */
157/* Order and hex values are very important!!! See next_token() */ 157/* Order and hex values are very important!!! See next_token() */
158#define TC_SEQSTART 1 /* ( */ 158#define TC_SEQSTART 1 /* ( */
159#define TC_SEQTERM (1 << 1) /* ) */ 159#define TC_SEQTERM (1 << 1) /* ) */
160#define TC_REGEXP (1 << 2) /* /.../ */ 160#define TC_REGEXP (1 << 2) /* /.../ */
161#define TC_OUTRDR (1 << 3) /* | > >> */ 161#define TC_OUTRDR (1 << 3) /* | > >> */
diff --git a/editors/diff.c b/editors/diff.c
index 3a3334640..b08ded3a1 100644
--- a/editors/diff.c
+++ b/editors/diff.c
@@ -843,7 +843,7 @@ static void diffdir(char *p[2], const char *s_start)
843 * add_to_dirlist will remove it. */ 843 * add_to_dirlist will remove it. */
844 list[i].len = strlen(p[i]); 844 list[i].len = strlen(p[i]);
845 recursive_action(p[i], ACTION_RECURSE | ACTION_FOLLOWLINKS, 845 recursive_action(p[i], ACTION_RECURSE | ACTION_FOLLOWLINKS,
846 add_to_dirlist, skip_dir, &list[i], 0); 846 add_to_dirlist, skip_dir, &list[i], 0);
847 /* Sort dl alphabetically. 847 /* Sort dl alphabetically.
848 * GNU diff does this ignoring any number of trailing dots. 848 * GNU diff does this ignoring any number of trailing dots.
849 * We don't, so for us dotted files almost always are 849 * We don't, so for us dotted files almost always are
diff --git a/editors/sed.c b/editors/sed.c
index 070af611a..f8ca5d351 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -1077,7 +1077,7 @@ static void process_files(void)
1077 /* or does this line matches our last address regex */ 1077 /* or does this line matches our last address regex */
1078 || (sed_cmd->end_match && old_matched 1078 || (sed_cmd->end_match && old_matched
1079 && (regexec(sed_cmd->end_match, 1079 && (regexec(sed_cmd->end_match,
1080 pattern_space, 0, NULL, 0) == 0) 1080 pattern_space, 0, NULL, 0) == 0)
1081 ) 1081 )
1082 ); 1082 );
1083 } 1083 }
diff --git a/editors/vi.c b/editors/vi.c
index 821583ec1..1fc66b931 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -14,7 +14,7 @@
14 * add :help command 14 * add :help command
15 * :map macros 15 * :map macros
16 * if mark[] values were line numbers rather than pointers 16 * if mark[] values were line numbers rather than pointers
17 * it would be easier to change the mark when add/delete lines 17 * it would be easier to change the mark when add/delete lines
18 * More intelligence in refresh() 18 * More intelligence in refresh()
19 * ":r !cmd" and "!cmd" to filter text through an external command 19 * ":r !cmd" and "!cmd" to filter text through an external command
20 * A true "undo" facility 20 * A true "undo" facility
@@ -1049,7 +1049,7 @@ static void colon(char *buf)
1049#endif 1049#endif
1050 // how many lines in text[]? 1050 // how many lines in text[]?
1051 li = count_lines(text, end - 1); 1051 li = count_lines(text, end - 1);
1052 status_line("\"%s\"%s" 1052 status_line("'%s'%s"
1053 IF_FEATURE_VI_READONLY("%s") 1053 IF_FEATURE_VI_READONLY("%s")
1054 " %dL, %dC", current_filename, 1054 " %dL, %dC", current_filename,
1055 (file_size(fn) < 0 ? " [New file]" : ""), 1055 (file_size(fn) < 0 ? " [New file]" : ""),
@@ -1165,7 +1165,7 @@ static void colon(char *buf)
1165 goto ret; // nothing was inserted 1165 goto ret; // nothing was inserted
1166 // how many lines in text[]? 1166 // how many lines in text[]?
1167 li = count_lines(q, q + ch - 1); 1167 li = count_lines(q, q + ch - 1);
1168 status_line("\"%s\"" 1168 status_line("'%s'"
1169 IF_FEATURE_VI_READONLY("%s") 1169 IF_FEATURE_VI_READONLY("%s")
1170 " %dL, %dC", fn, 1170 " %dL, %dC", fn,
1171 IF_FEATURE_VI_READONLY((readonly_mode ? " [Readonly]" : ""),) 1171 IF_FEATURE_VI_READONLY((readonly_mode ? " [Readonly]" : ""),)
@@ -1298,7 +1298,7 @@ static void colon(char *buf)
1298 } 1298 }
1299#if ENABLE_FEATURE_VI_READONLY 1299#if ENABLE_FEATURE_VI_READONLY
1300 if (readonly_mode && !useforce) { 1300 if (readonly_mode && !useforce) {
1301 status_line_bold("\"%s\" File is read only", fn); 1301 status_line_bold("'%s' is read only", fn);
1302 goto ret; 1302 goto ret;
1303 } 1303 }
1304#endif 1304#endif
@@ -1321,9 +1321,9 @@ static void colon(char *buf)
1321 } 1321 }
1322 if (l < 0) { 1322 if (l < 0) {
1323 if (l == -1) 1323 if (l == -1)
1324 status_line_bold("\"%s\" %s", fn, strerror(errno)); 1324 status_line_bold("'%s' %s", fn, strerror(errno));
1325 } else { 1325 } else {
1326 status_line("\"%s\" %dL, %dC", fn, li, l); 1326 status_line("'%s' %dL, %dC", fn, li, l);
1327 if (q == text && r == end - 1 && l == ch) { 1327 if (q == text && r == end - 1 && l == ch) {
1328 file_modified = 0; 1328 file_modified = 0;
1329 last_file_modified = -1; 1329 last_file_modified = -1;
@@ -1735,7 +1735,7 @@ static char *char_search(char *p, const char *pat, int dir, int range)
1735 q = (char *)re_compile_pattern(pat, strlen(pat), (struct re_pattern_buffer *)&preg); 1735 q = (char *)re_compile_pattern(pat, strlen(pat), (struct re_pattern_buffer *)&preg);
1736 if (q != 0) { 1736 if (q != 0) {
1737 // The pattern was not compiled 1737 // The pattern was not compiled
1738 status_line_bold("bad search pattern: \"%s\": %s", pat, q); 1738 status_line_bold("bad search pattern: '%s': %s", pat, q);
1739 i = 0; // return p if pattern not compiled 1739 i = 0; // return p if pattern not compiled
1740 goto cs1; 1740 goto cs1;
1741 } 1741 }
@@ -1929,11 +1929,11 @@ static int find_range(char **start, char **stop, char c)
1929 dot_end(); // find NL 1929 dot_end(); // find NL
1930 q = dot; 1930 q = dot;
1931 } else { 1931 } else {
1932 // nothing -- this causes any other values of c to 1932 // nothing -- this causes any other values of c to
1933 // represent the one-character range under the 1933 // represent the one-character range under the
1934 // cursor. this is correct for ' ' and 'l', but 1934 // cursor. this is correct for ' ' and 'l', but
1935 // perhaps no others. 1935 // perhaps no others.
1936 // 1936 //
1937 } 1937 }
1938 if (q < p) { 1938 if (q < p) {
1939 t = q; 1939 t = q;
@@ -2512,12 +2512,12 @@ static int file_insert(const char *fn, char *p, int update_ro_status)
2512 2512
2513 /* Validate file */ 2513 /* Validate file */
2514 if (stat(fn, &statbuf) < 0) { 2514 if (stat(fn, &statbuf) < 0) {
2515 status_line_bold("\"%s\" %s", fn, strerror(errno)); 2515 status_line_bold("'%s' %s", fn, strerror(errno));
2516 goto fi0; 2516 goto fi0;
2517 } 2517 }
2518 if (!S_ISREG(statbuf.st_mode)) { 2518 if (!S_ISREG(statbuf.st_mode)) {
2519 // This is not a regular file 2519 // This is not a regular file
2520 status_line_bold("\"%s\" Not a regular file", fn); 2520 status_line_bold("'%s' is not a regular file", fn);
2521 goto fi0; 2521 goto fi0;
2522 } 2522 }
2523 if (p < text || p > end) { 2523 if (p < text || p > end) {
@@ -2528,19 +2528,19 @@ static int file_insert(const char *fn, char *p, int update_ro_status)
2528 // read file to buffer 2528 // read file to buffer
2529 fd = open(fn, O_RDONLY); 2529 fd = open(fn, O_RDONLY);
2530 if (fd < 0) { 2530 if (fd < 0) {
2531 status_line_bold("\"%s\" %s", fn, strerror(errno)); 2531 status_line_bold("'%s' %s", fn, strerror(errno));
2532 goto fi0; 2532 goto fi0;
2533 } 2533 }
2534 size = statbuf.st_size; 2534 size = (statbuf.st_size < INT_MAX ? (int)statbuf.st_size : INT_MAX);
2535 p += text_hole_make(p, size); 2535 p += text_hole_make(p, size);
2536 cnt = safe_read(fd, p, size); 2536 cnt = safe_read(fd, p, size);
2537 if (cnt < 0) { 2537 if (cnt < 0) {
2538 status_line_bold("\"%s\" %s", fn, strerror(errno)); 2538 status_line_bold("'%s' %s", fn, strerror(errno));
2539 p = text_hole_delete(p, p + size - 1); // un-do buffer insert 2539 p = text_hole_delete(p, p + size - 1); // un-do buffer insert
2540 } else if (cnt < size) { 2540 } else if (cnt < size) {
2541 // There was a partial read, shrink unused space text[] 2541 // There was a partial read, shrink unused space text[]
2542 p = text_hole_delete(p + cnt, p + (size - cnt) - 1); // un-do buffer insert 2542 p = text_hole_delete(p + cnt, p + (size - cnt) - 1); // un-do buffer insert
2543 status_line_bold("can't read all of file \"%s\"", fn); 2543 status_line_bold("can't read '%s'", fn);
2544 } 2544 }
2545 if (cnt >= size) 2545 if (cnt >= size)
2546 file_modified++; 2546 file_modified++;
@@ -3478,7 +3478,7 @@ static void do_cmd(int c)
3478 } else { 3478 } else {
3479 file_modified = 0; 3479 file_modified = 0;
3480 last_file_modified = -1; 3480 last_file_modified = -1;
3481 status_line("\"%s\" %dL, %dC", current_filename, count_lines(text, end - 1), cnt); 3481 status_line("'%s' %dL, %dC", current_filename, count_lines(text, end - 1), cnt);
3482 if (p[0] == 'x' || p[1] == 'q' || p[1] == 'n' 3482 if (p[0] == 'x' || p[1] == 'q' || p[1] == 'n'
3483 || p[0] == 'X' || p[1] == 'Q' || p[1] == 'N' 3483 || p[0] == 'X' || p[1] == 'Q' || p[1] == 'N'
3484 ) { 3484 ) {
@@ -3676,7 +3676,7 @@ static void do_cmd(int c)
3676 } 3676 }
3677 if (file_modified) { 3677 if (file_modified) {
3678 if (ENABLE_FEATURE_VI_READONLY && readonly_mode) { 3678 if (ENABLE_FEATURE_VI_READONLY && readonly_mode) {
3679 status_line_bold("\"%s\" File is read only", current_filename); 3679 status_line_bold("'%s' is read only", current_filename);
3680 break; 3680 break;
3681 } 3681 }
3682 cnt = file_write(current_filename, text, end - 1); 3682 cnt = file_write(current_filename, text, end - 1);
diff --git a/findutils/find.c b/findutils/find.c
index b521e5b08..2235b5049 100644
--- a/findutils/find.c
+++ b/findutils/find.c
@@ -878,8 +878,8 @@ static action*** parse_params(char **argv)
878 IF_FEATURE_FIND_EXEC( "-exec\0" ) 878 IF_FEATURE_FIND_EXEC( "-exec\0" )
879 IF_FEATURE_FIND_PAREN( "(\0" ) 879 IF_FEATURE_FIND_PAREN( "(\0" )
880 /* All options/actions starting from here require argument */ 880 /* All options/actions starting from here require argument */
881 "-name\0" 881 "-name\0"
882 "-iname\0" 882 "-iname\0"
883 IF_FEATURE_FIND_PATH( "-path\0" ) 883 IF_FEATURE_FIND_PATH( "-path\0" )
884#if ENABLE_DESKTOP 884#if ENABLE_DESKTOP
885 IF_FEATURE_FIND_PATH( "-wholename\0") 885 IF_FEATURE_FIND_PATH( "-wholename\0")
diff --git a/findutils/grep.c b/findutils/grep.c
index 5b8ae3bff..6b47f4327 100644
--- a/findutils/grep.c
+++ b/findutils/grep.c
@@ -352,10 +352,34 @@ static int grep_file(FILE *file)
352 while (pattern_ptr) { 352 while (pattern_ptr) {
353 gl = (grep_list_data_t *)pattern_ptr->data; 353 gl = (grep_list_data_t *)pattern_ptr->data;
354 if (FGREP_FLAG) { 354 if (FGREP_FLAG) {
355 found |= (((option_mask32 & OPT_i) 355 char *match;
356 ? strcasestr(line, gl->pattern) 356 char *str = line;
357 : strstr(line, gl->pattern) 357 opt_f_again:
358 ) != NULL); 358 match = ((option_mask32 & OPT_i)
359 ? strcasestr(str, gl->pattern)
360 : strstr(str, gl->pattern)
361 );
362 if (match) {
363 if (option_mask32 & OPT_x) {
364 if (match != str)
365 goto opt_f_not_found;
366 if (str[strlen(gl->pattern)] != '\0')
367 goto opt_f_not_found;
368 } else
369 if (option_mask32 & OPT_w) {
370 char c = (match != str) ? match[-1] : ' ';
371 if (!isalnum(c) && c != '_') {
372 c = match[strlen(gl->pattern)];
373 if (!c || (!isalnum(c) && c != '_'))
374 goto opt_f_found;
375 }
376 str = match + 1;
377 goto opt_f_again;
378 }
379 opt_f_found:
380 found = 1;
381 opt_f_not_found: ;
382 }
359 } else { 383 } else {
360 if (!(gl->flg_mem_alocated_compiled & COMPILED)) { 384 if (!(gl->flg_mem_alocated_compiled & COMPILED)) {
361 gl->flg_mem_alocated_compiled |= COMPILED; 385 gl->flg_mem_alocated_compiled |= COMPILED;
@@ -384,7 +408,8 @@ static int grep_file(FILE *file)
384 if (option_mask32 & OPT_x) { 408 if (option_mask32 & OPT_x) {
385 found = (gl->matched_range.rm_so == 0 409 found = (gl->matched_range.rm_so == 0
386 && line[gl->matched_range.rm_eo] == '\0'); 410 && line[gl->matched_range.rm_eo] == '\0');
387 } else if (!(option_mask32 & OPT_w)) { 411 } else
412 if (!(option_mask32 & OPT_w)) {
388 found = 1; 413 found = 1;
389 } else { 414 } else {
390 char c = ' '; 415 char c = ' ';
@@ -395,6 +420,8 @@ static int grep_file(FILE *file)
395 if (!c || (!isalnum(c) && c != '_')) 420 if (!c || (!isalnum(c) && c != '_'))
396 found = 1; 421 found = 1;
397 } 422 }
423//BUG: "echo foop foo | grep -w foo" should match, but doesn't:
424//we bail out on first "mismatch" because it's not a word.
398 } 425 }
399 } 426 }
400 } 427 }
@@ -646,7 +673,7 @@ int grep_main(int argc UNUSED_PARAM, char **argv)
646 673
647 if (opts & OPT_C) { 674 if (opts & OPT_C) {
648 /* -C unsets prev -A and -B, but following -A or -B 675 /* -C unsets prev -A and -B, but following -A or -B
649 may override it */ 676 * may override it */
650 if (!(opts & OPT_A)) /* not overridden */ 677 if (!(opts & OPT_A)) /* not overridden */
651 lines_after = Copt; 678 lines_after = Copt;
652 if (!(opts & OPT_B)) /* not overridden */ 679 if (!(opts & OPT_B)) /* not overridden */
diff --git a/include/applets.src.h b/include/applets.src.h
index 597b1c9a6..29ab16706 100644
--- a/include/applets.src.h
+++ b/include/applets.src.h
@@ -328,6 +328,7 @@ IF_SETSEBOOL(APPLET(setsebool, BB_DIR_USR_SBIN, BB_SUID_DROP))
328IF_SETSID(APPLET(setsid, BB_DIR_USR_BIN, BB_SUID_DROP)) 328IF_SETSID(APPLET(setsid, BB_DIR_USR_BIN, BB_SUID_DROP))
329IF_SETUIDGID(APPLET_ODDNAME(setuidgid, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, setuidgid)) 329IF_SETUIDGID(APPLET_ODDNAME(setuidgid, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, setuidgid))
330IF_SHA1SUM(APPLET_NOEXEC(sha1sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha1sum)) 330IF_SHA1SUM(APPLET_NOEXEC(sha1sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha1sum))
331IF_SHA3SUM(APPLET_NOEXEC(sha3sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha3sum))
331IF_SHA256SUM(APPLET_NOEXEC(sha256sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha256sum)) 332IF_SHA256SUM(APPLET_NOEXEC(sha256sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha256sum))
332IF_SHA512SUM(APPLET_NOEXEC(sha512sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha512sum)) 333IF_SHA512SUM(APPLET_NOEXEC(sha512sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha512sum))
333IF_SHOWKEY(APPLET(showkey, BB_DIR_USR_BIN, BB_SUID_DROP)) 334IF_SHOWKEY(APPLET(showkey, BB_DIR_USR_BIN, BB_SUID_DROP))
diff --git a/include/bb_archive.h b/include/bb_archive.h
index 7bb5615da..a7a2a1135 100644
--- a/include/bb_archive.h
+++ b/include/bb_archive.h
@@ -220,9 +220,9 @@ IF_DESKTOP(long long) int unpack_xz_stream(transformer_aux_data_t *aux, int src_
220 220
221char* append_ext(char *filename, const char *expected_ext) FAST_FUNC; 221char* append_ext(char *filename, const char *expected_ext) FAST_FUNC;
222int bbunpack(char **argv, 222int bbunpack(char **argv,
223 IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(transformer_aux_data_t *aux), 223 IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(transformer_aux_data_t *aux),
224 char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext), 224 char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext),
225 const char *expected_ext 225 const char *expected_ext
226) FAST_FUNC; 226) FAST_FUNC;
227 227
228void check_errors_in_children(int signo); 228void check_errors_in_children(int signo);
diff --git a/include/grp_.h b/include/grp_.h
index 82ad90492..e5075e5a0 100644
--- a/include/grp_.h
+++ b/include/grp_.h
@@ -64,7 +64,7 @@ extern struct group *fgetgrent(FILE *__stream);
64 64
65/* Write the given entry onto the given stream. */ 65/* Write the given entry onto the given stream. */
66extern int putgrent(const struct group *__restrict __p, 66extern int putgrent(const struct group *__restrict __p,
67 FILE *__restrict __f); 67 FILE *__restrict __f);
68#endif 68#endif
69 69
70/* Search for an entry with a matching group ID. */ 70/* Search for an entry with a matching group ID. */
@@ -82,32 +82,32 @@ extern struct group *getgrnam(const char *__name);
82 POSIX people would choose. */ 82 POSIX people would choose. */
83 83
84extern int getgrent_r(struct group *__restrict __resultbuf, 84extern int getgrent_r(struct group *__restrict __resultbuf,
85 char *__restrict __buffer, size_t __buflen, 85 char *__restrict __buffer, size_t __buflen,
86 struct group **__restrict __result); 86 struct group **__restrict __result);
87 87
88/* Search for an entry with a matching group ID. */ 88/* Search for an entry with a matching group ID. */
89extern int getgrgid_r(gid_t __gid, struct group *__restrict __resultbuf, 89extern int getgrgid_r(gid_t __gid, struct group *__restrict __resultbuf,
90 char *__restrict __buffer, size_t __buflen, 90 char *__restrict __buffer, size_t __buflen,
91 struct group **__restrict __result); 91 struct group **__restrict __result);
92 92
93/* Search for an entry with a matching group name. */ 93/* Search for an entry with a matching group name. */
94extern int getgrnam_r(const char *__restrict __name, 94extern int getgrnam_r(const char *__restrict __name,
95 struct group *__restrict __resultbuf, 95 struct group *__restrict __resultbuf,
96 char *__restrict __buffer, size_t __buflen, 96 char *__restrict __buffer, size_t __buflen,
97 struct group **__restrict __result); 97 struct group **__restrict __result);
98 98
99/* Read a group entry from STREAM. This function is not standardized 99/* Read a group entry from STREAM. This function is not standardized
100 an probably never will. */ 100 an probably never will. */
101extern int fgetgrent_r(FILE *__restrict __stream, 101extern int fgetgrent_r(FILE *__restrict __stream,
102 struct group *__restrict __resultbuf, 102 struct group *__restrict __resultbuf,
103 char *__restrict __buffer, size_t __buflen, 103 char *__restrict __buffer, size_t __buflen,
104 struct group **__restrict __result); 104 struct group **__restrict __result);
105 105
106/* Store at most *NGROUPS members of the group set for USER into 106/* Store at most *NGROUPS members of the group set for USER into
107 *GROUPS. Also include GROUP. The actual number of groups found is 107 *GROUPS. Also include GROUP. The actual number of groups found is
108 returned in *NGROUPS. Return -1 if the if *NGROUPS is too small. */ 108 returned in *NGROUPS. Return -1 if the if *NGROUPS is too small. */
109extern int getgrouplist(const char *__user, gid_t __group, 109extern int getgrouplist(const char *__user, gid_t __group,
110 gid_t *__groups, int *__ngroups); 110 gid_t *__groups, int *__ngroups);
111 111
112/* Initialize the group set for the current user 112/* Initialize the group set for the current user
113 by reading the group database and using all groups 113 by reading the group database and using all groups
diff --git a/include/libbb.h b/include/libbb.h
index a749c0b92..c5ff51398 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1532,7 +1532,7 @@ struct smaprec {
1532 procps_read_smaps(pid, total) 1532 procps_read_smaps(pid, total)
1533#endif 1533#endif
1534int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, 1534int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total,
1535 void (*cb)(struct smaprec *, void *), void *data); 1535 void (*cb)(struct smaprec *, void *), void *data);
1536 1536
1537typedef struct procps_status_t { 1537typedef struct procps_status_t {
1538 DIR *dir; 1538 DIR *dir;
@@ -1655,8 +1655,12 @@ typedef struct sha512_ctx_t {
1655 uint64_t hash[8]; 1655 uint64_t hash[8];
1656 uint8_t wbuffer[128]; /* always correctly aligned for uint64_t */ 1656 uint8_t wbuffer[128]; /* always correctly aligned for uint64_t */
1657} sha512_ctx_t; 1657} sha512_ctx_t;
1658typedef struct sha3_ctx_t {
1659 uint64_t state[25];
1660 unsigned bytes_queued;
1661} sha3_ctx_t;
1658void md5_begin(md5_ctx_t *ctx) FAST_FUNC; 1662void md5_begin(md5_ctx_t *ctx) FAST_FUNC;
1659void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; 1663void md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
1660void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; 1664void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC;
1661void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; 1665void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC;
1662#define sha1_hash md5_hash 1666#define sha1_hash md5_hash
@@ -1667,6 +1671,9 @@ void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
1667void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; 1671void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
1668void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; 1672void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
1669void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; 1673void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC;
1674void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC;
1675void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
1676void sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC;
1670 1677
1671extern uint32_t *global_crc32_table; 1678extern uint32_t *global_crc32_table;
1672uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; 1679uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC;
diff --git a/include/platform.h b/include/platform.h
index 78d42fed9..b3eee55ee 100644
--- a/include/platform.h
+++ b/include/platform.h
@@ -222,6 +222,7 @@
222 222
223#include <stdint.h> 223#include <stdint.h>
224typedef int bb__aliased_int FIX_ALIASING; 224typedef int bb__aliased_int FIX_ALIASING;
225typedef long bb__aliased_long FIX_ALIASING;
225typedef uint16_t bb__aliased_uint16_t FIX_ALIASING; 226typedef uint16_t bb__aliased_uint16_t FIX_ALIASING;
226typedef uint32_t bb__aliased_uint32_t FIX_ALIASING; 227typedef uint32_t bb__aliased_uint32_t FIX_ALIASING;
227 228
@@ -229,7 +230,8 @@ typedef uint32_t bb__aliased_uint32_t FIX_ALIASING;
229 * a lvalue. This makes it more likely to not swap them by mistake 230 * a lvalue. This makes it more likely to not swap them by mistake
230 */ 231 */
231#if defined(i386) || defined(__x86_64__) || defined(__powerpc__) 232#if defined(i386) || defined(__x86_64__) || defined(__powerpc__)
232# define move_from_unaligned_int(v, intp) ((v) = *(bb__aliased_int*)(intp)) 233# define move_from_unaligned_int(v, intp) ((v) = *(bb__aliased_int*)(intp))
234# define move_from_unaligned_long(v, longp) ((v) = *(bb__aliased_long*)(longp))
233# define move_from_unaligned16(v, u16p) ((v) = *(bb__aliased_uint16_t*)(u16p)) 235# define move_from_unaligned16(v, u16p) ((v) = *(bb__aliased_uint16_t*)(u16p))
234# define move_from_unaligned32(v, u32p) ((v) = *(bb__aliased_uint32_t*)(u32p)) 236# define move_from_unaligned32(v, u32p) ((v) = *(bb__aliased_uint32_t*)(u32p))
235# define move_to_unaligned16(u16p, v) (*(bb__aliased_uint16_t*)(u16p) = (v)) 237# define move_to_unaligned16(u16p, v) (*(bb__aliased_uint16_t*)(u16p) = (v))
@@ -238,6 +240,7 @@ typedef uint32_t bb__aliased_uint32_t FIX_ALIASING;
238#else 240#else
239/* performs reasonably well (gcc usually inlines memcpy here) */ 241/* performs reasonably well (gcc usually inlines memcpy here) */
240# define move_from_unaligned_int(v, intp) (memcpy(&(v), (intp), sizeof(int))) 242# define move_from_unaligned_int(v, intp) (memcpy(&(v), (intp), sizeof(int)))
243# define move_from_unaligned_long(v, longp) (memcpy(&(v), (longp), sizeof(long)))
241# define move_from_unaligned16(v, u16p) (memcpy(&(v), (u16p), 2)) 244# define move_from_unaligned16(v, u16p) (memcpy(&(v), (u16p), 2))
242# define move_from_unaligned32(v, u32p) (memcpy(&(v), (u32p), 4)) 245# define move_from_unaligned32(v, u32p) (memcpy(&(v), (u32p), 4))
243# define move_to_unaligned16(u16p, v) do { \ 246# define move_to_unaligned16(u16p, v) do { \
diff --git a/include/pwd_.h b/include/pwd_.h
index ea158da45..625b6f5a2 100644
--- a/include/pwd_.h
+++ b/include/pwd_.h
@@ -63,7 +63,7 @@ extern struct passwd *fgetpwent(FILE *__stream);
63 63
64/* Write the given entry onto the given stream. */ 64/* Write the given entry onto the given stream. */
65extern int putpwent(const struct passwd *__restrict __p, 65extern int putpwent(const struct passwd *__restrict __p,
66 FILE *__restrict __f); 66 FILE *__restrict __f);
67#endif 67#endif
68 68
69/* Search for an entry with a matching user ID. */ 69/* Search for an entry with a matching user ID. */
@@ -81,25 +81,25 @@ extern struct passwd *getpwnam(const char *__name);
81 POSIX people would choose. */ 81 POSIX people would choose. */
82 82
83extern int getpwent_r(struct passwd *__restrict __resultbuf, 83extern int getpwent_r(struct passwd *__restrict __resultbuf,
84 char *__restrict __buffer, size_t __buflen, 84 char *__restrict __buffer, size_t __buflen,
85 struct passwd **__restrict __result); 85 struct passwd **__restrict __result);
86 86
87extern int getpwuid_r(uid_t __uid, 87extern int getpwuid_r(uid_t __uid,
88 struct passwd *__restrict __resultbuf, 88 struct passwd *__restrict __resultbuf,
89 char *__restrict __buffer, size_t __buflen, 89 char *__restrict __buffer, size_t __buflen,
90 struct passwd **__restrict __result); 90 struct passwd **__restrict __result);
91 91
92extern int getpwnam_r(const char *__restrict __name, 92extern int getpwnam_r(const char *__restrict __name,
93 struct passwd *__restrict __resultbuf, 93 struct passwd *__restrict __resultbuf,
94 char *__restrict __buffer, size_t __buflen, 94 char *__restrict __buffer, size_t __buflen,
95 struct passwd **__restrict __result); 95 struct passwd **__restrict __result);
96 96
97/* Read an entry from STREAM. This function is not standardized and 97/* Read an entry from STREAM. This function is not standardized and
98 probably never will. */ 98 probably never will. */
99extern int fgetpwent_r(FILE *__restrict __stream, 99extern int fgetpwent_r(FILE *__restrict __stream,
100 struct passwd *__restrict __resultbuf, 100 struct passwd *__restrict __resultbuf,
101 char *__restrict __buffer, size_t __buflen, 101 char *__restrict __buffer, size_t __buflen,
102 struct passwd **__restrict __result); 102 struct passwd **__restrict __result);
103 103
104POP_SAVED_FUNCTION_VISIBILITY 104POP_SAVED_FUNCTION_VISIBILITY
105 105
diff --git a/include/shadow_.h b/include/shadow_.h
index 648a62ab3..7babe4f30 100644
--- a/include/shadow_.h
+++ b/include/shadow_.h
@@ -79,21 +79,21 @@ extern int putspent(const struct spwd *__p, FILE *__stream);
79 79
80/* Reentrant versions of some of the functions above */ 80/* Reentrant versions of some of the functions above */
81extern int getspent_r(struct spwd *__result_buf, char *__buffer, 81extern int getspent_r(struct spwd *__result_buf, char *__buffer,
82 size_t __buflen, struct spwd **__result); 82 size_t __buflen, struct spwd **__result);
83#endif 83#endif
84 84
85extern int getspnam_r(const char *__name, struct spwd *__result_buf, 85extern int getspnam_r(const char *__name, struct spwd *__result_buf,
86 char *__buffer, size_t __buflen, 86 char *__buffer, size_t __buflen,
87 struct spwd **__result); 87 struct spwd **__result);
88 88
89#ifdef UNUSED_FOR_NOW 89#ifdef UNUSED_FOR_NOW
90extern int sgetspent_r(const char *__string, struct spwd *__result_buf, 90extern int sgetspent_r(const char *__string, struct spwd *__result_buf,
91 char *__buffer, size_t __buflen, 91 char *__buffer, size_t __buflen,
92 struct spwd **__result); 92 struct spwd **__result);
93 93
94extern int fgetspent_r(FILE *__stream, struct spwd *__result_buf, 94extern int fgetspent_r(FILE *__stream, struct spwd *__result_buf,
95 char *__buffer, size_t __buflen, 95 char *__buffer, size_t __buflen,
96 struct spwd **__result); 96 struct spwd **__result);
97/* Protect password file against multi writers */ 97/* Protect password file against multi writers */
98extern int lckpwdf(void); 98extern int lckpwdf(void);
99 99
diff --git a/init/init.c b/init/init.c
index 724894698..b84bdccbc 100644
--- a/init/init.c
+++ b/init/init.c
@@ -520,7 +520,7 @@ static pid_t run(const struct init_action *a)
520 520
521 /* Log the process name and args */ 521 /* Log the process name and args */
522 message(L_LOG, "starting pid %d, tty '%s': '%s'", 522 message(L_LOG, "starting pid %d, tty '%s': '%s'",
523 getpid(), a->terminal, a->command); 523 getpid(), a->terminal, a->command);
524 524
525 /* Now run it. The new program will take over this PID, 525 /* Now run it. The new program will take over this PID,
526 * so nothing further in init.c should be run. */ 526 * so nothing further in init.c should be run. */
diff --git a/libbb/Config.src b/libbb/Config.src
index ee1b66a45..19021fed1 100644
--- a/libbb/Config.src
+++ b/libbb/Config.src
@@ -28,6 +28,16 @@ config MD5_SMALL
28 2 3.0 5088 28 2 3.0 5088
29 3 (smallest) 5.1 4912 29 3 (smallest) 5.1 4912
30 30
31config SHA3_SMALL
32 int "SHA3: Trade bytes for speed (0:fast, 1:slow)"
33 default 1
34 range 0 1
35 help
36 Trade binary size versus speed for the sha3sum algorithm.
37 SHA3_SMALL=0 compared to SHA3_SMALL=1 (approximate):
38 64-bit x86: +270 bytes of code, 45% faster
39 32-bit x86: +450 bytes of code, 75% faster
40
31config FEATURE_FAST_TOP 41config FEATURE_FAST_TOP
32 bool "Faster /proc scanning code (+100 bytes)" 42 bool "Faster /proc scanning code (+100 bytes)"
33 default y 43 default y
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index 63ec010dd..fb06ab9a5 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -140,10 +140,9 @@ void FAST_FUNC bb_show_usage(void)
140} 140}
141 141
142#if NUM_APPLETS > 8 142#if NUM_APPLETS > 8
143/* NB: any char pointer will work as well, not necessarily applet_names */ 143static int applet_name_compare(const void *name, const void *idx)
144static int applet_name_compare(const void *name, const void *v)
145{ 144{
146 int i = (const char *)v - applet_names; 145 int i = (int)(ptrdiff_t)idx - 1;
147 return strcmp(name, APPLET_NAME(i)); 146 return strcmp(name, APPLET_NAME(i));
148} 147}
149#endif 148#endif
@@ -152,10 +151,12 @@ int FAST_FUNC find_applet_by_name(const char *name)
152#if NUM_APPLETS > 8 151#if NUM_APPLETS > 8
153 /* Do a binary search to find the applet entry given the name. */ 152 /* Do a binary search to find the applet entry given the name. */
154 const char *p; 153 const char *p;
155 p = bsearch(name, applet_names, ARRAY_SIZE(applet_main), 1, applet_name_compare); 154 p = bsearch(name, (void*)(ptrdiff_t)1, ARRAY_SIZE(applet_main), 1, applet_name_compare);
156 if (!p) 155 /*
157 return -1; 156 * if (!p) return -1;
158 return p - applet_names; 157 * ^^^^^^^^^^^^^^^^^^ the code below will do this if p == NULL :)
158 */
159 return (int)(ptrdiff_t)p - 1;
159#else 160#else
160 /* A version which does not pull in bsearch */ 161 /* A version which does not pull in bsearch */
161 int i = 0; 162 int i = 0;
@@ -749,8 +750,11 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv)
749 /* Special case. POSIX says "test --help" 750 /* Special case. POSIX says "test --help"
750 * should be no different from e.g. "test --foo". */ 751 * should be no different from e.g. "test --foo". */
751//TODO: just compare applet_no with APPLET_NO_test 752//TODO: just compare applet_no with APPLET_NO_test
752 if (!ENABLE_TEST || strcmp(applet_name, "test") != 0) 753 if (!ENABLE_TEST || strcmp(applet_name, "test") != 0) {
754 /* If you want "foo --help" to return 0: */
755 /*xfunc_error_retval = 0;*/
753 bb_show_usage(); 756 bb_show_usage();
757 }
754 } 758 }
755 if (ENABLE_FEATURE_SUID) 759 if (ENABLE_FEATURE_SUID)
756 check_suid(applet_no); 760 check_suid(applet_no);
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c
index a313c2a65..b4d955e5a 100644
--- a/libbb/hash_md5_sha.c
+++ b/libbb/hash_md5_sha.c
@@ -31,6 +31,11 @@ static ALWAYS_INLINE uint64_t rotr64(uint64_t x, unsigned n)
31 return (x >> n) | (x << (64 - n)); 31 return (x >> n) | (x << (64 - n));
32} 32}
33 33
34/* rotl64 only used for sha3 currently */
35static ALWAYS_INLINE uint64_t rotl64(uint64_t x, unsigned n)
36{
37 return (x << n) | (x >> (64 - n));
38}
34 39
35/* Feed data through a temporary buffer. 40/* Feed data through a temporary buffer.
36 * The internal buffer remembers previous data until it has 64 41 * The internal buffer remembers previous data until it has 64
@@ -51,7 +56,7 @@ static void FAST_FUNC common64_hash(md5_ctx_t *ctx, const void *buffer, size_t l
51 len -= remaining; 56 len -= remaining;
52 buffer = (const char *)buffer + remaining; 57 buffer = (const char *)buffer + remaining;
53 bufpos += remaining; 58 bufpos += remaining;
54 /* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */ 59 /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */
55 bufpos -= 64; 60 bufpos -= 64;
56 if (bufpos != 0) 61 if (bufpos != 0)
57 break; 62 break;
@@ -185,10 +190,9 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx)
185 int i; 190 int i;
186 uint32_t temp; 191 uint32_t temp;
187 192
188# if BB_BIG_ENDIAN 193 if (BB_BIG_ENDIAN)
189 for (i = 0; i < 16; i++) 194 for (i = 0; i < 16; i++)
190 words[i] = SWAP_LE32(words[i]); 195 words[i] = SWAP_LE32(words[i]);
191# endif
192 196
193# if MD5_SMALL == 3 197# if MD5_SMALL == 3
194 pc = C_array; 198 pc = C_array;
@@ -462,12 +466,13 @@ void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf)
462 common64_end(ctx, /*swap_needed:*/ BB_BIG_ENDIAN); 466 common64_end(ctx, /*swap_needed:*/ BB_BIG_ENDIAN);
463 467
464 /* The MD5 result is in little endian byte order */ 468 /* The MD5 result is in little endian byte order */
465#if BB_BIG_ENDIAN 469 if (BB_BIG_ENDIAN) {
466 ctx->hash[0] = SWAP_LE32(ctx->hash[0]); 470 ctx->hash[0] = SWAP_LE32(ctx->hash[0]);
467 ctx->hash[1] = SWAP_LE32(ctx->hash[1]); 471 ctx->hash[1] = SWAP_LE32(ctx->hash[1]);
468 ctx->hash[2] = SWAP_LE32(ctx->hash[2]); 472 ctx->hash[2] = SWAP_LE32(ctx->hash[2]);
469 ctx->hash[3] = SWAP_LE32(ctx->hash[3]); 473 ctx->hash[3] = SWAP_LE32(ctx->hash[3]);
470#endif 474 }
475
471 memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * 4); 476 memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * 4);
472} 477}
473 478
@@ -834,7 +839,7 @@ void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len)
834 len -= remaining; 839 len -= remaining;
835 buffer = (const char *)buffer + remaining; 840 buffer = (const char *)buffer + remaining;
836 bufpos += remaining; 841 bufpos += remaining;
837 /* clever way to do "if (bufpos != 128) break; ... ; bufpos = 0;" */ 842 /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */
838 bufpos -= 128; 843 bufpos -= 128;
839 if (bufpos != 0) 844 if (bufpos != 0)
840 break; 845 break;
@@ -896,3 +901,268 @@ void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf)
896 } 901 }
897 memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); 902 memcpy(resbuf, ctx->hash, sizeof(ctx->hash));
898} 903}
904
905
906/*
907 * The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
908 * Michael Peeters and Gilles Van Assche. For more information, feedback or
909 * questions, please refer to our website: http://keccak.noekeon.org/
910 *
911 * Implementation by Ronny Van Keer,
912 * hereby denoted as "the implementer".
913 *
914 * To the extent possible under law, the implementer has waived all copyright
915 * and related or neighboring rights to the source code in this file.
916 * http://creativecommons.org/publicdomain/zero/1.0/
917 *
918 * Busybox modifications (C) Lauri Kasanen, under the GPLv2.
919 */
920
921#if CONFIG_SHA3_SMALL < 0
922# define SHA3_SMALL 0
923#elif CONFIG_SHA3_SMALL > 1
924# define SHA3_SMALL 1
925#else
926# define SHA3_SMALL CONFIG_SHA3_SMALL
927#endif
928
929enum {
930 SHA3_IBLK_BYTES = 72, /* 576 bits / 8 */
931};
932
933/*
934 * In the crypto literature this function is usually called Keccak-f().
935 */
936static void sha3_process_block72(uint64_t *state)
937{
938 enum { NROUNDS = 24 };
939
940 /* Elements should be 64-bit, but top half is always zero or 0x80000000.
941 * We encode 63rd bits in a separate word below.
942 * Same is true for 31th bits, which lets us use 16-bit table instead of 64-bit.
943 * The speed penalty is lost in the noise.
944 */
945 static const uint16_t IOTA_CONST[NROUNDS] = {
946 0x0001,
947 0x8082,
948 0x808a,
949 0x8000,
950 0x808b,
951 0x0001,
952 0x8081,
953 0x8009,
954 0x008a,
955 0x0088,
956 0x8009,
957 0x000a,
958 0x808b,
959 0x008b,
960 0x8089,
961 0x8003,
962 0x8002,
963 0x0080,
964 0x800a,
965 0x000a,
966 0x8081,
967 0x8080,
968 0x0001,
969 0x8008,
970 };
971 /* bit for CONST[0] is in msb: 0011 0011 0000 0111 1101 1101 */
972 const uint32_t IOTA_CONST_bit63 = (uint32_t)(0x3307dd00);
973 /* bit for CONST[0] is in msb: 0001 0110 0011 1000 0001 1011 */
974 const uint32_t IOTA_CONST_bit31 = (uint32_t)(0x16381b00);
975
976 static const uint8_t ROT_CONST[24] = {
977 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14,
978 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44,
979 };
980 static const uint8_t PI_LANE[24] = {
981 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
982 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1,
983 };
984 /*static const uint8_t MOD5[10] = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, };*/
985
986 unsigned x, y;
987 unsigned round;
988
989 if (BB_BIG_ENDIAN) {
990 for (x = 0; x < 25; x++) {
991 state[x] = SWAP_LE64(state[x]);
992 }
993 }
994
995 for (round = 0; round < NROUNDS; ++round) {
996 /* Theta */
997 {
998 uint64_t BC[10];
999 for (x = 0; x < 5; ++x) {
1000 BC[x + 5] = BC[x] = state[x]
1001 ^ state[x + 5] ^ state[x + 10]
1002 ^ state[x + 15] ^ state[x + 20];
1003 }
1004 /* Using 2x5 vector above eliminates the need to use
1005 * BC[MOD5[x+N]] trick below to fetch BC[(x+N) % 5],
1006 * and the code is a bit _smaller_.
1007 */
1008 for (x = 0; x < 5; ++x) {
1009 uint64_t temp = BC[x + 4] ^ rotl64(BC[x + 1], 1);
1010 state[x] ^= temp;
1011 state[x + 5] ^= temp;
1012 state[x + 10] ^= temp;
1013 state[x + 15] ^= temp;
1014 state[x + 20] ^= temp;
1015 }
1016 }
1017
1018 /* Rho Pi */
1019 if (SHA3_SMALL) {
1020 uint64_t t1 = state[1];
1021 for (x = 0; x < 24; ++x) {
1022 uint64_t t0 = state[PI_LANE[x]];
1023 state[PI_LANE[x]] = rotl64(t1, ROT_CONST[x]);
1024 t1 = t0;
1025 }
1026 } else {
1027 /* Especially large benefit for 32-bit arch (75% faster):
1028 * 64-bit rotations by non-constant usually are SLOW on those.
1029 * We resort to unrolling here.
1030 * This optimizes out PI_LANE[] and ROT_CONST[],
1031 * but generates 300-500 more bytes of code.
1032 */
1033 uint64_t t0;
1034 uint64_t t1 = state[1];
1035#define RhoPi_twice(x) \
1036 t0 = state[PI_LANE[x ]]; \
1037 state[PI_LANE[x ]] = rotl64(t1, ROT_CONST[x ]); \
1038 t1 = state[PI_LANE[x+1]]; \
1039 state[PI_LANE[x+1]] = rotl64(t0, ROT_CONST[x+1]);
1040 RhoPi_twice(0); RhoPi_twice(2);
1041 RhoPi_twice(4); RhoPi_twice(6);
1042 RhoPi_twice(8); RhoPi_twice(10);
1043 RhoPi_twice(12); RhoPi_twice(14);
1044 RhoPi_twice(16); RhoPi_twice(18);
1045 RhoPi_twice(20); RhoPi_twice(22);
1046#undef RhoPi_twice
1047 }
1048
1049 /* Chi */
1050 for (y = 0; y <= 20; y += 5) {
1051 uint64_t BC0, BC1, BC2, BC3, BC4;
1052 BC0 = state[y + 0];
1053 BC1 = state[y + 1];
1054 BC2 = state[y + 2];
1055 state[y + 0] = BC0 ^ ((~BC1) & BC2);
1056 BC3 = state[y + 3];
1057 state[y + 1] = BC1 ^ ((~BC2) & BC3);
1058 BC4 = state[y + 4];
1059 state[y + 2] = BC2 ^ ((~BC3) & BC4);
1060 state[y + 3] = BC3 ^ ((~BC4) & BC0);
1061 state[y + 4] = BC4 ^ ((~BC0) & BC1);
1062 }
1063
1064 /* Iota */
1065 state[0] ^= IOTA_CONST[round]
1066 | (uint32_t)((IOTA_CONST_bit31 << round) & 0x80000000)
1067 | (uint64_t)((IOTA_CONST_bit63 << round) & 0x80000000) << 32;
1068 }
1069
1070 if (BB_BIG_ENDIAN) {
1071 for (x = 0; x < 25; x++) {
1072 state[x] = SWAP_LE64(state[x]);
1073 }
1074 }
1075}
1076
1077void FAST_FUNC sha3_begin(sha3_ctx_t *ctx)
1078{
1079 memset(ctx, 0, sizeof(*ctx));
1080}
1081
1082void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len)
1083{
1084#if SHA3_SMALL
1085 const uint8_t *data = buffer;
1086 unsigned bufpos = ctx->bytes_queued;
1087
1088 while (1) {
1089 unsigned remaining = SHA3_IBLK_BYTES - bufpos;
1090 if (remaining > len)
1091 remaining = len;
1092 len -= remaining;
1093 /* XOR data into buffer */
1094 while (remaining != 0) {
1095 uint8_t *buf = (uint8_t*)ctx->state;
1096 buf[bufpos] ^= *data++;
1097 bufpos++;
1098 remaining--;
1099 }
1100 /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */
1101 bufpos -= SHA3_IBLK_BYTES;
1102 if (bufpos != 0)
1103 break;
1104 /* Buffer is filled up, process it */
1105 sha3_process_block72(ctx->state);
1106 /*bufpos = 0; - already is */
1107 }
1108 ctx->bytes_queued = bufpos + SHA3_IBLK_BYTES;
1109#else
1110 /* +50 bytes code size, but a bit faster because of long-sized XORs */
1111 const uint8_t *data = buffer;
1112 unsigned bufpos = ctx->bytes_queued;
1113
1114 /* If already data in queue, continue queuing first */
1115 while (len != 0 && bufpos != 0) {
1116 uint8_t *buf = (uint8_t*)ctx->state;
1117 buf[bufpos] ^= *data++;
1118 len--;
1119 bufpos++;
1120 if (bufpos == SHA3_IBLK_BYTES) {
1121 bufpos = 0;
1122 goto do_block;
1123 }
1124 }
1125
1126 /* Absorb complete blocks */
1127 while (len >= SHA3_IBLK_BYTES) {
1128 /* XOR data onto beginning of state[].
1129 * We try to be efficient - operate one word at a time, not byte.
1130 * Careful wrt unaligned access: can't just use "*(long*)data"!
1131 */
1132 unsigned count = SHA3_IBLK_BYTES / sizeof(long);
1133 long *buf = (long*)ctx->state;
1134 do {
1135 long v;
1136 move_from_unaligned_long(v, (long*)data);
1137 *buf++ ^= v;
1138 data += sizeof(long);
1139 } while (--count);
1140 len -= SHA3_IBLK_BYTES;
1141 do_block:
1142 sha3_process_block72(ctx->state);
1143 }
1144
1145 /* Queue remaining data bytes */
1146 while (len != 0) {
1147 uint8_t *buf = (uint8_t*)ctx->state;
1148 buf[bufpos] ^= *data++;
1149 bufpos++;
1150 len--;
1151 }
1152
1153 ctx->bytes_queued = bufpos;
1154#endif
1155}
1156
1157void FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf)
1158{
1159 /* Padding */
1160 uint8_t *buf = (uint8_t*)ctx->state;
1161 buf[ctx->bytes_queued] ^= 1;
1162 buf[SHA3_IBLK_BYTES - 1] ^= 0x80;
1163
1164 sha3_process_block72(ctx->state);
1165
1166 /* Output */
1167 memcpy(resbuf, ctx->state, 64);
1168}
diff --git a/libbb/inet_common.c b/libbb/inet_common.c
index 7208db9ea..0f4fca1a2 100644
--- a/libbb/inet_common.c
+++ b/libbb/inet_common.c
@@ -97,7 +97,7 @@ char* FAST_FUNC INET_rresolve(struct sockaddr_in *s_in, int numeric, uint32_t ne
97 if (s_in->sin_family != AF_INET) { 97 if (s_in->sin_family != AF_INET) {
98#ifdef DEBUG 98#ifdef DEBUG
99 bb_error_msg("rresolve: unsupported address family %d!", 99 bb_error_msg("rresolve: unsupported address family %d!",
100 s_in->sin_family); 100 s_in->sin_family);
101#endif 101#endif
102 errno = EAFNOSUPPORT; 102 errno = EAFNOSUPPORT;
103 return NULL; 103 return NULL;
@@ -195,7 +195,7 @@ char* FAST_FUNC INET6_rresolve(struct sockaddr_in6 *sin6, int numeric)
195 if (sin6->sin6_family != AF_INET6) { 195 if (sin6->sin6_family != AF_INET6) {
196#ifdef DEBUG 196#ifdef DEBUG
197 bb_error_msg("rresolve: unsupported address family %d!", 197 bb_error_msg("rresolve: unsupported address family %d!",
198 sin6->sin6_family); 198 sin6->sin6_family);
199#endif 199#endif
200 errno = EAFNOSUPPORT; 200 errno = EAFNOSUPPORT;
201 return NULL; 201 return NULL;
diff --git a/libbb/loop.c b/libbb/loop.c
index b3a520848..823fba079 100644
--- a/libbb/loop.c
+++ b/libbb/loop.c
@@ -150,9 +150,9 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse
150 } 150 }
151 151
152 /* If this block device already set up right, re-use it. 152 /* If this block device already set up right, re-use it.
153 (Yes this is racy, but associating two loop devices with the same 153 * (Yes this is racy, but associating two loop devices with the same
154 file isn't pretty either. In general, mounting the same file twice 154 * file isn't pretty either. In general, mounting the same file twice
155 without using losetup manually is problematic.) 155 * without using losetup manually is problematic.)
156 */ 156 */
157 } else 157 } else
158 if (strcmp(file, (char *)loopinfo.lo_file_name) != 0 158 if (strcmp(file, (char *)loopinfo.lo_file_name) != 0
diff --git a/libbb/procps.c b/libbb/procps.c
index c6977da51..e2f54d730 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -181,7 +181,7 @@ static char *skip_fields(char *str, int count)
181 181
182#if ENABLE_FEATURE_TOPMEM || ENABLE_PMAP 182#if ENABLE_FEATURE_TOPMEM || ENABLE_PMAP
183int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, 183int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total,
184 void (*cb)(struct smaprec *, void *), void *data) 184 void (*cb)(struct smaprec *, void *), void *data)
185{ 185{
186 FILE *file; 186 FILE *file;
187 struct smaprec currec; 187 struct smaprec currec;
diff --git a/libbb/selinux_common.c b/libbb/selinux_common.c
index 62910e285..c2585557f 100644
--- a/libbb/selinux_common.c
+++ b/libbb/selinux_common.c
@@ -10,7 +10,7 @@
10#include <selinux/context.h> 10#include <selinux/context.h>
11 11
12context_t FAST_FUNC set_security_context_component(security_context_t cur_context, 12context_t FAST_FUNC set_security_context_component(security_context_t cur_context,
13 char *user, char *role, char *type, char *range) 13 char *user, char *role, char *type, char *range)
14{ 14{
15 context_t con = context_new(cur_context); 15 context_t con = context_new(cur_context);
16 if (!con) 16 if (!con)
diff --git a/libbb/xatonum_template.c b/libbb/xatonum_template.c
index 029f66202..e0471983c 100644
--- a/libbb/xatonum_template.c
+++ b/libbb/xatonum_template.c
@@ -59,7 +59,7 @@ unsigned type FAST_FUNC xstrtou(_range_sfx)(const char *numstr, int base,
59 } 59 }
60 60
61 /* Note: trailing space is an error. 61 /* Note: trailing space is an error.
62 It would be easy enough to allow though if desired. */ 62 * It would be easy enough to allow though if desired. */
63 if (*e) 63 if (*e)
64 goto inval; 64 goto inval;
65 chk_range: 65 chk_range:
diff --git a/libpwdgrp/pwd_grp.c b/libpwdgrp/pwd_grp.c
index edf53f350..2060d7811 100644
--- a/libpwdgrp/pwd_grp.c
+++ b/libpwdgrp/pwd_grp.c
@@ -300,8 +300,8 @@ struct group *getgrgid(gid_t gid)
300 * to have been created as a reentrant version of the non-standard 300 * to have been created as a reentrant version of the non-standard
301 * functions getspuid. Why getspuid was added, I do not know. */ 301 * functions getspuid. Why getspuid was added, I do not know. */
302int getspuid_r(uid_t uid, struct spwd *__restrict resultbuf, 302int getspuid_r(uid_t uid, struct spwd *__restrict resultbuf,
303 char *__restrict buffer, size_t buflen, 303 char *__restrict buffer, size_t buflen,
304 struct spwd **__restrict result) 304 struct spwd **__restrict result)
305{ 305{
306 int rv; 306 int rv;
307 struct passwd *pp; 307 struct passwd *pp;
@@ -403,8 +403,8 @@ void endpwent(void)
403 403
404 404
405int getpwent_r(struct passwd *__restrict resultbuf, 405int getpwent_r(struct passwd *__restrict resultbuf,
406 char *__restrict buffer, size_t buflen, 406 char *__restrict buffer, size_t buflen,
407 struct passwd **__restrict result) 407 struct passwd **__restrict result)
408{ 408{
409 int rv; 409 int rv;
410 410
@@ -451,8 +451,8 @@ void endgrent(void)
451} 451}
452 452
453int getgrent_r(struct group *__restrict resultbuf, 453int getgrent_r(struct group *__restrict resultbuf,
454 char *__restrict buffer, size_t buflen, 454 char *__restrict buffer, size_t buflen,
455 struct group **__restrict result) 455 struct group **__restrict result)
456{ 456{
457 int rv; 457 int rv;
458 458
@@ -501,7 +501,7 @@ void endspent(void)
501} 501}
502 502
503int getspent_r(struct spwd *resultbuf, char *buffer, 503int getspent_r(struct spwd *resultbuf, char *buffer,
504 size_t buflen, struct spwd **result) 504 size_t buflen, struct spwd **result)
505{ 505{
506 int rv; 506 int rv;
507 507
diff --git a/miscutils/crond.c b/miscutils/crond.c
index a0b73c774..582dc991a 100644
--- a/miscutils/crond.c
+++ b/miscutils/crond.c
@@ -885,7 +885,7 @@ int crond_main(int argc UNUSED_PARAM, char **argv)
885 xsetenv("SHELL", DEFAULT_SHELL); /* once, for all future children */ 885 xsetenv("SHELL", DEFAULT_SHELL); /* once, for all future children */
886 crondlog(LVL8 "crond (busybox "BB_VER") started, log level %d", G.log_level); 886 crondlog(LVL8 "crond (busybox "BB_VER") started, log level %d", G.log_level);
887 rescan_crontab_dir(); 887 rescan_crontab_dir();
888 write_pidfile("/var/run/crond.pid"); 888 write_pidfile(CONFIG_PID_FILE_PATH "/crond.pid");
889 889
890 /* Main loop */ 890 /* Main loop */
891 t2 = time(NULL); 891 t2 = time(NULL);
diff --git a/miscutils/dc.c b/miscutils/dc.c
index 6903761e4..6bcfbe249 100644
--- a/miscutils/dc.c
+++ b/miscutils/dc.c
@@ -11,11 +11,11 @@
11//usage: 11//usage:
12//usage:#define dc_full_usage "\n\n" 12//usage:#define dc_full_usage "\n\n"
13//usage: "Tiny RPN calculator. Operations:\n" 13//usage: "Tiny RPN calculator. Operations:\n"
14//usage: "+, add, -, sub, *, mul, /, div, %, mod, "IF_FEATURE_DC_LIBM("**, exp, ")"and, or, not, eor,\n" 14//usage: "+, add, -, sub, *, mul, /, div, %, mod, "IF_FEATURE_DC_LIBM("**, exp, ")"and, or, not, xor,\n"
15//usage: "p - print top of the stack (without popping),\n" 15//usage: "p - print top of the stack (without popping),\n"
16//usage: "f - print entire stack,\n" 16//usage: "f - print entire stack,\n"
17//usage: "o - pop the value and set output radix (must be 10, 16, 8 or 2).\n" 17//usage: "o - pop the value and set output radix (must be 10, 16, 8 or 2).\n"
18//usage: "Examples: 'dc 2 2 add p' -> 4, 'dc 8 8 * 2 2 + / p' -> 16" 18//usage: "Examples: 'dc 2 2 add p' -> 4, 'dc 8 8 mul 2 2 + / p' -> 16"
19//usage: 19//usage:
20//usage:#define dc_example_usage 20//usage:#define dc_example_usage
21//usage: "$ dc 2 2 + p\n" 21//usage: "$ dc 2 2 + p\n"
@@ -219,29 +219,29 @@ static const struct op operators[] = {
219 {"p", print_no_pop}, 219 {"p", print_no_pop},
220 {"f", print_stack_no_pop}, 220 {"f", print_stack_no_pop},
221 {"o", set_output_base}, 221 {"o", set_output_base},
222 { "", NULL }
223}; 222};
224 223
225static void stack_machine(const char *argument) 224static void stack_machine(const char *argument)
226{ 225{
227 char *endPointer; 226 char *end;
228 double d; 227 double d;
229 const struct op *o = operators; 228 const struct op *o;
230 229
231 d = strtod(argument, &endPointer); 230 d = strtod(argument, &end);
232 231 if (end != argument && *end == '\0') {
233 if (endPointer != argument && *endPointer == '\0') {
234 push(d); 232 push(d);
235 return; 233 return;
236 } 234 }
237 235
238 while (o->function) { 236 o = operators;
237 do {
239 if (strcmp(o->name, argument) == 0) { 238 if (strcmp(o->name, argument) == 0) {
240 o->function(); 239 o->function();
241 return; 240 return;
242 } 241 }
243 o++; 242 o++;
244 } 243 } while (o != operators + ARRAY_SIZE(operators));
244
245 bb_error_msg_and_die("syntax error at '%s'", argument); 245 bb_error_msg_and_die("syntax error at '%s'", argument);
246} 246}
247 247
diff --git a/miscutils/devfsd.c b/miscutils/devfsd.c
index 6493fe4f1..24c953bac 100644
--- a/miscutils/devfsd.c
+++ b/miscutils/devfsd.c
@@ -219,7 +219,7 @@ static void action_execute(const struct devfsd_notify_struct *, const struct con
219 const regmatch_t *, unsigned); 219 const regmatch_t *, unsigned);
220static void action_modload(const struct devfsd_notify_struct *info, const struct config_entry_struct *entry); 220static void action_modload(const struct devfsd_notify_struct *info, const struct config_entry_struct *entry);
221static void action_copy(const struct devfsd_notify_struct *, const struct config_entry_struct *, 221static void action_copy(const struct devfsd_notify_struct *, const struct config_entry_struct *,
222 const regmatch_t *, unsigned); 222 const regmatch_t *, unsigned);
223static void action_compat(const struct devfsd_notify_struct *, unsigned); 223static void action_compat(const struct devfsd_notify_struct *, unsigned);
224static void free_config(void); 224static void free_config(void);
225static void restore(char *spath, struct stat source_stat, int rootlen); 225static void restore(char *spath, struct stat source_stat, int rootlen);
@@ -229,12 +229,12 @@ static void signal_handler(int);
229static const char *get_variable(const char *, void *); 229static const char *get_variable(const char *, void *);
230static int make_dir_tree(const char *); 230static int make_dir_tree(const char *);
231static int expand_expression(char *, unsigned, const char *, const char *(*)(const char *, void *), void *, 231static int expand_expression(char *, unsigned, const char *, const char *(*)(const char *, void *), void *,
232 const char *, const regmatch_t *, unsigned); 232 const char *, const regmatch_t *, unsigned);
233static void expand_regexp(char *, size_t, const char *, const char *, const regmatch_t *, unsigned); 233static void expand_regexp(char *, size_t, const char *, const char *, const regmatch_t *, unsigned);
234static const char *expand_variable( char *, unsigned, unsigned *, const char *, 234static const char *expand_variable( char *, unsigned, unsigned *, const char *,
235 const char *(*)(const char *, void *), void *); 235 const char *(*)(const char *, void *), void *);
236static const char *get_variable_v2(const char *, const char *(*)(const char *, void *), void *); 236static const char *get_variable_v2(const char *, const char *(*)(const char *, void *), void *);
237static char get_old_ide_name(unsigned , unsigned); 237static char get_old_ide_name(unsigned, unsigned);
238static char *write_old_sd_name(char *, unsigned, unsigned, const char *); 238static char *write_old_sd_name(char *, unsigned, unsigned, const char *);
239 239
240/* busybox functions */ 240/* busybox functions */
@@ -580,9 +580,9 @@ static void process_config_line(const char *line, unsigned long *event_mask)
580 /*This action will pass "/dev/$devname"(i.e. "/dev/" prefixed to 580 /*This action will pass "/dev/$devname"(i.e. "/dev/" prefixed to
581 the device name) to the module loading facility. In addition, 581 the device name) to the module loading facility. In addition,
582 the /etc/modules.devfs configuration file is used.*/ 582 the /etc/modules.devfs configuration file is used.*/
583 if (ENABLE_DEVFSD_MODLOAD) 583 if (ENABLE_DEVFSD_MODLOAD)
584 new->action.what = AC_MODLOAD; 584 new->action.what = AC_MODLOAD;
585 break; 585 break;
586 case 6: /* EXECUTE */ 586 case 6: /* EXECUTE */
587 new->action.what = AC_EXECUTE; 587 new->action.what = AC_EXECUTE;
588 num_args -= 3; 588 num_args -= 3;
@@ -750,7 +750,7 @@ static void action_permissions(const struct devfsd_notify_struct *info,
750} /* End Function action_permissions */ 750} /* End Function action_permissions */
751 751
752static void action_modload(const struct devfsd_notify_struct *info, 752static void action_modload(const struct devfsd_notify_struct *info,
753 const struct config_entry_struct *entry UNUSED_PARAM) 753 const struct config_entry_struct *entry UNUSED_PARAM)
754/* [SUMMARY] Load a module. 754/* [SUMMARY] Load a module.
755 <info> The devfs change. 755 <info> The devfs change.
756 <entry> The config file entry. 756 <entry> The config file entry.
@@ -771,8 +771,8 @@ static void action_modload(const struct devfsd_notify_struct *info,
771} /* End Function action_modload */ 771} /* End Function action_modload */
772 772
773static void action_execute(const struct devfsd_notify_struct *info, 773static void action_execute(const struct devfsd_notify_struct *info,
774 const struct config_entry_struct *entry, 774 const struct config_entry_struct *entry,
775 const regmatch_t *regexpr, unsigned int numexpr) 775 const regmatch_t *regexpr, unsigned int numexpr)
776/* [SUMMARY] Execute a programme. 776/* [SUMMARY] Execute a programme.
777 <info> The devfs change. 777 <info> The devfs change.
778 <entry> The config file entry. 778 <entry> The config file entry.
@@ -803,8 +803,8 @@ static void action_execute(const struct devfsd_notify_struct *info,
803 803
804 804
805static void action_copy(const struct devfsd_notify_struct *info, 805static void action_copy(const struct devfsd_notify_struct *info,
806 const struct config_entry_struct *entry, 806 const struct config_entry_struct *entry,
807 const regmatch_t *regexpr, unsigned int numexpr) 807 const regmatch_t *regexpr, unsigned int numexpr)
808/* [SUMMARY] Copy permissions. 808/* [SUMMARY] Copy permissions.
809 <info> The devfs change. 809 <info> The devfs change.
810 <entry> The config file entry. 810 <entry> The config file entry.
@@ -1259,11 +1259,11 @@ static int make_dir_tree(const char *path)
1259} /* End Function make_dir_tree */ 1259} /* End Function make_dir_tree */
1260 1260
1261static int expand_expression(char *output, unsigned int outsize, 1261static int expand_expression(char *output, unsigned int outsize,
1262 const char *input, 1262 const char *input,
1263 const char *(*get_variable_func)(const char *variable, void *info), 1263 const char *(*get_variable_func)(const char *variable, void *info),
1264 void *info, 1264 void *info,
1265 const char *devname, 1265 const char *devname,
1266 const regmatch_t *ex, unsigned int numexp) 1266 const regmatch_t *ex, unsigned int numexp)
1267/* [SUMMARY] Expand environment variables and regular subexpressions in string. 1267/* [SUMMARY] Expand environment variables and regular subexpressions in string.
1268 <output> The output expanded expression is written here. 1268 <output> The output expanded expression is written here.
1269 <length> The size of the output buffer. 1269 <length> The size of the output buffer.
@@ -1288,8 +1288,8 @@ static int expand_expression(char *output, unsigned int outsize,
1288} /* End Function expand_expression */ 1288} /* End Function expand_expression */
1289 1289
1290static void expand_regexp(char *output, size_t outsize, const char *input, 1290static void expand_regexp(char *output, size_t outsize, const char *input,
1291 const char *devname, 1291 const char *devname,
1292 const regmatch_t *ex, unsigned int numex) 1292 const regmatch_t *ex, unsigned int numex)
1293/* [SUMMARY] Expand all occurrences of the regular subexpressions \0 to \9. 1293/* [SUMMARY] Expand all occurrences of the regular subexpressions \0 to \9.
1294 <output> The output expanded expression is written here. 1294 <output> The output expanded expression is written here.
1295 <outsize> The size of the output buffer. 1295 <outsize> The size of the output buffer.
@@ -1385,7 +1385,7 @@ static struct translate_struct translate_table[] =
1385}; 1385};
1386 1386
1387const char *get_old_name(const char *devname, unsigned int namelen, 1387const char *get_old_name(const char *devname, unsigned int namelen,
1388 char *buffer, unsigned int major, unsigned int minor) 1388 char *buffer, unsigned int major, unsigned int minor)
1389/* [SUMMARY] Translate a kernel-supplied name into an old name. 1389/* [SUMMARY] Translate a kernel-supplied name into an old name.
1390 <devname> The device name provided by the kernel. 1390 <devname> The device name provided by the kernel.
1391 <namelen> The length of the name. 1391 <namelen> The length of the name.
@@ -1423,7 +1423,7 @@ const char *get_old_name(const char *devname, unsigned int namelen,
1423 }; 1423 };
1424 1424
1425 for (trans = translate_table; trans->match != NULL; ++trans) { 1425 for (trans = translate_table; trans->match != NULL; ++trans) {
1426 len = strlen(trans->match); 1426 len = strlen(trans->match);
1427 1427
1428 if (strncmp(devname, trans->match, len) == 0) { 1428 if (strncmp(devname, trans->match, len) == 0) {
1429 if (trans->format == NULL) 1429 if (trans->format == NULL)
@@ -1549,9 +1549,9 @@ static char *write_old_sd_name(char *buffer,
1549/*EXPERIMENTAL_FUNCTION*/ 1549/*EXPERIMENTAL_FUNCTION*/
1550 1550
1551int st_expr_expand(char *output, unsigned int length, const char *input, 1551int st_expr_expand(char *output, unsigned int length, const char *input,
1552 const char *(*get_variable_func)(const char *variable, 1552 const char *(*get_variable_func)(const char *variable,
1553 void *info), 1553 void *info),
1554 void *info) 1554 void *info)
1555/* [SUMMARY] Expand an expression using Borne Shell-like unquoted rules. 1555/* [SUMMARY] Expand an expression using Borne Shell-like unquoted rules.
1556 <output> The output expanded expression is written here. 1556 <output> The output expanded expression is written here.
1557 <length> The size of the output buffer. 1557 <length> The size of the output buffer.
@@ -1641,10 +1641,10 @@ st_expr_expand_out:
1641/* Private functions follow */ 1641/* Private functions follow */
1642 1642
1643static const char *expand_variable(char *buffer, unsigned int length, 1643static const char *expand_variable(char *buffer, unsigned int length,
1644 unsigned int *out_pos, const char *input, 1644 unsigned int *out_pos, const char *input,
1645 const char *(*func)(const char *variable, 1645 const char *(*func)(const char *variable,
1646 void *info), 1646 void *info),
1647 void *info) 1647 void *info)
1648/* [SUMMARY] Expand a variable. 1648/* [SUMMARY] Expand a variable.
1649 <buffer> The buffer to write to. 1649 <buffer> The buffer to write to.
1650 <length> The length of the output buffer. 1650 <length> The length of the output buffer.
@@ -1786,8 +1786,8 @@ expand_variable_out:
1786 1786
1787 1787
1788static const char *get_variable_v2(const char *variable, 1788static const char *get_variable_v2(const char *variable,
1789 const char *(*func)(const char *variable, void *info), 1789 const char *(*func)(const char *variable, void *info),
1790 void *info) 1790 void *info)
1791/* [SUMMARY] Get a variable from the environment or . 1791/* [SUMMARY] Get a variable from the environment or .
1792 <variable> The variable name. 1792 <variable> The variable name.
1793 <func> A function which will be used to get the variable. If this returns 1793 <func> A function which will be used to get the variable. If this returns
diff --git a/miscutils/fbsplash.c b/miscutils/fbsplash.c
index 05a77da23..12a77b70f 100644
--- a/miscutils/fbsplash.c
+++ b/miscutils/fbsplash.c
@@ -150,7 +150,7 @@ static void fb_open(const char *strfb_device)
150 150
151 // map the device in memory 151 // map the device in memory
152 G.addr = mmap(NULL, 152 G.addr = mmap(NULL,
153 G.scr_var.yres * G.scr_fix.line_length, 153 G.scr_var.yres * G.scr_fix.line_length,
154 PROT_WRITE, MAP_SHARED, fbfd, 0); 154 PROT_WRITE, MAP_SHARED, fbfd, 0);
155 if (G.addr == MAP_FAILED) 155 if (G.addr == MAP_FAILED)
156 bb_perror_msg_and_die("mmap"); 156 bb_perror_msg_and_die("mmap");
diff --git a/miscutils/flashcp.c b/miscutils/flashcp.c
index 81cde9072..b526566a4 100644
--- a/miscutils/flashcp.c
+++ b/miscutils/flashcp.c
@@ -16,6 +16,7 @@
16#include "libbb.h" 16#include "libbb.h"
17#include <mtd/mtd-user.h> 17#include <mtd/mtd-user.h>
18 18
19/* If 1, simulates "flashing" by writing to existing regular file */
19#define MTD_DEBUG 0 20#define MTD_DEBUG 0
20 21
21#define OPT_v (1 << 0) 22#define OPT_v (1 << 0)
@@ -32,7 +33,7 @@ static void progress(int mode, uoff_t count, uoff_t total)
32 if (total) 33 if (total)
33 percent = (unsigned) (percent / total); 34 percent = (unsigned) (percent / total);
34 printf("\r%s: %"OFF_FMT"u/%"OFF_FMT"u (%u%%) ", 35 printf("\r%s: %"OFF_FMT"u/%"OFF_FMT"u (%u%%) ",
35 (mode == 0) ? "Erasing block" : ((mode == 1) ? "Writing kb" : "Verifying kb"), 36 (mode < 0) ? "Erasing block" : ((mode == 0) ? "Writing kb" : "Verifying kb"),
36 count, total, (unsigned)percent); 37 count, total, (unsigned)percent);
37 fflush_all(); 38 fflush_all();
38} 39}
@@ -97,8 +98,7 @@ int flashcp_main(int argc UNUSED_PARAM, char **argv)
97#endif 98#endif
98 e.start = 0; 99 e.start = 0;
99 for (i = 1; i <= erase_count; i++) { 100 for (i = 1; i <= erase_count; i++) {
100 progress(0, i, erase_count); 101 progress(-1, i, erase_count);
101 errno = 0;
102#if !MTD_DEBUG 102#if !MTD_DEBUG
103 if (ioctl(fd_d, MEMERASE, &e) < 0) { 103 if (ioctl(fd_d, MEMERASE, &e) < 0) {
104 bb_perror_msg_and_die("erase error at 0x%llx on %s", 104 bb_perror_msg_and_die("erase error at 0x%llx on %s",
@@ -113,7 +113,7 @@ int flashcp_main(int argc UNUSED_PARAM, char **argv)
113 113
114 /* doing this outer loop gives significantly smaller code 114 /* doing this outer loop gives significantly smaller code
115 * than doing two separate loops for writing and verifying */ 115 * than doing two separate loops for writing and verifying */
116 for (i = 1; i <= 2; i++) { 116 for (i = 0; i <= 1; i++) {
117 uoff_t done; 117 uoff_t done;
118 unsigned count; 118 unsigned count;
119 119
@@ -122,25 +122,29 @@ int flashcp_main(int argc UNUSED_PARAM, char **argv)
122 done = 0; 122 done = 0;
123 count = BUFSIZE; 123 count = BUFSIZE;
124 while (1) { 124 while (1) {
125 uoff_t rem = statb.st_size - done; 125 uoff_t rem;
126
127 progress(i, done / 1024, (uoff_t)statb.st_size / 1024);
128 rem = statb.st_size - done;
126 if (rem == 0) 129 if (rem == 0)
127 break; 130 break;
128 if (rem < BUFSIZE) 131 if (rem < BUFSIZE)
129 count = rem; 132 count = rem;
130 progress(i, done / 1024, (uoff_t)statb.st_size / 1024);
131 xread(fd_f, buf, count); 133 xread(fd_f, buf, count);
132 if (i == 1) { 134 if (i == 0) {
133 int ret; 135 int ret;
136 if (count < BUFSIZE)
137 memset((char*)buf + count, 0, BUFSIZE - count);
134 errno = 0; 138 errno = 0;
135 ret = full_write(fd_d, buf, count); 139 ret = full_write(fd_d, buf, BUFSIZE);
136 if (ret != count) { 140 if (ret != BUFSIZE) {
137 bb_perror_msg_and_die("write error at 0x%"OFF_FMT"x on %s, " 141 bb_perror_msg_and_die("write error at 0x%"OFF_FMT"x on %s, "
138 "write returned %d", 142 "write returned %d",
139 done, devicename, ret); 143 done, devicename, ret);
140 } 144 }
141 } else { /* i == 2 */ 145 } else { /* i == 1 */
142 xread(fd_d, buf2, count); 146 xread(fd_d, buf2, count);
143 if (memcmp(buf, buf2, count)) { 147 if (memcmp(buf, buf2, count) != 0) {
144 bb_error_msg_and_die("verification mismatch at 0x%"OFF_FMT"x", done); 148 bb_error_msg_and_die("verification mismatch at 0x%"OFF_FMT"x", done);
145 } 149 }
146 } 150 }
diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c
index a97f3e7b5..69726ae72 100644
--- a/miscutils/hdparm.c
+++ b/miscutils/hdparm.c
@@ -1022,8 +1022,8 @@ static void identify(uint16_t *val)
1022 } 1022 }
1023 if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) { 1023 if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) {
1024 /* We print out elsewhere whether the APM feature is enabled or 1024 /* We print out elsewhere whether the APM feature is enabled or
1025 not. If it's not enabled, let's not repeat the info; just print 1025 * not. If it's not enabled, let's not repeat the info; just print
1026 nothing here. */ 1026 * nothing here. */
1027 printf("\tAdvancedPM level: "); 1027 printf("\tAdvancedPM level: ");
1028 if ((val[ADV_PWR] & 0xFF00) == 0x4000) { 1028 if ((val[ADV_PWR] & 0xFF00) == 0x4000) {
1029 uint8_t apm_level = val[ADV_PWR] & 0x00FF; 1029 uint8_t apm_level = val[ADV_PWR] & 0x00FF;
@@ -1038,7 +1038,7 @@ static void identify(uint16_t *val)
1038 val[ACOUSTIC] & 0x00ff); 1038 val[ACOUSTIC] & 0x00ff);
1039 } 1039 }
1040 } else { 1040 } else {
1041 /* ATAPI */ 1041 /* ATAPI */
1042 if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ)) 1042 if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ))
1043 printf("\tATA sw reset required\n"); 1043 printf("\tATA sw reset required\n");
1044 1044
diff --git a/miscutils/last.c b/miscutils/last.c
index d52780374..24f6e1c78 100644
--- a/miscutils/last.c
+++ b/miscutils/last.c
@@ -71,7 +71,7 @@ int last_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
71 file = xopen(bb_path_wtmp_file, O_RDONLY); 71 file = xopen(bb_path_wtmp_file, O_RDONLY);
72 72
73 printf("%-10s %-14s %-18s %-12.12s %s\n", 73 printf("%-10s %-14s %-18s %-12.12s %s\n",
74 "USER", "TTY", "HOST", "LOGIN", "TIME"); 74 "USER", "TTY", "HOST", "LOGIN", "TIME");
75 /* yikes. We reverse over the file and that is a not too elegant way */ 75 /* yikes. We reverse over the file and that is a not too elegant way */
76 pos = xlseek(file, 0, SEEK_END); 76 pos = xlseek(file, 0, SEEK_END);
77 pos = lseek(file, pos - sizeof(ut), SEEK_SET); 77 pos = lseek(file, pos - sizeof(ut), SEEK_SET);
@@ -131,7 +131,7 @@ int last_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
131 * but some systems have it wrong */ 131 * but some systems have it wrong */
132 t_tmp = (time_t)ut.ut_tv.tv_sec; 132 t_tmp = (time_t)ut.ut_tv.tv_sec;
133 printf("%-10s %-14s %-18s %-12.12s\n", 133 printf("%-10s %-14s %-18s %-12.12s\n",
134 ut.ut_user, ut.ut_line, ut.ut_host, ctime(&t_tmp) + 4); 134 ut.ut_user, ut.ut_line, ut.ut_host, ctime(&t_tmp) + 4);
135 next: 135 next:
136 pos -= sizeof(ut); 136 pos -= sizeof(ut);
137 if (pos <= 0) 137 if (pos <= 0)
diff --git a/miscutils/last_fancy.c b/miscutils/last_fancy.c
index dc09b65fb..f687d7e16 100644
--- a/miscutils/last_fancy.c
+++ b/miscutils/last_fancy.c
@@ -93,14 +93,14 @@ static void show_entry(struct utmp *ut, int state, time_t dur_secs)
93 } 93 }
94 94
95 printf(HEADER_FORMAT, 95 printf(HEADER_FORMAT,
96 ut->ut_user, 96 ut->ut_user,
97 ut->ut_line, 97 ut->ut_line,
98 show_wide ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN, 98 show_wide ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN,
99 show_wide ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN, 99 show_wide ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN,
100 ut->ut_host, 100 ut->ut_host,
101 login_time, 101 login_time,
102 logout_str, 102 logout_str,
103 duration_str); 103 duration_str);
104} 104}
105 105
106static int get_ut_type(struct utmp *ut) 106static int get_ut_type(struct utmp *ut)
diff --git a/miscutils/less.c b/miscutils/less.c
index f0187bf8a..5ce0a1203 100644
--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -709,9 +709,9 @@ static void print_found(const char *line)
709 /* buf[] holds quarantined version of str */ 709 /* buf[] holds quarantined version of str */
710 710
711 /* Each part of the line that matches has the HIGHLIGHT 711 /* Each part of the line that matches has the HIGHLIGHT
712 and NORMAL escape sequences placed around it. 712 * and NORMAL escape sequences placed around it.
713 NB: we regex against line, but insert text 713 * NB: we regex against line, but insert text
714 from quarantined copy (buf[]) */ 714 * from quarantined copy (buf[]) */
715 str = buf; 715 str = buf;
716 growline = NULL; 716 growline = NULL;
717 eflags = 0; 717 eflags = 0;
diff --git a/miscutils/rx.c b/miscutils/rx.c
index af597320c..1dffb593a 100644
--- a/miscutils/rx.c
+++ b/miscutils/rx.c
@@ -193,8 +193,8 @@ static int receive(/*int read_fd, */int file_fd)
193 } 193 }
194 if (cksum_or_crc != expected) { 194 if (cksum_or_crc != expected) {
195 bb_error_msg(do_crc ? "crc error, expected 0x%04x, got 0x%04x" 195 bb_error_msg(do_crc ? "crc error, expected 0x%04x, got 0x%04x"
196 : "checksum error, expected 0x%02x, got 0x%02x", 196 : "checksum error, expected 0x%02x, got 0x%02x",
197 expected, cksum_or_crc); 197 expected, cksum_or_crc);
198 goto error; 198 goto error;
199 } 199 }
200 200
diff --git a/miscutils/time.c b/miscutils/time.c
index ffed38632..19b0b44c9 100644
--- a/miscutils/time.c
+++ b/miscutils/time.c
@@ -70,7 +70,7 @@ static void resuse_end(pid_t pid, resource_t *resp)
70 pid_t caught; 70 pid_t caught;
71 71
72 /* Ignore signals, but don't ignore the children. When wait3 72 /* Ignore signals, but don't ignore the children. When wait3
73 returns the child process, set the time the command finished. */ 73 * returns the child process, set the time the command finished. */
74 while ((caught = wait3(&resp->waitstatus, 0, &resp->ru)) != pid) { 74 while ((caught = wait3(&resp->waitstatus, 0, &resp->ru)) != pid) {
75 if (caught == -1 && errno != EINTR) { 75 if (caught == -1 && errno != EINTR) {
76 bb_perror_msg("wait"); 76 bb_perror_msg("wait");
diff --git a/miscutils/watchdog.c b/miscutils/watchdog.c
index ee28dc30d..d3a76edf0 100644
--- a/miscutils/watchdog.c
+++ b/miscutils/watchdog.c
@@ -31,6 +31,7 @@ static void watchdog_shutdown(int sig UNUSED_PARAM)
31{ 31{
32 static const char V = 'V'; 32 static const char V = 'V';
33 33
34 remove_pidfile(CONFIG_PID_FILE_PATH "/watchdog.pid");
34 write(3, &V, 1); /* Magic, see watchdog-api.txt in kernel */ 35 write(3, &V, 1); /* Magic, see watchdog-api.txt in kernel */
35 if (ENABLE_FEATURE_CLEAN_UP) 36 if (ENABLE_FEATURE_CLEAN_UP)
36 close(3); 37 close(3);
@@ -95,6 +96,8 @@ int watchdog_main(int argc, char **argv)
95 stimer_duration, htimer_duration * 1000); 96 stimer_duration, htimer_duration * 1000);
96#endif 97#endif
97 98
99 write_pidfile(CONFIG_PID_FILE_PATH "/watchdog.pid");
100
98 while (1) { 101 while (1) {
99 /* 102 /*
100 * Make sure we clear the counter before sleeping, 103 * Make sure we clear the counter before sleeping,
diff --git a/modutils/depmod.c b/modutils/depmod.c
index 775236126..aa228ec85 100644
--- a/modutils/depmod.c
+++ b/modutils/depmod.c
@@ -31,7 +31,7 @@ typedef struct module_info {
31} module_info; 31} module_info;
32 32
33static int FAST_FUNC parse_module(const char *fname, struct stat *sb UNUSED_PARAM, 33static int FAST_FUNC parse_module(const char *fname, struct stat *sb UNUSED_PARAM,
34 void *data, int depth UNUSED_PARAM) 34 void *data, int depth UNUSED_PARAM)
35{ 35{
36 char modname[MODULE_NAME_LEN]; 36 char modname[MODULE_NAME_LEN];
37 module_info **first = (module_info **) data; 37 module_info **first = (module_info **) data;
@@ -95,7 +95,7 @@ static module_info *find_module(module_info *modules, const char *modname)
95} 95}
96 96
97static void order_dep_list(module_info *modules, module_info *start, 97static void order_dep_list(module_info *modules, module_info *start,
98 llist_t *add) 98 llist_t *add)
99{ 99{
100 module_info *m; 100 module_info *m;
101 llist_t *n; 101 llist_t *n;
@@ -216,7 +216,7 @@ int depmod_main(int argc UNUSED_PARAM, char **argv)
216 } while (*++argv); 216 } while (*++argv);
217 } else { 217 } else {
218 recursive_action(".", ACTION_RECURSE, 218 recursive_action(".", ACTION_RECURSE,
219 parse_module, NULL, &modules, 0); 219 parse_module, NULL, &modules, 0);
220 } 220 }
221 221
222 /* Generate dependency and alias files */ 222 /* Generate dependency and alias files */
diff --git a/modutils/rmmod.c b/modutils/rmmod.c
index 4a4a91982..f13ff9eb6 100644
--- a/modutils/rmmod.c
+++ b/modutils/rmmod.c
@@ -60,7 +60,7 @@ int rmmod_main(int argc UNUSED_PARAM, char **argv)
60 filename2modname(bname, modname); 60 filename2modname(bname, modname);
61 if (bb_delete_module(modname, flags)) 61 if (bb_delete_module(modname, flags))
62 bb_error_msg_and_die("can't unload '%s': %s", 62 bb_error_msg_and_die("can't unload '%s': %s",
63 modname, moderror(errno)); 63 modname, moderror(errno));
64 } 64 }
65 65
66 return EXIT_SUCCESS; 66 return EXIT_SUCCESS;
diff --git a/networking/arp.c b/networking/arp.c
index 696c402e0..40d244116 100644
--- a/networking/arp.c
+++ b/networking/arp.c
@@ -22,12 +22,12 @@
22//usage:#define arp_full_usage "\n\n" 22//usage:#define arp_full_usage "\n\n"
23//usage: "Manipulate ARP cache\n" 23//usage: "Manipulate ARP cache\n"
24//usage: "\n -a Display (all) hosts" 24//usage: "\n -a Display (all) hosts"
25//usage: "\n -s Set new ARP entry" 25//usage: "\n -d Delete ARP entry"
26//usage: "\n -d Delete a specified entry" 26//usage: "\n -s Set new entry"
27//usage: "\n -v Verbose" 27//usage: "\n -v Verbose"
28//usage: "\n -n Don't resolve names" 28//usage: "\n -n Don't resolve names"
29//usage: "\n -i IF Network interface" 29//usage: "\n -i IF Network interface"
30//usage: "\n -D Read <hwaddr> from given device" 30//usage: "\n -D Read HWADDR from IFACE"
31//usage: "\n -A,-p AF Protocol family" 31//usage: "\n -A,-p AF Protocol family"
32//usage: "\n -H HWTYPE Hardware address type" 32//usage: "\n -H HWTYPE Hardware address type"
33 33
@@ -213,16 +213,15 @@ static int arp_del(char **args)
213} 213}
214 214
215/* Get the hardware address to a specified interface name */ 215/* Get the hardware address to a specified interface name */
216static void arp_getdevhw(char *ifname, struct sockaddr *sa, 216static void arp_getdevhw(char *ifname, struct sockaddr *sa)
217 const struct hwtype *hwt)
218{ 217{
219 struct ifreq ifr; 218 struct ifreq ifr;
220 const struct hwtype *xhw; 219 const struct hwtype *xhw;
221 220
222 strcpy(ifr.ifr_name, ifname); 221 strcpy(ifr.ifr_name, ifname);
223 ioctl_or_perror_and_die(sockfd, SIOCGIFHWADDR, &ifr, 222 ioctl_or_perror_and_die(sockfd, SIOCGIFHWADDR, &ifr,
224 "cant get HW-Address for '%s'", ifname); 223 "can't get HW-Address for '%s'", ifname);
225 if (hwt && (ifr.ifr_hwaddr.sa_family != hw->type)) { 224 if (hw_set && (ifr.ifr_hwaddr.sa_family != hw->type)) {
226 bb_error_msg_and_die("protocol type mismatch"); 225 bb_error_msg_and_die("protocol type mismatch");
227 } 226 }
228 memcpy(sa, &(ifr.ifr_hwaddr), sizeof(struct sockaddr)); 227 memcpy(sa, &(ifr.ifr_hwaddr), sizeof(struct sockaddr));
@@ -233,8 +232,8 @@ static void arp_getdevhw(char *ifname, struct sockaddr *sa,
233 xhw = get_hwntype(-1); 232 xhw = get_hwntype(-1);
234 } 233 }
235 bb_error_msg("device '%s' has HW address %s '%s'", 234 bb_error_msg("device '%s' has HW address %s '%s'",
236 ifname, xhw->name, 235 ifname, xhw->name,
237 xhw->print((unsigned char *) &ifr.ifr_hwaddr.sa_data)); 236 xhw->print((unsigned char *) &ifr.ifr_hwaddr.sa_data));
238 } 237 }
239} 238}
240 239
@@ -261,7 +260,7 @@ static int arp_set(char **args)
261 bb_error_msg_and_die("need hardware address"); 260 bb_error_msg_and_die("need hardware address");
262 } 261 }
263 if (option_mask32 & ARP_OPT_D) { 262 if (option_mask32 & ARP_OPT_D) {
264 arp_getdevhw(*args++, &req.arp_ha, hw_set ? hw : NULL); 263 arp_getdevhw(*args++, &req.arp_ha);
265 } else { 264 } else {
266 if (hw->input(*args++, &req.arp_ha) < 0) { 265 if (hw->input(*args++, &req.arp_ha) < 0) {
267 bb_error_msg_and_die("invalid hardware address"); 266 bb_error_msg_and_die("invalid hardware address");
@@ -345,7 +344,7 @@ static int arp_set(char **args)
345/* Print the contents of an ARP request block. */ 344/* Print the contents of an ARP request block. */
346static void 345static void
347arp_disp(const char *name, char *ip, int type, int arp_flags, 346arp_disp(const char *name, char *ip, int type, int arp_flags,
348 char *hwa, char *mask, char *dev) 347 char *hwa, char *mask, char *dev)
349{ 348{
350 static const int arp_masks[] = { 349 static const int arp_masks[] = {
351 ATF_PERM, ATF_PUBL, 350 ATF_PERM, ATF_PUBL,
@@ -428,7 +427,7 @@ static int arp_show(char *name)
428 /* All these strings can't overflow 427 /* All these strings can't overflow
429 * because fgets above reads limited amount of data */ 428 * because fgets above reads limited amount of data */
430 num = sscanf(line, "%s 0x%x 0x%x %s %s %s\n", 429 num = sscanf(line, "%s 0x%x 0x%x %s %s %s\n",
431 ip, &type, &flags, hwa, mask, dev); 430 ip, &type, &flags, hwa, mask, dev);
432 if (num < 4) 431 if (num < 4)
433 break; 432 break;
434 433
@@ -461,7 +460,7 @@ static int arp_show(char *name)
461 } 460 }
462 if (option_mask32 & ARP_OPT_v) 461 if (option_mask32 & ARP_OPT_v)
463 printf("Entries: %d\tSkipped: %d\tFound: %d\n", 462 printf("Entries: %d\tSkipped: %d\tFound: %d\n",
464 entries, entries - shown, shown); 463 entries, entries - shown, shown);
465 464
466 if (!shown) { 465 if (!shown) {
467 if (hw_set || host || device[0]) 466 if (hw_set || host || device[0])
@@ -477,28 +476,33 @@ static int arp_show(char *name)
477int arp_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 476int arp_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
478int arp_main(int argc UNUSED_PARAM, char **argv) 477int arp_main(int argc UNUSED_PARAM, char **argv)
479{ 478{
480 const char *hw_type = "ether"; 479 const char *hw_type;
481 const char *protocol; 480 const char *protocol;
482 unsigned opts; 481 unsigned opts;
483 482
484 INIT_G(); 483 INIT_G();
485 484
486 xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), sockfd); 485 xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), sockfd);
486
487 ap = get_aftype(DFLT_AF); 487 ap = get_aftype(DFLT_AF);
488 if (!ap) 488 /* Defaults are always supported */
489 bb_error_msg_and_die("%s: %s not supported", DFLT_AF, "address family"); 489 //if (!ap)
490 // bb_error_msg_and_die("%s: %s not supported", DFLT_AF, "address family");
491 hw = get_hwtype(DFLT_HW);
492 //if (!hw)
493 // bb_error_msg_and_die("%s: %s not supported", DFLT_HW, "hardware type");
490 494
491 opts = getopt32(argv, "A:p:H:t:i:adnDsv", &protocol, &protocol, 495 opts = getopt32(argv, "A:p:H:t:i:adnDsv", &protocol, &protocol,
492 &hw_type, &hw_type, &device); 496 &hw_type, &hw_type, &device);
493 argv += optind; 497 argv += optind;
494 if (opts & (ARP_OPT_A | ARP_OPT_p)) { 498 if (opts & (ARP_OPT_A | ARP_OPT_p)) {
495 ap = get_aftype(protocol); 499 ap = get_aftype(protocol);
496 if (ap == NULL) 500 if (!ap)
497 bb_error_msg_and_die("%s: unknown %s", protocol, "address family"); 501 bb_error_msg_and_die("%s: unknown %s", protocol, "address family");
498 } 502 }
499 if (opts & (ARP_OPT_A | ARP_OPT_p)) { 503 if (opts & (ARP_OPT_H | ARP_OPT_t)) {
500 hw = get_hwtype(hw_type); 504 hw = get_hwtype(hw_type);
501 if (hw == NULL) 505 if (!hw)
502 bb_error_msg_and_die("%s: unknown %s", hw_type, "hardware type"); 506 bb_error_msg_and_die("%s: unknown %s", hw_type, "hardware type");
503 hw_set = 1; 507 hw_set = 1;
504 } 508 }
@@ -507,17 +511,9 @@ int arp_main(int argc UNUSED_PARAM, char **argv)
507 if (ap->af != AF_INET) { 511 if (ap->af != AF_INET) {
508 bb_error_msg_and_die("%s: kernel only supports 'inet'", ap->name); 512 bb_error_msg_and_die("%s: kernel only supports 'inet'", ap->name);
509 } 513 }
510
511 /* If no hw type specified get default */
512 if (!hw) {
513 hw = get_hwtype(DFLT_HW);
514 if (!hw)
515 bb_error_msg_and_die("%s: %s not supported", DFLT_HW, "hardware type");
516 }
517
518 if (hw->alen <= 0) { 514 if (hw->alen <= 0) {
519 bb_error_msg_and_die("%s: %s without ARP support", 515 bb_error_msg_and_die("%s: %s without ARP support",
520 hw->name, "hardware type"); 516 hw->name, "hardware type");
521 } 517 }
522 518
523 /* Now see what we have to do here... */ 519 /* Now see what we have to do here... */
@@ -528,6 +524,7 @@ int arp_main(int argc UNUSED_PARAM, char **argv)
528 return arp_set(argv); 524 return arp_set(argv);
529 return arp_del(argv); 525 return arp_del(argv);
530 } 526 }
527
531 //if (opts & ARP_OPT_a) - default 528 //if (opts & ARP_OPT_a) - default
532 return arp_show(argv[0]); 529 return arp_show(argv[0]);
533} 530}
diff --git a/networking/brctl.c b/networking/brctl.c
index b4f5809df..207b069aa 100644
--- a/networking/brctl.c
+++ b/networking/brctl.c
@@ -133,9 +133,9 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
133 133
134 enum { ARG_addbr = 0, ARG_delbr, ARG_addif, ARG_delif 134 enum { ARG_addbr = 0, ARG_delbr, ARG_addif, ARG_delif
135 IF_FEATURE_BRCTL_FANCY(, 135 IF_FEATURE_BRCTL_FANCY(,
136 ARG_stp, 136 ARG_stp,
137 ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage, 137 ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage,
138 ARG_setpathcost, ARG_setportprio, ARG_setbridgeprio 138 ARG_setpathcost, ARG_setportprio, ARG_setbridgeprio
139 ) 139 )
140 IF_FEATURE_BRCTL_SHOW(, ARG_show) 140 IF_FEATURE_BRCTL_SHOW(, ARG_show)
141 }; 141 };
@@ -285,7 +285,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv)
285 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, "port"); 285 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, "port");
286 memset(ifidx, 0, sizeof ifidx); 286 memset(ifidx, 0, sizeof ifidx);
287 arm_ioctl(args, BRCTL_GET_PORT_LIST, (unsigned long)ifidx, 287 arm_ioctl(args, BRCTL_GET_PORT_LIST, (unsigned long)ifidx,
288 MAX_PORTS); 288 MAX_PORTS);
289 xioctl(fd, SIOCDEVPRIVATE, &ifr); 289 xioctl(fd, SIOCDEVPRIVATE, &ifr);
290 for (i = 0; i < MAX_PORTS; i++) { 290 for (i = 0; i < MAX_PORTS; i++) {
291 if (ifidx[i] == port) { 291 if (ifidx[i] == port) {
diff --git a/networking/ether-wake.c b/networking/ether-wake.c
index 6a88279f4..bf09cd529 100644
--- a/networking/ether-wake.c
+++ b/networking/ether-wake.c
@@ -49,9 +49,9 @@
49 * Copyright 1999-2003 Donald Becker and Scyld Computing Corporation. 49 * Copyright 1999-2003 Donald Becker and Scyld Computing Corporation.
50 * 50 *
51 * The author may be reached as becker@scyld, or C/O 51 * The author may be reached as becker@scyld, or C/O
52 * Scyld Computing Corporation 52 * Scyld Computing Corporation
53 * 914 Bay Ridge Road, Suite 220 53 * 914 Bay Ridge Road, Suite 220
54 * Annapolis MD 21403 54 * Annapolis MD 21403
55 * 55 *
56 * Notes: 56 * Notes:
57 * On some systems dropping root capability allows the process to be 57 * On some systems dropping root capability allows the process to be
@@ -113,7 +113,7 @@ void bb_debug_dump_packet(unsigned char *outpack, int pktsize)
113 * Host name 113 * Host name
114 * IP address string 114 * IP address string
115 * MAC address string 115 * MAC address string
116*/ 116 */
117static void get_dest_addr(const char *hostid, struct ether_addr *eaddr) 117static void get_dest_addr(const char *hostid, struct ether_addr *eaddr)
118{ 118{
119 struct ether_addr *eap; 119 struct ether_addr *eap;
@@ -238,9 +238,9 @@ int ether_wake_main(int argc UNUSED_PARAM, char **argv)
238 { 238 {
239 unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data; 239 unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data;
240 printf("The hardware address (SIOCGIFHWADDR) of %s is type %d " 240 printf("The hardware address (SIOCGIFHWADDR) of %s is type %d "
241 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n\n", ifname, 241 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n\n", ifname,
242 if_hwaddr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1], 242 if_hwaddr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1],
243 hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); 243 hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
244 } 244 }
245# endif 245# endif
246 } 246 }
diff --git a/networking/httpd.c b/networking/httpd.c
index a942794f5..1934bb27e 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -796,9 +796,9 @@ static void parse_conf(const char *path, int flag)
796 /* the line is not recognized */ 796 /* the line is not recognized */
797 config_error: 797 config_error:
798 bb_error_msg("config error '%s' in '%s'", buf, filename); 798 bb_error_msg("config error '%s' in '%s'", buf, filename);
799 } /* while (fgets) */ 799 } /* while (fgets) */
800 800
801 fclose(f); 801 fclose(f);
802} 802}
803 803
804#if ENABLE_FEATURE_HTTPD_ENCODE_URL_STR 804#if ENABLE_FEATURE_HTTPD_ENCODE_URL_STR
@@ -1708,7 +1708,7 @@ static int pam_talker(int num_msg,
1708 case PAM_PROMPT_ECHO_OFF: 1708 case PAM_PROMPT_ECHO_OFF:
1709 s = userinfo->pw; 1709 s = userinfo->pw;
1710 break; 1710 break;
1711 case PAM_ERROR_MSG: 1711 case PAM_ERROR_MSG:
1712 case PAM_TEXT_INFO: 1712 case PAM_TEXT_INFO:
1713 s = ""; 1713 s = "";
1714 break; 1714 break;
diff --git a/networking/httpd_ssi.c b/networking/httpd_ssi.c
index cfe64eb46..4bd9a6d97 100644
--- a/networking/httpd_ssi.c
+++ b/networking/httpd_ssi.c
@@ -133,7 +133,7 @@ static void process_includes(const char *filename)
133 process_includes(include_directive); 133 process_includes(include_directive);
134 134
135 /* Print everything after directive */ 135 /* Print everything after directive */
136 if (end) { 136 if (end) {
137 fputs(end, stdout); 137 fputs(end, stdout);
138 free(end); 138 free(end);
139 } 139 }
diff --git a/networking/ifconfig.c b/networking/ifconfig.c
index b6604f5d1..782374b35 100644
--- a/networking/ifconfig.c
+++ b/networking/ifconfig.c
@@ -174,10 +174,6 @@ struct in6_ifreq {
174#define ARG_ADD_DEL (A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER) 174#define ARG_ADD_DEL (A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER)
175 175
176 176
177/*
178 * Set up the tables. Warning! They must have corresponding order!
179 */
180
181struct arg1opt { 177struct arg1opt {
182 const char *name; 178 const char *name;
183 unsigned short selector; 179 unsigned short selector;
@@ -198,6 +194,10 @@ struct options {
198 194
199#define ifreq_offsetof(x) offsetof(struct ifreq, x) 195#define ifreq_offsetof(x) offsetof(struct ifreq, x)
200 196
197/*
198 * Set up the tables. Warning! They must have corresponding order!
199 */
200
201static const struct arg1opt Arg1Opt[] = { 201static const struct arg1opt Arg1Opt[] = {
202 { "SIFMETRIC", SIOCSIFMETRIC, ifreq_offsetof(ifr_metric) }, 202 { "SIFMETRIC", SIOCSIFMETRIC, ifreq_offsetof(ifr_metric) },
203 { "SIFMTU", SIOCSIFMTU, ifreq_offsetof(ifr_mtu) }, 203 { "SIFMTU", SIOCSIFMTU, ifreq_offsetof(ifr_mtu) },
@@ -220,11 +220,11 @@ static const struct arg1opt Arg1Opt[] = {
220 { "SIFMAP", SIOCSIFMAP, ifreq_offsetof(ifr_map.base_addr) }, 220 { "SIFMAP", SIOCSIFMAP, ifreq_offsetof(ifr_map.base_addr) },
221 { "SIFMAP", SIOCSIFMAP, ifreq_offsetof(ifr_map.irq) }, 221 { "SIFMAP", SIOCSIFMAP, ifreq_offsetof(ifr_map.irq) },
222#endif 222#endif
223 /* Last entry if for unmatched (possibly hostname) arg. */
224#if ENABLE_FEATURE_IPV6 223#if ENABLE_FEATURE_IPV6
225 { "SIFADDR", SIOCSIFADDR, ifreq_offsetof(ifr_addr) }, /* IPv6 version ignores the offset */ 224 { "SIFADDR", SIOCSIFADDR, ifreq_offsetof(ifr_addr) }, /* IPv6 version ignores the offset */
226 { "DIFADDR", SIOCDIFADDR, ifreq_offsetof(ifr_addr) }, /* IPv6 version ignores the offset */ 225 { "DIFADDR", SIOCDIFADDR, ifreq_offsetof(ifr_addr) }, /* IPv6 version ignores the offset */
227#endif 226#endif
227 /* Last entry is for unmatched (assumed to be hostname/address) arg. */
228 { "SIFADDR", SIOCSIFADDR, ifreq_offsetof(ifr_addr) }, 228 { "SIFADDR", SIOCSIFADDR, ifreq_offsetof(ifr_addr) },
229}; 229};
230 230
@@ -265,16 +265,49 @@ static const struct options OptArray[] = {
265 { NULL, 0, ARG_HOSTNAME, (IFF_UP | IFF_RUNNING) } 265 { NULL, 0, ARG_HOSTNAME, (IFF_UP | IFF_RUNNING) }
266}; 266};
267 267
268/*
269 * A couple of prototypes.
270 */
271#if ENABLE_FEATURE_IFCONFIG_HW 268#if ENABLE_FEATURE_IFCONFIG_HW
272static int in_ether(const char *bufp, struct sockaddr *sap); 269/* Input an Ethernet address and convert to binary. */
270static int in_ether(const char *bufp, struct sockaddr *sap)
271{
272 char *ptr;
273 int i, j;
274 unsigned char val;
275 unsigned char c;
276
277 sap->sa_family = ARPHRD_ETHER;
278 ptr = (char *) sap->sa_data;
279
280 i = 0;
281 do {
282 j = val = 0;
283
284 /* We might get a semicolon here - not required. */
285 if (i && (*bufp == ':')) {
286 bufp++;
287 }
288
289 do {
290 c = *bufp;
291 if (((unsigned char)(c - '0')) <= 9) {
292 c -= '0';
293 } else if ((unsigned char)((c|0x20) - 'a') <= 5) {
294 c = (unsigned char)((c|0x20) - 'a') + 10;
295 } else if (j && (c == ':' || c == 0)) {
296 break;
297 } else {
298 return -1;
299 }
300 ++bufp;
301 val <<= 4;
302 val += c;
303 } while (++j < 2);
304 *ptr++ = val;
305 } while (++i < ETH_ALEN);
306
307 return *bufp; /* Error if we don't end at end of string. */
308}
273#endif 309#endif
274 310
275/*
276 * Our main function.
277 */
278int ifconfig_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 311int ifconfig_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
279int ifconfig_main(int argc UNUSED_PARAM, char **argv) 312int ifconfig_main(int argc UNUSED_PARAM, char **argv)
280{ 313{
@@ -330,7 +363,7 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv)
330 strncpy_IFNAMSIZ(ifr.ifr_name, *argv); 363 strncpy_IFNAMSIZ(ifr.ifr_name, *argv);
331 364
332 /* Process the remaining arguments. */ 365 /* Process the remaining arguments. */
333 while (*++argv != (char *) NULL) { 366 while (*++argv != NULL) {
334 p = *argv; 367 p = *argv;
335 mask = N_MASK; 368 mask = N_MASK;
336 if (*p == '-') { /* If the arg starts with '-'... */ 369 if (*p == '-') { /* If the arg starts with '-'... */
@@ -356,9 +389,9 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv)
356 FOUND_ARG: 389 FOUND_ARG:
357 if (mask & ARG_MASK) { 390 if (mask & ARG_MASK) {
358 mask = op->arg_flags; 391 mask = op->arg_flags;
359 a1op = Arg1Opt + (op - OptArray);
360 if (mask & A_NETMASK & did_flags) 392 if (mask & A_NETMASK & did_flags)
361 bb_show_usage(); 393 bb_show_usage();
394 a1op = Arg1Opt + (op - OptArray);
362 if (*++argv == NULL) { 395 if (*++argv == NULL) {
363 if (mask & A_ARG_REQ) 396 if (mask & A_ARG_REQ)
364 bb_show_usage(); 397 bb_show_usage();
@@ -371,19 +404,9 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv)
371#if ENABLE_FEATURE_IFCONFIG_HW 404#if ENABLE_FEATURE_IFCONFIG_HW
372 if (mask & A_CAST_RESOLVE) { 405 if (mask & A_CAST_RESOLVE) {
373#endif 406#endif
374#if ENABLE_FEATURE_IPV6
375 char *prefix;
376 int prefix_len = 0;
377#endif
378 /*safe_strncpy(host, *argv, (sizeof host));*/
379 host = *argv; 407 host = *argv;
380#if ENABLE_FEATURE_IPV6 408 if (strcmp(host, "inet") == 0)
381 prefix = strchr(host, '/'); 409 continue; /* compat stuff */
382 if (prefix) {
383 prefix_len = xatou_range(prefix + 1, 0, 128);
384 *prefix = '\0';
385 }
386#endif
387 sai.sin_family = AF_INET; 410 sai.sin_family = AF_INET;
388 sai.sin_port = 0; 411 sai.sin_port = 0;
389 if (strcmp(host, "default") == 0) { 412 if (strcmp(host, "default") == 0) {
@@ -391,7 +414,8 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv)
391 sai.sin_addr.s_addr = INADDR_ANY; 414 sai.sin_addr.s_addr = INADDR_ANY;
392 } 415 }
393#if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS 416#if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS
394 else if ((host[0] == '+' && !host[1]) && (mask & A_BROADCAST) 417 else if ((host[0] == '+' && !host[1])
418 && (mask & A_BROADCAST)
395 && (did_flags & (A_NETMASK|A_HOSTNAME)) == (A_NETMASK|A_HOSTNAME) 419 && (did_flags & (A_NETMASK|A_HOSTNAME)) == (A_NETMASK|A_HOSTNAME)
396 ) { 420 ) {
397 /* + is special, meaning broadcast is derived. */ 421 /* + is special, meaning broadcast is derived. */
@@ -400,23 +424,36 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv)
400#endif 424#endif
401 else { 425 else {
402 len_and_sockaddr *lsa; 426 len_and_sockaddr *lsa;
403 if (strcmp(host, "inet") == 0) 427#if ENABLE_FEATURE_IPV6
404 continue; /* compat stuff */ 428 char *prefix;
429 int prefix_len = 0;
430 prefix = strchr(host, '/');
431 if (prefix) {
432 prefix_len = xatou_range(prefix + 1, 0, 128);
433 *prefix = '\0';
434 }
435 resolve:
436#endif
405 lsa = xhost2sockaddr(host, 0); 437 lsa = xhost2sockaddr(host, 0);
406#if ENABLE_FEATURE_IPV6 438#if ENABLE_FEATURE_IPV6
439 if (lsa->u.sa.sa_family != AF_INET6 && prefix) {
440/* TODO: we do not support "ifconfig eth0 up 1.2.3.4/17".
441 * For now, just make it fail instead of silently ignoring "/17" part:
442 */
443 *prefix = '/';
444 goto resolve;
445 }
407 if (lsa->u.sa.sa_family == AF_INET6) { 446 if (lsa->u.sa.sa_family == AF_INET6) {
408 int sockfd6; 447 int sockfd6;
409 struct in6_ifreq ifr6; 448 struct in6_ifreq ifr6;
410 449
411 memcpy((char *) &ifr6.ifr6_addr,
412 (char *) &(lsa->u.sin6.sin6_addr),
413 sizeof(struct in6_addr));
414
415 /* Create a channel to the NET kernel. */
416 sockfd6 = xsocket(AF_INET6, SOCK_DGRAM, 0); 450 sockfd6 = xsocket(AF_INET6, SOCK_DGRAM, 0);
417 xioctl(sockfd6, SIOGIFINDEX, &ifr); 451 xioctl(sockfd6, SIOCGIFINDEX, &ifr);
418 ifr6.ifr6_ifindex = ifr.ifr_ifindex; 452 ifr6.ifr6_ifindex = ifr.ifr_ifindex;
419 ifr6.ifr6_prefixlen = prefix_len; 453 ifr6.ifr6_prefixlen = prefix_len;
454 memcpy(&ifr6.ifr6_addr,
455 &lsa->u.sin6.sin6_addr,
456 sizeof(struct in6_addr));
420 ioctl_or_perror_and_die(sockfd6, a1op->selector, &ifr6, "SIOC%s", a1op->name); 457 ioctl_or_perror_and_die(sockfd6, a1op->selector, &ifr6, "SIOC%s", a1op->name);
421 if (ENABLE_FEATURE_CLEAN_UP) 458 if (ENABLE_FEATURE_CLEAN_UP)
422 free(lsa); 459 free(lsa);
@@ -437,19 +474,18 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv)
437#if ENABLE_FEATURE_IFCONFIG_HW 474#if ENABLE_FEATURE_IFCONFIG_HW
438 } else { /* A_CAST_HOST_COPY_IN_ETHER */ 475 } else { /* A_CAST_HOST_COPY_IN_ETHER */
439 /* This is the "hw" arg case. */ 476 /* This is the "hw" arg case. */
440 smalluint hw_class= index_in_substrings("ether\0" 477 smalluint hw_class = index_in_substrings("ether\0"
441 IF_FEATURE_HWIB("infiniband\0"), *argv) + 1; 478 IF_FEATURE_HWIB("infiniband\0"), *argv) + 1;
442 if (!hw_class || !*++argv) 479 if (!hw_class || !*++argv)
443 bb_show_usage(); 480 bb_show_usage();
444 /*safe_strncpy(host, *argv, sizeof(host));*/
445 host = *argv; 481 host = *argv;
446 if (hw_class == 1 ? in_ether(host, &sa) : in_ib(host, &sa)) 482 if (hw_class == 1 ? in_ether(host, &sa) : in_ib(host, &sa))
447 bb_error_msg_and_die("invalid hw-addr %s", host); 483 bb_error_msg_and_die("invalid hw-addr %s", host);
448 p = (char *) &sa; 484 p = (char *) &sa;
449 } 485 }
450#endif 486#endif
451 memcpy( (((char *)&ifr) + a1op->ifr_offset), 487 memcpy( ((char *)&ifr) + a1op->ifr_offset,
452 p, sizeof(struct sockaddr)); 488 p, sizeof(struct sockaddr));
453 } else { 489 } else {
454 /* FIXME: error check?? */ 490 /* FIXME: error check?? */
455 unsigned long i = strtoul(*argv, NULL, 0); 491 unsigned long i = strtoul(*argv, NULL, 0);
@@ -458,17 +494,17 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv)
458 if (mask & A_MAP_TYPE) { 494 if (mask & A_MAP_TYPE) {
459 xioctl(sockfd, SIOCGIFMAP, &ifr); 495 xioctl(sockfd, SIOCGIFMAP, &ifr);
460 if ((mask & A_MAP_UCHAR) == A_MAP_UCHAR) 496 if ((mask & A_MAP_UCHAR) == A_MAP_UCHAR)
461 *((unsigned char *) p) = i; 497 *(unsigned char *) p = i;
462 else if (mask & A_MAP_USHORT) 498 else if (mask & A_MAP_USHORT)
463 *((unsigned short *) p) = i; 499 *(unsigned short *) p = i;
464 else 500 else
465 *((unsigned long *) p) = i; 501 *(unsigned long *) p = i;
466 } else 502 } else
467#endif 503#endif
468 if (mask & A_CAST_CHAR_PTR) 504 if (mask & A_CAST_CHAR_PTR)
469 *((caddr_t *) p) = (caddr_t) i; 505 *(caddr_t *) p = (caddr_t) i;
470 else /* A_CAST_INT */ 506 else /* A_CAST_INT */
471 *((int *) p) = i; 507 *(int *) p = i;
472 } 508 }
473 509
474 ioctl_or_perror_and_die(sockfd, a1op->selector, &ifr, "SIOC%s", a1op->name); 510 ioctl_or_perror_and_die(sockfd, a1op->selector, &ifr, "SIOC%s", a1op->name);
@@ -494,7 +530,7 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv)
494 if (!(mask & A_SET_AFTER)) 530 if (!(mask & A_SET_AFTER))
495 continue; 531 continue;
496 mask = N_SET; 532 mask = N_SET;
497 } 533 } /* if (mask & ARG_MASK) */
498 534
499 xioctl(sockfd, SIOCGIFFLAGS, &ifr); 535 xioctl(sockfd, SIOCGIFFLAGS, &ifr);
500 selector = op->selector; 536 selector = op->selector;
@@ -509,46 +545,3 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv)
509 close(sockfd); 545 close(sockfd);
510 return 0; 546 return 0;
511} 547}
512
513#if ENABLE_FEATURE_IFCONFIG_HW
514/* Input an Ethernet address and convert to binary. */
515static int in_ether(const char *bufp, struct sockaddr *sap)
516{
517 char *ptr;
518 int i, j;
519 unsigned char val;
520 unsigned char c;
521
522 sap->sa_family = ARPHRD_ETHER;
523 ptr = (char *) sap->sa_data;
524
525 i = 0;
526 do {
527 j = val = 0;
528
529 /* We might get a semicolon here - not required. */
530 if (i && (*bufp == ':')) {
531 bufp++;
532 }
533
534 do {
535 c = *bufp;
536 if (((unsigned char)(c - '0')) <= 9) {
537 c -= '0';
538 } else if (((unsigned char)((c|0x20) - 'a')) <= 5) {
539 c = (c|0x20) - ('a'-10);
540 } else if (j && (c == ':' || c == 0)) {
541 break;
542 } else {
543 return -1;
544 }
545 ++bufp;
546 val <<= 4;
547 val += c;
548 } while (++j < 2);
549 *ptr++ = val;
550 } while (++i < ETH_ALEN);
551
552 return *bufp; /* Error if we don't end at end of string. */
553}
554#endif
diff --git a/networking/ifenslave.c b/networking/ifenslave.c
index ae7719f52..c3be8180b 100644
--- a/networking/ifenslave.c
+++ b/networking/ifenslave.c
@@ -270,7 +270,7 @@ static int set_if_addr(char *master_ifname, char *slave_ifname)
270 if (res < 0) { 270 if (res < 0) {
271 ifr.ifr_addr.sa_family = AF_INET; 271 ifr.ifr_addr.sa_family = AF_INET;
272 memset(ifr.ifr_addr.sa_data, 0, 272 memset(ifr.ifr_addr.sa_data, 0,
273 sizeof(ifr.ifr_addr.sa_data)); 273 sizeof(ifr.ifr_addr.sa_data));
274 } 274 }
275 275
276 res = set_ifrname_and_do_ioctl(ifra[i].s_ioctl, &ifr, slave_ifname); 276 res = set_ifrname_and_do_ioctl(ifra[i].s_ioctl, &ifr, slave_ifname);
@@ -546,7 +546,7 @@ int ifenslave_main(int argc UNUSED_PARAM, char **argv)
546#ifdef WHY_BOTHER 546#ifdef WHY_BOTHER
547 /* Neither -c[hange] nor -d[etach] -> it's "enslave" then; 547 /* Neither -c[hange] nor -d[etach] -> it's "enslave" then;
548 * and -f[orce] is not there too. Check that it's ethernet. */ 548 * and -f[orce] is not there too. Check that it's ethernet. */
549 if (!(opt & (OPT_d|OPT_c|OPT_f)) { 549 if (!(opt & (OPT_d|OPT_c|OPT_f))) {
550 /* The family '1' is ARPHRD_ETHER for ethernet. */ 550 /* The family '1' is ARPHRD_ETHER for ethernet. */
551 if (master.hwaddr.ifr_hwaddr.sa_family != 1) { 551 if (master.hwaddr.ifr_hwaddr.sa_family != 1) {
552 bb_error_msg_and_die( 552 bb_error_msg_and_die(
diff --git a/networking/ifplugd.c b/networking/ifplugd.c
index 88bf448fa..86586f0fe 100644
--- a/networking/ifplugd.c
+++ b/networking/ifplugd.c
@@ -551,7 +551,7 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv)
551 applet_name = xasprintf("ifplugd(%s)", G.iface); 551 applet_name = xasprintf("ifplugd(%s)", G.iface);
552 552
553#if ENABLE_FEATURE_PIDFILE 553#if ENABLE_FEATURE_PIDFILE
554 pidfile_name = xasprintf(_PATH_VARRUN"ifplugd.%s.pid", G.iface); 554 pidfile_name = xasprintf(CONFIG_PID_FILE_PATH "/ifplugd.%s.pid", G.iface);
555 pid_from_pidfile = read_pid(pidfile_name); 555 pid_from_pidfile = read_pid(pidfile_name);
556 556
557 if (opts & FLAG_KILL) { 557 if (opts & FLAG_KILL) {
diff --git a/networking/inetd.c b/networking/inetd.c
index 00baf6971..584c5e5e4 100644
--- a/networking/inetd.c
+++ b/networking/inetd.c
@@ -186,8 +186,6 @@
186#define ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN 0 186#define ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN 0
187#endif 187#endif
188 188
189#define _PATH_INETDPID "/var/run/inetd.pid"
190
191#define CNT_INTERVAL 60 /* servers in CNT_INTERVAL sec. */ 189#define CNT_INTERVAL 60 /* servers in CNT_INTERVAL sec. */
192#define RETRYTIME 60 /* retry after bind or server fail */ 190#define RETRYTIME 60 /* retry after bind or server fail */
193 191
@@ -1132,7 +1130,7 @@ static void clean_up_and_exit(int sig UNUSED_PARAM)
1132 if (ENABLE_FEATURE_CLEAN_UP) 1130 if (ENABLE_FEATURE_CLEAN_UP)
1133 close(sep->se_fd); 1131 close(sep->se_fd);
1134 } 1132 }
1135 remove_pidfile(_PATH_INETDPID); 1133 remove_pidfile(CONFIG_PID_FILE_PATH "/inetd.pid");
1136 exit(EXIT_SUCCESS); 1134 exit(EXIT_SUCCESS);
1137} 1135}
1138 1136
@@ -1181,7 +1179,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv)
1181 setgroups(1, &gid); 1179 setgroups(1, &gid);
1182 } 1180 }
1183 1181
1184 write_pidfile(_PATH_INETDPID); 1182 write_pidfile(CONFIG_PID_FILE_PATH "/inetd.pid");
1185 1183
1186 /* never fails under Linux (except if you pass it bad arguments) */ 1184 /* never fails under Linux (except if you pass it bad arguments) */
1187 getrlimit(RLIMIT_NOFILE, &rlim_ofile); 1185 getrlimit(RLIMIT_NOFILE, &rlim_ofile);
diff --git a/networking/interface.c b/networking/interface.c
index 79c322ec0..9ae8b3f03 100644
--- a/networking/interface.c
+++ b/networking/interface.c
@@ -27,7 +27,7 @@
27 * {1.34} - 19980630 - Arnaldo Carvalho de Melo <acme@conectiva.com.br> 27 * {1.34} - 19980630 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
28 * - gettext instead of catgets for i18n 28 * - gettext instead of catgets for i18n
29 * 10/1998 - Andi Kleen. Use interface list primitives. 29 * 10/1998 - Andi Kleen. Use interface list primitives.
30 * 20001008 - Bernd Eckenfels, Patch from RH for setting mtu 30 * 20001008 - Bernd Eckenfels, Patch from RH for setting mtu
31 * (default AF was wrong) 31 * (default AF was wrong)
32 */ 32 */
33 33
@@ -950,8 +950,8 @@ static void ife_print6(struct interface *ptr)
950 (struct sockaddr *) &sap.sin6_addr); 950 (struct sockaddr *) &sap.sin6_addr);
951 sap.sin6_family = AF_INET6; 951 sap.sin6_family = AF_INET6;
952 printf(" inet6 addr: %s/%d", 952 printf(" inet6 addr: %s/%d",
953 INET6_sprint((struct sockaddr *) &sap, 1), 953 INET6_sprint((struct sockaddr *) &sap, 1),
954 plen); 954 plen);
955 printf(" Scope:"); 955 printf(" Scope:");
956 switch (scope & IPV6_ADDR_SCOPE_MASK) { 956 switch (scope & IPV6_ADDR_SCOPE_MASK) {
957 case 0: 957 case 0:
@@ -1019,7 +1019,7 @@ static void ife_print(struct interface *ptr)
1019 1019
1020 if (ptr->has_ip) { 1020 if (ptr->has_ip) {
1021 printf(" %s addr:%s ", ap->name, 1021 printf(" %s addr:%s ", ap->name,
1022 ap->sprint(&ptr->addr, 1)); 1022 ap->sprint(&ptr->addr, 1));
1023 if (ptr->flags & IFF_POINTOPOINT) { 1023 if (ptr->flags & IFF_POINTOPOINT) {
1024 printf(" P-t-P:%s ", ap->sprint(&ptr->dstaddr, 1)); 1024 printf(" P-t-P:%s ", ap->sprint(&ptr->dstaddr, 1));
1025 } 1025 }
@@ -1102,17 +1102,17 @@ static void ife_print(struct interface *ptr)
1102 printf(" "); 1102 printf(" ");
1103 1103
1104 printf("RX packets:%llu errors:%lu dropped:%lu overruns:%lu frame:%lu\n", 1104 printf("RX packets:%llu errors:%lu dropped:%lu overruns:%lu frame:%lu\n",
1105 ptr->stats.rx_packets, ptr->stats.rx_errors, 1105 ptr->stats.rx_packets, ptr->stats.rx_errors,
1106 ptr->stats.rx_dropped, ptr->stats.rx_fifo_errors, 1106 ptr->stats.rx_dropped, ptr->stats.rx_fifo_errors,
1107 ptr->stats.rx_frame_errors); 1107 ptr->stats.rx_frame_errors);
1108 if (can_compress) 1108 if (can_compress)
1109 printf(" compressed:%lu\n", 1109 printf(" compressed:%lu\n",
1110 ptr->stats.rx_compressed); 1110 ptr->stats.rx_compressed);
1111 printf(" "); 1111 printf(" ");
1112 printf("TX packets:%llu errors:%lu dropped:%lu overruns:%lu carrier:%lu\n", 1112 printf("TX packets:%llu errors:%lu dropped:%lu overruns:%lu carrier:%lu\n",
1113 ptr->stats.tx_packets, ptr->stats.tx_errors, 1113 ptr->stats.tx_packets, ptr->stats.tx_errors,
1114 ptr->stats.tx_dropped, ptr->stats.tx_fifo_errors, 1114 ptr->stats.tx_dropped, ptr->stats.tx_fifo_errors,
1115 ptr->stats.tx_carrier_errors); 1115 ptr->stats.tx_carrier_errors);
1116 printf(" collisions:%lu ", ptr->stats.collisions); 1116 printf(" collisions:%lu ", ptr->stats.collisions);
1117 if (can_compress) 1117 if (can_compress)
1118 printf("compressed:%lu ", ptr->stats.tx_compressed); 1118 printf("compressed:%lu ", ptr->stats.tx_compressed);
@@ -1129,13 +1129,12 @@ static void ife_print(struct interface *ptr)
1129 printf(" "); 1129 printf(" ");
1130 if (ptr->map.irq) 1130 if (ptr->map.irq)
1131 printf("Interrupt:%d ", ptr->map.irq); 1131 printf("Interrupt:%d ", ptr->map.irq);
1132 if (ptr->map.base_addr >= 0x100) /* Only print devices using it for 1132 if (ptr->map.base_addr >= 0x100) /* Only print devices using it for I/O maps */
1133 I/O maps */
1134 printf("Base address:0x%lx ", 1133 printf("Base address:0x%lx ",
1135 (unsigned long) ptr->map.base_addr); 1134 (unsigned long) ptr->map.base_addr);
1136 if (ptr->map.mem_start) { 1135 if (ptr->map.mem_start) {
1137 printf("Memory:%lx-%lx ", ptr->map.mem_start, 1136 printf("Memory:%lx-%lx ", ptr->map.mem_start,
1138 ptr->map.mem_end); 1137 ptr->map.mem_end);
1139 } 1138 }
1140 if (ptr->map.dma) 1139 if (ptr->map.dma)
1141 printf("DMA chan:%x ", ptr->map.dma); 1140 printf("DMA chan:%x ", ptr->map.dma);
@@ -1168,7 +1167,7 @@ static struct interface *lookup_interface(char *name)
1168 1167
1169#ifdef UNUSED 1168#ifdef UNUSED
1170static int for_all_interfaces(int (*doit) (struct interface *, void *), 1169static int for_all_interfaces(int (*doit) (struct interface *, void *),
1171 void *cookie) 1170 void *cookie)
1172{ 1171{
1173 struct interface *ife; 1172 struct interface *ife;
1174 1173
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
index b3748e8c5..3fd3f4478 100644
--- a/networking/libiproute/ipaddress.c
+++ b/networking/libiproute/ipaddress.c
@@ -314,14 +314,16 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM,
314 if (rta_tb[IFA_BROADCAST]) { 314 if (rta_tb[IFA_BROADCAST]) {
315 printf("brd %s ", 315 printf("brd %s ",
316 rt_addr_n2a(ifa->ifa_family, 316 rt_addr_n2a(ifa->ifa_family,
317 RTA_DATA(rta_tb[IFA_BROADCAST]), 317 RTA_DATA(rta_tb[IFA_BROADCAST]),
318 abuf, sizeof(abuf))); 318 abuf, sizeof(abuf))
319 );
319 } 320 }
320 if (rta_tb[IFA_ANYCAST]) { 321 if (rta_tb[IFA_ANYCAST]) {
321 printf("any %s ", 322 printf("any %s ",
322 rt_addr_n2a(ifa->ifa_family, 323 rt_addr_n2a(ifa->ifa_family,
323 RTA_DATA(rta_tb[IFA_ANYCAST]), 324 RTA_DATA(rta_tb[IFA_ANYCAST]),
324 abuf, sizeof(abuf))); 325 abuf, sizeof(abuf))
326 );
325 } 327 }
326 printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1)); 328 printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1));
327 if (ifa->ifa_flags & IFA_F_SECONDARY) { 329 if (ifa->ifa_flags & IFA_F_SECONDARY) {
diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c
index dd3265c7c..241a6bf9d 100644
--- a/networking/libiproute/iprule.c
+++ b/networking/libiproute/iprule.c
@@ -73,15 +73,17 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM,
73 if (tb[RTA_SRC]) { 73 if (tb[RTA_SRC]) {
74 if (r->rtm_src_len != host_len) { 74 if (r->rtm_src_len != host_len) {
75 printf("%s/%u", rt_addr_n2a(r->rtm_family, 75 printf("%s/%u", rt_addr_n2a(r->rtm_family,
76 RTA_DATA(tb[RTA_SRC]), 76 RTA_DATA(tb[RTA_SRC]),
77 abuf, sizeof(abuf)), 77 abuf, sizeof(abuf)),
78 r->rtm_src_len 78 r->rtm_src_len
79 ); 79 );
80 } else { 80 } else {
81 fputs(format_host(r->rtm_family, 81 fputs(format_host(r->rtm_family,
82 RTA_PAYLOAD(tb[RTA_SRC]), 82 RTA_PAYLOAD(tb[RTA_SRC]),
83 RTA_DATA(tb[RTA_SRC]), 83 RTA_DATA(tb[RTA_SRC]),
84 abuf, sizeof(abuf)), stdout); 84 abuf, sizeof(abuf)),
85 stdout
86 );
85 } 87 }
86 } else if (r->rtm_src_len) { 88 } else if (r->rtm_src_len) {
87 printf("0/%d", r->rtm_src_len); 89 printf("0/%d", r->rtm_src_len);
diff --git a/networking/libiproute/iptunnel.c b/networking/libiproute/iptunnel.c
index 5942feafc..2b651b926 100644
--- a/networking/libiproute/iptunnel.c
+++ b/networking/libiproute/iptunnel.c
@@ -438,7 +438,7 @@ static void print_tunnel(struct ip_tunnel_parm *p)
438 printf(" inherit"); 438 printf(" inherit");
439 if (p->iph.tos & ~1) 439 if (p->iph.tos & ~1)
440 printf("%c%s ", p->iph.tos & 1 ? '/' : ' ', 440 printf("%c%s ", p->iph.tos & 1 ? '/' : ' ',
441 rtnl_dsfield_n2a(p->iph.tos & ~1, b1)); 441 rtnl_dsfield_n2a(p->iph.tos & ~1, b1));
442 } 442 }
443 if (!(p->iph.frag_off & htons(IP_DF))) 443 if (!(p->iph.frag_off & htons(IP_DF)))
444 printf(" nopmtudisc"); 444 printf(" nopmtudisc");
diff --git a/networking/nc.c b/networking/nc.c
index 1b32e3aa3..0c843a686 100644
--- a/networking/nc.c
+++ b/networking/nc.c
@@ -120,7 +120,7 @@ int nc_main(int argc, char **argv)
120 /* getopt32 is _almost_ usable: 120 /* getopt32 is _almost_ usable:
121 ** it cannot handle "... -e PROG -prog-opt" */ 121 ** it cannot handle "... -e PROG -prog-opt" */
122 while ((opt = getopt(argc, argv, 122 while ((opt = getopt(argc, argv,
123 "" IF_NC_SERVER("lp:") IF_NC_EXTRA("w:i:f:e:") )) > 0 123 "" IF_NC_SERVER("lp:") IF_NC_EXTRA("w:i:f:e:") )) > 0
124 ) { 124 ) {
125 if (ENABLE_NC_SERVER && opt == 'l') 125 if (ENABLE_NC_SERVER && opt == 'l')
126 IF_NC_SERVER(do_listen++); 126 IF_NC_SERVER(do_listen++);
diff --git a/networking/netstat.c b/networking/netstat.c
index 9c239579f..c0c6ba501 100644
--- a/networking/netstat.c
+++ b/networking/netstat.c
@@ -187,7 +187,7 @@ static void prg_cache_add(long inode, char *name)
187 for (pnp = prg_hash + hi; (pn = *pnp) != NULL; pnp = &pn->next) { 187 for (pnp = prg_hash + hi; (pn = *pnp) != NULL; pnp = &pn->next) {
188 if (pn->inode == inode) { 188 if (pn->inode == inode) {
189 /* Some warning should be appropriate here 189 /* Some warning should be appropriate here
190 as we got multiple processes for one i-node */ 190 * as we got multiple processes for one i-node */
191 return; 191 return;
192 } 192 }
193 } 193 }
diff --git a/networking/ntpd.c b/networking/ntpd.c
index 5b92db6f6..79b7c3793 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -1851,10 +1851,10 @@ recv_and_process_client_pkt(void /*int fd*/)
1851 1851
1852 /* Build a reply packet */ 1852 /* Build a reply packet */
1853 memset(&msg, 0, sizeof(msg)); 1853 memset(&msg, 0, sizeof(msg));
1854 msg.m_status = G.stratum < MAXSTRAT ? G.ntp_status : LI_ALARM; 1854 msg.m_status = G.stratum < MAXSTRAT ? (G.ntp_status & LI_MASK) : LI_ALARM;
1855 msg.m_status |= (query_status & VERSION_MASK); 1855 msg.m_status |= (query_status & VERSION_MASK);
1856 msg.m_status |= ((query_status & MODE_MASK) == MODE_CLIENT) ? 1856 msg.m_status |= ((query_status & MODE_MASK) == MODE_CLIENT) ?
1857 MODE_SERVER : MODE_SYM_PAS; 1857 MODE_SERVER : MODE_SYM_PAS;
1858 msg.m_stratum = G.stratum; 1858 msg.m_stratum = G.stratum;
1859 msg.m_ppoll = G.poll_exp; 1859 msg.m_ppoll = G.poll_exp;
1860 msg.m_precision_exp = G_precision_exp; 1860 msg.m_precision_exp = G_precision_exp;
@@ -2080,6 +2080,8 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
2080 */ 2080 */
2081 cnt = G.peer_cnt * (INITIAL_SAMPLES + 1); 2081 cnt = G.peer_cnt * (INITIAL_SAMPLES + 1);
2082 2082
2083 write_pidfile(CONFIG_PID_FILE_PATH "/ntpd.pid");
2084
2083 while (!bb_got_signal) { 2085 while (!bb_got_signal) {
2084 llist_t *item; 2086 llist_t *item;
2085 unsigned i, j; 2087 unsigned i, j;
@@ -2195,6 +2197,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
2195 } 2197 }
2196 } /* while (!bb_got_signal) */ 2198 } /* while (!bb_got_signal) */
2197 2199
2200 remove_pidfile(CONFIG_PID_FILE_PATH "/ntpd.pid");
2198 kill_myself_with_sig(bb_got_signal); 2201 kill_myself_with_sig(bb_got_signal);
2199} 2202}
2200 2203
@@ -2325,14 +2328,13 @@ set_freq(double freq) /* frequency update */
2325 if (pps_enable) { 2328 if (pps_enable) {
2326 if (!(pll_status & STA_PPSTIME)) 2329 if (!(pll_status & STA_PPSTIME))
2327 report_event(EVNT_KERN, 2330 report_event(EVNT_KERN,
2328 NULL, "PPS enabled"); 2331 NULL, "PPS enabled");
2329 ntv.status |= STA_PPSTIME | STA_PPSFREQ; 2332 ntv.status |= STA_PPSTIME | STA_PPSFREQ;
2330 } else { 2333 } else {
2331 if (pll_status & STA_PPSTIME) 2334 if (pll_status & STA_PPSTIME)
2332 report_event(EVNT_KERN, 2335 report_event(EVNT_KERN,
2333 NULL, "PPS disabled"); 2336 NULL, "PPS disabled");
2334 ntv.status &= ~(STA_PPSTIME | 2337 ntv.status &= ~(STA_PPSTIME | STA_PPSFREQ);
2335 STA_PPSFREQ);
2336 } 2338 }
2337 if (sys_leap == LEAP_ADDSECOND) 2339 if (sys_leap == LEAP_ADDSECOND)
2338 ntv.status |= STA_INS; 2340 ntv.status |= STA_INS;
@@ -2348,7 +2350,7 @@ set_freq(double freq) /* frequency update */
2348 if (ntp_adjtime(&ntv) == TIME_ERROR) { 2350 if (ntp_adjtime(&ntv) == TIME_ERROR) {
2349 if (!(ntv.status & STA_PPSSIGNAL)) 2351 if (!(ntv.status & STA_PPSSIGNAL))
2350 report_event(EVNT_KERN, NULL, 2352 report_event(EVNT_KERN, NULL,
2351 "PPS no signal"); 2353 "PPS no signal");
2352 } 2354 }
2353 pll_status = ntv.status; 2355 pll_status = ntv.status;
2354#ifdef STA_NANO 2356#ifdef STA_NANO
diff --git a/networking/ntpd_simple.c b/networking/ntpd_simple.c
index 1b7c66b84..55bded8ff 100644
--- a/networking/ntpd_simple.c
+++ b/networking/ntpd_simple.c
@@ -710,7 +710,7 @@ recv_and_process_client_pkt(void /*int fd*/)
710 msg.m_status = G.synced ? G.leap : LI_ALARM; 710 msg.m_status = G.synced ? G.leap : LI_ALARM;
711 msg.m_status |= (query_status & VERSION_MASK); 711 msg.m_status |= (query_status & VERSION_MASK);
712 msg.m_status |= ((query_status & MODE_MASK) == MODE_CLIENT) ? 712 msg.m_status |= ((query_status & MODE_MASK) == MODE_CLIENT) ?
713 MODE_SERVER : MODE_SYM_PAS; 713 MODE_SERVER : MODE_SYM_PAS;
714 msg.m_stratum = G.stratum; 714 msg.m_stratum = G.stratum;
715 msg.m_ppoll = query_ppoll; 715 msg.m_ppoll = query_ppoll;
716 msg.m_precision_exp = G_precision_exp; 716 msg.m_precision_exp = G_precision_exp;
diff --git a/networking/ping.c b/networking/ping.c
index b8a438ba8..3df67f5c3 100644
--- a/networking/ping.c
+++ b/networking/ping.c
@@ -724,7 +724,7 @@ static void ping6(len_and_sockaddr *lsa)
724 ICMP6_FILTER_SETPASSALL(&filt); 724 ICMP6_FILTER_SETPASSALL(&filt);
725 } 725 }
726 if (setsockopt(pingsock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, 726 if (setsockopt(pingsock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
727 sizeof(filt)) < 0) 727 sizeof(filt)) < 0)
728 bb_error_msg_and_die("setsockopt(ICMP6_FILTER)"); 728 bb_error_msg_and_die("setsockopt(ICMP6_FILTER)");
729 } 729 }
730#endif /*ICMP6_FILTER*/ 730#endif /*ICMP6_FILTER*/
diff --git a/networking/route.c b/networking/route.c
index b7b5a02e6..4235ea72c 100644
--- a/networking/route.c
+++ b/networking/route.c
@@ -409,7 +409,7 @@ static NOINLINE void INET6_setroute(int action, char **args)
409 bb_error_msg_and_die("resolving %s", args_m1); 409 bb_error_msg_and_die("resolving %s", args_m1);
410 } 410 }
411 memcpy(&rt.rtmsg_gateway, sa6.sin6_addr.s6_addr, 411 memcpy(&rt.rtmsg_gateway, sa6.sin6_addr.s6_addr,
412 sizeof(struct in6_addr)); 412 sizeof(struct in6_addr));
413 rt.rtmsg_flags |= RTF_GATEWAY; 413 rt.rtmsg_flags |= RTF_GATEWAY;
414 continue; 414 continue;
415 } 415 }
@@ -435,7 +435,7 @@ static NOINLINE void INET6_setroute(int action, char **args)
435 struct ifreq ifr; 435 struct ifreq ifr;
436 memset(&ifr, 0, sizeof(ifr)); 436 memset(&ifr, 0, sizeof(ifr));
437 strncpy_IFNAMSIZ(ifr.ifr_name, devname); 437 strncpy_IFNAMSIZ(ifr.ifr_name, devname);
438 xioctl(skfd, SIOGIFINDEX, &ifr); 438 xioctl(skfd, SIOCGIFINDEX, &ifr);
439 rt.rtmsg_ifindex = ifr.ifr_ifindex; 439 rt.rtmsg_ifindex = ifr.ifr_ifindex;
440 } 440 }
441 441
@@ -498,17 +498,17 @@ void FAST_FUNC bb_displayroutes(int noresolve, int netstatfmt)
498 FILE *fp = xfopen_for_read("/proc/net/route"); 498 FILE *fp = xfopen_for_read("/proc/net/route");
499 499
500 printf("Kernel IP routing table\n" 500 printf("Kernel IP routing table\n"
501 "Destination Gateway Genmask Flags %s Iface\n", 501 "Destination Gateway Genmask Flags %s Iface\n",
502 netstatfmt ? " MSS Window irtt" : "Metric Ref Use"); 502 netstatfmt ? " MSS Window irtt" : "Metric Ref Use");
503 503
504 if (fscanf(fp, "%*[^\n]\n") < 0) { /* Skip the first line. */ 504 if (fscanf(fp, "%*[^\n]\n") < 0) { /* Skip the first line. */
505 goto ERROR; /* Empty or missing line, or read error. */ 505 goto ERROR; /* Empty or missing line, or read error. */
506 } 506 }
507 while (1) { 507 while (1) {
508 int r; 508 int r;
509 r = fscanf(fp, "%63s%lx%lx%X%d%d%d%lx%d%d%d\n", 509 r = fscanf(fp, "%63s%lx%lx%X%d%d%d%lx%d%d%d\n",
510 devname, &d, &g, &flgs, &ref, &use, &metric, &m, 510 devname, &d, &g, &flgs, &ref, &use, &metric, &m,
511 &mtu, &win, &ir); 511 &mtu, &win, &ir);
512 if (r != 11) { 512 if (r != 11) {
513 if ((r < 0) && feof(fp)) { /* EOF with no (nonspace) chars read. */ 513 if ((r < 0) && feof(fp)) { /* EOF with no (nonspace) chars read. */
514 break; 514 break;
@@ -567,8 +567,8 @@ static void INET6_displayroutes(void)
567 FILE *fp = xfopen_for_read("/proc/net/ipv6_route"); 567 FILE *fp = xfopen_for_read("/proc/net/ipv6_route");
568 568
569 printf("Kernel IPv6 routing table\n%-44s%-40s" 569 printf("Kernel IPv6 routing table\n%-44s%-40s"
570 "Flags Metric Ref Use Iface\n", 570 "Flags Metric Ref Use Iface\n",
571 "Destination", "Next Hop"); 571 "Destination", "Next Hop");
572 572
573 while (1) { 573 while (1) {
574 int r; 574 int r;
@@ -618,8 +618,8 @@ static void INET6_displayroutes(void)
618 (struct sockaddr *) &snaddr6.sin6_addr); 618 (struct sockaddr *) &snaddr6.sin6_addr);
619 snaddr6.sin6_family = AF_INET6; 619 snaddr6.sin6_family = AF_INET6;
620 naddr6 = INET6_rresolve((struct sockaddr_in6 *) &snaddr6, 620 naddr6 = INET6_rresolve((struct sockaddr_in6 *) &snaddr6,
621 0x0fff /* Apparently, upstream never resolves. */ 621 0x0fff /* Apparently, upstream never resolves. */
622 ); 622 );
623 623
624 if (!r) { /* 1st pass */ 624 if (!r) { /* 1st pass */
625 snprintf(addr6, sizeof(addr6), "%s/%d", naddr6, prefix_len); 625 snprintf(addr6, sizeof(addr6), "%s/%d", naddr6, prefix_len);
diff --git a/networking/tc.c b/networking/tc.c
index 1574353a5..f968707a9 100644
--- a/networking/tc.c
+++ b/networking/tc.c
@@ -391,7 +391,7 @@ static int print_class(const struct sockaddr_nl *who UNUSED_PARAM,
391 printf("root "); 391 printf("root ");
392 else if (msg->tcm_parent) { 392 else if (msg->tcm_parent) {
393 classid = print_tc_classid(filter_qdisc ? 393 classid = print_tc_classid(filter_qdisc ?
394 TC_H_MIN(msg->tcm_parent) : msg->tcm_parent); 394 TC_H_MIN(msg->tcm_parent) : msg->tcm_parent);
395 printf("parent %s ", classid); 395 printf("parent %s ", classid);
396 if (ENABLE_FEATURE_CLEAN_UP) 396 if (ENABLE_FEATURE_CLEAN_UP)
397 free(classid); 397 free(classid);
@@ -526,7 +526,8 @@ int tc_main(int argc UNUSED_PARAM, char **argv)
526 duparg(*argv, "handle"); 526 duparg(*argv, "handle");
527 /* reject LONG_MIN || LONG_MAX */ 527 /* reject LONG_MIN || LONG_MAX */
528 /* TODO: for fw 528 /* TODO: for fw
529 if ((slash = strchr(handle, '/')) != NULL) 529 slash = strchr(handle, '/');
530 if (slash != NULL)
530 *slash = '\0'; 531 *slash = '\0';
531 */ 532 */
532 msg.tcm_handle = get_u32(*argv, "handle"); 533 msg.tcm_handle = get_u32(*argv, "handle");
diff --git a/networking/traceroute.c b/networking/traceroute.c
index d197e5410..6b7b2ebdd 100644
--- a/networking/traceroute.c
+++ b/networking/traceroute.c
@@ -290,9 +290,10 @@
290#endif 290#endif
291 291
292 292
293#define OPT_STRING "FIlnrdvxt:i:m:p:q:s:w:z:f:" \ 293#define OPT_STRING \
294 IF_FEATURE_TRACEROUTE_SOURCE_ROUTE("g:") \ 294 "FIlnrdvxt:i:m:p:q:s:w:z:f:" \
295 "4" IF_TRACEROUTE6("6") 295 IF_FEATURE_TRACEROUTE_SOURCE_ROUTE("g:") \
296 "4" IF_TRACEROUTE6("6")
296enum { 297enum {
297 OPT_DONT_FRAGMNT = (1 << 0), /* F */ 298 OPT_DONT_FRAGMNT = (1 << 0), /* F */
298 OPT_USE_ICMP = (1 << 1) * ENABLE_FEATURE_TRACEROUTE_USE_ICMP, /* I */ 299 OPT_USE_ICMP = (1 << 1) * ENABLE_FEATURE_TRACEROUTE_USE_ICMP, /* I */
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c
index c44220bf9..b0f0798e5 100644
--- a/networking/udhcp/d6_dhcpc.c
+++ b/networking/udhcp/d6_dhcpc.c
@@ -311,8 +311,8 @@ static int d6_mcast_from_client_config_ifindex(struct d6_packet *packet, uint8_t
311 311
312 return d6_send_raw_packet( 312 return d6_send_raw_packet(
313 packet, (end - (uint8_t*) packet), 313 packet, (end - (uint8_t*) packet),
314 /*src*/ NULL, CLIENT_PORT, 314 /*src*/ NULL, CLIENT_PORT6,
315 /*dst*/ (struct in6_addr*)FF02__1_2, SERVER_PORT, MAC_BCAST_ADDR, 315 /*dst*/ (struct in6_addr*)FF02__1_2, SERVER_PORT6, MAC_BCAST_ADDR,
316 client_config.ifindex 316 client_config.ifindex
317 ); 317 );
318} 318}
@@ -554,8 +554,8 @@ static NOINLINE int send_d6_renew(uint32_t xid, struct in6_addr *server_ipv6, st
554 if (server_ipv6) 554 if (server_ipv6)
555 return d6_send_kernel_packet( 555 return d6_send_kernel_packet(
556 &packet, (opt_ptr - (uint8_t*) &packet), 556 &packet, (opt_ptr - (uint8_t*) &packet),
557 our_cur_ipv6, CLIENT_PORT, 557 our_cur_ipv6, CLIENT_PORT6,
558 server_ipv6, SERVER_PORT 558 server_ipv6, SERVER_PORT6
559 ); 559 );
560 return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); 560 return d6_mcast_from_client_config_ifindex(&packet, opt_ptr);
561} 561}
@@ -576,8 +576,8 @@ static int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cu
576 bb_info_msg("Sending release..."); 576 bb_info_msg("Sending release...");
577 return d6_send_kernel_packet( 577 return d6_send_kernel_packet(
578 &packet, (opt_ptr - (uint8_t*) &packet), 578 &packet, (opt_ptr - (uint8_t*) &packet),
579 our_cur_ipv6, CLIENT_PORT, 579 our_cur_ipv6, CLIENT_PORT6,
580 server_ipv6, SERVER_PORT 580 server_ipv6, SERVER_PORT6
581 ); 581 );
582} 582}
583 583
@@ -614,7 +614,7 @@ static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6
614 /* make sure its the right packet for us, and that it passes sanity checks */ 614 /* make sure its the right packet for us, and that it passes sanity checks */
615 if (packet.ip6.ip6_nxt != IPPROTO_UDP 615 if (packet.ip6.ip6_nxt != IPPROTO_UDP
616 || (packet.ip6.ip6_vfc >> 4) != 6 616 || (packet.ip6.ip6_vfc >> 4) != 6
617 || packet.udp.dest != htons(CLIENT_PORT) 617 || packet.udp.dest != htons(CLIENT_PORT6)
618 /* || bytes > (int) sizeof(packet) - can't happen */ 618 /* || bytes > (int) sizeof(packet) - can't happen */
619 || packet.udp.len != packet.ip6.ip6_plen 619 || packet.udp.len != packet.ip6.ip6_plen
620 ) { 620 ) {
@@ -708,7 +708,7 @@ static int d6_raw_socket(int ifindex)
708 BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0), 708 BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0),
709 /* load udp destination port from halfword[header_len + 2] */ 709 /* load udp destination port from halfword[header_len + 2] */
710 BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2), 710 BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2),
711 /* jump to L3 if udp dport is CLIENT_PORT, else to L4 */ 711 /* jump to L3 if udp dport is CLIENT_PORT6, else to L4 */
712 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1), 712 BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1),
713 /* L3: accept packet */ 713 /* L3: accept packet */
714 BPF_STMT(BPF_RET|BPF_K, 0xffffffff), 714 BPF_STMT(BPF_RET|BPF_K, 0xffffffff),
@@ -733,7 +733,7 @@ static int d6_raw_socket(int ifindex)
733 xbind(fd, (struct sockaddr *) &sock, sizeof(sock)); 733 xbind(fd, (struct sockaddr *) &sock, sizeof(sock));
734 734
735#if 0 735#if 0
736 if (CLIENT_PORT == 68) { 736 if (CLIENT_PORT6 == 546) {
737 /* Use only if standard port is in use */ 737 /* Use only if standard port is in use */
738 /* Ignoring error (kernel may lack support for this) */ 738 /* Ignoring error (kernel may lack support for this) */
739 if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, 739 if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog,
@@ -761,7 +761,7 @@ static void change_listen_mode(int new_mode)
761 sockfd = -1; 761 sockfd = -1;
762 } 762 }
763 if (new_mode == LISTEN_KERNEL) 763 if (new_mode == LISTEN_KERNEL)
764 sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT, client_config.interface); 764 sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT6, client_config.interface);
765 else if (new_mode != LISTEN_NONE) 765 else if (new_mode != LISTEN_NONE)
766 sockfd = d6_raw_socket(client_config.ifindex); 766 sockfd = d6_raw_socket(client_config.ifindex);
767 /* else LISTEN_NONE: sockfd stays closed */ 767 /* else LISTEN_NONE: sockfd stays closed */
@@ -931,8 +931,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
931 fd_set rfds; 931 fd_set rfds;
932 932
933 /* Default options */ 933 /* Default options */
934 IF_FEATURE_UDHCP_PORT(SERVER_PORT = 547;) 934 IF_FEATURE_UDHCP_PORT(SERVER_PORT6 = 547;)
935 IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 546;) 935 IF_FEATURE_UDHCP_PORT(CLIENT_PORT6 = 546;)
936 client_config.interface = "eth0"; 936 client_config.interface = "eth0";
937 client_config.script = CONFIG_UDHCPC_DEFAULT_SCRIPT; 937 client_config.script = CONFIG_UDHCPC_DEFAULT_SCRIPT;
938 938
@@ -961,8 +961,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
961 } 961 }
962#if ENABLE_FEATURE_UDHCP_PORT 962#if ENABLE_FEATURE_UDHCP_PORT
963 if (opt & OPT_P) { 963 if (opt & OPT_P) {
964 CLIENT_PORT = xatou16(str_P); 964 CLIENT_PORT6 = xatou16(str_P);
965 SERVER_PORT = CLIENT_PORT - 1; 965 SERVER_PORT6 = CLIENT_PORT6 + 1;
966 } 966 }
967#endif 967#endif
968 while (list_O) { 968 while (list_O) {
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index f72217c84..086228871 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -1723,7 +1723,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1723#endif 1723#endif
1724 /* enter bound state */ 1724 /* enter bound state */
1725 timeout = lease_seconds / 2; 1725 timeout = lease_seconds / 2;
1726 temp_addr.s_addr = packet.yiaddr; 1726 temp_addr.s_addr = packet.yiaddr;
1727 bb_info_msg("Lease of %s obtained, lease time %u", 1727 bb_info_msg("Lease of %s obtained, lease time %u",
1728 inet_ntoa(temp_addr), (unsigned)lease_seconds); 1728 inet_ntoa(temp_addr), (unsigned)lease_seconds);
1729 requested_ip = packet.yiaddr; 1729 requested_ip = packet.yiaddr;
diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h
index 2859a0772..9f423a5b2 100644
--- a/networking/udhcp/dhcpc.h
+++ b/networking/udhcp/dhcpc.h
@@ -29,9 +29,11 @@ struct client_config_t {
29#define client_config (*(struct client_config_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE / 2])) 29#define client_config (*(struct client_config_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE / 2]))
30 30
31#if ENABLE_FEATURE_UDHCP_PORT 31#if ENABLE_FEATURE_UDHCP_PORT
32#define CLIENT_PORT (client_config.port) 32#define CLIENT_PORT (client_config.port)
33#define CLIENT_PORT6 (client_config.port)
33#else 34#else
34#define CLIENT_PORT 68 35#define CLIENT_PORT 68
36#define CLIENT_PORT6 546
35#endif 37#endif
36 38
37POP_SAVED_FUNCTION_VISIBILITY 39POP_SAVED_FUNCTION_VISIBILITY
diff --git a/networking/udhcp/dhcpd.h b/networking/udhcp/dhcpd.h
index 7c801bf6b..a77724f20 100644
--- a/networking/udhcp/dhcpd.h
+++ b/networking/udhcp/dhcpd.h
@@ -61,9 +61,11 @@ struct server_config_t {
61/* client_config sits in 2nd half of bb_common_bufsiz1 */ 61/* client_config sits in 2nd half of bb_common_bufsiz1 */
62 62
63#if ENABLE_FEATURE_UDHCP_PORT 63#if ENABLE_FEATURE_UDHCP_PORT
64#define SERVER_PORT (server_config.port) 64#define SERVER_PORT (server_config.port)
65#define SERVER_PORT6 (server_config.port)
65#else 66#else
66#define SERVER_PORT 67 67#define SERVER_PORT 67
68#define SERVER_PORT6 547
67#endif 69#endif
68 70
69 71
diff --git a/procps/nmeter.c b/procps/nmeter.c
index ed5479024..6a3b32743 100644
--- a/procps/nmeter.c
+++ b/procps/nmeter.c
@@ -271,7 +271,7 @@ static int rdval_loadavg(const char* p, ullong *vec, ...)
271} 271}
272 272
273// Parses /proc/diskstats 273// Parses /proc/diskstats
274// 1 2 3 4 5 6(rd) 7 8 9 10(wr) 11 12 13 14 274// 1 2 3 4 5 6(rd) 7 8 9 10(wr) 11 12 13 14
275// 3 0 hda 51292 14441 841783 926052 25717 79650 843256 3029804 0 148459 3956933 275// 3 0 hda 51292 14441 841783 926052 25717 79650 843256 3029804 0 148459 3956933
276// 3 1 hda1 0 0 0 0 <- ignore if only 4 fields 276// 3 1 hda1 0 0 0 0 <- ignore if only 4 fields
277// Linux 3.0 (maybe earlier) started printing full stats for hda1 too. 277// Linux 3.0 (maybe earlier) started printing full stats for hda1 too.
diff --git a/procps/powertop.c b/procps/powertop.c
index b4c45edbc..71988a295 100644
--- a/procps/powertop.c
+++ b/procps/powertop.c
@@ -493,7 +493,7 @@ static NOINLINE int process_timer_stats(void)
493 * Get information about CPU using CPUID opcode. 493 * Get information about CPU using CPUID opcode.
494 */ 494 */
495static void cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, 495static void cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
496 unsigned int *edx) 496 unsigned int *edx)
497{ 497{
498 /* EAX value specifies what information to return */ 498 /* EAX value specifies what information to return */
499 __asm__( 499 __asm__(
@@ -650,7 +650,7 @@ static void show_timerstats(void)
650 } else { 650 } else {
651 bb_putchar('\n'); 651 bb_putchar('\n');
652 bb_error_msg("no stats available; run as root or" 652 bb_error_msg("no stats available; run as root or"
653 " enable the cpufreq_stats module"); 653 " enable the timer_stats module");
654 } 654 }
655} 655}
656 656
diff --git a/procps/ps.c b/procps/ps.c
index e14356482..0dfda2039 100644
--- a/procps/ps.c
+++ b/procps/ps.c
@@ -70,7 +70,7 @@
70enum { MAX_WIDTH = 2*1024 }; 70enum { MAX_WIDTH = 2*1024 };
71 71
72#if ENABLE_FEATURE_PS_TIME || ENABLE_FEATURE_PS_LONG 72#if ENABLE_FEATURE_PS_TIME || ENABLE_FEATURE_PS_LONG
73static long get_uptime(void) 73static unsigned long get_uptime(void)
74{ 74{
75#ifdef __linux__ 75#ifdef __linux__
76 struct sysinfo info; 76 struct sysinfo info;
@@ -78,12 +78,15 @@ static long get_uptime(void)
78 return 0; 78 return 0;
79 return info.uptime; 79 return info.uptime;
80#elif 1 80#elif 1
81 char buf[64]; 81 unsigned long uptime;
82 long uptime; 82 char buf[sizeof(uptime)*3 + 2];
83 /* /proc/uptime is "UPTIME_SEC.NN IDLE_SEC.NN\n"
84 * (where IDLE is cumulative over all CPUs)
85 */
83 if (open_read_close("/proc/uptime", buf, sizeof(buf)) <= 0) 86 if (open_read_close("/proc/uptime", buf, sizeof(buf)) <= 0)
84 bb_perror_msg_and_die("can't read %s", "/proc/uptime"); 87 bb_perror_msg_and_die("can't read '%s'", "/proc/uptime");
85 buf[sizeof(buf)-1] = '\0'; 88 buf[sizeof(buf)-1] = '\0';
86 sscanf(buf, "%l", &uptime); 89 sscanf(buf, "%lu", &uptime);
87 return uptime; 90 return uptime;
88#else 91#else
89 struct timespec ts; 92 struct timespec ts;
@@ -138,7 +141,7 @@ struct globals {
138 unsigned terminal_width; 141 unsigned terminal_width;
139#if ENABLE_FEATURE_PS_TIME 142#if ENABLE_FEATURE_PS_TIME
140 unsigned kernel_HZ; 143 unsigned kernel_HZ;
141 unsigned long long seconds_since_boot; 144 unsigned long seconds_since_boot;
142#endif 145#endif
143} FIX_ALIASING; 146} FIX_ALIASING;
144#define G (*(struct globals*)&bb_common_bufsiz1) 147#define G (*(struct globals*)&bb_common_bufsiz1)
@@ -149,14 +152,13 @@ struct globals {
149#define buffer (G.buffer ) 152#define buffer (G.buffer )
150#define terminal_width (G.terminal_width ) 153#define terminal_width (G.terminal_width )
151#define kernel_HZ (G.kernel_HZ ) 154#define kernel_HZ (G.kernel_HZ )
152#define seconds_since_boot (G.seconds_since_boot)
153#define INIT_G() do { } while (0) 155#define INIT_G() do { } while (0)
154 156
155#if ENABLE_FEATURE_PS_TIME 157#if ENABLE_FEATURE_PS_TIME
156/* for ELF executables, notes are pushed before environment and args */ 158/* for ELF executables, notes are pushed before environment and args */
157static ptrdiff_t find_elf_note(ptrdiff_t findme) 159static uintptr_t find_elf_note(uintptr_t findme)
158{ 160{
159 ptrdiff_t *ep = (ptrdiff_t *) environ; 161 uintptr_t *ep = (uintptr_t *) environ;
160 162
161 while (*ep++) 163 while (*ep++)
162 continue; 164 continue;
@@ -222,7 +224,6 @@ static inline unsigned get_HZ_by_waiting(void)
222 224
223static unsigned get_kernel_HZ(void) 225static unsigned get_kernel_HZ(void)
224{ 226{
225
226 if (kernel_HZ) 227 if (kernel_HZ)
227 return kernel_HZ; 228 return kernel_HZ;
228 229
@@ -231,7 +232,7 @@ static unsigned get_kernel_HZ(void)
231 if (kernel_HZ == (unsigned)-1) 232 if (kernel_HZ == (unsigned)-1)
232 kernel_HZ = get_HZ_by_waiting(); 233 kernel_HZ = get_HZ_by_waiting();
233 234
234 seconds_since_boot = get_uptime(); 235 G.seconds_since_boot = get_uptime();
235 236
236 return kernel_HZ; 237 return kernel_HZ;
237} 238}
@@ -350,7 +351,7 @@ static void func_etime(char *buf, int size, const procps_status_t *ps)
350 351
351 mm = ps->start_time / get_kernel_HZ(); 352 mm = ps->start_time / get_kernel_HZ();
352 /* must be after get_kernel_HZ()! */ 353 /* must be after get_kernel_HZ()! */
353 mm = seconds_since_boot - mm; 354 mm = G.seconds_since_boot - mm;
354 ss = mm % 60; 355 ss = mm % 60;
355 mm /= 60; 356 mm /= 60;
356 snprintf(buf, size+1, "%3lu:%02u", mm, ss); 357 snprintf(buf, size+1, "%3lu:%02u", mm, ss);
@@ -598,7 +599,7 @@ int ps_main(int argc UNUSED_PARAM, char **argv)
598 // -o col1,col2,col3=header 599 // -o col1,col2,col3=header
599 // Select which columns to display 600 // Select which columns to display
600 /* We allow (and ignore) most of the above. FIXME. 601 /* We allow (and ignore) most of the above. FIXME.
601 * -T is picked for threads (POSIX hasn't it standardized). 602 * -T is picked for threads (POSIX hasn't standardized it).
602 * procps v3.2.7 supports -T and shows tids as SPID column, 603 * procps v3.2.7 supports -T and shows tids as SPID column,
603 * it also supports -L where it shows tids as LWP column. 604 * it also supports -L where it shows tids as LWP column.
604 */ 605 */
@@ -609,7 +610,9 @@ int ps_main(int argc UNUSED_PARAM, char **argv)
609 parse_o(llist_pop(&opt_o)); 610 parse_o(llist_pop(&opt_o));
610 } while (opt_o); 611 } while (opt_o);
611 } else { 612 } else {
612 /* Below: parse_o() needs char*, NOT const char*, can't give it default_o */ 613 /* Below: parse_o() needs char*, NOT const char*,
614 * can't pass it constant string. Need to make a copy first.
615 */
613#if ENABLE_SELINUX 616#if ENABLE_SELINUX
614 if (!(opt & OPT_Z) || !is_selinux_enabled()) { 617 if (!(opt & OPT_Z) || !is_selinux_enabled()) {
615 /* no -Z or no SELinux: do not show LABEL */ 618 /* no -Z or no SELinux: do not show LABEL */
@@ -663,7 +666,7 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
663 }; 666 };
664#if ENABLE_FEATURE_PS_LONG 667#if ENABLE_FEATURE_PS_LONG
665 time_t now = now; 668 time_t now = now;
666 long uptime; 669 unsigned long uptime;
667#endif 670#endif
668 /* If we support any options, parse argv */ 671 /* If we support any options, parse argv */
669#if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE || ENABLE_FEATURE_PS_LONG 672#if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE || ENABLE_FEATURE_PS_LONG
diff --git a/procps/sysctl.c b/procps/sysctl.c
index 878656862..c6a1de21d 100644
--- a/procps/sysctl.c
+++ b/procps/sysctl.c
@@ -205,7 +205,7 @@ static int sysctl_act_recursive(const char *path)
205 continue; /* d_name is "." or ".." */ 205 continue; /* d_name is "." or ".." */
206 /* if path was ".", drop "./" prefix: */ 206 /* if path was ".", drop "./" prefix: */
207 retval |= sysctl_act_recursive((next[0] == '.' && next[1] == '/') ? 207 retval |= sysctl_act_recursive((next[0] == '.' && next[1] == '/') ?
208 next + 2 : next); 208 next + 2 : next);
209 free(next); 209 free(next);
210 } 210 }
211 closedir(dirp); 211 closedir(dirp);
diff --git a/procps/top.c b/procps/top.c
index b08444a76..abee69806 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -294,7 +294,7 @@ static void get_jiffy_counts(void)
294 * they are used to calculate per process CPU% */ 294 * they are used to calculate per process CPU% */
295 prev_jif = cur_jif; 295 prev_jif = cur_jif;
296 if (read_cpu_jiffy(fp, &cur_jif) < 4) 296 if (read_cpu_jiffy(fp, &cur_jif) < 4)
297 bb_error_msg_and_die("can't read /proc/stat"); 297 bb_error_msg_and_die("can't read '%s'", "/proc/stat");
298 298
299#if !ENABLE_FEATURE_TOP_SMP_CPU 299#if !ENABLE_FEATURE_TOP_SMP_CPU
300 fclose(fp); 300 fclose(fp);
@@ -995,7 +995,7 @@ static unsigned handle_input(unsigned scan_mask, unsigned interval)
995 } 995 }
996# if ENABLE_FEATURE_SHOW_THREADS 996# if ENABLE_FEATURE_SHOW_THREADS
997 if (c == 'h' 997 if (c == 'h'
998 IF_FEATURE_TOPMEM(&& scan_mask != TOPMEM_MASK) 998 IF_FEATURE_TOPMEM(&& scan_mask != TOPMEM_MASK)
999 ) { 999 ) {
1000 scan_mask ^= PSSCAN_TASKS; 1000 scan_mask ^= PSSCAN_TASKS;
1001 continue; 1001 continue;
diff --git a/runit/runsv.c b/runit/runsv.c
index ad8d84f74..3e1a3c8e5 100644
--- a/runit/runsv.c
+++ b/runit/runsv.c
@@ -172,7 +172,7 @@ static void update_status(struct svdir *s)
172 } 172 }
173 close(fd); 173 close(fd);
174 if (rename_or_warn("supervise/pid.new", 174 if (rename_or_warn("supervise/pid.new",
175 s->islog ? "log/supervise/pid" : "log/supervise/pid"+4)) 175 s->islog ? "log/supervise/pid" : "log/supervise/pid"+4))
176 return; 176 return;
177 pidchanged = 0; 177 pidchanged = 0;
178 } 178 }
diff --git a/runit/svlogd.c b/runit/svlogd.c
index b0ba21bb6..b7a0a6e71 100644
--- a/runit/svlogd.c
+++ b/runit/svlogd.c
@@ -601,12 +601,12 @@ static int buffer_pwrite(int n, char *s, unsigned len)
601 601
602 while (fchdir(ld->fddir) == -1) 602 while (fchdir(ld->fddir) == -1)
603 pause2cannot("change directory, want remove old logfile", 603 pause2cannot("change directory, want remove old logfile",
604 ld->name); 604 ld->name);
605 oldest[0] = 'A'; 605 oldest[0] = 'A';
606 oldest[1] = oldest[27] = '\0'; 606 oldest[1] = oldest[27] = '\0';
607 while (!(d = opendir("."))) 607 while (!(d = opendir(".")))
608 pause2cannot("open directory, want remove old logfile", 608 pause2cannot("open directory, want remove old logfile",
609 ld->name); 609 ld->name);
610 errno = 0; 610 errno = 0;
611 while ((f = readdir(d))) 611 while ((f = readdir(d)))
612 if ((f->d_name[0] == '@') && (strlen(f->d_name) == 27)) { 612 if ((f->d_name[0] == '@') && (strlen(f->d_name) == 27)) {
diff --git a/selinux/chcon.c b/selinux/chcon.c
index 88d0cfec6..f947c2c12 100644
--- a/selinux/chcon.c
+++ b/selinux/chcon.c
@@ -92,7 +92,7 @@ static int FAST_FUNC change_filedir_context(
92 92
93 if (specified_context == NULL) { 93 if (specified_context == NULL) {
94 context = set_security_context_component(file_context, 94 context = set_security_context_component(file_context,
95 user, role, type, range); 95 user, role, type, range);
96 if (!context) { 96 if (!context) {
97 bb_error_msg("can't compute security context from %s", file_context); 97 bb_error_msg("can't compute security context from %s", file_context);
98 goto skip; 98 goto skip;
@@ -121,15 +121,15 @@ static int FAST_FUNC change_filedir_context(
121 } 121 }
122 if ((option_mask32 & OPT_VERBOSE) || ((option_mask32 & OPT_CHANHES) && !fail)) { 122 if ((option_mask32 & OPT_VERBOSE) || ((option_mask32 & OPT_CHANHES) && !fail)) {
123 printf(!fail 123 printf(!fail
124 ? "context of %s changed to %s\n" 124 ? "context of %s changed to %s\n"
125 : "can't change context of %s to %s\n", 125 : "can't change context of %s to %s\n",
126 fname, context_string); 126 fname, context_string);
127 } 127 }
128 if (!fail) { 128 if (!fail) {
129 rc = TRUE; 129 rc = TRUE;
130 } else if ((option_mask32 & OPT_QUIET) == 0) { 130 } else if ((option_mask32 & OPT_QUIET) == 0) {
131 bb_error_msg("can't change context of %s to %s", 131 bb_error_msg("can't change context of %s to %s",
132 fname, context_string); 132 fname, context_string);
133 } 133 }
134 } else if (option_mask32 & OPT_VERBOSE) { 134 } else if (option_mask32 & OPT_VERBOSE) {
135 printf("context of %s retained as %s\n", fname, context_string); 135 printf("context of %s retained as %s\n", fname, context_string);
@@ -181,7 +181,7 @@ int chcon_main(int argc UNUSED_PARAM, char **argv)
181#if ENABLE_FEATURE_CHCON_LONG_OPTIONS 181#if ENABLE_FEATURE_CHCON_LONG_OPTIONS
182 if (option_mask32 & OPT_REFERENCE) { 182 if (option_mask32 & OPT_REFERENCE) {
183 /* FIXME: lgetfilecon() should be used when '-h' is specified. 183 /* FIXME: lgetfilecon() should be used when '-h' is specified.
184 But current implementation follows the original one. */ 184 * But current implementation follows the original one. */
185 if (getfilecon(reference_file, &specified_context) < 0) 185 if (getfilecon(reference_file, &specified_context) < 0)
186 bb_perror_msg_and_die("getfilecon('%s') failed", reference_file); 186 bb_perror_msg_and_die("getfilecon('%s') failed", reference_file);
187 } else 187 } else
@@ -201,10 +201,10 @@ int chcon_main(int argc UNUSED_PARAM, char **argv)
201 fname[fname_len] = '\0'; 201 fname[fname_len] = '\0';
202 202
203 if (recursive_action(fname, 203 if (recursive_action(fname,
204 1<<option_mask32 & OPT_RECURSIVE, 204 1<<option_mask32 & OPT_RECURSIVE,
205 change_filedir_context, 205 change_filedir_context,
206 change_filedir_context, 206 change_filedir_context,
207 NULL, 0) != TRUE) 207 NULL, 0) != TRUE)
208 errors = 1; 208 errors = 1;
209 } 209 }
210 return errors; 210 return errors;
diff --git a/selinux/runcon.c b/selinux/runcon.c
index 3183a2274..27f2be3a9 100644
--- a/selinux/runcon.c
+++ b/selinux/runcon.c
@@ -56,7 +56,7 @@
56#include "libbb.h" 56#include "libbb.h"
57 57
58static context_t runcon_compute_new_context(char *user, char *role, char *type, char *range, 58static context_t runcon_compute_new_context(char *user, char *role, char *type, char *range,
59 char *command, int compute_trans) 59 char *command, int compute_trans)
60{ 60{
61 context_t con; 61 context_t con;
62 security_context_t cur_context; 62 security_context_t cur_context;
@@ -69,9 +69,9 @@ static context_t runcon_compute_new_context(char *user, char *role, char *type,
69 69
70 if (getfilecon(command, &file_context) < 0) 70 if (getfilecon(command, &file_context) < 0)
71 bb_error_msg_and_die("can't retrieve attributes of '%s'", 71 bb_error_msg_and_die("can't retrieve attributes of '%s'",
72 command); 72 command);
73 if (security_compute_create(cur_context, file_context, 73 if (security_compute_create(cur_context, file_context,
74 SECCLASS_PROCESS, &new_context)) 74 SECCLASS_PROCESS, &new_context))
75 bb_error_msg_and_die("unable to compute a new context"); 75 bb_error_msg_and_die("unable to compute a new context");
76 cur_context = new_context; 76 cur_context = new_context;
77 } 77 }
@@ -147,11 +147,11 @@ int runcon_main(int argc UNUSED_PARAM, char **argv)
147 147
148 if (security_check_context(context_str(con))) 148 if (security_check_context(context_str(con)))
149 bb_error_msg_and_die("'%s' is not a valid context", 149 bb_error_msg_and_die("'%s' is not a valid context",
150 context_str(con)); 150 context_str(con));
151 151
152 if (setexeccon(context_str(con))) 152 if (setexeccon(context_str(con)))
153 bb_error_msg_and_die("can't set up security context '%s'", 153 bb_error_msg_and_die("can't set up security context '%s'",
154 context_str(con)); 154 context_str(con));
155 155
156 BB_EXECVP_or_die(argv); 156 BB_EXECVP_or_die(argv);
157} 157}
diff --git a/selinux/sestatus.c b/selinux/sestatus.c
index 0bd1a0dda..e59431873 100644
--- a/selinux/sestatus.c
+++ b/selinux/sestatus.c
@@ -41,7 +41,7 @@ static void display_boolean(void)
41 if (pending < 0) 41 if (pending < 0)
42 goto skip; 42 goto skip;
43 printf(COL_FMT "%s", 43 printf(COL_FMT "%s",
44 bools[i], active == 0 ? "off" : "on"); 44 bools[i], active == 0 ? "off" : "on");
45 if (active != pending) 45 if (active != pending)
46 printf(" (%sactivate pending)", pending == 0 ? "in" : ""); 46 printf(" (%sactivate pending)", pending == 0 ? "in" : "");
47 bb_putchar('\n'); 47 bb_putchar('\n');
diff --git a/selinux/setfiles.c b/selinux/setfiles.c
index ca3fd9361..0173db99e 100644
--- a/selinux/setfiles.c
+++ b/selinux/setfiles.c
@@ -498,10 +498,11 @@ static int process_one(char *name)
498 498
499 if (S_ISDIR(sb.st_mode) && recurse) { 499 if (S_ISDIR(sb.st_mode) && recurse) {
500 if (recursive_action(name, 500 if (recursive_action(name,
501 ACTION_RECURSE, 501 ACTION_RECURSE,
502 apply_spec, 502 apply_spec,
503 apply_spec, 503 apply_spec,
504 NULL, 0) != TRUE) { 504 NULL, 0) != TRUE
505 ) {
505 bb_error_msg("error while labeling %s", name); 506 bb_error_msg("error while labeling %s", name);
506 goto err; 507 goto err;
507 } 508 }
@@ -584,7 +585,7 @@ int setfiles_main(int argc UNUSED_PARAM, char **argv)
584 flags = getopt32(argv, "de:f:ilnpqr:svo:FW" 585 flags = getopt32(argv, "de:f:ilnpqr:svo:FW"
585 IF_FEATURE_SETFILES_CHECK_OPTION("c:"), 586 IF_FEATURE_SETFILES_CHECK_OPTION("c:"),
586 &exclude_dir, &input_filename, &rootpath, &out_filename, 587 &exclude_dir, &input_filename, &rootpath, &out_filename,
587 IF_FEATURE_SETFILES_CHECK_OPTION(&policyfile,) 588 IF_FEATURE_SETFILES_CHECK_OPTION(&policyfile,)
588 &verbose); 589 &verbose);
589 } 590 }
590 argv += optind; 591 argv += optind;
@@ -600,8 +601,8 @@ int setfiles_main(int argc UNUSED_PARAM, char **argv)
600 fclose(policystream); 601 fclose(policystream);
601 602
602 /* Only process the specified file_contexts file, not 603 /* Only process the specified file_contexts file, not
603 any .homedirs or .local files, and do not perform 604 * any .homedirs or .local files, and do not perform
604 context translations. */ 605 * context translations. */
605 set_matchpathcon_flags(MATCHPATHCON_BASEONLY | 606 set_matchpathcon_flags(MATCHPATHCON_BASEONLY |
606 MATCHPATHCON_NOTRANS | 607 MATCHPATHCON_NOTRANS |
607 MATCHPATHCON_VALIDATE); 608 MATCHPATHCON_VALIDATE);
@@ -631,8 +632,8 @@ int setfiles_main(int argc UNUSED_PARAM, char **argv)
631 632
632 if (applet_name[0] == 's') { /* setfiles */ 633 if (applet_name[0] == 's') { /* setfiles */
633 /* Use our own invalid context checking function so that 634 /* Use our own invalid context checking function so that
634 we can support either checking against the active policy or 635 * we can support either checking against the active policy or
635 checking against a binary policy file. */ 636 * checking against a binary policy file. */
636 set_matchpathcon_canoncon(&canoncon); 637 set_matchpathcon_canoncon(&canoncon);
637 if (!argv[0]) 638 if (!argv[0])
638 bb_show_usage(); 639 bb_show_usage();
diff --git a/shell/ash.c b/shell/ash.c
index 7a50e73f3..75c01ec14 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -3737,7 +3737,8 @@ set_curjob(struct job *jp, unsigned mode)
3737 break; 3737 break;
3738 case CUR_RUNNING: 3738 case CUR_RUNNING:
3739 /* newly created job or backgrounded job, 3739 /* newly created job or backgrounded job,
3740 put after all stopped jobs. */ 3740 * put after all stopped jobs.
3741 */
3741 while (1) { 3742 while (1) {
3742 jp1 = *jpp; 3743 jp1 = *jpp;
3743#if JOBS 3744#if JOBS
@@ -9101,8 +9102,17 @@ expredir(union node *n)
9101#if ENABLE_ASH_BASH_COMPAT 9102#if ENABLE_ASH_BASH_COMPAT
9102 store_expfname: 9103 store_expfname:
9103#endif 9104#endif
9105#if 0
9106// By the design of stack allocator, the loop of this kind:
9107// while true; do while true; do break; done </dev/null; done
9108// will look like a memory leak: ash plans to free expfname's
9109// of "/dev/null" as soon as it finishes running the loop
9110// (in this case, never).
9111// This "fix" is wrong:
9104 if (redir->nfile.expfname) 9112 if (redir->nfile.expfname)
9105 stunalloc(redir->nfile.expfname); 9113 stunalloc(redir->nfile.expfname);
9114// It results in corrupted state of stacked allocations.
9115#endif
9106 redir->nfile.expfname = fn.list->text; 9116 redir->nfile.expfname = fn.list->text;
9107 break; 9117 break;
9108 case NFROMFD: 9118 case NFROMFD:
@@ -12138,8 +12148,9 @@ parsebackq: {
12138 INT_ON; 12148 INT_ON;
12139 if (oldstyle) { 12149 if (oldstyle) {
12140 /* We must read until the closing backquote, giving special 12150 /* We must read until the closing backquote, giving special
12141 treatment to some slashes, and then push the string and 12151 * treatment to some slashes, and then push the string and
12142 reread it as input, interpreting it normally. */ 12152 * reread it as input, interpreting it normally.
12153 */
12143 char *pout; 12154 char *pout;
12144 size_t psavelen; 12155 size_t psavelen;
12145 char *pstr; 12156 char *pstr;
diff --git a/shell/hush.c b/shell/hush.c
index b9e763cc8..e2dc1e2d0 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -4219,7 +4219,7 @@ static struct pipe *parse_stream(char **pstring,
4219 /* (this makes bare "&" cmd a no-op. 4219 /* (this makes bare "&" cmd a no-op.
4220 * bash says: "syntax error near unexpected token '&'") */ 4220 * bash says: "syntax error near unexpected token '&'") */
4221 if (pi->num_cmds == 0 4221 if (pi->num_cmds == 0
4222 IF_HAS_KEYWORDS( && pi->res_word == RES_NONE) 4222 IF_HAS_KEYWORDS(&& pi->res_word == RES_NONE)
4223 ) { 4223 ) {
4224 free_pipe_list(pi); 4224 free_pipe_list(pi);
4225 pi = NULL; 4225 pi = NULL;
@@ -4372,7 +4372,7 @@ static struct pipe *parse_stream(char **pstring,
4372 debug_printf_parse("dest.o_assignment='%s'\n", assignment_flag[dest.o_assignment]); 4372 debug_printf_parse("dest.o_assignment='%s'\n", assignment_flag[dest.o_assignment]);
4373 /* Do we sit outside of any if's, loops or case's? */ 4373 /* Do we sit outside of any if's, loops or case's? */
4374 if (!HAS_KEYWORDS 4374 if (!HAS_KEYWORDS
4375 IF_HAS_KEYWORDS(|| (ctx.ctx_res_w == RES_NONE && ctx.old_flag == 0)) 4375 IF_HAS_KEYWORDS(|| (ctx.ctx_res_w == RES_NONE && ctx.old_flag == 0))
4376 ) { 4376 ) {
4377 o_free(&dest); 4377 o_free(&dest);
4378#if !BB_MMU 4378#if !BB_MMU
@@ -8281,7 +8281,7 @@ static int FAST_FUNC builtin_exit(char **argv)
8281 * (if there are _stopped_ jobs, running ones don't count) 8281 * (if there are _stopped_ jobs, running ones don't count)
8282 * # exit 8282 * # exit
8283 * exit 8283 * exit
8284 # EEE (then bash exits) 8284 * EEE (then bash exits)
8285 * 8285 *
8286 * TODO: we can use G.exiting = -1 as indicator "last cmd was exit" 8286 * TODO: we can use G.exiting = -1 as indicator "last cmd was exit"
8287 */ 8287 */
diff --git a/shell/math.c b/shell/math.c
index 760645d0f..15c003965 100644
--- a/shell/math.c
+++ b/shell/math.c
@@ -410,7 +410,7 @@ arith_apply(arith_state_t *math_state, operator op, var_or_num_t *numstack, var_
410 return "exponent less than 0"; 410 return "exponent less than 0";
411 c = 1; 411 c = 1;
412 while (--right_side_val >= 0) 412 while (--right_side_val >= 0)
413 c *= rez; 413 c *= rez;
414 rez = c; 414 rez = c;
415 } 415 }
416 else if (right_side_val == 0) 416 else if (right_side_val == 0)
diff --git a/sysklogd/Config.src b/sysklogd/Config.src
index b7a494eff..fcf993054 100644
--- a/sysklogd/Config.src
+++ b/sysklogd/Config.src
@@ -113,6 +113,19 @@ config FEATURE_LOGREAD_REDUCED_LOCKING
113 from circular buffer, minimizing semaphore 113 from circular buffer, minimizing semaphore
114 contention at some minor memory expense. 114 contention at some minor memory expense.
115 115
116config FEATURE_KMSG_SYSLOG
117 bool "Linux kernel printk buffer support"
118 default y
119 depends on SYSLOGD
120 select PLATFORM_LINUX
121 help
122 When you enable this feature, the syslogd utility will
123 write system log message to the Linux kernel's printk buffer.
124 This can be used as a smaller alternative to the syslogd IPC
125 support, as klogd and logread aren't needed.
126
127 NOTICE: Syslog facilities in log entries needs kernel 3.5+.
128
116config KLOGD 129config KLOGD
117 bool "klogd" 130 bool "klogd"
118 default y 131 default y
@@ -123,6 +136,9 @@ config KLOGD
123 you wish to record the messages produced by the kernel, 136 you wish to record the messages produced by the kernel,
124 you should enable this option. 137 you should enable this option.
125 138
139comment "klogd should not be used together with syslog to kernel printk buffer"
140 depends on KLOGD && FEATURE_KMSG_SYSLOG
141
126config FEATURE_KLOGD_KLOGCTL 142config FEATURE_KLOGD_KLOGCTL
127 bool "Use the klogctl() interface" 143 bool "Use the klogctl() interface"
128 default y 144 default y
diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c
index efa0e537a..432ded153 100644
--- a/sysklogd/klogd.c
+++ b/sysklogd/klogd.c
@@ -195,6 +195,8 @@ int klogd_main(int argc UNUSED_PARAM, char **argv)
195 195
196 syslog(LOG_NOTICE, "klogd started: %s", bb_banner); 196 syslog(LOG_NOTICE, "klogd started: %s", bb_banner);
197 197
198 write_pidfile(CONFIG_PID_FILE_PATH "/klogd.pid");
199
198 used = 0; 200 used = 0;
199 while (!bb_got_signal) { 201 while (!bb_got_signal) {
200 int n; 202 int n;
@@ -238,11 +240,8 @@ int klogd_main(int argc UNUSED_PARAM, char **argv)
238 priority = LOG_INFO; 240 priority = LOG_INFO;
239 if (*start == '<') { 241 if (*start == '<') {
240 start++; 242 start++;
241 if (*start) { 243 if (*start)
242 /* kernel never generates multi-digit prios */ 244 priority = strtoul(start, &start, 10);
243 priority = (*start - '0');
244 start++;
245 }
246 if (*start == '>') 245 if (*start == '>')
247 start++; 246 start++;
248 } 247 }
@@ -258,6 +257,7 @@ int klogd_main(int argc UNUSED_PARAM, char **argv)
258 257
259 klogd_close(); 258 klogd_close();
260 syslog(LOG_NOTICE, "klogd: exiting"); 259 syslog(LOG_NOTICE, "klogd: exiting");
260 remove_pidfile(CONFIG_PID_FILE_PATH "/klogd.pid");
261 if (bb_got_signal) 261 if (bb_got_signal)
262 kill_myself_with_sig(bb_got_signal); 262 kill_myself_with_sig(bb_got_signal);
263 return EXIT_FAILURE; 263 return EXIT_FAILURE;
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index fc380d9f9..3fe3f5348 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -43,6 +43,9 @@
43//usage: "\n -f FILE Use FILE as config (default:/etc/syslog.conf)" 43//usage: "\n -f FILE Use FILE as config (default:/etc/syslog.conf)"
44//usage: ) 44//usage: )
45/* //usage: "\n -m MIN Minutes between MARK lines (default:20, 0=off)" */ 45/* //usage: "\n -m MIN Minutes between MARK lines (default:20, 0=off)" */
46//usage: IF_FEATURE_KMSG_SYSLOG(
47//usage: "\n -K Log to kernel printk buffer (use dmesg to read it)"
48//usage: )
46//usage: 49//usage:
47//usage:#define syslogd_example_usage 50//usage:#define syslogd_example_usage
48//usage: "$ syslogd -R masterlog:514\n" 51//usage: "$ syslogd -R masterlog:514\n"
@@ -140,6 +143,10 @@ IF_FEATURE_IPC_SYSLOG( \
140) \ 143) \
141IF_FEATURE_SYSLOGD_CFG( \ 144IF_FEATURE_SYSLOGD_CFG( \
142 logRule_t *log_rules; \ 145 logRule_t *log_rules; \
146) \
147IF_FEATURE_KMSG_SYSLOG( \
148 int kmsgfd; \
149 int primask; \
143) 150)
144 151
145struct init_globals { 152struct init_globals {
@@ -212,6 +219,7 @@ enum {
212 IF_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C 219 IF_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C
213 IF_FEATURE_SYSLOGD_DUP( OPTBIT_dup ,) // -D 220 IF_FEATURE_SYSLOGD_DUP( OPTBIT_dup ,) // -D
214 IF_FEATURE_SYSLOGD_CFG( OPTBIT_cfg ,) // -f 221 IF_FEATURE_SYSLOGD_CFG( OPTBIT_cfg ,) // -f
222 IF_FEATURE_KMSG_SYSLOG( OPTBIT_kmsg ,) // -K
215 223
216 OPT_mark = 1 << OPTBIT_mark , 224 OPT_mark = 1 << OPTBIT_mark ,
217 OPT_nofork = 1 << OPTBIT_nofork , 225 OPT_nofork = 1 << OPTBIT_nofork ,
@@ -225,6 +233,8 @@ enum {
225 OPT_circularlog = IF_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0, 233 OPT_circularlog = IF_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0,
226 OPT_dup = IF_FEATURE_SYSLOGD_DUP( (1 << OPTBIT_dup )) + 0, 234 OPT_dup = IF_FEATURE_SYSLOGD_DUP( (1 << OPTBIT_dup )) + 0,
227 OPT_cfg = IF_FEATURE_SYSLOGD_CFG( (1 << OPTBIT_cfg )) + 0, 235 OPT_cfg = IF_FEATURE_SYSLOGD_CFG( (1 << OPTBIT_cfg )) + 0,
236 OPT_kmsg = IF_FEATURE_KMSG_SYSLOG( (1 << OPTBIT_kmsg )) + 0,
237
228}; 238};
229#define OPTION_STR "m:nO:l:S" \ 239#define OPTION_STR "m:nO:l:S" \
230 IF_FEATURE_ROTATE_LOGFILE("s:" ) \ 240 IF_FEATURE_ROTATE_LOGFILE("s:" ) \
@@ -233,7 +243,8 @@ enum {
233 IF_FEATURE_REMOTE_LOG( "L" ) \ 243 IF_FEATURE_REMOTE_LOG( "L" ) \
234 IF_FEATURE_IPC_SYSLOG( "C::") \ 244 IF_FEATURE_IPC_SYSLOG( "C::") \
235 IF_FEATURE_SYSLOGD_DUP( "D" ) \ 245 IF_FEATURE_SYSLOGD_DUP( "D" ) \
236 IF_FEATURE_SYSLOGD_CFG( "f:" ) 246 IF_FEATURE_SYSLOGD_CFG( "f:" ) \
247 IF_FEATURE_KMSG_SYSLOG( "K" )
237#define OPTION_DECL *opt_m, *opt_l \ 248#define OPTION_DECL *opt_m, *opt_l \
238 IF_FEATURE_ROTATE_LOGFILE(,*opt_s) \ 249 IF_FEATURE_ROTATE_LOGFILE(,*opt_s) \
239 IF_FEATURE_ROTATE_LOGFILE(,*opt_b) \ 250 IF_FEATURE_ROTATE_LOGFILE(,*opt_b) \
@@ -242,7 +253,7 @@ enum {
242#define OPTION_PARAM &opt_m, &(G.logFile.path), &opt_l \ 253#define OPTION_PARAM &opt_m, &(G.logFile.path), &opt_l \
243 IF_FEATURE_ROTATE_LOGFILE(,&opt_s) \ 254 IF_FEATURE_ROTATE_LOGFILE(,&opt_s) \
244 IF_FEATURE_ROTATE_LOGFILE(,&opt_b) \ 255 IF_FEATURE_ROTATE_LOGFILE(,&opt_b) \
245 IF_FEATURE_REMOTE_LOG( ,&remoteAddrList) \ 256 IF_FEATURE_REMOTE_LOG( ,&remoteAddrList) \
246 IF_FEATURE_IPC_SYSLOG( ,&opt_C) \ 257 IF_FEATURE_IPC_SYSLOG( ,&opt_C) \
247 IF_FEATURE_SYSLOGD_CFG( ,&opt_f) 258 IF_FEATURE_SYSLOGD_CFG( ,&opt_f)
248 259
@@ -418,7 +429,9 @@ static void parse_syslogdcfg(const char *file)
418 return; 429 return;
419 430
420 cfgerr: 431 cfgerr:
421 bb_error_msg_and_die("error in '%s' at line %d", file, parser->lineno); 432 bb_error_msg_and_die("error in '%s' at line %d",
433 file ? file : "/etc/syslog.conf",
434 parser->lineno);
422} 435}
423#endif 436#endif
424 437
@@ -518,11 +531,49 @@ static void log_to_shmem(const char *msg)
518 printf("tail:%d\n", G.shbuf->tail); 531 printf("tail:%d\n", G.shbuf->tail);
519} 532}
520#else 533#else
521void ipcsyslog_cleanup(void); 534static void ipcsyslog_cleanup(void) {}
522void ipcsyslog_init(void); 535static void ipcsyslog_init(void) {}
523void log_to_shmem(const char *msg); 536void log_to_shmem(const char *msg);
524#endif /* FEATURE_IPC_SYSLOG */ 537#endif /* FEATURE_IPC_SYSLOG */
525 538
539#if ENABLE_FEATURE_KMSG_SYSLOG
540static void kmsg_init(void)
541{
542 G.kmsgfd = xopen("/dev/kmsg", O_WRONLY);
543
544 /*
545 * kernel < 3.5 expects single char printk KERN_* priority prefix,
546 * from 3.5 onwards the full syslog facility/priority format is supported
547 */
548 if (get_linux_version_code() < KERNEL_VERSION(3,5,0))
549 G.primask = LOG_PRIMASK;
550 else
551 G.primask = -1;
552}
553
554static void kmsg_cleanup(void)
555{
556 if (ENABLE_FEATURE_CLEAN_UP)
557 close(G.kmsgfd);
558}
559
560/* Write message to /dev/kmsg */
561static void log_to_kmsg(int pri, const char *msg)
562{
563 /*
564 * kernel < 3.5 expects single char printk KERN_* priority prefix,
565 * from 3.5 onwards the full syslog facility/priority format is supported
566 */
567 pri &= G.primask;
568
569 write(G.kmsgfd, G.printbuf, sprintf(G.printbuf, "<%d>%s\n", pri, msg));
570}
571#else
572static void kmsg_init(void) {}
573static void kmsg_cleanup(void) {}
574static void log_to_kmsg(int pri UNUSED_PARAM, const char *msg UNUSED_PARAM) {}
575#endif /* FEATURE_KMSG_SYSLOG */
576
526/* Print a message to the log file. */ 577/* Print a message to the log file. */
527static void log_locally(time_t now, char *msg, logFile_t *log_file) 578static void log_locally(time_t now, char *msg, logFile_t *log_file)
528{ 579{
@@ -657,6 +708,11 @@ static void timestamp_and_log(int pri, char *msg, int len)
657 } 708 }
658 timestamp[15] = '\0'; 709 timestamp[15] = '\0';
659 710
711 if (option_mask32 & OPT_kmsg) {
712 log_to_kmsg(pri, msg);
713 return;
714 }
715
660 if (option_mask32 & OPT_small) 716 if (option_mask32 & OPT_small)
661 sprintf(G.printbuf, "%s %s\n", timestamp, msg); 717 sprintf(G.printbuf, "%s %s\n", timestamp, msg);
662 else { 718 else {
@@ -827,9 +883,11 @@ static void do_syslogd(void)
827#endif 883#endif
828 sock_fd = create_socket(); 884 sock_fd = create_socket();
829 885
830 if (ENABLE_FEATURE_IPC_SYSLOG && (option_mask32 & OPT_circularlog)) { 886 if (option_mask32 & OPT_circularlog)
831 ipcsyslog_init(); 887 ipcsyslog_init();
832 } 888
889 if (option_mask32 & OPT_kmsg)
890 kmsg_init();
833 891
834 timestamp_and_log_internal("syslogd started: BusyBox v" BB_VER); 892 timestamp_and_log_internal("syslogd started: BusyBox v" BB_VER);
835 893
@@ -916,8 +974,10 @@ static void do_syslogd(void)
916 974
917 timestamp_and_log_internal("syslogd exiting"); 975 timestamp_and_log_internal("syslogd exiting");
918 puts("syslogd exiting"); 976 puts("syslogd exiting");
919 if (ENABLE_FEATURE_IPC_SYSLOG) 977 remove_pidfile(CONFIG_PID_FILE_PATH "/syslogd.pid");
920 ipcsyslog_cleanup(); 978 ipcsyslog_cleanup();
979 if (option_mask32 & OPT_kmsg)
980 kmsg_cleanup();
921 kill_myself_with_sig(bb_got_signal); 981 kill_myself_with_sig(bb_got_signal);
922#undef recvbuf 982#undef recvbuf
923} 983}
@@ -979,8 +1039,10 @@ int syslogd_main(int argc UNUSED_PARAM, char **argv)
979 if (!(opts & OPT_nofork)) { 1039 if (!(opts & OPT_nofork)) {
980 bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); 1040 bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
981 } 1041 }
1042
982 //umask(0); - why?? 1043 //umask(0); - why??
983 write_pidfile("/var/run/syslogd.pid"); 1044 write_pidfile(CONFIG_PID_FILE_PATH "/syslogd.pid");
1045
984 do_syslogd(); 1046 do_syslogd();
985 /* return EXIT_SUCCESS; */ 1047 /* return EXIT_SUCCESS; */
986} 1048}
diff --git a/testsuite/du/du-k-works b/testsuite/du/du-k-works
index 36dcaa85d..417b0daa5 100644
--- a/testsuite/du/du-k-works
+++ b/testsuite/du/du-k-works
@@ -2,6 +2,10 @@ mkdir du.testdir
2cd du.testdir 2cd du.testdir
3dd if=/dev/zero of=file1 bs=1k count=64 2>/dev/null 3dd if=/dev/zero of=file1 bs=1k count=64 2>/dev/null
4dd if=/dev/zero of=file2 bs=1k count=16 2>/dev/null 4dd if=/dev/zero of=file2 bs=1k count=16 2>/dev/null
5# ext4 on images <512M gives 81kb
6# ext3 on images <512M gives 83kb
5test x"`busybox du -k .`" = x"80 ." \ 7test x"`busybox du -k .`" = x"80 ." \
8 -o x"`busybox du -k .`" = x"81 ." \
9 -o x"`busybox du -k .`" = x"83 ." \
6 -o x"`busybox du -k .`" = x"84 ." \ 10 -o x"`busybox du -k .`" = x"84 ." \
7 -o x"`busybox du -k .`" = x"88 ." 11 -o x"`busybox du -k .`" = x"88 ."
diff --git a/testsuite/grep.tests b/testsuite/grep.tests
index 006a215e1..4781f2284 100755
--- a/testsuite/grep.tests
+++ b/testsuite/grep.tests
@@ -115,6 +115,18 @@ testing "grep -v -f EMPTY_FILE" \
115 "" \ 115 "" \
116 "test\n" 116 "test\n"
117 117
118testing "grep -Fw matches only words" \
119 "grep -Fw foo input" \
120 "" \
121 "foop\n" \
122 ""
123
124testing "grep -Fw doesn't stop on 1st mismatch" \
125 "grep -Fw foo input" \
126 "foop foo\n" \
127 "foop foo\n" \
128 ""
129
118# testing "test name" "commands" "expected result" "file input" "stdin" 130# testing "test name" "commands" "expected result" "file input" "stdin"
119# file input will be file called "input" 131# file input will be file called "input"
120# test can create a file "actual" instead of writing to stdout 132# test can create a file "actual" instead of writing to stdout
diff --git a/testsuite/mdev.tests b/testsuite/mdev.tests
index 7320e17dd..48d3dcc2c 100755
--- a/testsuite/mdev.tests
+++ b/testsuite/mdev.tests
@@ -11,7 +11,7 @@ FILTER_LS="grep -v '^total ' | sed -e 's/, */,/g' -e 's/ */ /g' | cut -d' ' -f
11# cut: remove size+date 11# cut: remove size+date
12FILTER_LS2="grep -v '^total ' | sed -e 's/, */,/g' -e 's/ */ /g' | cut -d' ' -f 1-4,9-" 12FILTER_LS2="grep -v '^total ' | sed -e 's/, */,/g' -e 's/ */ /g' | cut -d' ' -f 1-4,9-"
13 13
14# testing "test name" "options" "expected result" "file input" "stdin" 14# testing "test name" "commands" "expected result" "file input" "stdin"
15 15
16rm -rf mdev.testdir 16rm -rf mdev.testdir
17mkdir mdev.testdir 17mkdir mdev.testdir
@@ -128,6 +128,26 @@ SKIP=
128 128
129# continuing to use directory structure from prev test 129# continuing to use directory structure from prev test
130rm -rf mdev.testdir/dev/* 130rm -rf mdev.testdir/dev/*
131echo "sda 0:0 444 =disk/sd/a" >mdev.testdir/etc/mdev.conf
132optional STATIC FEATURE_MDEV_CONF FEATURE_MDEV_RENAME FEATURE_LS_RECURSIVE FEATURE_LS_TIMESTAMPS FEATURE_LS_USERNAME
133testing "mdev move rule '=bar/baz/fname'" \
134 "env - PATH=$PATH ACTION=add DEVPATH=/block/sda chroot mdev.testdir /mdev 2>&1;
135 ls -lnR mdev.testdir/dev | $FILTER_LS2" \
136"\
137mdev.testdir/dev:
138drwxr-xr-x 3 0 0 disk
139
140mdev.testdir/dev/disk:
141drwxr-xr-x 2 0 0 sd
142
143mdev.testdir/dev/disk/sd:
144br--r--r-- 1 0 0 a
145" \
146 "" ""
147SKIP=
148
149# continuing to use directory structure from prev test
150rm -rf mdev.testdir/dev/*
131# here we complicate things by having non-matching group 1 and using %0 151# here we complicate things by having non-matching group 1 and using %0
132echo "s([0-9])*d([a-z]+) 0:0 644 >sd/%2_%0" >mdev.testdir/etc/mdev.conf 152echo "s([0-9])*d([a-z]+) 0:0 644 >sd/%2_%0" >mdev.testdir/etc/mdev.conf
133optional STATIC FEATURE_MDEV_CONF FEATURE_MDEV_RENAME FEATURE_MDEV_RENAME_REGEXP FEATURE_LS_RECURSIVE FEATURE_LS_TIMESTAMPS FEATURE_LS_USERNAME FEATURE_LS_SORTFILES 153optional STATIC FEATURE_MDEV_CONF FEATURE_MDEV_RENAME FEATURE_MDEV_RENAME_REGEXP FEATURE_LS_RECURSIVE FEATURE_LS_TIMESTAMPS FEATURE_LS_USERNAME FEATURE_LS_SORTFILES
diff --git a/testsuite/mkfs.minix.tests b/testsuite/mkfs.minix.tests
index 7eecaf230..324eaafce 100755
--- a/testsuite/mkfs.minix.tests
+++ b/testsuite/mkfs.minix.tests
@@ -9,7 +9,7 @@
9# testing "test name" "options" "expected result" "file input" "stdin" 9# testing "test name" "options" "expected result" "file input" "stdin"
10 10
11# '\n' produces 10 on little endian, but not on big endian 11# '\n' produces 10 on little endian, but not on big endian
12cr=`echo | od -i | sed 's/.* //g;2d'` 12cr=`echo | od -i | sed 's/ *$//g;s/.* //g;2d'`
13if [ x"$cr" = x"10" ]; then 13if [ x"$cr" = x"10" ]; then
14 hash=4f35f7afeba07d56055bed1f29ae20b7 14 hash=4f35f7afeba07d56055bed1f29ae20b7
15else 15else
diff --git a/testsuite/sha3sum.tests b/testsuite/sha3sum.tests
new file mode 100755
index 000000000..82fada633
--- /dev/null
+++ b/testsuite/sha3sum.tests
@@ -0,0 +1,3 @@
1#!/bin/sh
2
3. ./md5sum.tests sha3sum c29d77bc548fa2b20a04c861400a5360879c52156e2a54a3415b99a9a3123e1d5f36714a24eca8c1f05a8e2d8ba859c930d41141f64a255c6794436fc99c486a
diff --git a/util-linux/Config.src b/util-linux/Config.src
index e4516ddb7..6c1b928da 100644
--- a/util-linux/Config.src
+++ b/util-linux/Config.src
@@ -841,6 +841,16 @@ config FEATURE_VOLUMEID_ROMFS
841 help 841 help
842 TODO 842 TODO
843 843
844config FEATURE_VOLUMEID_SQUASHFS
845 bool "SquashFS filesystem"
846 default y
847 depends on VOLUMEID && FEATURE_BLKID_TYPE
848 help
849 Squashfs is a compressed read-only filesystem for Linux. Squashfs is
850 intended for general read-only filesystem use and in constrained block
851 device/memory systems (e.g. embedded systems) where low overhead is
852 needed.
853
844config FEATURE_VOLUMEID_SYSV 854config FEATURE_VOLUMEID_SYSV
845 bool "sysv filesystem" 855 bool "sysv filesystem"
846 default y 856 default y
diff --git a/util-linux/acpid.c b/util-linux/acpid.c
index 5d2792948..38421c2d7 100644
--- a/util-linux/acpid.c
+++ b/util-linux/acpid.c
@@ -235,7 +235,7 @@ int acpid_main(int argc UNUSED_PARAM, char **argv)
235 const char *opt_action = "/etc/acpid.conf"; 235 const char *opt_action = "/etc/acpid.conf";
236 const char *opt_map = "/etc/acpi.map"; 236 const char *opt_map = "/etc/acpi.map";
237#if ENABLE_FEATURE_PIDFILE 237#if ENABLE_FEATURE_PIDFILE
238 const char *opt_pidfile = "/var/run/acpid.pid"; 238 const char *opt_pidfile = CONFIG_PID_FILE_PATH "/acpid.pid";
239#endif 239#endif
240 240
241 INIT_G(); 241 INIT_G();
diff --git a/util-linux/dmesg.c b/util-linux/dmesg.c
index 6505da54b..81ba1c9d1 100644
--- a/util-linux/dmesg.c
+++ b/util-linux/dmesg.c
@@ -59,16 +59,15 @@ int dmesg_main(int argc UNUSED_PARAM, char **argv)
59 int last = '\n'; 59 int last = '\n';
60 int in = 0; 60 int in = 0;
61 61
62 /* Skip <#> at the start of lines */ 62 /* Skip <[0-9]+> at the start of lines */
63 while (1) { 63 while (1) {
64 if (last == '\n' && buf[in] == '<') { 64 if (last == '\n' && buf[in] == '<') {
65 in += 3; 65 while (buf[in++] != '>' && in < len)
66 if (in >= len) 66 ;
67 break; 67 } else {
68 last = buf[in++];
69 putchar(last);
68 } 70 }
69 last = buf[in];
70 putchar(last);
71 in++;
72 if (in >= len) 71 if (in >= len)
73 break; 72 break;
74 } 73 }
diff --git a/util-linux/fdformat.c b/util-linux/fdformat.c
index 2f0854a30..b3e918fb0 100644
--- a/util-linux/fdformat.c
+++ b/util-linux/fdformat.c
@@ -116,7 +116,7 @@ int fdformat_main(int argc UNUSED_PARAM, char **argv)
116 /* Check backwards so we don't need a counter */ 116 /* Check backwards so we don't need a counter */
117 while (--read_bytes >= 0) { 117 while (--read_bytes >= 0) {
118 if (data[read_bytes] != FD_FILL_BYTE) { 118 if (data[read_bytes] != FD_FILL_BYTE) {
119 printf("bad data in cyl %d\nContinuing... ", cyl); 119 printf("bad data in cyl %d\nContinuing... ", cyl);
120 } 120 }
121 } 121 }
122 } 122 }
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c
index c0be15a3a..39eb27b47 100644
--- a/util-linux/fdisk.c
+++ b/util-linux/fdisk.c
@@ -3023,7 +3023,7 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv)
3023 printf("\nThe current boot file is: %s\n", 3023 printf("\nThe current boot file is: %s\n",
3024 sgi_get_bootfile()); 3024 sgi_get_bootfile());
3025 if (read_maybe_empty("Please enter the name of the " 3025 if (read_maybe_empty("Please enter the name of the "
3026 "new boot file: ") == '\n') 3026 "new boot file: ") == '\n')
3027 printf("Boot file unchanged\n"); 3027 printf("Boot file unchanged\n");
3028 else 3028 else
3029 sgi_set_bootfile(line_ptr); 3029 sgi_set_bootfile(line_ptr);
diff --git a/util-linux/fdisk_osf.c b/util-linux/fdisk_osf.c
index 65e6bd7c4..ff16389bd 100644
--- a/util-linux/fdisk_osf.c
+++ b/util-linux/fdisk_osf.c
@@ -898,8 +898,7 @@ xbsd_initlabel(struct partition *p)
898 pp->p_fstype = BSD_FS_UNUSED; 898 pp->p_fstype = BSD_FS_UNUSED;
899#else 899#else
900 d->d_npartitions = 3; 900 d->d_npartitions = 3;
901 pp = &d->d_partitions[2]; /* Partition C should be 901 pp = &d->d_partitions[2]; /* Partition C should be the whole disk */
902 the whole disk */
903 pp->p_offset = 0; 902 pp->p_offset = 0;
904 pp->p_size = d->d_secperunit; 903 pp->p_size = d->d_secperunit;
905 pp->p_fstype = BSD_FS_UNUSED; 904 pp->p_fstype = BSD_FS_UNUSED;
@@ -935,7 +934,7 @@ xbsd_readlabel(struct partition *p)
935 fdisk_fatal(unable_to_read); 934 fdisk_fatal(unable_to_read);
936 935
937 memmove(d, &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET], 936 memmove(d, &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET],
938 sizeof(struct xbsd_disklabel)); 937 sizeof(struct xbsd_disklabel));
939 938
940 if (d->d_magic != BSD_DISKMAGIC || d->d_magic2 != BSD_DISKMAGIC) 939 if (d->d_magic != BSD_DISKMAGIC || d->d_magic2 != BSD_DISKMAGIC)
941 return 0; 940 return 0;
diff --git a/util-linux/flock.c b/util-linux/flock.c
index e9be4eee9..05a747f72 100644
--- a/util-linux/flock.c
+++ b/util-linux/flock.c
@@ -45,7 +45,7 @@ int flock_main(int argc UNUSED_PARAM, char **argv)
45 if (argv[1]) { 45 if (argv[1]) {
46 fd = open(argv[0], O_RDONLY|O_NOCTTY|O_CREAT, 0666); 46 fd = open(argv[0], O_RDONLY|O_NOCTTY|O_CREAT, 0666);
47 if (fd < 0 && errno == EISDIR) 47 if (fd < 0 && errno == EISDIR)
48 fd = open(argv[0], O_RDONLY|O_NOCTTY); 48 fd = open(argv[0], O_RDONLY|O_NOCTTY);
49 if (fd < 0) 49 if (fd < 0)
50 bb_perror_msg_and_die("can't open '%s'", argv[0]); 50 bb_perror_msg_and_die("can't open '%s'", argv[0]);
51 //TODO? close_on_exec_on(fd); 51 //TODO? close_on_exec_on(fd);
diff --git a/util-linux/fsck_minix.c b/util-linux/fsck_minix.c
index 1508ecb03..c1d1b2cc3 100644
--- a/util-linux/fsck_minix.c
+++ b/util-linux/fsck_minix.c
@@ -13,7 +13,7 @@
13 * 10.11.91 - updated, does checking, no repairs yet. 13 * 10.11.91 - updated, does checking, no repairs yet.
14 * Sent out to the mailing-list for testing. 14 * Sent out to the mailing-list for testing.
15 * 15 *
16 * 14.11.91 - Testing seems to have gone well. Added some 16 * 14.11.91 - Testing seems to have gone well. Added some
17 * correction-code, and changed some functions. 17 * correction-code, and changed some functions.
18 * 18 *
19 * 15.11.91 - More correction code. Hopefully it notices most 19 * 15.11.91 - More correction code. Hopefully it notices most
@@ -22,11 +22,10 @@
22 * 16.11.91 - More corrections (thanks to Mika Jalava). Most 22 * 16.11.91 - More corrections (thanks to Mika Jalava). Most
23 * things seem to work now. Yeah, sure. 23 * things seem to work now. Yeah, sure.
24 * 24 *
25 * 25 * 19.04.92 - Had to start over again from this old version, as a
26 * 19.04.92 - Had to start over again from this old version, as a
27 * kernel bug ate my enhanced fsck in february. 26 * kernel bug ate my enhanced fsck in february.
28 * 27 *
29 * 28.02.93 - added support for different directory entry sizes.. 28 * 28.02.93 - added support for different directory entry sizes..
30 * 29 *
31 * Sat Mar 6 18:59:42 1993, faith@cs.unc.edu: Output namelen with 30 * Sat Mar 6 18:59:42 1993, faith@cs.unc.edu: Output namelen with
32 * superblock information 31 * superblock information
@@ -35,31 +34,31 @@
35 * to that required by fsutil 34 * to that required by fsutil
36 * 35 *
37 * Mon Jan 3 11:06:52 1994 - Dr. Wettstein (greg%wind.uucp@plains.nodak.edu) 36 * Mon Jan 3 11:06:52 1994 - Dr. Wettstein (greg%wind.uucp@plains.nodak.edu)
38 * Added support for file system valid flag. Also 37 * Added support for file system valid flag. Also
39 * added program_version variable and output of 38 * added program_version variable and output of
40 * program name and version number when program 39 * program name and version number when program
41 * is executed. 40 * is executed.
42 * 41 *
43 * 30.10.94 - added support for v2 filesystem 42 * 30.10.94 - added support for v2 filesystem
44 * (Andreas Schwab, schwab@issan.informatik.uni-dortmund.de) 43 * (Andreas Schwab, schwab@issan.informatik.uni-dortmund.de)
45 * 44 *
46 * 10.12.94 - added test to prevent checking of mounted fs adapted 45 * 10.12.94 - added test to prevent checking of mounted fs adapted
47 * from Theodore Ts'o's (tytso@athena.mit.edu) e2fsck 46 * from Theodore Ts'o's (tytso@athena.mit.edu) e2fsck
48 * program. (Daniel Quinlan, quinlan@yggdrasil.com) 47 * program. (Daniel Quinlan, quinlan@yggdrasil.com)
49 * 48 *
50 * 01.07.96 - Fixed the v2 fs stuff to use the right #defines and such 49 * 01.07.96 - Fixed the v2 fs stuff to use the right #defines and such
51 * for modern libcs (janl@math.uio.no, Nicolai Langfeldt) 50 * for modern libcs (janl@math.uio.no, Nicolai Langfeldt)
52 * 51 *
53 * 02.07.96 - Added C bit fiddling routines from rmk@ecs.soton.ac.uk 52 * 02.07.96 - Added C bit fiddling routines from rmk@ecs.soton.ac.uk
54 * (Russell King). He made them for ARM. It would seem 53 * (Russell King). He made them for ARM. It would seem
55 * that the ARM is powerful enough to do this in C whereas 54 * that the ARM is powerful enough to do this in C whereas
56 * i386 and m64k must use assembly to get it fast >:-) 55 * i386 and m64k must use assembly to get it fast >:-)
57 * This should make minix fsck system-independent. 56 * This should make minix fsck system-independent.
58 * (janl@math.uio.no, Nicolai Langfeldt) 57 * (janl@math.uio.no, Nicolai Langfeldt)
59 * 58 *
60 * 04.11.96 - Added minor fixes from Andreas Schwab to avoid compiler 59 * 04.11.96 - Added minor fixes from Andreas Schwab to avoid compiler
61 * warnings. Added mc68k bitops from 60 * warnings. Added mc68k bitops from
62 * Joerg Dorchain <dorchain@mpi-sb.mpg.de>. 61 * Joerg Dorchain <dorchain@mpi-sb.mpg.de>.
63 * 62 *
64 * 06.11.96 - Added v2 code submitted by Joerg Dorchain, but written by 63 * 06.11.96 - Added v2 code submitted by Joerg Dorchain, but written by
65 * Andreas Schwab. 64 * Andreas Schwab.
@@ -1131,7 +1130,7 @@ static void check_counts(void)
1131 continue; 1130 continue;
1132 } 1131 }
1133 printf("Zone %d: %sin use, counted=%d\n", 1132 printf("Zone %d: %sin use, counted=%d\n",
1134 i, zone_in_use(i) ? "" : "not ", zone_count[i]); 1133 i, zone_in_use(i) ? "" : "not ", zone_count[i]);
1135 } 1134 }
1136} 1135}
1137 1136
@@ -1183,7 +1182,7 @@ static void check_counts2(void)
1183 continue; 1182 continue;
1184 } 1183 }
1185 printf("Zone %d: %sin use, counted=%d\n", 1184 printf("Zone %d: %sin use, counted=%d\n",
1186 i, zone_in_use(i) ? "" : "not ", zone_count[i]); 1185 i, zone_in_use(i) ? "" : "not ", zone_count[i]);
1187 } 1186 }
1188} 1187}
1189#endif 1188#endif
@@ -1253,7 +1252,7 @@ int fsck_minix_main(int argc UNUSED_PARAM, char **argv)
1253 printf("Forcing filesystem check on %s\n", device_name); 1252 printf("Forcing filesystem check on %s\n", device_name);
1254 else if (OPT_repair) 1253 else if (OPT_repair)
1255 printf("Filesystem on %s is dirty, needs checking\n", 1254 printf("Filesystem on %s is dirty, needs checking\n",
1256 device_name); 1255 device_name);
1257 1256
1258 read_tables(); 1257 read_tables();
1259 1258
@@ -1280,23 +1279,23 @@ int fsck_minix_main(int argc UNUSED_PARAM, char **argv)
1280 if (!inode_in_use(i)) 1279 if (!inode_in_use(i))
1281 free_cnt++; 1280 free_cnt++;
1282 printf("\n%6u inodes used (%u%%)\n", (INODES - free_cnt), 1281 printf("\n%6u inodes used (%u%%)\n", (INODES - free_cnt),
1283 100 * (INODES - free_cnt) / INODES); 1282 100 * (INODES - free_cnt) / INODES);
1284 for (i = FIRSTZONE, free_cnt = 0; i < ZONES; i++) 1283 for (i = FIRSTZONE, free_cnt = 0; i < ZONES; i++)
1285 if (!zone_in_use(i)) 1284 if (!zone_in_use(i))
1286 free_cnt++; 1285 free_cnt++;
1287 printf("%6u zones used (%u%%)\n\n" 1286 printf("%6u zones used (%u%%)\n\n"
1288 "%6u regular files\n" 1287 "%6u regular files\n"
1289 "%6u directories\n" 1288 "%6u directories\n"
1290 "%6u character device files\n" 1289 "%6u character device files\n"
1291 "%6u block device files\n" 1290 "%6u block device files\n"
1292 "%6u links\n" 1291 "%6u links\n"
1293 "%6u symbolic links\n" 1292 "%6u symbolic links\n"
1294 "------\n" 1293 "------\n"
1295 "%6u files\n", 1294 "%6u files\n",
1296 (ZONES - free_cnt), 100 * (ZONES - free_cnt) / ZONES, 1295 (ZONES - free_cnt), 100 * (ZONES - free_cnt) / ZONES,
1297 regular, directory, chardev, blockdev, 1296 regular, directory, chardev, blockdev,
1298 links - 2 * directory + 1, symlinks, 1297 links - 2 * directory + 1, symlinks,
1299 total - 2 * directory + 1); 1298 total - 2 * directory + 1);
1300 } 1299 }
1301 if (changed) { 1300 if (changed) {
1302 write_tables(); 1301 write_tables();
diff --git a/util-linux/getopt.c b/util-linux/getopt.c
index d662c813a..58df1c823 100644
--- a/util-linux/getopt.c
+++ b/util-linux/getopt.c
@@ -35,27 +35,32 @@
35//usage: "[OPTIONS] [--] OPTSTRING PARAMS" 35//usage: "[OPTIONS] [--] OPTSTRING PARAMS"
36//usage:#define getopt_full_usage "\n\n" 36//usage:#define getopt_full_usage "\n\n"
37//usage: IF_LONG_OPTS( 37//usage: IF_LONG_OPTS(
38//usage: " -a,--alternative Allow long options starting with single -" 38//usage: IF_FEATURE_GETOPT_LONG(
39//usage: "\n -l,--longoptions=LOPT[,...] Long options to be recognized" 39//usage: " -a,--alternative Allow long options starting with single -\n"
40//usage: "\n -n,--name=PROGNAME The name under which errors are reported" 40//usage: " -l,--longoptions=LOPT[,...] Long options to recognize\n"
41//usage: "\n -o,--options=OPTSTRING Short options to be recognized" 41//usage: )
42//usage: "\n -q,--quiet Disable error reporting by getopt(3)" 42//usage: " -n,--name=PROGNAME The name under which errors are reported"
43//usage: "\n -o,--options=OPTSTRING Short options to recognize"
44//usage: "\n -q,--quiet No error messages on unrecognized options"
43//usage: "\n -Q,--quiet-output No normal output" 45//usage: "\n -Q,--quiet-output No normal output"
44//usage: "\n -s,--shell=SHELL Set shell quoting conventions" 46//usage: "\n -s,--shell=SHELL Set shell quoting conventions"
45//usage: "\n -T,--test Test for getopt(1) version" 47//usage: "\n -T,--test Version test (exits with 4)"
46//usage: "\n -u,--unquoted Don't quote the output" 48//usage: "\n -u,--unquoted Don't quote output"
47//usage: ) 49//usage: )
48//usage: IF_NOT_LONG_OPTS( 50//usage: IF_NOT_LONG_OPTS(
49//usage: " -a Allow long options starting with single -" 51//usage: IF_FEATURE_GETOPT_LONG(
50//usage: "\n -l LOPT[,...] Long options to be recognized" 52//usage: " -a Allow long options starting with single -\n"
51//usage: "\n -n PROGNAME The name under which errors are reported" 53//usage: " -l LOPT[,...] Long options to recognize\n"
52//usage: "\n -o OPTSTRING Short options to be recognized" 54//usage: )
53//usage: "\n -q Disable error reporting by getopt(3)" 55//usage: " -n PROGNAME The name under which errors are reported"
56//usage: "\n -o OPTSTRING Short options to recognize"
57//usage: "\n -q No error messages on unrecognized options"
54//usage: "\n -Q No normal output" 58//usage: "\n -Q No normal output"
55//usage: "\n -s SHELL Set shell quoting conventions" 59//usage: "\n -s SHELL Set shell quoting conventions"
56//usage: "\n -T Test for getopt(1) version" 60//usage: "\n -T Version test (exits with 4)"
57//usage: "\n -u Don't quote the output" 61//usage: "\n -u Don't quote output"
58//usage: ) 62//usage: )
63//usage: IF_FEATURE_GETOPT_LONG( /* example uses -l, needs FEATURE_GETOPT_LONG */
59//usage: "\n" 64//usage: "\n"
60//usage: "\nExample:" 65//usage: "\nExample:"
61//usage: "\n" 66//usage: "\n"
@@ -73,6 +78,7 @@
73//usage: "\n *) echo Error; exit 1;;" 78//usage: "\n *) echo Error; exit 1;;"
74//usage: "\n esac" 79//usage: "\n esac"
75//usage: "\ndone" 80//usage: "\ndone"
81//usage: )
76//usage: 82//usage:
77//usage:#define getopt_example_usage 83//usage:#define getopt_example_usage
78//usage: "$ cat getopt.test\n" 84//usage: "$ cat getopt.test\n"
@@ -214,11 +220,6 @@ static const char *normalize(const char *arg)
214static int generate_output(char **argv, int argc, const char *optstr, const struct option *longopts) 220static int generate_output(char **argv, int argc, const char *optstr, const struct option *longopts)
215{ 221{
216 int exit_code = 0; /* We assume everything will be OK */ 222 int exit_code = 0; /* We assume everything will be OK */
217 int opt;
218#if ENABLE_FEATURE_GETOPT_LONG
219 int longindex;
220#endif
221 const char *charptr;
222 223
223 if (quiet_errors) /* No error reporting from getopt(3) */ 224 if (quiet_errors) /* No error reporting from getopt(3) */
224 opterr = 0; 225 opterr = 0;
@@ -233,13 +234,14 @@ static int generate_output(char **argv, int argc, const char *optstr, const stru
233#endif 234#endif
234 235
235 while (1) { 236 while (1) {
236 opt =
237#if ENABLE_FEATURE_GETOPT_LONG 237#if ENABLE_FEATURE_GETOPT_LONG
238 alternative ? 238 int longindex;
239 getopt_long_only(argc, argv, optstr, longopts, &longindex) : 239 int opt = alternative
240 getopt_long(argc, argv, optstr, longopts, &longindex); 240 ? getopt_long_only(argc, argv, optstr, longopts, &longindex)
241 : getopt_long(argc, argv, optstr, longopts, &longindex)
242 ;
241#else 243#else
242 getopt(argc, argv, optstr); 244 int opt = getopt(argc, argv, optstr);
243#endif 245#endif
244 if (opt == -1) 246 if (opt == -1)
245 break; 247 break;
@@ -257,9 +259,10 @@ static int generate_output(char **argv, int argc, const char *optstr, const stru
257 if (opt == NON_OPT) 259 if (opt == NON_OPT)
258 printf(" %s", normalize(optarg)); 260 printf(" %s", normalize(optarg));
259 else { 261 else {
262 const char *charptr;
260 printf(" -%c", opt); 263 printf(" -%c", opt);
261 charptr = strchr(optstr, opt); 264 charptr = strchr(optstr, opt);
262 if (charptr != NULL && *++charptr == ':') 265 if (charptr && *++charptr == ':')
263 printf(" %s", 266 printf(" %s",
264 normalize(optarg ? optarg : "")); 267 normalize(optarg ? optarg : ""));
265 } 268 }
@@ -267,9 +270,11 @@ static int generate_output(char **argv, int argc, const char *optstr, const stru
267 } 270 }
268 271
269 if (!quiet_output) { 272 if (!quiet_output) {
273 unsigned idx;
270 printf(" --"); 274 printf(" --");
271 while (optind < argc) 275 idx = optind;
272 printf(" %s", normalize(argv[optind++])); 276 while (argv[idx])
277 printf(" %s", normalize(argv[idx++]));
273 bb_putchar('\n'); 278 bb_putchar('\n');
274 } 279 }
275 return exit_code; 280 return exit_code;
@@ -372,7 +377,7 @@ int getopt_main(int argc, char **argv)
372 if (!argv[1]) { 377 if (!argv[1]) {
373 if (compatible) { 378 if (compatible) {
374 /* For some reason, the original getopt gave no error 379 /* For some reason, the original getopt gave no error
375 when there were no arguments. */ 380 * when there were no arguments. */
376 printf(" --\n"); 381 printf(" --\n");
377 return 0; 382 return 0;
378 } 383 }
diff --git a/util-linux/ipcrm.c b/util-linux/ipcrm.c
index 274050cdf..888f70ef8 100644
--- a/util-linux/ipcrm.c
+++ b/util-linux/ipcrm.c
@@ -160,7 +160,7 @@ int ipcrm_main(int argc, char **argv)
160 160
161 /* convert key to id */ 161 /* convert key to id */
162 id = ((c == 'q') ? msgget(key, 0) : 162 id = ((c == 'q') ? msgget(key, 0) :
163 (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0)); 163 (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0));
164 164
165 if (id < 0) { 165 if (id < 0) {
166 const char *errmsg; 166 const char *errmsg;
@@ -189,8 +189,8 @@ int ipcrm_main(int argc, char **argv)
189 } 189 }
190 190
191 result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) : 191 result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) :
192 (c == 'm') ? shmctl(id, IPC_RMID, NULL) : 192 (c == 'm') ? shmctl(id, IPC_RMID, NULL) :
193 semctl(id, 0, IPC_RMID, arg)); 193 semctl(id, 0, IPC_RMID, arg));
194 194
195 if (result) { 195 if (result) {
196 const char *errmsg; 196 const char *errmsg;
diff --git a/util-linux/ipcs.c b/util-linux/ipcs.c
index ee7df5e33..2668cafd4 100644
--- a/util-linux/ipcs.c
+++ b/util-linux/ipcs.c
@@ -152,54 +152,54 @@ static NOINLINE void do_shm(void)
152 if ((shmctl(0, IPC_INFO, (struct shmid_ds *) (void *) &shminfo)) < 0) 152 if ((shmctl(0, IPC_INFO, (struct shmid_ds *) (void *) &shminfo)) < 0)
153 return; 153 return;
154 /* glibc 2.1.3 and all earlier libc's have ints as fields 154 /* glibc 2.1.3 and all earlier libc's have ints as fields
155 of struct shminfo; glibc 2.1.91 has unsigned long; ach */ 155 * of struct shminfo; glibc 2.1.91 has unsigned long; ach */
156 printf("max number of segments = %lu\n" 156 printf("max number of segments = %lu\n"
157 "max seg size (kbytes) = %lu\n" 157 "max seg size (kbytes) = %lu\n"
158 "max total shared memory (pages) = %lu\n" 158 "max total shared memory (pages) = %lu\n"
159 "min seg size (bytes) = %lu\n", 159 "min seg size (bytes) = %lu\n",
160 (unsigned long) shminfo.shmmni, 160 (unsigned long) shminfo.shmmni,
161 (unsigned long) (shminfo.shmmax >> 10), 161 (unsigned long) (shminfo.shmmax >> 10),
162 (unsigned long) shminfo.shmall, 162 (unsigned long) shminfo.shmall,
163 (unsigned long) shminfo.shmmin); 163 (unsigned long) shminfo.shmmin);
164 return; 164 return;
165 165
166 case STATUS: 166 case STATUS:
167 printf("------ Shared Memory %s --------\n", "Status"); 167 printf("------ Shared Memory %s --------\n", "Status");
168 printf( "segments allocated %d\n" 168 printf("segments allocated %d\n"
169 "pages allocated %ld\n" 169 "pages allocated %ld\n"
170 "pages resident %ld\n" 170 "pages resident %ld\n"
171 "pages swapped %ld\n" 171 "pages swapped %ld\n"
172 "Swap performance: %ld attempts\t%ld successes\n", 172 "Swap performance: %ld attempts\t%ld successes\n",
173 shm_info.used_ids, 173 shm_info.used_ids,
174 shm_info.shm_tot, 174 shm_info.shm_tot,
175 shm_info.shm_rss, 175 shm_info.shm_rss,
176 shm_info.shm_swp, 176 shm_info.shm_swp,
177 shm_info.swap_attempts, shm_info.swap_successes); 177 shm_info.swap_attempts, shm_info.swap_successes);
178 return; 178 return;
179 179
180 case CREATOR: 180 case CREATOR:
181 printf("------ Shared Memory %s --------\n", "Segment Creators/Owners"); 181 printf("------ Shared Memory %s --------\n", "Segment Creators/Owners");
182 printf( "%-10s %-10s %-10s %-10s %-10s %-10s\n", 182 printf("%-10s %-10s %-10s %-10s %-10s %-10s\n",
183 "shmid", "perms", "cuid", "cgid", "uid", "gid"); 183 "shmid", "perms", "cuid", "cgid", "uid", "gid");
184 break; 184 break;
185 185
186 case TIME: 186 case TIME:
187 printf("------ Shared Memory %s --------\n", "Attach/Detach/Change Times"); 187 printf("------ Shared Memory %s --------\n", "Attach/Detach/Change Times");
188 printf( "%-10s %-10s %-20s %-20s %-20s\n", 188 printf("%-10s %-10s %-20s %-20s %-20s\n",
189 "shmid", "owner", "attached", "detached", "changed"); 189 "shmid", "owner", "attached", "detached", "changed");
190 break; 190 break;
191 191
192 case PID: 192 case PID:
193 printf("------ Shared Memory %s --------\n", "Creator/Last-op"); 193 printf("------ Shared Memory %s --------\n", "Creator/Last-op");
194 printf( "%-10s %-10s %-10s %-10s\n", 194 printf("%-10s %-10s %-10s %-10s\n",
195 "shmid", "owner", "cpid", "lpid"); 195 "shmid", "owner", "cpid", "lpid");
196 break; 196 break;
197 197
198 default: 198 default:
199 printf("------ Shared Memory %s --------\n", "Segments"); 199 printf("------ Shared Memory %s --------\n", "Segments");
200 printf( "%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n", 200 printf("%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n",
201 "key", "shmid", "owner", "perms", "bytes", "nattch", 201 "key", "shmid", "owner", "perms", "bytes", "nattch",
202 "status"); 202 "status");
203 break; 203 break;
204 } 204 }
205 205
@@ -220,11 +220,11 @@ static NOINLINE void do_shm(void)
220 printf("%-10d %-10d", shmid, ipcp->uid); 220 printf("%-10d %-10d", shmid, ipcp->uid);
221 /* ctime uses static buffer: use separate calls */ 221 /* ctime uses static buffer: use separate calls */
222 printf(" %-20.16s", shmseg.shm_atime 222 printf(" %-20.16s", shmseg.shm_atime
223 ? ctime(&shmseg.shm_atime) + 4 : "Not set"); 223 ? ctime(&shmseg.shm_atime) + 4 : "Not set");
224 printf(" %-20.16s", shmseg.shm_dtime 224 printf(" %-20.16s", shmseg.shm_dtime
225 ? ctime(&shmseg.shm_dtime) + 4 : "Not set"); 225 ? ctime(&shmseg.shm_dtime) + 4 : "Not set");
226 printf(" %-20.16s\n", shmseg.shm_ctime 226 printf(" %-20.16s\n", shmseg.shm_ctime
227 ? ctime(&shmseg.shm_ctime) + 4 : "Not set"); 227 ? ctime(&shmseg.shm_ctime) + 4 : "Not set");
228 break; 228 break;
229 case PID: 229 case PID:
230 if (pw) 230 if (pw)
@@ -241,17 +241,17 @@ static NOINLINE void do_shm(void)
241 else 241 else
242 printf("%-10d %-10d", shmid, ipcp->uid); 242 printf("%-10d %-10d", shmid, ipcp->uid);
243 printf(" %-10o %-10lu %-10ld %-6s %-6s\n", ipcp->mode & 0777, 243 printf(" %-10o %-10lu %-10ld %-6s %-6s\n", ipcp->mode & 0777,
244 /* 244 /*
245 * earlier: int, Austin has size_t 245 * earlier: int, Austin has size_t
246 */ 246 */
247 (unsigned long) shmseg.shm_segsz, 247 (unsigned long) shmseg.shm_segsz,
248 /* 248 /*
249 * glibc-2.1.3 and earlier has unsigned short; 249 * glibc-2.1.3 and earlier has unsigned short;
250 * Austin has shmatt_t 250 * Austin has shmatt_t
251 */ 251 */
252 (long) shmseg.shm_nattch, 252 (long) shmseg.shm_nattch,
253 ipcp->mode & SHM_DEST ? "dest" : " ", 253 ipcp->mode & SHM_DEST ? "dest" : " ",
254 ipcp->mode & SHM_LOCKED ? "locked" : " "); 254 ipcp->mode & SHM_LOCKED ? "locked" : " ");
255 break; 255 break;
256 } 256 }
257 } 257 }
@@ -281,32 +281,32 @@ static NOINLINE void do_sem(void)
281 if ((semctl(0, 0, IPC_INFO, arg)) < 0) 281 if ((semctl(0, 0, IPC_INFO, arg)) < 0)
282 return; 282 return;
283 printf("max number of arrays = %d\n" 283 printf("max number of arrays = %d\n"
284 "max semaphores per array = %d\n" 284 "max semaphores per array = %d\n"
285 "max semaphores system wide = %d\n" 285 "max semaphores system wide = %d\n"
286 "max ops per semop call = %d\n" 286 "max ops per semop call = %d\n"
287 "semaphore max value = %d\n", 287 "semaphore max value = %d\n",
288 seminfo.semmni, 288 seminfo.semmni,
289 seminfo.semmsl, 289 seminfo.semmsl,
290 seminfo.semmns, seminfo.semopm, seminfo.semvmx); 290 seminfo.semmns, seminfo.semopm, seminfo.semvmx);
291 return; 291 return;
292 292
293 case STATUS: 293 case STATUS:
294 printf("------ Semaphore %s --------\n", "Status"); 294 printf("------ Semaphore %s --------\n", "Status");
295 printf( "used arrays = %d\n" 295 printf("used arrays = %d\n"
296 "allocated semaphores = %d\n", 296 "allocated semaphores = %d\n",
297 seminfo.semusz, seminfo.semaem); 297 seminfo.semusz, seminfo.semaem);
298 return; 298 return;
299 299
300 case CREATOR: 300 case CREATOR:
301 printf("------ Semaphore %s --------\n", "Arrays Creators/Owners"); 301 printf("------ Semaphore %s --------\n", "Arrays Creators/Owners");
302 printf( "%-10s %-10s %-10s %-10s %-10s %-10s\n", 302 printf("%-10s %-10s %-10s %-10s %-10s %-10s\n",
303 "semid", "perms", "cuid", "cgid", "uid", "gid"); 303 "semid", "perms", "cuid", "cgid", "uid", "gid");
304 break; 304 break;
305 305
306 case TIME: 306 case TIME:
307 printf("------ Shared Memory %s --------\n", "Operation/Change Times"); 307 printf("------ Shared Memory %s --------\n", "Operation/Change Times");
308 printf( "%-8s %-10s %-26.24s %-26.24s\n", 308 printf("%-8s %-10s %-26.24s %-26.24s\n",
309 "shmid", "owner", "last-op", "last-changed"); 309 "shmid", "owner", "last-op", "last-changed");
310 break; 310 break;
311 311
312 case PID: 312 case PID:
@@ -314,8 +314,8 @@ static NOINLINE void do_sem(void)
314 314
315 default: 315 default:
316 printf("------ Semaphore %s --------\n", "Arrays"); 316 printf("------ Semaphore %s --------\n", "Arrays");
317 printf( "%-10s %-10s %-10s %-10s %-10s\n", 317 printf("%-10s %-10s %-10s %-10s %-10s\n",
318 "key", "semid", "owner", "perms", "nsems"); 318 "key", "semid", "owner", "perms", "nsems");
319 break; 319 break;
320 } 320 }
321 321
@@ -337,9 +337,9 @@ static NOINLINE void do_sem(void)
337 printf("%-8d %-10d", semid, ipcp->uid); 337 printf("%-8d %-10d", semid, ipcp->uid);
338 /* ctime uses static buffer: use separate calls */ 338 /* ctime uses static buffer: use separate calls */
339 printf(" %-26.24s", semary.sem_otime 339 printf(" %-26.24s", semary.sem_otime
340 ? ctime(&semary.sem_otime) : "Not set"); 340 ? ctime(&semary.sem_otime) : "Not set");
341 printf(" %-26.24s\n", semary.sem_ctime 341 printf(" %-26.24s\n", semary.sem_ctime
342 ? ctime(&semary.sem_ctime) : "Not set"); 342 ? ctime(&semary.sem_ctime) : "Not set");
343 break; 343 break;
344 case PID: 344 case PID:
345 break; 345 break;
@@ -351,13 +351,13 @@ static NOINLINE void do_sem(void)
351 else 351 else
352 printf("%-10d %-9d", semid, ipcp->uid); 352 printf("%-10d %-9d", semid, ipcp->uid);
353 printf(" %-10o %-10ld\n", ipcp->mode & 0777, 353 printf(" %-10o %-10ld\n", ipcp->mode & 0777,
354 /* 354 /*
355 * glibc-2.1.3 and earlier has unsigned short; 355 * glibc-2.1.3 and earlier has unsigned short;
356 * glibc-2.1.91 has variation between 356 * glibc-2.1.91 has variation between
357 * unsigned short and unsigned long 357 * unsigned short and unsigned long
358 * Austin prescribes unsigned short. 358 * Austin prescribes unsigned short.
359 */ 359 */
360 (long) semary.sem_nsems); 360 (long) semary.sem_nsems);
361 break; 361 break;
362 } 362 }
363 } 363 }
@@ -383,42 +383,42 @@ static NOINLINE void do_msg(void)
383 if ((msgctl(0, IPC_INFO, (struct msqid_ds *) (void *) &msginfo)) < 0) 383 if ((msgctl(0, IPC_INFO, (struct msqid_ds *) (void *) &msginfo)) < 0)
384 return; 384 return;
385 printf("------ Message%s --------\n", "s: Limits"); 385 printf("------ Message%s --------\n", "s: Limits");
386 printf( "max queues system wide = %d\n" 386 printf("max queues system wide = %d\n"
387 "max size of message (bytes) = %d\n" 387 "max size of message (bytes) = %d\n"
388 "default max size of queue (bytes) = %d\n", 388 "default max size of queue (bytes) = %d\n",
389 msginfo.msgmni, msginfo.msgmax, msginfo.msgmnb); 389 msginfo.msgmni, msginfo.msgmax, msginfo.msgmnb);
390 return; 390 return;
391 391
392 case STATUS: 392 case STATUS:
393 printf("------ Message%s --------\n", "s: Status"); 393 printf("------ Message%s --------\n", "s: Status");
394 printf( "allocated queues = %d\n" 394 printf("allocated queues = %d\n"
395 "used headers = %d\n" 395 "used headers = %d\n"
396 "used space = %d bytes\n", 396 "used space = %d bytes\n",
397 msginfo.msgpool, msginfo.msgmap, msginfo.msgtql); 397 msginfo.msgpool, msginfo.msgmap, msginfo.msgtql);
398 return; 398 return;
399 399
400 case CREATOR: 400 case CREATOR:
401 printf("------ Message%s --------\n", " Queues: Creators/Owners"); 401 printf("------ Message%s --------\n", " Queues: Creators/Owners");
402 printf( "%-10s %-10s %-10s %-10s %-10s %-10s\n", 402 printf("%-10s %-10s %-10s %-10s %-10s %-10s\n",
403 "msqid", "perms", "cuid", "cgid", "uid", "gid"); 403 "msqid", "perms", "cuid", "cgid", "uid", "gid");
404 break; 404 break;
405 405
406 case TIME: 406 case TIME:
407 printf("------ Message%s --------\n", " Queues Send/Recv/Change Times"); 407 printf("------ Message%s --------\n", " Queues Send/Recv/Change Times");
408 printf( "%-8s %-10s %-20s %-20s %-20s\n", 408 printf("%-8s %-10s %-20s %-20s %-20s\n",
409 "msqid", "owner", "send", "recv", "change"); 409 "msqid", "owner", "send", "recv", "change");
410 break; 410 break;
411 411
412 case PID: 412 case PID:
413 printf("------ Message%s --------\n", " Queues PIDs"); 413 printf("------ Message%s --------\n", " Queues PIDs");
414 printf( "%-10s %-10s %-10s %-10s\n", 414 printf("%-10s %-10s %-10s %-10s\n",
415 "msqid", "owner", "lspid", "lrpid"); 415 "msqid", "owner", "lspid", "lrpid");
416 break; 416 break;
417 417
418 default: 418 default:
419 printf("------ Message%s --------\n", " Queues"); 419 printf("------ Message%s --------\n", " Queues");
420 printf( "%-10s %-10s %-10s %-10s %-12s %-12s\n", 420 printf("%-10s %-10s %-10s %-10s %-12s %-12s\n",
421 "key", "msqid", "owner", "perms", "used-bytes", "messages"); 421 "key", "msqid", "owner", "perms", "used-bytes", "messages");
422 break; 422 break;
423 } 423 }
424 424
@@ -438,11 +438,11 @@ static NOINLINE void do_msg(void)
438 else 438 else
439 printf("%-8d %-10d", msqid, ipcp->uid); 439 printf("%-8d %-10d", msqid, ipcp->uid);
440 printf(" %-20.16s", msgque.msg_stime 440 printf(" %-20.16s", msgque.msg_stime
441 ? ctime(&msgque.msg_stime) + 4 : "Not set"); 441 ? ctime(&msgque.msg_stime) + 4 : "Not set");
442 printf(" %-20.16s", msgque.msg_rtime 442 printf(" %-20.16s", msgque.msg_rtime
443 ? ctime(&msgque.msg_rtime) + 4 : "Not set"); 443 ? ctime(&msgque.msg_rtime) + 4 : "Not set");
444 printf(" %-20.16s\n", msgque.msg_ctime 444 printf(" %-20.16s\n", msgque.msg_ctime
445 ? ctime(&msgque.msg_ctime) + 4 : "Not set"); 445 ? ctime(&msgque.msg_ctime) + 4 : "Not set");
446 break; 446 break;
447 case PID: 447 case PID:
448 if (pw) 448 if (pw)
@@ -459,13 +459,13 @@ static NOINLINE void do_msg(void)
459 else 459 else
460 printf("%-10d %-10d", msqid, ipcp->uid); 460 printf("%-10d %-10d", msqid, ipcp->uid);
461 printf(" %-10o %-12ld %-12ld\n", ipcp->mode & 0777, 461 printf(" %-10o %-12ld %-12ld\n", ipcp->mode & 0777,
462 /* 462 /*
463 * glibc-2.1.3 and earlier has unsigned short; 463 * glibc-2.1.3 and earlier has unsigned short;
464 * glibc-2.1.91 has variation between 464 * glibc-2.1.91 has variation between
465 * unsigned short, unsigned long 465 * unsigned short, unsigned long
466 * Austin has msgqnum_t 466 * Austin has msgqnum_t
467 */ 467 */
468 (long) msgque.msg_cbytes, (long) msgque.msg_qnum); 468 (long) msgque.msg_cbytes, (long) msgque.msg_qnum);
469 break; 469 break;
470 } 470 }
471 } 471 }
@@ -483,18 +483,18 @@ static void print_shm(int shmid)
483 } 483 }
484 484
485 printf("\nShared memory Segment shmid=%d\n" 485 printf("\nShared memory Segment shmid=%d\n"
486 "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n" 486 "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n"
487 "mode=%#o\taccess_perms=%#o\n" 487 "mode=%#o\taccess_perms=%#o\n"
488 "bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n", 488 "bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n",
489 shmid, 489 shmid,
490 ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, 490 ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
491 ipcp->mode, ipcp->mode & 0777, 491 ipcp->mode, ipcp->mode & 0777,
492 (long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid, 492 (long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid,
493 (long) shmds.shm_nattch); 493 (long) shmds.shm_nattch);
494 printf("att_time=%-26.24s\n", 494 printf("att_time=%-26.24s\n",
495 shmds.shm_atime ? ctime(&shmds.shm_atime) : "Not set"); 495 shmds.shm_atime ? ctime(&shmds.shm_atime) : "Not set");
496 printf("det_time=%-26.24s\n", 496 printf("det_time=%-26.24s\n",
497 shmds.shm_dtime ? ctime(&shmds.shm_dtime) : "Not set"); 497 shmds.shm_dtime ? ctime(&shmds.shm_dtime) : "Not set");
498 printf("change_time=%-26.24s\n\n", ctime(&shmds.shm_ctime)); 498 printf("change_time=%-26.24s\n\n", ctime(&shmds.shm_ctime));
499} 499}
500 500
@@ -510,24 +510,24 @@ static void print_msg(int msqid)
510 } 510 }
511 511
512 printf("\nMessage Queue msqid=%d\n" 512 printf("\nMessage Queue msqid=%d\n"
513 "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n" 513 "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n"
514 "cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n", 514 "cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n",
515 msqid, ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode, 515 msqid, ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode,
516 /* 516 /*
517 * glibc-2.1.3 and earlier has unsigned short; 517 * glibc-2.1.3 and earlier has unsigned short;
518 * glibc-2.1.91 has variation between 518 * glibc-2.1.91 has variation between
519 * unsigned short, unsigned long 519 * unsigned short, unsigned long
520 * Austin has msgqnum_t (for msg_qbytes) 520 * Austin has msgqnum_t (for msg_qbytes)
521 */ 521 */
522 (long) buf.msg_cbytes, (long) buf.msg_qbytes, 522 (long) buf.msg_cbytes, (long) buf.msg_qbytes,
523 (long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid); 523 (long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid);
524 524
525 printf("send_time=%-26.24s\n", 525 printf("send_time=%-26.24s\n",
526 buf.msg_stime ? ctime(&buf.msg_stime) : "Not set"); 526 buf.msg_stime ? ctime(&buf.msg_stime) : "Not set");
527 printf("rcv_time=%-26.24s\n", 527 printf("rcv_time=%-26.24s\n",
528 buf.msg_rtime ? ctime(&buf.msg_rtime) : "Not set"); 528 buf.msg_rtime ? ctime(&buf.msg_rtime) : "Not set");
529 printf("change_time=%-26.24s\n\n", 529 printf("change_time=%-26.24s\n\n",
530 buf.msg_ctime ? ctime(&buf.msg_ctime) : "Not set"); 530 buf.msg_ctime ? ctime(&buf.msg_ctime) : "Not set");
531} 531}
532 532
533static void print_sem(int semid) 533static void print_sem(int semid)
@@ -544,19 +544,19 @@ static void print_sem(int semid)
544 } 544 }
545 545
546 printf("\nSemaphore Array semid=%d\n" 546 printf("\nSemaphore Array semid=%d\n"
547 "uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n" 547 "uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n"
548 "mode=%#o, access_perms=%#o\n" 548 "mode=%#o, access_perms=%#o\n"
549 "nsems = %ld\n" 549 "nsems = %ld\n"
550 "otime = %-26.24s\n", 550 "otime = %-26.24s\n",
551 semid, 551 semid,
552 ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, 552 ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
553 ipcp->mode, ipcp->mode & 0777, 553 ipcp->mode, ipcp->mode & 0777,
554 (long) semds.sem_nsems, 554 (long) semds.sem_nsems,
555 semds.sem_otime ? ctime(&semds.sem_otime) : "Not set"); 555 semds.sem_otime ? ctime(&semds.sem_otime) : "Not set");
556 printf("ctime = %-26.24s\n" 556 printf("ctime = %-26.24s\n"
557 "%-10s %-10s %-10s %-10s %-10s\n", 557 "%-10s %-10s %-10s %-10s %-10s\n",
558 ctime(&semds.sem_ctime), 558 ctime(&semds.sem_ctime),
559 "semnum", "value", "ncount", "zcount", "pid"); 559 "semnum", "value", "ncount", "zcount", "pid");
560 560
561 arg.val = 0; 561 arg.val = 0;
562 for (i = 0; i < semds.sem_nsems; i++) { 562 for (i = 0; i < semds.sem_nsems; i++) {
diff --git a/util-linux/lspci.c b/util-linux/lspci.c
index 5184858d1..514678afd 100644
--- a/util-linux/lspci.c
+++ b/util-linux/lspci.c
@@ -74,11 +74,11 @@ static int FAST_FUNC fileAction(
74 74
75 if (option_mask32 & OPT_m) { 75 if (option_mask32 & OPT_m) {
76 printf("%s \"Class %04x\" \"%04x\" \"%04x\" \"%04x\" \"%04x\"", 76 printf("%s \"Class %04x\" \"%04x\" \"%04x\" \"%04x\" \"%04x\"",
77 pci_slot_name, pci_class, pci_vid, pci_did, 77 pci_slot_name, pci_class, pci_vid, pci_did,
78 pci_subsys_vid, pci_subsys_did); 78 pci_subsys_vid, pci_subsys_did);
79 } else { 79 } else {
80 printf("%s Class %04x: %04x:%04x", 80 printf("%s Class %04x: %04x:%04x",
81 pci_slot_name, pci_class, pci_vid, pci_did); 81 pci_slot_name, pci_class, pci_vid, pci_did);
82 } 82 }
83 83
84 if ((option_mask32 & OPT_k) && driver) { 84 if ((option_mask32 & OPT_k) && driver) {
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index 79871d30e..c592ef687 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -429,6 +429,18 @@ static const struct rule *next_rule(void)
429 429
430#endif 430#endif
431 431
432static void mkdir_recursive(char *name)
433{
434 /* if name has many levels ("dir1/dir2"),
435 * bb_make_directory() will create dir1 according to umask,
436 * not according to its "mode" parameter.
437 * Since we run with umask=0, need to temporarily switch it.
438 */
439 umask(022); /* "dir1" (if any) will be 0755 too */
440 bb_make_directory(name, 0755, FILEUTILS_RECUR);
441 umask(0);
442}
443
432/* Builds an alias path. 444/* Builds an alias path.
433 * This function potentionally reallocates the alias parameter. 445 * This function potentionally reallocates the alias parameter.
434 * Only used for ENABLE_FEATURE_MDEV_RENAME 446 * Only used for ENABLE_FEATURE_MDEV_RENAME
@@ -442,7 +454,7 @@ static char *build_alias(char *alias, const char *device_name)
442 dest = strrchr(alias, '/'); 454 dest = strrchr(alias, '/');
443 if (dest) { /* ">bar/[baz]" ? */ 455 if (dest) { /* ">bar/[baz]" ? */
444 *dest = '\0'; /* mkdir bar */ 456 *dest = '\0'; /* mkdir bar */
445 bb_make_directory(alias, 0755, FILEUTILS_RECUR); 457 mkdir_recursive(alias);
446 *dest = '/'; 458 *dest = '/';
447 if (dest[1] == '\0') { /* ">bar/" => ">bar/device_name" */ 459 if (dest[1] == '\0') { /* ">bar/" => ">bar/device_name" */
448 dest = alias; 460 dest = alias;
@@ -641,7 +653,7 @@ static void make_device(char *device_name, char *path, int operation)
641 char *slash = strrchr(node_name, '/'); 653 char *slash = strrchr(node_name, '/');
642 if (slash) { 654 if (slash) {
643 *slash = '\0'; 655 *slash = '\0';
644 bb_make_directory(node_name, 0755, FILEUTILS_RECUR); 656 mkdir_recursive(node_name);
645 *slash = '/'; 657 *slash = '/';
646 } 658 }
647 if (G.verbose) 659 if (G.verbose)
@@ -649,6 +661,8 @@ static void make_device(char *device_name, char *path, int operation)
649 if (mknod(node_name, rule->mode | type, makedev(major, minor)) && errno != EEXIST) 661 if (mknod(node_name, rule->mode | type, makedev(major, minor)) && errno != EEXIST)
650 bb_perror_msg("can't create '%s'", node_name); 662 bb_perror_msg("can't create '%s'", node_name);
651 if (ENABLE_FEATURE_MDEV_CONF) { 663 if (ENABLE_FEATURE_MDEV_CONF) {
664 if (G.verbose)
665 bb_error_msg("chmod: %o chown: %u:%u", rule->mode, rule->ugid.uid, rule->ugid.gid);
652 chmod(node_name, rule->mode); 666 chmod(node_name, rule->mode);
653 chown(node_name, rule->ugid.uid, rule->ugid.gid); 667 chown(node_name, rule->ugid.uid, rule->ugid.gid);
654 } 668 }
@@ -801,6 +815,7 @@ static void load_firmware(const char *firmware, const char *sysfs_path)
801 full_write(loading_fd, "-1", 2); 815 full_write(loading_fd, "-1", 2);
802 816
803 out: 817 out:
818 xchdir("/dev");
804 if (ENABLE_FEATURE_CLEAN_UP) { 819 if (ENABLE_FEATURE_CLEAN_UP) {
805 close(firmware_fd); 820 close(firmware_fd);
806 close(loading_fd); 821 close(loading_fd);
@@ -907,11 +922,13 @@ int mdev_main(int argc UNUSED_PARAM, char **argv)
907 } 922 }
908 923
909 { 924 {
910 int logfd = open("/dev/mdev.log", O_WRONLY | O_APPEND); 925 int logfd = open("mdev.log", O_WRONLY | O_APPEND);
911 if (logfd >= 0) { 926 if (logfd >= 0) {
912 xmove_fd(logfd, STDERR_FILENO); 927 xmove_fd(logfd, STDERR_FILENO);
913 G.verbose = 1; 928 G.verbose = 1;
914 bb_error_msg("seq: %s action: %s", seq, action); 929 if (seq)
930 applet_name = xasprintf("%s[%s]", applet_name, seq);
931 bb_error_msg("action: %s", action);
915 } 932 }
916 } 933 }
917 934
diff --git a/util-linux/mount.c b/util-linux/mount.c
index 525fdcce9..62fd41fd7 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -36,6 +36,10 @@
36//usage: IF_FEATURE_MTAB_SUPPORT( 36//usage: IF_FEATURE_MTAB_SUPPORT(
37//usage: "\n -n Don't update /etc/mtab" 37//usage: "\n -n Don't update /etc/mtab"
38//usage: ) 38//usage: )
39//usage: IF_FEATURE_MOUNT_VERBOSE(
40//usage: "\n -v Verbose"
41//usage: )
42////usage: "\n -s Sloppy (ignored)"
39//usage: "\n -r Read-only mount" 43//usage: "\n -r Read-only mount"
40//usage: "\n -w Read-write mount (default)" 44//usage: "\n -w Read-write mount (default)"
41//usage: "\n -t FSTYPE[,...] Filesystem type(s)" 45//usage: "\n -t FSTYPE[,...] Filesystem type(s)"
@@ -224,7 +228,7 @@ static const int32_t mount_options[] = {
224 IF_DESKTOP(/* "user" */ MOUNT_USERS,) 228 IF_DESKTOP(/* "user" */ MOUNT_USERS,)
225 IF_DESKTOP(/* "users" */ MOUNT_USERS,) 229 IF_DESKTOP(/* "users" */ MOUNT_USERS,)
226 /* "_netdev" */ 0, 230 /* "_netdev" */ 0,
227 IF_DESKTOP(/* "comment" */ 0,) /* systemd uses this in fstab */ 231 IF_DESKTOP(/* "comment=" */ 0,) /* systemd uses this in fstab */
228 ) 232 )
229 233
230 IF_FEATURE_MOUNT_FLAGS( 234 IF_FEATURE_MOUNT_FLAGS(
@@ -283,7 +287,7 @@ static const char mount_option_str[] =
283 IF_DESKTOP("user\0") 287 IF_DESKTOP("user\0")
284 IF_DESKTOP("users\0") 288 IF_DESKTOP("users\0")
285 "_netdev\0" 289 "_netdev\0"
286 IF_DESKTOP("comment\0") /* systemd uses this in fstab */ 290 IF_DESKTOP("comment=\0") /* systemd uses this in fstab */
287 ) 291 )
288 IF_FEATURE_MOUNT_FLAGS( 292 IF_FEATURE_MOUNT_FLAGS(
289 // vfs flags 293 // vfs flags
@@ -475,10 +479,13 @@ static unsigned long parse_mount_options(char *options, char **unrecognized)
475// FIXME: use hasmntopt() 479// FIXME: use hasmntopt()
476 // Find this option in mount_options 480 // Find this option in mount_options
477 for (i = 0; i < ARRAY_SIZE(mount_options); i++) { 481 for (i = 0; i < ARRAY_SIZE(mount_options); i++) {
478 /* We support "option=" match for "comment=" thingy */
479 unsigned opt_len = strlen(option_str); 482 unsigned opt_len = strlen(option_str);
483
480 if (strncasecmp(option_str, options, opt_len) == 0 484 if (strncasecmp(option_str, options, opt_len) == 0
481 && (options[opt_len] == '\0' || options[opt_len] == '=') 485 && (options[opt_len] == '\0'
486 /* or is it "comment=" thingy in fstab? */
487 IF_FEATURE_MOUNT_FSTAB(IF_DESKTOP( || option_str[opt_len-1] == '=' ))
488 )
482 ) { 489 ) {
483 unsigned long fl = mount_options[i]; 490 unsigned long fl = mount_options[i];
484 if (fl & BB_MS_INVERTED_VALUE) 491 if (fl & BB_MS_INVERTED_VALUE)
@@ -927,7 +934,7 @@ static bool_t xdr_fhandle(XDR *xdrs, fhandle objp)
927static bool_t xdr_fhstatus(XDR *xdrs, fhstatus *objp) 934static bool_t xdr_fhstatus(XDR *xdrs, fhstatus *objp)
928{ 935{
929 if (!xdr_u_int(xdrs, &objp->fhs_status)) 936 if (!xdr_u_int(xdrs, &objp->fhs_status))
930 return FALSE; 937 return FALSE;
931 if (objp->fhs_status == 0) 938 if (objp->fhs_status == 0)
932 return xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle); 939 return xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle);
933 return TRUE; 940 return TRUE;
@@ -941,8 +948,8 @@ static bool_t xdr_dirpath(XDR *xdrs, dirpath *objp)
941static bool_t xdr_fhandle3(XDR *xdrs, fhandle3 *objp) 948static bool_t xdr_fhandle3(XDR *xdrs, fhandle3 *objp)
942{ 949{
943 return xdr_bytes(xdrs, (char **)&objp->fhandle3_val, 950 return xdr_bytes(xdrs, (char **)&objp->fhandle3_val,
944 (unsigned int *) &objp->fhandle3_len, 951 (unsigned int *) &objp->fhandle3_len,
945 FHSIZE3); 952 FHSIZE3);
946} 953}
947 954
948static bool_t xdr_mountres3_ok(XDR *xdrs, mountres3_ok *objp) 955static bool_t xdr_mountres3_ok(XDR *xdrs, mountres3_ok *objp)
@@ -950,10 +957,10 @@ static bool_t xdr_mountres3_ok(XDR *xdrs, mountres3_ok *objp)
950 if (!xdr_fhandle3(xdrs, &objp->fhandle)) 957 if (!xdr_fhandle3(xdrs, &objp->fhandle))
951 return FALSE; 958 return FALSE;
952 return xdr_array(xdrs, &(objp->auth_flavours.auth_flavours_val), 959 return xdr_array(xdrs, &(objp->auth_flavours.auth_flavours_val),
953 &(objp->auth_flavours.auth_flavours_len), 960 &(objp->auth_flavours.auth_flavours_len),
954 ~0, 961 ~0,
955 sizeof(int), 962 sizeof(int),
956 (xdrproc_t) xdr_int); 963 (xdrproc_t) xdr_int);
957} 964}
958 965
959static bool_t xdr_mountstat3(XDR *xdrs, mountstat3 *objp) 966static bool_t xdr_mountstat3(XDR *xdrs, mountstat3 *objp)
@@ -1522,19 +1529,19 @@ static NOINLINE int nfsmount(struct mntent *mp, unsigned long vfsflags, char *fi
1522 switch (pm_mnt.pm_prot) { 1529 switch (pm_mnt.pm_prot) {
1523 case IPPROTO_UDP: 1530 case IPPROTO_UDP:
1524 mclient = clntudp_create(&mount_server_addr, 1531 mclient = clntudp_create(&mount_server_addr,
1525 pm_mnt.pm_prog, 1532 pm_mnt.pm_prog,
1526 pm_mnt.pm_vers, 1533 pm_mnt.pm_vers,
1527 retry_timeout, 1534 retry_timeout,
1528 &msock); 1535 &msock);
1529 if (mclient) 1536 if (mclient)
1530 break; 1537 break;
1531 mount_server_addr.sin_port = htons(pm_mnt.pm_port); 1538 mount_server_addr.sin_port = htons(pm_mnt.pm_port);
1532 msock = RPC_ANYSOCK; 1539 msock = RPC_ANYSOCK;
1533 case IPPROTO_TCP: 1540 case IPPROTO_TCP:
1534 mclient = clnttcp_create(&mount_server_addr, 1541 mclient = clnttcp_create(&mount_server_addr,
1535 pm_mnt.pm_prog, 1542 pm_mnt.pm_prog,
1536 pm_mnt.pm_vers, 1543 pm_mnt.pm_vers,
1537 &msock, 0, 0); 1544 &msock, 0, 0);
1538 break; 1545 break;
1539 default: 1546 default:
1540 mclient = NULL; 1547 mclient = NULL;
@@ -1555,18 +1562,18 @@ static NOINLINE int nfsmount(struct mntent *mp, unsigned long vfsflags, char *fi
1555 1562
1556 if (pm_mnt.pm_vers == 3) 1563 if (pm_mnt.pm_vers == 3)
1557 clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT, 1564 clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT,
1558 (xdrproc_t) xdr_dirpath, 1565 (xdrproc_t) xdr_dirpath,
1559 (caddr_t) &pathname, 1566 (caddr_t) &pathname,
1560 (xdrproc_t) xdr_mountres3, 1567 (xdrproc_t) xdr_mountres3,
1561 (caddr_t) &status, 1568 (caddr_t) &status,
1562 total_timeout); 1569 total_timeout);
1563 else 1570 else
1564 clnt_stat = clnt_call(mclient, MOUNTPROC_MNT, 1571 clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
1565 (xdrproc_t) xdr_dirpath, 1572 (xdrproc_t) xdr_dirpath,
1566 (caddr_t) &pathname, 1573 (caddr_t) &pathname,
1567 (xdrproc_t) xdr_fhstatus, 1574 (xdrproc_t) xdr_fhstatus,
1568 (caddr_t) &status, 1575 (caddr_t) &status,
1569 total_timeout); 1576 total_timeout);
1570 1577
1571 if (clnt_stat == RPC_SUCCESS) 1578 if (clnt_stat == RPC_SUCCESS)
1572 goto prepare_kernel_data; /* we're done */ 1579 goto prepare_kernel_data; /* we're done */
@@ -1817,17 +1824,44 @@ static int singlemount(struct mntent *mp, int ignore_busy)
1817 ) { 1824 ) {
1818 int len; 1825 int len;
1819 char c; 1826 char c;
1827 char *hostname, *share;
1828 char *dotted, *ip;
1820 len_and_sockaddr *lsa; 1829 len_and_sockaddr *lsa;
1821 char *hostname, *dotted, *ip; 1830
1831 // Parse mp->mnt_fsname of the form "//hostname/share[/dir1/dir2]"
1822 1832
1823 hostname = mp->mnt_fsname + 2; 1833 hostname = mp->mnt_fsname + 2;
1824 len = strcspn(hostname, "/\\"); 1834 len = strcspn(hostname, "/\\");
1825 if (len == 0 || hostname[len] == '\0') 1835 share = hostname + len + 1;
1836 if (len == 0 // 3rd char is a [back]slash (IOW: empty hostname)
1837 || share[-1] == '\0' // no [back]slash after hostname
1838 || share[0] == '\0' // empty share name
1839 ) {
1826 goto report_error; 1840 goto report_error;
1827 c = hostname[len]; 1841 }
1828 hostname[len] = '\0'; 1842 c = share[-1];
1843 share[-1] = '\0';
1844 len = strcspn(share, "/\\");
1845
1846 // "unc=\\hostname\share" option is mandatory
1847 // after CIFS option parsing was rewritten in Linux 3.4.
1848 // Must use backslashes.
1849 // If /dir1/dir2 is present, also add "prefixpath=dir1/dir2"
1850 {
1851 char *unc = xasprintf(
1852 share[len] != '\0' /* "/dir1/dir2" exists? */
1853 ? "unc=\\\\%s\\%.*s,prefixpath=%s"
1854 : "unc=\\\\%s\\%.*s",
1855 hostname,
1856 len, share,
1857 share + len + 1 /* "dir1/dir2" */
1858 );
1859 parse_mount_options(unc, &filteropts);
1860 if (ENABLE_FEATURE_CLEAN_UP) free(unc);
1861 }
1862
1829 lsa = host2sockaddr(hostname, 0); 1863 lsa = host2sockaddr(hostname, 0);
1830 hostname[len] = c; 1864 share[-1] = c;
1831 if (!lsa) 1865 if (!lsa)
1832 goto report_error; 1866 goto report_error;
1833 1867
@@ -1839,8 +1873,6 @@ static int singlemount(struct mntent *mp, int ignore_busy)
1839 parse_mount_options(ip, &filteropts); 1873 parse_mount_options(ip, &filteropts);
1840 if (ENABLE_FEATURE_CLEAN_UP) free(ip); 1874 if (ENABLE_FEATURE_CLEAN_UP) free(ip);
1841 1875
1842 // "-o mand" is required [why?]
1843 vfsflags |= MS_MANDLOCK;
1844 mp->mnt_type = (char*)"cifs"; 1876 mp->mnt_type = (char*)"cifs";
1845 rc = mount_it_now(mp, vfsflags, filteropts); 1877 rc = mount_it_now(mp, vfsflags, filteropts);
1846 1878
diff --git a/util-linux/readprofile.c b/util-linux/readprofile.c
index 4ed801137..974fe89c4 100644
--- a/util-linux/readprofile.c
+++ b/util-linux/readprofile.c
@@ -163,7 +163,7 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv)
163 while (fgets(mapline, S_LEN, map)) { 163 while (fgets(mapline, S_LEN, map)) {
164 if (sscanf(mapline, "%llx %s %s", &fn_add, mode, fn_name) != 3) 164 if (sscanf(mapline, "%llx %s %s", &fn_add, mode, fn_name) != 3)
165 bb_error_msg_and_die("%s(%i): wrong map line", 165 bb_error_msg_and_die("%s(%i): wrong map line",
166 mapFile, maplineno); 166 mapFile, maplineno);
167 167
168 if (!strcmp(fn_name, "_stext")) /* only elf works like this */ { 168 if (!strcmp(fn_name, "_stext")) /* only elf works like this */ {
169 add0 = fn_add; 169 add0 = fn_add;
@@ -198,7 +198,7 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv)
198 198
199 if (indx >= len / sizeof(*buf)) 199 if (indx >= len / sizeof(*buf))
200 bb_error_msg_and_die("profile address out of range. " 200 bb_error_msg_and_die("profile address out of range. "
201 "Wrong map file?"); 201 "Wrong map file?");
202 202
203 while (indx < (next_add-add0)/step) { 203 while (indx < (next_add-add0)/step) {
204 if (optBins && (buf[indx] || optAll)) { 204 if (optBins && (buf[indx] || optAll)) {
@@ -220,10 +220,10 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv)
220 ) { 220 ) {
221 if (optVerbose) 221 if (optVerbose)
222 printf("%016llx %-40s %6i %8.4f\n", fn_add, 222 printf("%016llx %-40s %6i %8.4f\n", fn_add,
223 fn_name, this, this/(double)fn_len); 223 fn_name, this, this/(double)fn_len);
224 else 224 else
225 printf("%6i %-40s %8.4f\n", 225 printf("%6i %-40s %8.4f\n",
226 this, fn_name, this/(double)fn_len); 226 this, fn_name, this/(double)fn_len);
227 if (optSub) { 227 if (optSub) {
228 unsigned long long scan; 228 unsigned long long scan;
229 229
@@ -233,8 +233,8 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv)
233 233
234 addr = (scan - 1)*step + add0; 234 addr = (scan - 1)*step + add0;
235 printf("\t%#llx\t%s+%#llx\t%u\n", 235 printf("\t%#llx\t%s+%#llx\t%u\n",
236 addr, fn_name, addr - fn_add, 236 addr, fn_name, addr - fn_add,
237 buf[scan]); 237 buf[scan]);
238 } 238 }
239 } 239 }
240 } 240 }
@@ -251,10 +251,10 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv)
251 /* trailer */ 251 /* trailer */
252 if (optVerbose) 252 if (optVerbose)
253 printf("%016x %-40s %6i %8.4f\n", 253 printf("%016x %-40s %6i %8.4f\n",
254 0, "total", total, total/(double)(fn_add-add0)); 254 0, "total", total, total/(double)(fn_add-add0));
255 else 255 else
256 printf("%6i %-40s %8.4f\n", 256 printf("%6i %-40s %8.4f\n",
257 total, "total", total/(double)(fn_add-add0)); 257 total, "total", total/(double)(fn_add-add0));
258 258
259 fclose(map); 259 fclose(map);
260 free(buf); 260 free(buf);
diff --git a/util-linux/volume_id/hfs.c b/util-linux/volume_id/hfs.c
index f3f19dba7..3d9704d12 100644
--- a/util-linux/volume_id/hfs.c
+++ b/util-linux/volume_id/hfs.c
@@ -131,6 +131,27 @@ struct hfsplus_vol_header {
131#define HFS_NODE_LEAF 0xff 131#define HFS_NODE_LEAF 0xff
132#define HFSPLUS_POR_CNID 1 132#define HFSPLUS_POR_CNID 1
133 133
134static void FAST_FUNC hfs_set_uuid(struct volume_id *id, const uint8_t *hfs_id)
135{
136#define hfs_id_len 8
137 md5_ctx_t md5c;
138 uint8_t uuid[16];
139 unsigned i;
140
141 for (i = 0; i < hfs_id_len; i++)
142 if (hfs_id[i] != 0)
143 goto do_md5;
144 return;
145 do_md5:
146 md5_begin(&md5c);
147 md5_hash(&md5c, "\263\342\17\71\362\222\21\326\227\244\0\60\145\103\354\254", 16);
148 md5_hash(&md5c, hfs_id, hfs_id_len);
149 md5_end(&md5c, uuid);
150 uuid[6] = 0x30 | (uuid[6] & 0x0f);
151 uuid[8] = 0x80 | (uuid[8] & 0x3f);
152 volume_id_set_uuid(id, uuid, UUID_DCE);
153}
154
134int FAST_FUNC volume_id_probe_hfs_hfsplus(struct volume_id *id /*,uint64_t off*/) 155int FAST_FUNC volume_id_probe_hfs_hfsplus(struct volume_id *id /*,uint64_t off*/)
135{ 156{
136 uint64_t off = 0; 157 uint64_t off = 0;
@@ -193,7 +214,7 @@ int FAST_FUNC volume_id_probe_hfs_hfsplus(struct volume_id *id /*,uint64_t off*/
193 volume_id_set_label_string(id, hfs->label, hfs->label_len) ; 214 volume_id_set_label_string(id, hfs->label, hfs->label_len) ;
194 } 215 }
195 216
196 volume_id_set_uuid(id, hfs->finder_info.id, UUID_HFS); 217 hfs_set_uuid(id, hfs->finder_info.id);
197// volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); 218// volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
198 IF_FEATURE_BLKID_TYPE(id->type = "hfs";) 219 IF_FEATURE_BLKID_TYPE(id->type = "hfs";)
199 220
@@ -207,7 +228,7 @@ int FAST_FUNC volume_id_probe_hfs_hfsplus(struct volume_id *id /*,uint64_t off*/
207 return -1; 228 return -1;
208 229
209 hfsplus: 230 hfsplus:
210 volume_id_set_uuid(id, hfsplus->finder_info.id, UUID_HFS); 231 hfs_set_uuid(id, hfsplus->finder_info.id);
211 232
212 blocksize = be32_to_cpu(hfsplus->blocksize); 233 blocksize = be32_to_cpu(hfsplus->blocksize);
213 dbg("blocksize %u", blocksize); 234 dbg("blocksize %u", blocksize);
@@ -286,7 +307,7 @@ int FAST_FUNC volume_id_probe_hfs_hfsplus(struct volume_id *id /*,uint64_t off*/
286 307
287 found: 308 found:
288// volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); 309// volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
289// id->type = "hfsplus"; 310 IF_FEATURE_BLKID_TYPE(id->type = "hfsplus";)
290 311
291 return 0; 312 return 0;
292} 313}
diff --git a/util-linux/volume_id/linux_raid.c b/util-linux/volume_id/linux_raid.c
index 761e54f9f..209eaabe9 100644
--- a/util-linux/volume_id/linux_raid.c
+++ b/util-linux/volume_id/linux_raid.c
@@ -69,9 +69,9 @@ int FAST_FUNC volume_id_probe_linux_raid(struct volume_id *id /*,uint64_t off*/,
69 volume_id_set_uuid(id, uuid, UUID_DCE); 69 volume_id_set_uuid(id, uuid, UUID_DCE);
70 70
71// snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u.%u", 71// snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u.%u",
72// le32_to_cpu(mdp->major_version), 72// le32_to_cpu(mdp->major_version),
73// le32_to_cpu(mdp->minor_version), 73// le32_to_cpu(mdp->minor_version),
74// le32_to_cpu(mdp->patch_version)); 74// le32_to_cpu(mdp->patch_version));
75 75
76 dbg("found raid signature"); 76 dbg("found raid signature");
77// volume_id_set_usage(id, VOLUME_ID_RAID); 77// volume_id_set_usage(id, VOLUME_ID_RAID);
diff --git a/util-linux/volume_id/nilfs.c b/util-linux/volume_id/nilfs.c
index ffa86d43c..b88a9e435 100644
--- a/util-linux/volume_id/nilfs.c
+++ b/util-linux/volume_id/nilfs.c
@@ -86,7 +86,7 @@ int FAST_FUNC volume_id_probe_nilfs(struct volume_id *id /*,uint64_t off*/)
86 // When used it is at 4K from the end of the partition (sb->s_dev_size - NILFS_SB2_OFFSET). 86 // When used it is at 4K from the end of the partition (sb->s_dev_size - NILFS_SB2_OFFSET).
87 87
88 volume_id_set_label_string(id, sb->s_volume_name, NILFS_LABEL_SIZE < VOLUME_ID_LABEL_SIZE ? 88 volume_id_set_label_string(id, sb->s_volume_name, NILFS_LABEL_SIZE < VOLUME_ID_LABEL_SIZE ?
89 NILFS_LABEL_SIZE : VOLUME_ID_LABEL_SIZE); 89 NILFS_LABEL_SIZE : VOLUME_ID_LABEL_SIZE);
90 volume_id_set_uuid(id, sb->s_uuid, UUID_DCE); 90 volume_id_set_uuid(id, sb->s_uuid, UUID_DCE);
91 91
92 if (sb->s_rev_level == 2) 92 if (sb->s_rev_level == 2)
diff --git a/util-linux/volume_id/ntfs.c b/util-linux/volume_id/ntfs.c
index 547f141c9..7b2612f01 100644
--- a/util-linux/volume_id/ntfs.c
+++ b/util-linux/volume_id/ntfs.c
@@ -132,7 +132,7 @@ int FAST_FUNC volume_id_probe_ntfs(struct volume_id *id /*,uint64_t off*/)
132 dbg("mft record size %i", mft_record_size); 132 dbg("mft record size %i", mft_record_size);
133 133
134 buf = volume_id_get_buffer(id, off + mft_off + (MFT_RECORD_VOLUME * mft_record_size), 134 buf = volume_id_get_buffer(id, off + mft_off + (MFT_RECORD_VOLUME * mft_record_size),
135 mft_record_size); 135 mft_record_size);
136 if (buf == NULL) 136 if (buf == NULL)
137 goto found; 137 goto found;
138 138
@@ -165,7 +165,7 @@ int FAST_FUNC volume_id_probe_ntfs(struct volume_id *id /*,uint64_t off*/)
165 break; 165 break;
166 166
167 dbg("found attribute type 0x%x, len %i, at offset %i", 167 dbg("found attribute type 0x%x, len %i, at offset %i",
168 attr_type, attr_len, attr_off); 168 attr_type, attr_len, attr_off);
169 169
170// if (attr_type == MFT_RECORD_ATTR_VOLUME_INFO) { 170// if (attr_type == MFT_RECORD_ATTR_VOLUME_INFO) {
171// struct volume_info *info; 171// struct volume_info *info;
diff --git a/util-linux/volume_id/squashfs.c b/util-linux/volume_id/squashfs.c
new file mode 100644
index 000000000..c5b4f9ced
--- /dev/null
+++ b/util-linux/volume_id/squashfs.c
@@ -0,0 +1,49 @@
1/*
2 * volume_id - reads filesystem label and uuid
3 *
4 * Copyright (C) 2012 S-G Bergh <sgb@systemasis.org>
5 *
6 * Licensed under GPLv2, see file LICENSE in this source tree.
7 */
8
9//kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_SQUASHFS) += squashfs.o
10
11#include "volume_id_internal.h"
12
13struct squashfs_superblock {
14 uint32_t magic;
15/*
16 uint32_t dummy[6];
17 uint16_t major;
18 uint16_t minor;
19*/
20} PACKED;
21
22int FAST_FUNC volume_id_probe_squashfs(struct volume_id *id /*,uint64_t off*/)
23{
24#define off ((uint64_t)0)
25 struct squashfs_superblock *sb;
26
27 dbg("SquashFS: probing at offset 0x%llx", (unsigned long long) off);
28 sb = volume_id_get_buffer(id, off, 0x200);
29 if (!sb)
30 return -1;
31
32 // Old SquashFS (pre 4.0) can be both big and little endian, so test for both.
33 // Likewise, it is commonly used in firwmare with some non-standard signatures.
34#define pack(a,b,c,d) ( (uint32_t)((a * 256 + b) * 256 + c) * 256 + d )
35#define SIG1 pack('s','q','s','h')
36#define SIG2 pack('h','s','q','s')
37#define SIG3 pack('s','h','s','q')
38#define SIG4 pack('q','s','h','s')
39 if (sb->magic == SIG1
40 || sb->magic == SIG2
41 || sb->magic == SIG3
42 || sb->magic == SIG4
43 ) {
44 IF_FEATURE_BLKID_TYPE(id->type = "squashfs";)
45 return 0;
46 }
47
48 return -1;
49}
diff --git a/util-linux/volume_id/udf.c b/util-linux/volume_id/udf.c
index cd63c8d8a..d3747fb8e 100644
--- a/util-linux/volume_id/udf.c
+++ b/util-linux/volume_id/udf.c
@@ -109,7 +109,7 @@ nsr:
109 return -1; 109 return -1;
110 110
111 dbg("vsd: %c%c%c%c%c", 111 dbg("vsd: %c%c%c%c%c",
112 vsd->id[0], vsd->id[1], vsd->id[2], vsd->id[3], vsd->id[4]); 112 vsd->id[0], vsd->id[1], vsd->id[2], vsd->id[3], vsd->id[4]);
113 113
114 if (vsd->id[0] == '\0') 114 if (vsd->id[0] == '\0')
115 return -1; 115 return -1;
diff --git a/util-linux/volume_id/unused_msdos.c b/util-linux/volume_id/unused_msdos.c
index 65fb88501..2e8cb196a 100644
--- a/util-linux/volume_id/unused_msdos.c
+++ b/util-linux/volume_id/unused_msdos.c
@@ -109,7 +109,7 @@ int FAST_FUNC volume_id_probe_msdos_part_table(struct volume_id *id, uint64_t of
109 extended = off + poff; 109 extended = off + poff;
110 } else { 110 } else {
111 dbg("found 0x%x data partition at 0x%llx, len 0x%llx", 111 dbg("found 0x%x data partition at 0x%llx, len 0x%llx",
112 part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen); 112 part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen);
113 113
114// if (is_raid(part[i].sys_ind)) 114// if (is_raid(part[i].sys_ind))
115// volume_id_set_usage_part(p, VOLUME_ID_RAID); 115// volume_id_set_usage_part(p, VOLUME_ID_RAID);
diff --git a/util-linux/volume_id/unused_silicon_raid.c b/util-linux/volume_id/unused_silicon_raid.c
index d1c439ecf..878b88197 100644
--- a/util-linux/volume_id/unused_silicon_raid.c
+++ b/util-linux/volume_id/unused_silicon_raid.c
@@ -62,7 +62,7 @@ int FAST_FUNC volume_id_probe_silicon_medley_raid(struct volume_id *id, uint64_t
62 62
63// volume_id_set_usage(id, VOLUME_ID_RAID); 63// volume_id_set_usage(id, VOLUME_ID_RAID);
64// snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u", 64// snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u",
65// le16_to_cpu(sil->major_ver), le16_to_cpu(sil->minor_ver)); 65// le16_to_cpu(sil->major_ver), le16_to_cpu(sil->minor_ver));
66// id->type = "silicon_medley_raid_member"; 66// id->type = "silicon_medley_raid_member";
67 67
68 return 0; 68 return 0;
diff --git a/util-linux/volume_id/util.c b/util-linux/volume_id/util.c
index 69e43dda8..061545fde 100644
--- a/util-linux/volume_id/util.c
+++ b/util-linux/volume_id/util.c
@@ -129,30 +129,14 @@ void volume_id_set_label_string(struct volume_id *id, const uint8_t *buf, size_t
129 129
130void volume_id_set_label_unicode16(struct volume_id *id, const uint8_t *buf, enum endian endianess, size_t count) 130void volume_id_set_label_unicode16(struct volume_id *id, const uint8_t *buf, enum endian endianess, size_t count)
131{ 131{
132 volume_id_set_unicode16(id->label, sizeof(id->label), buf, endianess, count); 132 volume_id_set_unicode16(id->label, sizeof(id->label), buf, endianess, count);
133} 133}
134 134
135void volume_id_set_uuid(struct volume_id *id, const uint8_t *buf, enum uuid_format format) 135void volume_id_set_uuid(struct volume_id *id, const uint8_t *buf, enum uuid_format format)
136{ 136{
137 unsigned i; 137 unsigned i;
138 unsigned count = 0; 138 unsigned count = (format == UUID_DCE_STRING ? VOLUME_ID_UUID_SIZE : 4 << format);
139 139
140 switch (format) {
141 case UUID_DOS:
142 count = 4;
143 break;
144 case UUID_NTFS:
145 case UUID_HFS:
146 count = 8;
147 break;
148 case UUID_DCE:
149 count = 16;
150 break;
151 case UUID_DCE_STRING:
152 /* 36 is ok, id->uuid has one extra byte for NUL */
153 count = VOLUME_ID_UUID_SIZE;
154 break;
155 }
156// memcpy(id->uuid_raw, buf, count); 140// memcpy(id->uuid_raw, buf, count);
157// id->uuid_raw_len = count; 141// id->uuid_raw_len = count;
158 142
@@ -173,11 +157,6 @@ set:
173 buf[7], buf[6], buf[5], buf[4], 157 buf[7], buf[6], buf[5], buf[4],
174 buf[3], buf[2], buf[1], buf[0]); 158 buf[3], buf[2], buf[1], buf[0]);
175 break; 159 break;
176 case UUID_HFS:
177 sprintf(id->uuid, "%02X%02X%02X%02X%02X%02X%02X%02X",
178 buf[0], buf[1], buf[2], buf[3],
179 buf[4], buf[5], buf[6], buf[7]);
180 break;
181 case UUID_DCE: 160 case UUID_DCE:
182 sprintf(id->uuid, 161 sprintf(id->uuid,
183 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", 162 "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
diff --git a/util-linux/volume_id/volume_id.c b/util-linux/volume_id/volume_id.c
index 3c3c69818..f0fc84c05 100644
--- a/util-linux/volume_id/volume_id.c
+++ b/util-linux/volume_id/volume_id.c
@@ -99,6 +99,9 @@ static const probe_fptr fs1[] = {
99#if ENABLE_FEATURE_VOLUMEID_MAC 99#if ENABLE_FEATURE_VOLUMEID_MAC
100 volume_id_probe_mac_partition_map, 100 volume_id_probe_mac_partition_map,
101#endif 101#endif
102#if ENABLE_FEATURE_VOLUMEID_SQUASHFS
103 volume_id_probe_squashfs,
104#endif
102#if ENABLE_FEATURE_VOLUMEID_XFS 105#if ENABLE_FEATURE_VOLUMEID_XFS
103 volume_id_probe_xfs, 106 volume_id_probe_xfs,
104#endif 107#endif
diff --git a/util-linux/volume_id/volume_id_internal.h b/util-linux/volume_id/volume_id_internal.h
index 03dc46f27..3f02bd50d 100644
--- a/util-linux/volume_id/volume_id_internal.h
+++ b/util-linux/volume_id/volume_id_internal.h
@@ -136,12 +136,15 @@ void FAST_FUNC free_volume_id(struct volume_id *id);
136#define cpu_to_be32(x) (x) 136#define cpu_to_be32(x) (x)
137#endif 137#endif
138 138
139/* volume_id_set_uuid(id,buf,fmt) assumes size of uuid buf
140 * by shifting: 4 << fmt, except for fmt == UUID_DCE_STRING.
141 * The constants below should match sizes.
142 */
139enum uuid_format { 143enum uuid_format {
140 UUID_DCE_STRING, 144 UUID_DOS = 0, /* 4 bytes */
141 UUID_DCE, 145 UUID_NTFS = 1, /* 8 bytes */
142 UUID_DOS, 146 UUID_DCE = 2, /* 16 bytes */
143 UUID_NTFS, 147 UUID_DCE_STRING = 3, /* 36 bytes (VOLUME_ID_UUID_SIZE) */
144 UUID_HFS,
145}; 148};
146 149
147enum endian { 150enum endian {
@@ -224,6 +227,8 @@ int FAST_FUNC volume_id_probe_reiserfs(struct volume_id *id /*,uint64_t off*/);
224 227
225int FAST_FUNC volume_id_probe_romfs(struct volume_id *id /*,uint64_t off*/); 228int FAST_FUNC volume_id_probe_romfs(struct volume_id *id /*,uint64_t off*/);
226 229
230int FAST_FUNC volume_id_probe_squashfs(struct volume_id *id /*,uint64_t off*/);
231
227int FAST_FUNC volume_id_probe_sysv(struct volume_id *id /*,uint64_t off*/); 232int FAST_FUNC volume_id_probe_sysv(struct volume_id *id /*,uint64_t off*/);
228 233
229int FAST_FUNC volume_id_probe_udf(struct volume_id *id /*,uint64_t off*/); 234int FAST_FUNC volume_id_probe_udf(struct volume_id *id /*,uint64_t off*/);