aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2019-08-16 09:42:39 +0100
committerRon Yorston <rmy@pobox.com>2019-08-16 09:45:21 +0100
commit517cf74f6265ec4308b790b637b3f9778cbdc6e0 (patch)
treebe9337069b60ca1bb03565d8575bacfc71181003
parentae65dc37bcc9b1d9cef0b111131c79dc4ba1bf51 (diff)
parentac78f2ac96b3efd6551a08e7dc609efa1fb69481 (diff)
downloadbusybox-w32-517cf74f6265ec4308b790b637b3f9778cbdc6e0.tar.gz
busybox-w32-517cf74f6265ec4308b790b637b3f9778cbdc6e0.tar.bz2
busybox-w32-517cf74f6265ec4308b790b637b3f9778cbdc6e0.zip
Merge branch 'busybox' into merge
-rw-r--r--Config.in13
-rw-r--r--Makefile2
-rw-r--r--archival/bbunzip.c2
-rw-r--r--archival/bzip2.c4
-rw-r--r--archival/dpkg.c14
-rw-r--r--archival/gzip.c4
-rw-r--r--archival/libarchive/data_extract_all.c4
-rw-r--r--archival/libarchive/decompress_bunzip2.c2
-rw-r--r--archival/libarchive/decompress_gunzip.c14
-rw-r--r--archival/libarchive/decompress_uncompress.c10
-rw-r--r--archival/libarchive/decompress_unlzma.c6
-rw-r--r--archival/libarchive/decompress_unxz.c4
-rw-r--r--archival/libarchive/get_header_ar.c8
-rw-r--r--archival/libarchive/get_header_cpio.c6
-rw-r--r--archival/libarchive/get_header_tar.c14
-rw-r--r--archival/libarchive/open_transformer.c6
-rw-r--r--archival/libarchive/seek_by_jump.c2
-rw-r--r--archival/libarchive/unpack_ar_archive.c2
-rw-r--r--archival/lzop.c14
-rw-r--r--archival/rpm.c2
-rw-r--r--archival/tar.c101
-rw-r--r--archival/unzip.c18
-rw-r--r--console-tools/loadfont.c20
-rw-r--r--console-tools/loadkmap.c2
-rw-r--r--console-tools/openvt.c4
-rw-r--r--console-tools/showkey.c2
-rw-r--r--coreutils/cp.c4
-rw-r--r--coreutils/cut.c6
-rw-r--r--coreutils/date.c2
-rw-r--r--coreutils/df.c2
-rw-r--r--coreutils/echo.c2
-rw-r--r--coreutils/env.c2
-rw-r--r--coreutils/expand.c47
-rw-r--r--coreutils/expr.c16
-rw-r--r--coreutils/id.c2
-rw-r--r--coreutils/install.c2
-rw-r--r--coreutils/ln.c2
-rw-r--r--coreutils/logname.c2
-rw-r--r--coreutils/md5_sha1_sum.c2
-rw-r--r--coreutils/od_bloaty.c12
-rw-r--r--coreutils/paste.c2
-rw-r--r--coreutils/printf.c2
-rw-r--r--coreutils/rm.c2
-rw-r--r--coreutils/sort.c12
-rw-r--r--coreutils/split.c4
-rw-r--r--coreutils/stat.c75
-rw-r--r--coreutils/stty.c6
-rw-r--r--coreutils/tail.c4
-rw-r--r--coreutils/test.c4
-rw-r--r--coreutils/tr.c4
-rw-r--r--coreutils/uudecode.c8
-rw-r--r--coreutils/uuencode.c2
-rw-r--r--debianutils/start_stop_daemon.c22
-rw-r--r--e2fsprogs/chattr.c6
-rw-r--r--e2fsprogs/fsck.c6
-rw-r--r--editors/awk.c4
-rw-r--r--editors/diff.c4
-rw-r--r--editors/ed.c34
-rw-r--r--editors/patch_bbox.c6
-rw-r--r--editors/patch_toybox.c2
-rw-r--r--editors/sed.c18
-rw-r--r--editors/vi.c6
-rw-r--r--findutils/find.c4
-rw-r--r--findutils/xargs.c4
-rw-r--r--include/libbb.h54
-rw-r--r--init/bootchartd.c2
-rw-r--r--init/init.c2
-rw-r--r--libbb/appletlib.c10
-rw-r--r--libbb/bb_getgroups.c2
-rw-r--r--libbb/bbunit.c2
-rw-r--r--libbb/capability.c2
-rw-r--r--libbb/change_identity.c2
-rw-r--r--libbb/copy_file.c2
-rw-r--r--libbb/copyfd.c6
-rw-r--r--libbb/die_if_bad_username.c2
-rw-r--r--libbb/dump.c4
-rw-r--r--libbb/fflush_stdout_and_exit.c2
-rw-r--r--libbb/find_pid_by_name.c6
-rw-r--r--libbb/get_console.c2
-rw-r--r--libbb/get_volsize.c4
-rw-r--r--libbb/getpty.c6
-rw-r--r--libbb/herror_msg.c10
-rw-r--r--libbb/loop.c42
-rw-r--r--libbb/mtab.c4
-rw-r--r--libbb/perror_nomsg.c4
-rw-r--r--libbb/perror_nomsg_and_die.c4
-rw-r--r--libbb/pw_encrypt.c2
-rw-r--r--libbb/read_printf.c2
-rw-r--r--libbb/safe_poll.c2
-rw-r--r--libbb/selinux_common.c2
-rw-r--r--libbb/time.c2
-rw-r--r--libbb/unicode.c6
-rw-r--r--libbb/update_passwd.c12
-rw-r--r--libbb/uuencode.c2
-rw-r--r--libbb/verror_msg.c15
-rw-r--r--libbb/warn_ignoring_args.c2
-rw-r--r--libbb/xconnect.c40
-rw-r--r--libbb/xfuncs.c2
-rw-r--r--libbb/xfuncs_printf.c44
-rw-r--r--libbb/xgetcwd.c2
-rw-r--r--libbb/xgethostbyname.c2
-rw-r--r--libbb/xreadlink.c29
-rw-r--r--loginutils/addgroup.c2
-rw-r--r--loginutils/adduser.c4
-rw-r--r--loginutils/chpasswd.c4
-rw-r--r--loginutils/deluser.c2
-rw-r--r--loginutils/getty.c16
-rw-r--r--loginutils/login.c4
-rw-r--r--loginutils/su.c4
-rw-r--r--loginutils/sulogin.c8
-rw-r--r--mailutils/mail.c6
-rw-r--r--mailutils/popmaildir.c2
-rw-r--r--mailutils/sendmail.c2
-rw-r--r--miscutils/bc.c16
-rw-r--r--miscutils/chat.c2
-rw-r--r--miscutils/crond.c4
-rw-r--r--miscutils/crontab.c2
-rw-r--r--miscutils/dc.c4
-rw-r--r--miscutils/devfsd.c15
-rw-r--r--miscutils/devmem.c8
-rw-r--r--miscutils/fbsplash.c2
-rw-r--r--miscutils/flash_eraseall.c6
-rw-r--r--miscutils/hdparm.c12
-rw-r--r--miscutils/hexedit.c2
-rw-r--r--miscutils/i2c_tools.c44
-rw-r--r--miscutils/inotifyd.c2
-rw-r--r--miscutils/nandwrite.c10
-rw-r--r--miscutils/rfkill.c2
-rw-r--r--miscutils/rx.c6
-rw-r--r--miscutils/time.c2
-rw-r--r--miscutils/ubi_tools.c10
-rw-r--r--miscutils/ubirename.c2
-rw-r--r--modutils/modutils-24.c26
-rw-r--r--modutils/rmmod.c2
-rw-r--r--networking/arp.c36
-rw-r--r--networking/arping.c4
-rw-r--r--networking/brctl.c4
-rw-r--r--networking/dnsd.c8
-rw-r--r--networking/ether-wake.c4
-rw-r--r--networking/ftpgetput.c2
-rw-r--r--networking/hostname.c2
-rw-r--r--networking/httpd.c12
-rw-r--r--networking/ifconfig.c2
-rw-r--r--networking/ifplugd.c26
-rw-r--r--networking/ifupdown.c4
-rw-r--r--networking/inetd.c20
-rw-r--r--networking/ipcalc.c2
-rw-r--r--networking/isrv.c4
-rw-r--r--networking/libiproute/ipaddress.c10
-rw-r--r--networking/libiproute/ipneigh.c8
-rw-r--r--networking/libiproute/iproute.c12
-rw-r--r--networking/libiproute/iptunnel.c10
-rw-r--r--networking/libiproute/libnetlink.c30
-rw-r--r--networking/libiproute/utils.c2
-rw-r--r--networking/nbd-client.c10
-rw-r--r--networking/nc.c6
-rw-r--r--networking/nc_bloaty.c18
-rw-r--r--networking/netstat.c4
-rw-r--r--networking/nslookup.c2
-rw-r--r--networking/ntpd.c34
-rw-r--r--networking/ping.c16
-rw-r--r--networking/route.c6
-rw-r--r--networking/slattach.c4
-rw-r--r--networking/tcpudp.c6
-rw-r--r--networking/telnetd.c2
-rw-r--r--networking/tftp.c61
-rw-r--r--networking/tls.c14
-rw-r--r--networking/tls.h2
-rw-r--r--networking/traceroute.c6
-rw-r--r--networking/udhcp/Config.src2
-rw-r--r--networking/udhcp/arpping.c4
-rw-r--r--networking/udhcp/common.c2
-rw-r--r--networking/udhcp/common.h19
-rw-r--r--networking/udhcp/d6_common.h2
-rw-r--r--networking/udhcp/d6_dhcpc.c48
-rw-r--r--networking/udhcp/d6_packet.c4
-rw-r--r--networking/udhcp/d6_socket.c2
-rw-r--r--networking/udhcp/dhcpc.c73
-rw-r--r--networking/udhcp/dhcpd.c186
-rw-r--r--networking/udhcp/dhcpd.h8
-rw-r--r--networking/udhcp/dhcprelay.c4
-rw-r--r--networking/udhcp/packet.c4
-rw-r--r--networking/udhcp/signalpipe.c33
-rw-r--r--networking/udhcp/socket.c2
-rw-r--r--networking/wget.c22
-rw-r--r--networking/zcip.c6
-rw-r--r--printutils/lpd.c6
-rw-r--r--printutils/lpr.c12
-rw-r--r--procps/free.c30
-rw-r--r--procps/kill.c2
-rw-r--r--procps/mpstat.c2
-rw-r--r--procps/nmeter.c10
-rw-r--r--procps/powertop.c4
-rw-r--r--procps/pstree.c2
-rw-r--r--procps/top.c7
-rw-r--r--runit/chpst.c6
-rw-r--r--runit/svlogd.c2
-rw-r--r--selinux/chcon.c4
-rw-r--r--selinux/getenforce.c4
-rw-r--r--selinux/getsebool.c2
-rw-r--r--selinux/load_policy.c2
-rw-r--r--selinux/runcon.c6
-rw-r--r--selinux/sestatus.c2
-rw-r--r--selinux/setenforce.c2
-rw-r--r--selinux/setfiles.c2
-rw-r--r--selinux/setsebool.c2
-rw-r--r--shell/ash.c193
-rw-r--r--shell/hush.c45
-rw-r--r--shell/shell_common.c2
-rw-r--r--sysklogd/klogd.c2
-rw-r--r--sysklogd/logread.c2
-rw-r--r--sysklogd/syslogd.c10
-rwxr-xr-xtestsuite/awk.tests6
-rw-r--r--testsuite/expand/expand-works-like-GNU20
-rw-r--r--testsuite/unexpand/unexpand-works-like-GNU56
-rw-r--r--util-linux/acpid.c2
-rw-r--r--util-linux/blockdev.c12
-rw-r--r--util-linux/dmesg.c4
-rw-r--r--util-linux/eject.c2
-rw-r--r--util-linux/fdformat.c2
-rw-r--r--util-linux/fdisk.c2
-rw-r--r--util-linux/flock.c2
-rw-r--r--util-linux/fsck_minix.c2
-rw-r--r--util-linux/getopt.c6
-rw-r--r--util-linux/hwclock.c4
-rw-r--r--util-linux/ipcs.c8
-rw-r--r--util-linux/last.c2
-rw-r--r--util-linux/losetup.c37
-rw-r--r--util-linux/mdev.c270
-rw-r--r--util-linux/mesg.c2
-rw-r--r--util-linux/mkfs_ext2.c6
-rw-r--r--util-linux/mkfs_minix.c22
-rw-r--r--util-linux/mkfs_reiser.c2
-rw-r--r--util-linux/mkfs_vfat.c6
-rw-r--r--util-linux/mkswap.c2
-rw-r--r--util-linux/mount.c40
-rw-r--r--util-linux/nsenter.c2
-rw-r--r--util-linux/rdate.c6
-rw-r--r--util-linux/readprofile.c4
-rw-r--r--util-linux/rtcwake.c2
-rw-r--r--util-linux/setpriv.c8
-rw-r--r--util-linux/switch_root.c6
-rw-r--r--util-linux/uevent.c41
-rw-r--r--util-linux/unshare.c2
244 files changed, 1714 insertions, 1248 deletions
diff --git a/Config.in b/Config.in
index f6ad627b2..c60f38a8a 100644
--- a/Config.in
+++ b/Config.in
@@ -781,6 +781,19 @@ config WERROR
781 781
782 Most people should answer N. 782 Most people should answer N.
783 783
784config WARN_SIMPLE_MSG
785 bool "Warn about single parameter bb_xx_msg calls"
786 default n
787 help
788 This will cause warnings to be shown for any instances of
789 bb_error_msg(), bb_error_msg_and_die(), bb_perror_msg(),
790 bb_perror_msg_and_die(), bb_herror_msg() or bb_herror_msg_and_die()
791 being called with a single parameter. In these cases the equivalent
792 bb_simple_xx_msg function should be used instead.
793 Note that use of STRERROR_FMT may give false positives.
794
795 If you aren't developing busybox, say N here.
796
784choice 797choice
785 prompt "Additional debugging library" 798 prompt "Additional debugging library"
786 default NO_DEBUG_LIB 799 default NO_DEBUG_LIB
diff --git a/Makefile b/Makefile
index cb1a932b5..32f6dfae9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
1VERSION = 1 1VERSION = 1
2PATCHLEVEL = 31 2PATCHLEVEL = 32
3SUBLEVEL = 0 3SUBLEVEL = 0
4EXTRAVERSION = .git 4EXTRAVERSION = .git
5NAME = Unnamed 5NAME = Unnamed
diff --git a/archival/bbunzip.c b/archival/bbunzip.c
index bf99656e2..24033c9f5 100644
--- a/archival/bbunzip.c
+++ b/archival/bbunzip.c
@@ -114,7 +114,7 @@ int FAST_FUNC bbunpack(char **argv,
114 114
115 /* Check that the input is sane */ 115 /* Check that the input is sane */
116 if (!(option_mask32 & BBUNPK_OPT_FORCE) && isatty(STDIN_FILENO)) { 116 if (!(option_mask32 & BBUNPK_OPT_FORCE) && isatty(STDIN_FILENO)) {
117 bb_error_msg_and_die("compressed data not read from terminal, " 117 bb_simple_error_msg_and_die("compressed data not read from terminal, "
118 "use -f to force it"); 118 "use -f to force it");
119 } 119 }
120 120
diff --git a/archival/bzip2.c b/archival/bzip2.c
index 38cc0219a..d0390a92a 100644
--- a/archival/bzip2.c
+++ b/archival/bzip2.c
@@ -145,7 +145,7 @@ IF_DESKTOP(long long) int bz_write(bz_stream *strm, void* rbuf, ssize_t rlen, vo
145 if (n2 != n) { 145 if (n2 != n) {
146 if (n2 >= 0) 146 if (n2 >= 0)
147 errno = 0; /* prevent bogus error message */ 147 errno = 0; /* prevent bogus error message */
148 bb_perror_msg(n2 >= 0 ? "short write" : bb_msg_write_error); 148 bb_simple_perror_msg(n2 >= 0 ? "short write" : bb_msg_write_error);
149 return -1; 149 return -1;
150 } 150 }
151 } 151 }
@@ -187,7 +187,7 @@ IF_DESKTOP(long long) int FAST_FUNC compressStream(transformer_state_t *xstate U
187 while (1) { 187 while (1) {
188 count = full_read(STDIN_FILENO, rbuf, IOBUF_SIZE); 188 count = full_read(STDIN_FILENO, rbuf, IOBUF_SIZE);
189 if (count < 0) { 189 if (count < 0) {
190 bb_perror_msg(bb_msg_read_error); 190 bb_simple_perror_msg(bb_msg_read_error);
191 total = -1; 191 total = -1;
192 break; 192 break;
193 } 193 }
diff --git a/archival/dpkg.c b/archival/dpkg.c
index 08f15ad44..6f28b994c 100644
--- a/archival/dpkg.c
+++ b/archival/dpkg.c
@@ -492,7 +492,7 @@ static void add_split_dependencies(common_node_t *parent_node, const char *whole
492 } else if (strncmp(version, ">=", offset_ch) == 0) { 492 } else if (strncmp(version, ">=", offset_ch) == 0) {
493 edge->operator = VER_MORE_EQUAL; 493 edge->operator = VER_MORE_EQUAL;
494 } else { 494 } else {
495 bb_error_msg_and_die("illegal operator"); 495 bb_simple_error_msg_and_die("illegal operator");
496 } 496 }
497 } 497 }
498 /* skip to start of version numbers */ 498 /* skip to start of version numbers */
@@ -735,7 +735,7 @@ static void set_status(const unsigned status_node_num, const char *new_value, co
735 status = new_value_num; 735 status = new_value_num;
736 break; 736 break;
737 default: 737 default:
738 bb_error_msg_and_die("DEBUG ONLY: this shouldnt happen"); 738 bb_simple_error_msg_and_die("DEBUG ONLY: this shouldnt happen");
739 } 739 }
740 740
741 new_status = xasprintf("%s %s %s", name_hashtable[want], name_hashtable[flag], name_hashtable[status]); 741 new_status = xasprintf("%s %s %s", name_hashtable[want], name_hashtable[flag], name_hashtable[status]);
@@ -949,10 +949,10 @@ static void write_status_file(deb_file_t **deb_file)
949 /* Create a separate backfile to dpkg */ 949 /* Create a separate backfile to dpkg */
950 if (rename("/var/lib/dpkg/status", "/var/lib/dpkg/status.udeb.bak") == -1) { 950 if (rename("/var/lib/dpkg/status", "/var/lib/dpkg/status.udeb.bak") == -1) {
951 if (errno != ENOENT) 951 if (errno != ENOENT)
952 bb_error_msg_and_die("can't create backup status file"); 952 bb_simple_error_msg_and_die("can't create backup status file");
953 /* Its ok if renaming the status file fails because status 953 /* Its ok if renaming the status file fails because status
954 * file doesn't exist, maybe we are starting from scratch */ 954 * file doesn't exist, maybe we are starting from scratch */
955 bb_error_msg("no status file found, creating new one"); 955 bb_simple_error_msg("no status file found, creating new one");
956 } 956 }
957 957
958 xrename("/var/lib/dpkg/status.udeb", "/var/lib/dpkg/status"); 958 xrename("/var/lib/dpkg/status.udeb", "/var/lib/dpkg/status");
@@ -1845,7 +1845,7 @@ int dpkg_main(int argc UNUSED_PARAM, char **argv)
1845 init_archive_deb_control(archive_handle); 1845 init_archive_deb_control(archive_handle);
1846 deb_file[deb_count]->control_file = deb_extract_control_file_to_buffer(archive_handle, control_list); 1846 deb_file[deb_count]->control_file = deb_extract_control_file_to_buffer(archive_handle, control_list);
1847 if (deb_file[deb_count]->control_file == NULL) { 1847 if (deb_file[deb_count]->control_file == NULL) {
1848 bb_error_msg_and_die("can't extract control file"); 1848 bb_simple_error_msg_and_die("can't extract control file");
1849 } 1849 }
1850 deb_file[deb_count]->filename = xstrdup(argv[0]); 1850 deb_file[deb_count]->filename = xstrdup(argv[0]);
1851 package_num = fill_package_struct(deb_file[deb_count]->control_file); 1851 package_num = fill_package_struct(deb_file[deb_count]->control_file);
@@ -1908,13 +1908,13 @@ int dpkg_main(int argc UNUSED_PARAM, char **argv)
1908 argv++; 1908 argv++;
1909 } 1909 }
1910 if (!deb_count) 1910 if (!deb_count)
1911 bb_error_msg_and_die("no package files specified"); 1911 bb_simple_error_msg_and_die("no package files specified");
1912 deb_file[deb_count] = NULL; 1912 deb_file[deb_count] = NULL;
1913 1913
1914 /* Check that the deb file arguments are installable */ 1914 /* Check that the deb file arguments are installable */
1915 if (!(opt & OPT_force_ignore_depends)) { 1915 if (!(opt & OPT_force_ignore_depends)) {
1916 if (!check_deps(deb_file, 0 /*, deb_count*/)) { 1916 if (!check_deps(deb_file, 0 /*, deb_count*/)) {
1917 bb_error_msg_and_die("dependency check failed"); 1917 bb_simple_error_msg_and_die("dependency check failed");
1918 } 1918 }
1919 } 1919 }
1920 1920
diff --git a/archival/gzip.c b/archival/gzip.c
index 12c1df242..17341de45 100644
--- a/archival/gzip.c
+++ b/archival/gzip.c
@@ -99,7 +99,7 @@ aa: 85.1% -- replaced with aa.gz
99/* Diagnostic functions */ 99/* Diagnostic functions */
100#ifdef DEBUG 100#ifdef DEBUG
101static int verbose; 101static int verbose;
102# define Assert(cond,msg) { if (!(cond)) bb_error_msg(msg); } 102# define Assert(cond,msg) { if (!(cond)) bb_simple_error_msg(msg); }
103# define Trace(x) fprintf x 103# define Trace(x) fprintf x
104# define Tracev(x) {if (verbose) fprintf x; } 104# define Tracev(x) {if (verbose) fprintf x; }
105# define Tracevv(x) {if (verbose > 1) fprintf x; } 105# define Tracevv(x) {if (verbose > 1) fprintf x; }
@@ -787,7 +787,7 @@ static void check_match(IPos start, IPos match, int length)
787 /* check that the match is indeed a match */ 787 /* check that the match is indeed a match */
788 if (memcmp(G1.window + match, G1.window + start, length) != 0) { 788 if (memcmp(G1.window + match, G1.window + start, length) != 0) {
789 bb_error_msg(" start %d, match %d, length %d", start, match, length); 789 bb_error_msg(" start %d, match %d, length %d", start, match, length);
790 bb_error_msg("invalid match"); 790 bb_simple_error_msg("invalid match");
791 } 791 }
792 if (verbose > 1) { 792 if (verbose > 1) {
793 bb_error_msg("\\[%d,%d]", start - match, length); 793 bb_error_msg("\\[%d,%d]", start - match, length);
diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c
index 4c95db4a6..3142405a3 100644
--- a/archival/libarchive/data_extract_all.c
+++ b/archival/libarchive/data_extract_all.c
@@ -103,7 +103,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
103 struct stat existing_sb; 103 struct stat existing_sb;
104 if (lstat(dst_name, &existing_sb) == -1) { 104 if (lstat(dst_name, &existing_sb) == -1) {
105 if (errno != ENOENT) { 105 if (errno != ENOENT) {
106 bb_perror_msg_and_die("can't stat old file"); 106 bb_simple_perror_msg_and_die("can't stat old file");
107 } 107 }
108 } 108 }
109 else if (existing_sb.st_mtime >= file_header->mtime) { 109 else if (existing_sb.st_mtime >= file_header->mtime) {
@@ -207,7 +207,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
207 } 207 }
208 break; 208 break;
209 default: 209 default:
210 bb_error_msg_and_die("unrecognized file type"); 210 bb_simple_error_msg_and_die("unrecognized file type");
211 } 211 }
212 212
213 if (!S_ISLNK(file_header->mode)) { 213 if (!S_ISLNK(file_header->mode)) {
diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c
index 1f535b32a..42e2b4f88 100644
--- a/archival/libarchive/decompress_bunzip2.c
+++ b/archival/libarchive/decompress_bunzip2.c
@@ -817,7 +817,7 @@ unpack_bz2_stream(transformer_state_t *xstate)
817 break; 817 break;
818 } 818 }
819 if (bd->headerCRC != bd->totalCRC) { 819 if (bd->headerCRC != bd->totalCRC) {
820 bb_error_msg("CRC error"); 820 bb_simple_error_msg("CRC error");
821 break; 821 break;
822 } 822 }
823 823
diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c
index 32fcb6b51..cf07f71df 100644
--- a/archival/libarchive/decompress_gunzip.c
+++ b/archival/libarchive/decompress_gunzip.c
@@ -1012,7 +1012,7 @@ inflate_unzip_internal(STATE_PARAM transformer_state_t *xstate)
1012 error_msg = "corrupted data"; 1012 error_msg = "corrupted data";
1013 if (setjmp(error_jmp)) { 1013 if (setjmp(error_jmp)) {
1014 /* Error from deep inside zip machinery */ 1014 /* Error from deep inside zip machinery */
1015 bb_error_msg(error_msg); 1015 bb_simple_error_msg(error_msg);
1016 n = -1; 1016 n = -1;
1017 goto ret; 1017 goto ret;
1018 } 1018 }
@@ -1085,7 +1085,7 @@ static int top_up(STATE_PARAM unsigned n)
1085 bytebuffer_offset = 0; 1085 bytebuffer_offset = 0;
1086 bytebuffer_size = full_read(gunzip_src_fd, &bytebuffer[count], bytebuffer_max - count); 1086 bytebuffer_size = full_read(gunzip_src_fd, &bytebuffer[count], bytebuffer_max - count);
1087 if ((int)bytebuffer_size < 0) { 1087 if ((int)bytebuffer_size < 0) {
1088 bb_error_msg(bb_msg_read_error); 1088 bb_simple_error_msg(bb_msg_read_error);
1089 return 0; 1089 return 0;
1090 } 1090 }
1091 bytebuffer_size += count; 1091 bytebuffer_size += count;
@@ -1217,7 +1217,7 @@ unpack_gz_stream(transformer_state_t *xstate)
1217 1217
1218 if (full_read(xstate->src_fd, &magic2, 2) != 2) { 1218 if (full_read(xstate->src_fd, &magic2, 2) != 2) {
1219 bad_magic: 1219 bad_magic:
1220 bb_error_msg("invalid magic"); 1220 bb_simple_error_msg("invalid magic");
1221 return -1; 1221 return -1;
1222 } 1222 }
1223 if (magic2 == COMPRESS_MAGIC) { 1223 if (magic2 == COMPRESS_MAGIC) {
@@ -1239,7 +1239,7 @@ unpack_gz_stream(transformer_state_t *xstate)
1239 1239
1240 again: 1240 again:
1241 if (!check_header_gzip(PASS_STATE xstate)) { 1241 if (!check_header_gzip(PASS_STATE xstate)) {
1242 bb_error_msg("corrupted data"); 1242 bb_simple_error_msg("corrupted data");
1243 total = -1; 1243 total = -1;
1244 goto ret; 1244 goto ret;
1245 } 1245 }
@@ -1252,7 +1252,7 @@ unpack_gz_stream(transformer_state_t *xstate)
1252 total += n; 1252 total += n;
1253 1253
1254 if (!top_up(PASS_STATE 8)) { 1254 if (!top_up(PASS_STATE 8)) {
1255 bb_error_msg("corrupted data"); 1255 bb_simple_error_msg("corrupted data");
1256 total = -1; 1256 total = -1;
1257 goto ret; 1257 goto ret;
1258 } 1258 }
@@ -1260,7 +1260,7 @@ unpack_gz_stream(transformer_state_t *xstate)
1260 /* Validate decompression - crc */ 1260 /* Validate decompression - crc */
1261 v32 = buffer_read_le_u32(PASS_STATE_ONLY); 1261 v32 = buffer_read_le_u32(PASS_STATE_ONLY);
1262 if ((~gunzip_crc) != v32) { 1262 if ((~gunzip_crc) != v32) {
1263 bb_error_msg("crc error"); 1263 bb_simple_error_msg("crc error");
1264 total = -1; 1264 total = -1;
1265 goto ret; 1265 goto ret;
1266 } 1266 }
@@ -1268,7 +1268,7 @@ unpack_gz_stream(transformer_state_t *xstate)
1268 /* Validate decompression - size */ 1268 /* Validate decompression - size */
1269 v32 = buffer_read_le_u32(PASS_STATE_ONLY); 1269 v32 = buffer_read_le_u32(PASS_STATE_ONLY);
1270 if ((uint32_t)gunzip_bytes_out != v32) { 1270 if ((uint32_t)gunzip_bytes_out != v32) {
1271 bb_error_msg("incorrect length"); 1271 bb_simple_error_msg("incorrect length");
1272 total = -1; 1272 total = -1;
1273 } 1273 }
1274 1274
diff --git a/archival/libarchive/decompress_uncompress.c b/archival/libarchive/decompress_uncompress.c
index 1517559c6..2725a7f09 100644
--- a/archival/libarchive/decompress_uncompress.c
+++ b/archival/libarchive/decompress_uncompress.c
@@ -113,7 +113,7 @@ unpack_Z_stream(transformer_state_t *xstate)
113 /* xread isn't good here, we have to return - caller may want 113 /* xread isn't good here, we have to return - caller may want
114 * to do some cleanup (e.g. delete incomplete unpacked file etc) */ 114 * to do some cleanup (e.g. delete incomplete unpacked file etc) */
115 if (full_read(xstate->src_fd, inbuf, 1) != 1) { 115 if (full_read(xstate->src_fd, inbuf, 1) != 1) {
116 bb_error_msg("short read"); 116 bb_simple_error_msg("short read");
117 goto err; 117 goto err;
118 } 118 }
119 119
@@ -166,7 +166,7 @@ unpack_Z_stream(transformer_state_t *xstate)
166 if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { 166 if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) {
167 rsize = safe_read(xstate->src_fd, inbuf + insize, IBUFSIZ); 167 rsize = safe_read(xstate->src_fd, inbuf + insize, IBUFSIZ);
168 if (rsize < 0) 168 if (rsize < 0)
169 bb_error_msg_and_die(bb_msg_read_error); 169 bb_simple_error_msg_and_die(bb_msg_read_error);
170 insize += rsize; 170 insize += rsize;
171 } 171 }
172 172
@@ -200,7 +200,7 @@ unpack_Z_stream(transformer_state_t *xstate)
200 200
201 if (oldcode == -1) { 201 if (oldcode == -1) {
202 if (code >= 256) 202 if (code >= 256)
203 bb_error_msg_and_die("corrupted data"); /* %ld", code); */ 203 bb_simple_error_msg_and_die("corrupted data"); /* %ld", code); */
204 oldcode = code; 204 oldcode = code;
205 finchar = (int) oldcode; 205 finchar = (int) oldcode;
206 outbuf[outpos++] = (unsigned char) finchar; 206 outbuf[outpos++] = (unsigned char) finchar;
@@ -236,7 +236,7 @@ unpack_Z_stream(transformer_state_t *xstate)
236 insize, posbits, p[-1], p[0], p[1], p[2], p[3], 236 insize, posbits, p[-1], p[0], p[1], p[2], p[3],
237 (posbits & 07)); 237 (posbits & 07));
238*/ 238*/
239 bb_error_msg("corrupted data"); 239 bb_simple_error_msg("corrupted data");
240 goto err; 240 goto err;
241 } 241 }
242 242
@@ -247,7 +247,7 @@ unpack_Z_stream(transformer_state_t *xstate)
247 /* Generate output characters in reverse order */ 247 /* Generate output characters in reverse order */
248 while (code >= 256) { 248 while (code >= 256) {
249 if (stackp <= &htabof(0)) 249 if (stackp <= &htabof(0))
250 bb_error_msg_and_die("corrupted data"); 250 bb_simple_error_msg_and_die("corrupted data");
251 *--stackp = tab_suffixof(code); 251 *--stackp = tab_suffixof(code);
252 code = tab_prefixof(code); 252 code = tab_prefixof(code);
253 } 253 }
diff --git a/archival/libarchive/decompress_unlzma.c b/archival/libarchive/decompress_unlzma.c
index 668b01618..0744f231a 100644
--- a/archival/libarchive/decompress_unlzma.c
+++ b/archival/libarchive/decompress_unlzma.c
@@ -59,7 +59,7 @@ static void rc_read(rc_t *rc)
59//TODO: return -1 instead 59//TODO: return -1 instead
60//This will make unlzma delete broken unpacked file on unpack errors 60//This will make unlzma delete broken unpacked file on unpack errors
61 if (buffer_size <= 0) 61 if (buffer_size <= 0)
62 bb_error_msg_and_die("unexpected EOF"); 62 bb_simple_error_msg_and_die("unexpected EOF");
63 rc->buffer_end = RC_BUFFER + buffer_size; 63 rc->buffer_end = RC_BUFFER + buffer_size;
64 rc->ptr = RC_BUFFER; 64 rc->ptr = RC_BUFFER;
65} 65}
@@ -234,7 +234,7 @@ unpack_lzma_stream(transformer_state_t *xstate)
234 if (full_read(xstate->src_fd, &header, sizeof(header)) != sizeof(header) 234 if (full_read(xstate->src_fd, &header, sizeof(header)) != sizeof(header)
235 || header.pos >= (9 * 5 * 5) 235 || header.pos >= (9 * 5 * 5)
236 ) { 236 ) {
237 bb_error_msg("bad lzma header"); 237 bb_simple_error_msg("bad lzma header");
238 return -1; 238 return -1;
239 } 239 }
240 240
@@ -513,7 +513,7 @@ unpack_lzma_stream(transformer_state_t *xstate)
513 * potentially more detailed information). 513 * potentially more detailed information).
514 * Do not fail silently. 514 * Do not fail silently.
515 */ 515 */
516 bb_error_msg("corrupted data"); 516 bb_simple_error_msg("corrupted data");
517 total_written = -1; /* failure */ 517 total_written = -1; /* failure */
518 } 518 }
519 rc_free(rc); 519 rc_free(rc);
diff --git a/archival/libarchive/decompress_unxz.c b/archival/libarchive/decompress_unxz.c
index 8ae7a275b..f03341384 100644
--- a/archival/libarchive/decompress_unxz.c
+++ b/archival/libarchive/decompress_unxz.c
@@ -74,7 +74,7 @@ unpack_xz_stream(transformer_state_t *xstate)
74 if (iobuf.in_pos == iobuf.in_size) { 74 if (iobuf.in_pos == iobuf.in_size) {
75 int rd = safe_read(xstate->src_fd, membuf, BUFSIZ); 75 int rd = safe_read(xstate->src_fd, membuf, BUFSIZ);
76 if (rd < 0) { 76 if (rd < 0) {
77 bb_error_msg(bb_msg_read_error); 77 bb_simple_error_msg(bb_msg_read_error);
78 total = -1; 78 total = -1;
79 break; 79 break;
80 } 80 }
@@ -123,7 +123,7 @@ unpack_xz_stream(transformer_state_t *xstate)
123 continue; 123 continue;
124 } 124 }
125 if (xz_result != XZ_OK && xz_result != XZ_UNSUPPORTED_CHECK) { 125 if (xz_result != XZ_OK && xz_result != XZ_UNSUPPORTED_CHECK) {
126 bb_error_msg("corrupted data"); 126 bb_simple_error_msg("corrupted data");
127 total = -1; 127 total = -1;
128 break; 128 break;
129 } 129 }
diff --git a/archival/libarchive/get_header_ar.c b/archival/libarchive/get_header_ar.c
index 7ce9c615c..b6ecd596c 100644
--- a/archival/libarchive/get_header_ar.c
+++ b/archival/libarchive/get_header_ar.c
@@ -22,7 +22,7 @@ static unsigned read_num(char *str, int base, int len)
22 * on misformatted numbers bb_strtou returns all-ones */ 22 * on misformatted numbers bb_strtou returns all-ones */
23 err = bb_strtou(str, NULL, base); 23 err = bb_strtou(str, NULL, base);
24 if (err == -1) 24 if (err == -1)
25 bb_error_msg_and_die("invalid ar header"); 25 bb_simple_error_msg_and_die("invalid ar header");
26 return err; 26 return err;
27} 27}
28 28
@@ -53,7 +53,7 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle)
53 archive_handle->offset += 60; 53 archive_handle->offset += 60;
54 54
55 if (ar.formatted.magic[0] != '`' || ar.formatted.magic[1] != '\n') 55 if (ar.formatted.magic[0] != '`' || ar.formatted.magic[1] != '\n')
56 bb_error_msg_and_die("invalid ar header"); 56 bb_simple_error_msg_and_die("invalid ar header");
57 57
58 /* 58 /*
59 * Note that the fields MUST be read in reverse order as 59 * Note that the fields MUST be read in reverse order as
@@ -86,7 +86,7 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle)
86 return get_header_ar(archive_handle); 86 return get_header_ar(archive_handle);
87 } 87 }
88#else 88#else
89 bb_error_msg_and_die("long filenames not supported"); 89 bb_simple_error_msg_and_die("long filenames not supported");
90#endif 90#endif
91 } 91 }
92 /* Only size is always present, the rest may be missing in 92 /* Only size is always present, the rest may be missing in
@@ -107,7 +107,7 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle)
107 long_offset = read_num(&ar.formatted.name[1], 10, 107 long_offset = read_num(&ar.formatted.name[1], 10,
108 sizeof(ar.formatted.name) - 1); 108 sizeof(ar.formatted.name) - 1);
109 if (long_offset >= archive_handle->ar__long_name_size) { 109 if (long_offset >= archive_handle->ar__long_name_size) {
110 bb_error_msg_and_die("can't resolve long filename"); 110 bb_simple_error_msg_and_die("can't resolve long filename");
111 } 111 }
112 typed->name = xstrdup(archive_handle->ar__long_names + long_offset); 112 typed->name = xstrdup(archive_handle->ar__long_names + long_offset);
113 } else 113 } else
diff --git a/archival/libarchive/get_header_cpio.c b/archival/libarchive/get_header_cpio.c
index 75fc6a406..4ad174732 100644
--- a/archival/libarchive/get_header_cpio.c
+++ b/archival/libarchive/get_header_cpio.c
@@ -33,14 +33,14 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle)
33 goto create_hardlinks; 33 goto create_hardlinks;
34 } 34 }
35 if (size != 110) { 35 if (size != 110) {
36 bb_error_msg_and_die("short read"); 36 bb_simple_error_msg_and_die("short read");
37 } 37 }
38 archive_handle->offset += 110; 38 archive_handle->offset += 110;
39 39
40 if (!is_prefixed_with(&cpio_header[0], "07070") 40 if (!is_prefixed_with(&cpio_header[0], "07070")
41 || (cpio_header[5] != '1' && cpio_header[5] != '2') 41 || (cpio_header[5] != '1' && cpio_header[5] != '2')
42 ) { 42 ) {
43 bb_error_msg_and_die("unsupported cpio format, use newc or crc"); 43 bb_simple_error_msg_and_die("unsupported cpio format, use newc or crc");
44 } 44 }
45 45
46 if (sscanf(cpio_header + 6, 46 if (sscanf(cpio_header + 6,
@@ -50,7 +50,7 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle)
50 &inode, &mode, &uid, &gid, 50 &inode, &mode, &uid, &gid,
51 &nlink, &mtime, &size, 51 &nlink, &mtime, &size,
52 &major, &minor, &namesize) != 10) 52 &major, &minor, &namesize) != 10)
53 bb_error_msg_and_die("damaged cpio file"); 53 bb_simple_error_msg_and_die("damaged cpio file");
54 file_header->mode = mode; 54 file_header->mode = mode;
55 /* "cpio -R USER:GRP" support: */ 55 /* "cpio -R USER:GRP" support: */
56 if (archive_handle->cpio__owner.uid != (uid_t)-1L) 56 if (archive_handle->cpio__owner.uid != (uid_t)-1L)
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c
index 52fa4554a..b3131ff2d 100644
--- a/archival/libarchive/get_header_tar.c
+++ b/archival/libarchive/get_header_tar.c
@@ -32,7 +32,7 @@ static unsigned long long getOctal(char *str, int len)
32 if (*end != '\0' && *end != ' ') { 32 if (*end != '\0' && *end != ' ') {
33 int8_t first = str[0]; 33 int8_t first = str[0];
34 if (!(first & 0x80)) 34 if (!(first & 0x80))
35 bb_error_msg_and_die("corrupted octal value in tar header"); 35 bb_simple_error_msg_and_die("corrupted octal value in tar header");
36 /* 36 /*
37 * GNU tar uses "base-256 encoding" for very large numbers. 37 * GNU tar uses "base-256 encoding" for very large numbers.
38 * Encoding is binary, with highest bit always set as a marker 38 * Encoding is binary, with highest bit always set as a marker
@@ -100,7 +100,7 @@ static void process_pax_hdr(archive_handle_t *archive_handle, unsigned sz, int g
100 || errno != EINVAL 100 || errno != EINVAL
101 || *end != ' ' 101 || *end != ' '
102 ) { 102 ) {
103 bb_error_msg("malformed extended header, skipped"); 103 bb_simple_error_msg("malformed extended header, skipped");
104 // More verbose version: 104 // More verbose version:
105 //bb_error_msg("malformed extended header at %"OFF_FMT"d, skipped", 105 //bb_error_msg("malformed extended header at %"OFF_FMT"d, skipped",
106 // archive_handle->offset - (sz + len)); 106 // archive_handle->offset - (sz + len));
@@ -194,13 +194,13 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
194 * the very first read fails. Grrr. 194 * the very first read fails. Grrr.
195 */ 195 */
196 if (archive_handle->offset == 0) 196 if (archive_handle->offset == 0)
197 bb_error_msg("short read"); 197 bb_simple_error_msg("short read");
198 /* this merely signals end of archive, not exit(1): */ 198 /* this merely signals end of archive, not exit(1): */
199 return EXIT_FAILURE; 199 return EXIT_FAILURE;
200 } 200 }
201 if (i != 512) { 201 if (i != 512) {
202 IF_FEATURE_TAR_AUTODETECT(goto autodetect;) 202 IF_FEATURE_TAR_AUTODETECT(goto autodetect;)
203 bb_error_msg_and_die("short read"); 203 bb_simple_error_msg_and_die("short read");
204 } 204 }
205 205
206#else 206#else
@@ -243,11 +243,11 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
243 goto err; 243 goto err;
244 if (setup_unzip_on_fd(archive_handle->src_fd, /*fail_if_not_compressed:*/ 0) != 0) 244 if (setup_unzip_on_fd(archive_handle->src_fd, /*fail_if_not_compressed:*/ 0) != 0)
245 err: 245 err:
246 bb_error_msg_and_die("invalid tar magic"); 246 bb_simple_error_msg_and_die("invalid tar magic");
247 archive_handle->offset = 0; 247 archive_handle->offset = 0;
248 goto again_after_align; 248 goto again_after_align;
249#endif 249#endif
250 bb_error_msg_and_die("invalid tar magic"); 250 bb_simple_error_msg_and_die("invalid tar magic");
251 } 251 }
252 252
253 /* Do checksum on headers. 253 /* Do checksum on headers.
@@ -282,7 +282,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
282 if (sum_u != sum 282 if (sum_u != sum
283 IF_FEATURE_TAR_OLDSUN_COMPATIBILITY(&& sum_s != sum) 283 IF_FEATURE_TAR_OLDSUN_COMPATIBILITY(&& sum_s != sum)
284 ) { 284 ) {
285 bb_error_msg_and_die("invalid tar header checksum"); 285 bb_simple_error_msg_and_die("invalid tar header checksum");
286 } 286 }
287 287
288 /* GET_OCTAL trashes subsequent field, therefore we call it 288 /* GET_OCTAL trashes subsequent field, therefore we call it
diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c
index 3a0fc4712..1ac72af79 100644
--- a/archival/libarchive/open_transformer.c
+++ b/archival/libarchive/open_transformer.c
@@ -15,7 +15,7 @@ int FAST_FUNC check_signature16(transformer_state_t *xstate, unsigned magic16)
15 if (!xstate->signature_skipped) { 15 if (!xstate->signature_skipped) {
16 uint16_t magic2; 16 uint16_t magic2;
17 if (full_read(xstate->src_fd, &magic2, 2) != 2 || magic2 != magic16) { 17 if (full_read(xstate->src_fd, &magic2, 2) != 2 || magic2 != magic16) {
18 bb_error_msg("invalid magic"); 18 bb_simple_error_msg("invalid magic");
19 return -1; 19 return -1;
20 } 20 }
21 xstate->signature_skipped = 2; 21 xstate->signature_skipped = 2;
@@ -46,7 +46,7 @@ ssize_t FAST_FUNC transformer_write(transformer_state_t *xstate, const void *buf
46 } else { 46 } else {
47 nwrote = full_write(xstate->dst_fd, buf, bufsize); 47 nwrote = full_write(xstate->dst_fd, buf, bufsize);
48 if (nwrote != (ssize_t)bufsize) { 48 if (nwrote != (ssize_t)bufsize) {
49 bb_perror_msg("write"); 49 bb_simple_perror_msg("write");
50 nwrote = -1; 50 nwrote = -1;
51 goto ret; 51 goto ret;
52 } 52 }
@@ -226,7 +226,7 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_comp
226 226
227 /* No known magic seen */ 227 /* No known magic seen */
228 if (fail_if_not_compressed) 228 if (fail_if_not_compressed)
229 bb_error_msg_and_die("no gzip" 229 bb_simple_error_msg_and_die("no gzip"
230 IF_FEATURE_SEAMLESS_BZ2("/bzip2") 230 IF_FEATURE_SEAMLESS_BZ2("/bzip2")
231 IF_FEATURE_SEAMLESS_XZ("/xz") 231 IF_FEATURE_SEAMLESS_XZ("/xz")
232 " magic"); 232 " magic");
diff --git a/archival/libarchive/seek_by_jump.c b/archival/libarchive/seek_by_jump.c
index 232d97e53..dddaa3732 100644
--- a/archival/libarchive/seek_by_jump.c
+++ b/archival/libarchive/seek_by_jump.c
@@ -13,6 +13,6 @@ void FAST_FUNC seek_by_jump(int fd, off_t amount)
13 if (errno == ESPIPE) 13 if (errno == ESPIPE)
14 seek_by_read(fd, amount); 14 seek_by_read(fd, amount);
15 else 15 else
16 bb_perror_msg_and_die("seek failure"); 16 bb_simple_perror_msg_and_die("seek failure");
17 } 17 }
18} 18}
diff --git a/archival/libarchive/unpack_ar_archive.c b/archival/libarchive/unpack_ar_archive.c
index 4f9f89874..584c18ce8 100644
--- a/archival/libarchive/unpack_ar_archive.c
+++ b/archival/libarchive/unpack_ar_archive.c
@@ -12,7 +12,7 @@ void FAST_FUNC unpack_ar_archive(archive_handle_t *ar_archive)
12 12
13 xread(ar_archive->src_fd, magic, AR_MAGIC_LEN); 13 xread(ar_archive->src_fd, magic, AR_MAGIC_LEN);
14 if (!is_prefixed_with(magic, AR_MAGIC)) { 14 if (!is_prefixed_with(magic, AR_MAGIC)) {
15 bb_error_msg_and_die("invalid ar magic"); 15 bb_simple_error_msg_and_die("invalid ar magic");
16 } 16 }
17 ar_archive->offset += AR_MAGIC_LEN; 17 ar_archive->offset += AR_MAGIC_LEN;
18 18
diff --git a/archival/lzop.c b/archival/lzop.c
index 585632c4e..bdd21598c 100644
--- a/archival/lzop.c
+++ b/archival/lzop.c
@@ -752,7 +752,7 @@ static FAST_FUNC void lzo_check(
752 */ 752 */
753 uint32_t c = fn(init, buf, len); 753 uint32_t c = fn(init, buf, len);
754 if (c != ref) 754 if (c != ref)
755 bb_error_msg_and_die("checksum error"); 755 bb_simple_error_msg_and_die("checksum error");
756} 756}
757 757
758/**********************************************************************/ 758/**********************************************************************/
@@ -785,15 +785,15 @@ static NOINLINE int lzo_decompress(uint32_t h_flags32)
785 /* error if split file */ 785 /* error if split file */
786 if (dst_len == 0xffffffffL) 786 if (dst_len == 0xffffffffL)
787 /* should not happen - not yet implemented */ 787 /* should not happen - not yet implemented */
788 bb_error_msg_and_die("this file is a split lzop file"); 788 bb_simple_error_msg_and_die("this file is a split lzop file");
789 789
790 if (dst_len > MAX_BLOCK_SIZE) 790 if (dst_len > MAX_BLOCK_SIZE)
791 bb_error_msg_and_die("corrupted data"); 791 bb_simple_error_msg_and_die("corrupted data");
792 792
793 /* read compressed block size */ 793 /* read compressed block size */
794 src_len = read32(); 794 src_len = read32();
795 if (src_len <= 0 || src_len > dst_len) 795 if (src_len <= 0 || src_len > dst_len)
796 bb_error_msg_and_die("corrupted data"); 796 bb_simple_error_msg_and_die("corrupted data");
797 797
798 if (dst_len > block_size) { 798 if (dst_len > block_size) {
799 if (b2) { 799 if (b2) {
@@ -846,7 +846,7 @@ static NOINLINE int lzo_decompress(uint32_t h_flags32)
846 r = lzo1x_decompress_safe(b1, src_len, b2, &d /*, NULL*/); 846 r = lzo1x_decompress_safe(b1, src_len, b2, &d /*, NULL*/);
847 847
848 if (r != 0 /*LZO_E_OK*/ || dst_len != d) { 848 if (r != 0 /*LZO_E_OK*/ || dst_len != d) {
849 bb_error_msg_and_die("corrupted data"); 849 bb_simple_error_msg_and_die("corrupted data");
850 } 850 }
851 dst = b2; 851 dst = b2;
852 } else { 852 } else {
@@ -913,7 +913,7 @@ static void check_magic(void)
913 unsigned char magic[sizeof(lzop_magic)]; 913 unsigned char magic[sizeof(lzop_magic)];
914 xread(0, magic, sizeof(magic)); 914 xread(0, magic, sizeof(magic));
915 if (memcmp(magic, lzop_magic, sizeof(lzop_magic)) != 0) 915 if (memcmp(magic, lzop_magic, sizeof(lzop_magic)) != 0)
916 bb_error_msg_and_die("bad magic number"); 916 bb_simple_error_msg_and_die("bad magic number");
917} 917}
918 918
919/**********************************************************************/ 919/**********************************************************************/
@@ -1049,7 +1049,7 @@ static void lzo_set_method(header_t *h)
1049 else if (option_mask32 & OPT_8) 1049 else if (option_mask32 & OPT_8)
1050 level = 8; 1050 level = 8;
1051#else 1051#else
1052 bb_error_msg_and_die("high compression not compiled in"); 1052 bb_simple_error_msg_and_die("high compression not compiled in");
1053#endif 1053#endif
1054 } 1054 }
1055 1055
diff --git a/archival/rpm.c b/archival/rpm.c
index c9e8785e2..0d8f641b9 100644
--- a/archival/rpm.c
+++ b/archival/rpm.c
@@ -555,7 +555,7 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv)
555 } 555 }
556 556
557 if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0) 557 if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0)
558 bb_error_msg_and_die("error unpacking"); 558 bb_simple_error_msg_and_die("error unpacking");
559 559
560 if (ENABLE_FEATURE_CLEAN_UP) { 560 if (ENABLE_FEATURE_CLEAN_UP) {
561 close(rpm_fd); 561 close(rpm_fd);
diff --git a/archival/tar.c b/archival/tar.c
index 54961ff07..6618c9ecc 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -234,7 +234,7 @@ static HardLinkInfo *findHardLinkInfo(HardLinkInfo *hlInfo, struct stat *statbuf
234} 234}
235 235
236/* Put an octal string into the specified buffer. 236/* Put an octal string into the specified buffer.
237 * The number is zero padded and possibly null terminated. 237 * The number is zero padded and possibly NUL terminated.
238 * Stores low-order bits only if whole value does not fit. */ 238 * Stores low-order bits only if whole value does not fit. */
239static void putOctal(char *cp, int len, off_t value) 239static void putOctal(char *cp, int len, off_t value)
240{ 240{
@@ -285,31 +285,32 @@ static void chksum_and_xwrite(int fd, struct tar_header_t* hp)
285# if ENABLE_FEATURE_TAR_GNU_EXTENSIONS 285# if ENABLE_FEATURE_TAR_GNU_EXTENSIONS
286static void writeLongname(int fd, int type, const char *name, int dir) 286static void writeLongname(int fd, int type, const char *name, int dir)
287{ 287{
288 static const struct { 288 struct prefilled {
289 char mode[8]; /* 100-107 */ 289 char mode[8]; /* 100-107 */
290 char uid[8]; /* 108-115 */ 290 char uid[8]; /* 108-115 */
291 char gid[8]; /* 116-123 */ 291 char gid[8]; /* 116-123 */
292 char size[12]; /* 124-135 */ 292 char size[12]; /* 124-135 */
293 char mtime[12]; /* 136-147 */ 293 char mtime[12]; /* 136-147 */
294 } prefilled = {
295 "0000000",
296 "0000000",
297 "0000000",
298 "00000000000",
299 "00000000000",
300 }; 294 };
301 struct tar_header_t header; 295 struct tar_header_t header;
302 int size; 296 int size;
303 297
298 memset(&header, 0, sizeof(header));
299 header.typeflag = type;
300 strcpy(header.name, "././@LongLink");
301 /* This sets mode/uid/gid/mtime to "00...00<NUL>" strings */
302 memset(header.mode, '0', sizeof(struct prefilled));
303 header.mode [sizeof(header.mode ) - 1] = '\0';
304 header.uid [sizeof(header.uid ) - 1] = '\0';
305 header.gid [sizeof(header.gid ) - 1] = '\0';
306 /* header.size is filled by '0' now, will be corrected below */
307 header.mtime[sizeof(header.mtime) - 1] = '\0';
308
304 dir = !!dir; /* normalize: 0/1 */ 309 dir = !!dir; /* normalize: 0/1 */
305 size = strlen(name) + 1 + dir; /* GNU tar uses strlen+1 */ 310 size = strlen(name) + 1 + dir; /* GNU tar uses strlen+1 */
306 /* + dir: account for possible '/' */ 311 /* + dir: account for possible '/' */
307 312
308 memset(&header, 0, sizeof(header));
309 strcpy(header.name, "././@LongLink");
310 memcpy(header.mode, prefilled.mode, sizeof(prefilled));
311 PUT_OCTAL(header.size, size); 313 PUT_OCTAL(header.size, size);
312 header.typeflag = type;
313 chksum_and_xwrite(fd, &header); 314 chksum_and_xwrite(fd, &header);
314 315
315 /* Write filename[/] and pad the block. */ 316 /* Write filename[/] and pad the block. */
@@ -371,7 +372,7 @@ static int writeTarHeader(struct TarBallInfo *tbInfo,
371 /* If it is larger than 100 bytes, bail out */ 372 /* If it is larger than 100 bytes, bail out */
372 if (header.linkname[sizeof(header.linkname)-1]) { 373 if (header.linkname[sizeof(header.linkname)-1]) {
373 free(lpath); 374 free(lpath);
374 bb_error_msg("names longer than "NAME_SIZE_STR" chars not supported"); 375 bb_simple_error_msg("names longer than "NAME_SIZE_STR" chars not supported");
375 return FALSE; 376 return FALSE;
376 } 377 }
377# endif 378# endif
@@ -550,7 +551,7 @@ static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statb
550 551
551# if !ENABLE_FEATURE_TAR_GNU_EXTENSIONS 552# if !ENABLE_FEATURE_TAR_GNU_EXTENSIONS
552 if (strlen(header_name) >= NAME_SIZE) { 553 if (strlen(header_name) >= NAME_SIZE) {
553 bb_error_msg("names longer than "NAME_SIZE_STR" chars not supported"); 554 bb_simple_error_msg("names longer than "NAME_SIZE_STR" chars not supported");
554 return TRUE; 555 return TRUE;
555 } 556 }
556# endif 557# endif
@@ -645,8 +646,14 @@ static void NOINLINE vfork_compressor(int tar_fd, const char *gzip)
645 } 646 }
646 xmove_fd(data.rd, 0); 647 xmove_fd(data.rd, 0);
647 xmove_fd(tfd, 1); 648 xmove_fd(tfd, 1);
648 /* exec gzip/bzip2 program/applet */ 649
649 BB_EXECLP(gzip, gzip, "-f", (char *)0); 650 /* exec gzip/bzip2/... program */
651 //BB_EXECLP(gzip, gzip, "-f", (char *)0); - WRONG for "xz",
652 // if xz is an enabled applet, it'll be a version which
653 // can only decompress. We do need to execute external
654 // program, not applet.
655 execlp(gzip, gzip, "-f", (char *)0);
656
650 vfork_exec_errno = errno; 657 vfork_exec_errno = errno;
651 _exit(EXIT_FAILURE); 658 _exit(EXIT_FAILURE);
652 } 659 }
@@ -748,17 +755,17 @@ static NOINLINE int writeTarFile(
748 freeHardLinkInfo(&tbInfo->hlInfoHead); 755 freeHardLinkInfo(&tbInfo->hlInfoHead);
749 756
750 if (errorFlag) 757 if (errorFlag)
751 bb_error_msg("error exit delayed from previous errors"); 758 bb_simple_error_msg("error exit delayed from previous errors");
752 759
753# if SEAMLESS_COMPRESSION 760# if SEAMLESS_COMPRESSION
754 if (gzip) { 761 if (gzip) {
755 int status; 762 int status;
756#if !ENABLE_PLATFORM_MINGW32 763# if !ENABLE_PLATFORM_MINGW32
757 if (safe_waitpid(-1, &status, 0) == -1) 764 if (safe_waitpid(-1, &status, 0) == -1)
758#else 765# else
759 if (safe_waitpid(pid, &status, 0) == -1) 766 if (safe_waitpid(pid, &status, 0) == -1)
760#endif 767# endif
761 bb_perror_msg("waitpid"); 768 bb_simple_perror_msg("waitpid");
762 else if (!WIFEXITED(status) || WEXITSTATUS(status)) 769 else if (!WIFEXITED(status) || WEXITSTATUS(status))
763 /* gzip was killed or has exited with nonzero! */ 770 /* gzip was killed or has exited with nonzero! */
764 errorFlag = TRUE; 771 errorFlag = TRUE;
@@ -798,7 +805,7 @@ static llist_t *append_file_list_to_list(llist_t *list)
798//usage: IF_FEATURE_SEAMLESS_GZ("z") 805//usage: IF_FEATURE_SEAMLESS_GZ("z")
799//usage: IF_FEATURE_SEAMLESS_XZ("J") 806//usage: IF_FEATURE_SEAMLESS_XZ("J")
800//usage: IF_FEATURE_SEAMLESS_BZ2("j") 807//usage: IF_FEATURE_SEAMLESS_BZ2("j")
801//usage: IF_FEATURE_SEAMLESS_LZMA("a") 808//usage: "a"
802//usage: IF_FEATURE_TAR_CREATE("h") 809//usage: IF_FEATURE_TAR_CREATE("h")
803//usage: IF_FEATURE_TAR_NOPRESERVE_TIME("m") 810//usage: IF_FEATURE_TAR_NOPRESERVE_TIME("m")
804//usage: "vokO] " 811//usage: "vokO] "
@@ -837,9 +844,7 @@ static llist_t *append_file_list_to_list(llist_t *list)
837//usage: IF_FEATURE_SEAMLESS_BZ2( 844//usage: IF_FEATURE_SEAMLESS_BZ2(
838//usage: "\n -j (De)compress using bzip2" 845//usage: "\n -j (De)compress using bzip2"
839//usage: ) 846//usage: )
840//usage: IF_FEATURE_SEAMLESS_LZMA( 847//usage: "\n -a (De)compress based on extension"
841//usage: "\n -a (De)compress using lzma"
842//usage: )
843//usage: IF_FEATURE_TAR_CREATE( 848//usage: IF_FEATURE_TAR_CREATE(
844//usage: "\n -h Follow symlinks" 849//usage: "\n -h Follow symlinks"
845//usage: ) 850//usage: )
@@ -856,6 +861,7 @@ static llist_t *append_file_list_to_list(llist_t *list)
856//usage: "$ tar -cf /tmp/tarball.tar /usr/local\n" 861//usage: "$ tar -cf /tmp/tarball.tar /usr/local\n"
857 862
858// Supported but aren't in --help: 863// Supported but aren't in --help:
864// lzma
859// no-recursion 865// no-recursion
860// numeric-owner 866// numeric-owner
861// no-same-permissions 867// no-same-permissions
@@ -869,15 +875,16 @@ enum {
869 IF_FEATURE_TAR_CREATE( OPTBIT_CREATE ,) 875 IF_FEATURE_TAR_CREATE( OPTBIT_CREATE ,)
870 IF_FEATURE_TAR_CREATE( OPTBIT_DEREFERENCE ,) 876 IF_FEATURE_TAR_CREATE( OPTBIT_DEREFERENCE ,)
871 IF_FEATURE_SEAMLESS_BZ2( OPTBIT_BZIP2 ,) 877 IF_FEATURE_SEAMLESS_BZ2( OPTBIT_BZIP2 ,)
872 IF_FEATURE_SEAMLESS_LZMA(OPTBIT_LZMA ,)
873 IF_FEATURE_TAR_FROM( OPTBIT_INCLUDE_FROM,) 878 IF_FEATURE_TAR_FROM( OPTBIT_INCLUDE_FROM,)
874 IF_FEATURE_TAR_FROM( OPTBIT_EXCLUDE_FROM,) 879 IF_FEATURE_TAR_FROM( OPTBIT_EXCLUDE_FROM,)
875 IF_FEATURE_SEAMLESS_GZ( OPTBIT_GZIP ,) 880 IF_FEATURE_SEAMLESS_GZ( OPTBIT_GZIP ,)
876 IF_FEATURE_SEAMLESS_XZ( OPTBIT_XZ ,) // 16th bit 881 IF_FEATURE_SEAMLESS_XZ( OPTBIT_XZ ,)
877 IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) 882 IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) // 16th bit
883 OPTBIT_AUTOCOMPRESS_BY_EXT,
878 IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) 884 IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,)
879#if ENABLE_FEATURE_TAR_LONG_OPTIONS 885#if ENABLE_FEATURE_TAR_LONG_OPTIONS
880 OPTBIT_STRIP_COMPONENTS, 886 OPTBIT_STRIP_COMPONENTS,
887 IF_FEATURE_SEAMLESS_LZMA(OPTBIT_LZMA ,)
881 OPTBIT_NORECURSION, 888 OPTBIT_NORECURSION,
882 IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,) 889 IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,)
883 OPTBIT_NUMERIC_OWNER, 890 OPTBIT_NUMERIC_OWNER,
@@ -896,14 +903,15 @@ enum {
896 OPT_CREATE = IF_FEATURE_TAR_CREATE( (1 << OPTBIT_CREATE )) + 0, // c 903 OPT_CREATE = IF_FEATURE_TAR_CREATE( (1 << OPTBIT_CREATE )) + 0, // c
897 OPT_DEREFERENCE = IF_FEATURE_TAR_CREATE( (1 << OPTBIT_DEREFERENCE )) + 0, // h 904 OPT_DEREFERENCE = IF_FEATURE_TAR_CREATE( (1 << OPTBIT_DEREFERENCE )) + 0, // h
898 OPT_BZIP2 = IF_FEATURE_SEAMLESS_BZ2( (1 << OPTBIT_BZIP2 )) + 0, // j 905 OPT_BZIP2 = IF_FEATURE_SEAMLESS_BZ2( (1 << OPTBIT_BZIP2 )) + 0, // j
899 OPT_LZMA = IF_FEATURE_SEAMLESS_LZMA((1 << OPTBIT_LZMA )) + 0, // a
900 OPT_INCLUDE_FROM = IF_FEATURE_TAR_FROM( (1 << OPTBIT_INCLUDE_FROM)) + 0, // T 906 OPT_INCLUDE_FROM = IF_FEATURE_TAR_FROM( (1 << OPTBIT_INCLUDE_FROM)) + 0, // T
901 OPT_EXCLUDE_FROM = IF_FEATURE_TAR_FROM( (1 << OPTBIT_EXCLUDE_FROM)) + 0, // X 907 OPT_EXCLUDE_FROM = IF_FEATURE_TAR_FROM( (1 << OPTBIT_EXCLUDE_FROM)) + 0, // X
902 OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z 908 OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z
903 OPT_XZ = IF_FEATURE_SEAMLESS_XZ( (1 << OPTBIT_XZ )) + 0, // J 909 OPT_XZ = IF_FEATURE_SEAMLESS_XZ( (1 << OPTBIT_XZ )) + 0, // J
904 OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z 910 OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z
911 OPT_AUTOCOMPRESS_BY_EXT = 1 << OPTBIT_AUTOCOMPRESS_BY_EXT, // a
905 OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m 912 OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m
906 OPT_STRIP_COMPONENTS = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_STRIP_COMPONENTS)) + 0, // strip-components 913 OPT_STRIP_COMPONENTS = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_STRIP_COMPONENTS)) + 0, // strip-components
914 OPT_LZMA = IF_FEATURE_TAR_LONG_OPTIONS(IF_FEATURE_SEAMLESS_LZMA((1 << OPTBIT_LZMA))) + 0, // lzma
907 OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion 915 OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion
908 OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command 916 OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command
909 OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner 917 OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner
@@ -933,9 +941,6 @@ static const char tar_longopts[] ALIGN1 =
933# if ENABLE_FEATURE_SEAMLESS_BZ2 941# if ENABLE_FEATURE_SEAMLESS_BZ2
934 "bzip2\0" No_argument "j" 942 "bzip2\0" No_argument "j"
935# endif 943# endif
936# if ENABLE_FEATURE_SEAMLESS_LZMA
937 "lzma\0" No_argument "a"
938# endif
939# if ENABLE_FEATURE_TAR_FROM 944# if ENABLE_FEATURE_TAR_FROM
940 "files-from\0" Required_argument "T" 945 "files-from\0" Required_argument "T"
941 "exclude-from\0" Required_argument "X" 946 "exclude-from\0" Required_argument "X"
@@ -949,10 +954,14 @@ static const char tar_longopts[] ALIGN1 =
949# if ENABLE_FEATURE_SEAMLESS_Z 954# if ENABLE_FEATURE_SEAMLESS_Z
950 "compress\0" No_argument "Z" 955 "compress\0" No_argument "Z"
951# endif 956# endif
957 "auto-compress\0" No_argument "a"
952# if ENABLE_FEATURE_TAR_NOPRESERVE_TIME 958# if ENABLE_FEATURE_TAR_NOPRESERVE_TIME
953 "touch\0" No_argument "m" 959 "touch\0" No_argument "m"
954# endif 960# endif
955 "strip-components\0" Required_argument "\xf9" 961 "strip-components\0" Required_argument "\xf8"
962# if ENABLE_FEATURE_SEAMLESS_LZMA
963 "lzma\0" No_argument "\xf9"
964# endif
956 "no-recursion\0" No_argument "\xfa" 965 "no-recursion\0" No_argument "\xfa"
957# if ENABLE_FEATURE_TAR_TO_COMMAND 966# if ENABLE_FEATURE_TAR_TO_COMMAND
958 "to-command\0" Required_argument "\xfb" 967 "to-command\0" Required_argument "\xfb"
@@ -1041,13 +1050,13 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
1041 "txC:f:Oopvk" 1050 "txC:f:Oopvk"
1042 IF_FEATURE_TAR_CREATE( "ch" ) 1051 IF_FEATURE_TAR_CREATE( "ch" )
1043 IF_FEATURE_SEAMLESS_BZ2( "j" ) 1052 IF_FEATURE_SEAMLESS_BZ2( "j" )
1044 IF_FEATURE_SEAMLESS_LZMA("a" )
1045 IF_FEATURE_TAR_FROM( "T:*X:*") 1053 IF_FEATURE_TAR_FROM( "T:*X:*")
1046 IF_FEATURE_SEAMLESS_GZ( "z" ) 1054 IF_FEATURE_SEAMLESS_GZ( "z" )
1047 IF_FEATURE_SEAMLESS_XZ( "J" ) 1055 IF_FEATURE_SEAMLESS_XZ( "J" )
1048 IF_FEATURE_SEAMLESS_Z( "Z" ) 1056 IF_FEATURE_SEAMLESS_Z( "Z" )
1057 "a"
1049 IF_FEATURE_TAR_NOPRESERVE_TIME("m") 1058 IF_FEATURE_TAR_NOPRESERVE_TIME("m")
1050 IF_FEATURE_TAR_LONG_OPTIONS("\xf9:") // --strip-components 1059 IF_FEATURE_TAR_LONG_OPTIONS("\xf8:") // --strip-components
1051 "\0" 1060 "\0"
1052 "tt:vv:" // count -t,-v 1061 "tt:vv:" // count -t,-v
1053#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM 1062#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
@@ -1076,7 +1085,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
1076 ); 1085 );
1077#if DBG_OPTION_PARSING 1086#if DBG_OPTION_PARSING
1078 bb_error_msg("opt: 0x%08x", opt); 1087 bb_error_msg("opt: 0x%08x", opt);
1079# define showopt(o) bb_error_msg("opt & %s(%x): %x", #o, o, opt & o); 1088# define showopt(o) bb_error_msg("opt & %s(%x):\t%x", #o, o, opt & o);
1080 showopt(OPT_TEST ); 1089 showopt(OPT_TEST );
1081 showopt(OPT_EXTRACT ); 1090 showopt(OPT_EXTRACT );
1082 showopt(OPT_BASEDIR ); 1091 showopt(OPT_BASEDIR );
@@ -1089,14 +1098,15 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
1089 showopt(OPT_CREATE ); 1098 showopt(OPT_CREATE );
1090 showopt(OPT_DEREFERENCE ); 1099 showopt(OPT_DEREFERENCE );
1091 showopt(OPT_BZIP2 ); 1100 showopt(OPT_BZIP2 );
1092 showopt(OPT_LZMA );
1093 showopt(OPT_INCLUDE_FROM ); 1101 showopt(OPT_INCLUDE_FROM );
1094 showopt(OPT_EXCLUDE_FROM ); 1102 showopt(OPT_EXCLUDE_FROM );
1095 showopt(OPT_GZIP ); 1103 showopt(OPT_GZIP );
1096 showopt(OPT_XZ ); 1104 showopt(OPT_XZ );
1097 showopt(OPT_COMPRESS ); 1105 showopt(OPT_COMPRESS );
1106 showopt(OPT_AUTOCOMPRESS_BY_EXT);
1098 showopt(OPT_NOPRESERVE_TIME ); 1107 showopt(OPT_NOPRESERVE_TIME );
1099 showopt(OPT_STRIP_COMPONENTS); 1108 showopt(OPT_STRIP_COMPONENTS);
1109 showopt(OPT_LZMA );
1100 showopt(OPT_NORECURSION ); 1110 showopt(OPT_NORECURSION );
1101 showopt(OPT_2COMMAND ); 1111 showopt(OPT_2COMMAND );
1102 showopt(OPT_NUMERIC_OWNER ); 1112 showopt(OPT_NUMERIC_OWNER );
@@ -1187,7 +1197,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
1187 if (opt & OPT_CREATE) { 1197 if (opt & OPT_CREATE) {
1188 /* Make sure there is at least one file to tar up */ 1198 /* Make sure there is at least one file to tar up */
1189 if (tar_handle->accept == NULL) 1199 if (tar_handle->accept == NULL)
1190 bb_error_msg_and_die("empty archive"); 1200 bb_simple_error_msg_and_die("empty archive");
1191 1201
1192 tar_fd = STDOUT_FILENO; 1202 tar_fd = STDOUT_FILENO;
1193 /* Mimicking GNU tar 1.15.1: */ 1203 /* Mimicking GNU tar 1.15.1: */
@@ -1215,6 +1225,21 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
1215 bb_perror_msg_and_die("can't open '%s'", tar_filename); 1225 bb_perror_msg_and_die("can't open '%s'", tar_filename);
1216 } else { 1226 } else {
1217 tar_handle->src_fd = xopen(tar_filename, flags); 1227 tar_handle->src_fd = xopen(tar_filename, flags);
1228#if ENABLE_FEATURE_TAR_CREATE
1229 if ((OPT_GZIP | OPT_BZIP2 | OPT_XZ | OPT_LZMA) != 0 /* at least one is config-enabled */
1230 && (opt & OPT_AUTOCOMPRESS_BY_EXT)
1231 && flags != O_RDONLY
1232 ) {
1233 if (OPT_GZIP != 0 && is_suffixed_with(tar_filename, "gz"))
1234 opt |= OPT_GZIP;
1235 if (OPT_BZIP2 != 0 && is_suffixed_with(tar_filename, "bz2"))
1236 opt |= OPT_BZIP2;
1237 if (OPT_XZ != 0 && is_suffixed_with(tar_filename, "xz"))
1238 opt |= OPT_XZ;
1239 if (OPT_LZMA != 0 && is_suffixed_with(tar_filename, "lzma"))
1240 opt |= OPT_LZMA;
1241 }
1242#endif
1218 } 1243 }
1219 } 1244 }
1220 1245
diff --git a/archival/unzip.c b/archival/unzip.c
index 4e8ed0eae..759456c1d 100644
--- a/archival/unzip.c
+++ b/archival/unzip.c
@@ -325,7 +325,7 @@ static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf)
325static void die_if_bad_fnamesize(unsigned sz) 325static void die_if_bad_fnamesize(unsigned sz)
326{ 326{
327 if (sz > 0xfff) /* more than 4k?! no funny business please */ 327 if (sz > 0xfff) /* more than 4k?! no funny business please */
328 bb_error_msg_and_die("bad archive"); 328 bb_simple_error_msg_and_die("bad archive");
329} 329}
330 330
331static void unzip_skip(off_t skip) 331static void unzip_skip(off_t skip)
@@ -365,7 +365,7 @@ static void unzip_extract_symlink(llist_t **symlink_placeholders,
365 xread(zip_fd, target, zip->fmt.ucmpsize); 365 xread(zip_fd, target, zip->fmt.ucmpsize);
366 } else { 366 } else {
367#if 1 367#if 1
368 bb_error_msg_and_die("compressed symlink is not supported"); 368 bb_simple_error_msg_and_die("compressed symlink is not supported");
369#else 369#else
370 transformer_state_t xstate; 370 transformer_state_t xstate;
371 init_transformer_state(&xstate); 371 init_transformer_state(&xstate);
@@ -405,10 +405,10 @@ static void unzip_extract(zip_header_t *zip, int dst_fd)
405 if (zip->fmt.method == 8) { 405 if (zip->fmt.method == 8) {
406 /* Method 8 - inflate */ 406 /* Method 8 - inflate */
407 if (inflate_unzip(&xstate) < 0) 407 if (inflate_unzip(&xstate) < 0)
408 bb_error_msg_and_die("inflate error"); 408 bb_simple_error_msg_and_die("inflate error");
409 /* Validate decompression - crc */ 409 /* Validate decompression - crc */
410 if (zip->fmt.crc32 != (xstate.crc32 ^ 0xffffffffL)) { 410 if (zip->fmt.crc32 != (xstate.crc32 ^ 0xffffffffL)) {
411 bb_error_msg_and_die("crc error"); 411 bb_simple_error_msg_and_die("crc error");
412 } 412 }
413 } 413 }
414#if ENABLE_FEATURE_UNZIP_BZIP2 414#if ENABLE_FEATURE_UNZIP_BZIP2
@@ -418,7 +418,7 @@ static void unzip_extract(zip_header_t *zip, int dst_fd)
418 */ 418 */
419 xstate.bytes_out = unpack_bz2_stream(&xstate); 419 xstate.bytes_out = unpack_bz2_stream(&xstate);
420 if (xstate.bytes_out < 0) 420 if (xstate.bytes_out < 0)
421 bb_error_msg_and_die("inflate error"); 421 bb_simple_error_msg_and_die("inflate error");
422 } 422 }
423#endif 423#endif
424#if ENABLE_FEATURE_UNZIP_LZMA 424#if ENABLE_FEATURE_UNZIP_LZMA
@@ -426,7 +426,7 @@ static void unzip_extract(zip_header_t *zip, int dst_fd)
426 /* Not tested yet */ 426 /* Not tested yet */
427 xstate.bytes_out = unpack_lzma_stream(&xstate); 427 xstate.bytes_out = unpack_lzma_stream(&xstate);
428 if (xstate.bytes_out < 0) 428 if (xstate.bytes_out < 0)
429 bb_error_msg_and_die("inflate error"); 429 bb_simple_error_msg_and_die("inflate error");
430 } 430 }
431#endif 431#endif
432#if ENABLE_FEATURE_UNZIP_XZ 432#if ENABLE_FEATURE_UNZIP_XZ
@@ -434,7 +434,7 @@ static void unzip_extract(zip_header_t *zip, int dst_fd)
434 /* Not tested yet */ 434 /* Not tested yet */
435 xstate.bytes_out = unpack_xz_stream(&xstate); 435 xstate.bytes_out = unpack_xz_stream(&xstate);
436 if (xstate.bytes_out < 0) 436 if (xstate.bytes_out < 0)
437 bb_error_msg_and_die("inflate error"); 437 bb_simple_error_msg_and_die("inflate error");
438 } 438 }
439#endif 439#endif
440 else { 440 else {
@@ -445,7 +445,7 @@ static void unzip_extract(zip_header_t *zip, int dst_fd)
445 if (zip->fmt.ucmpsize != xstate.bytes_out) { 445 if (zip->fmt.ucmpsize != xstate.bytes_out) {
446 /* Don't die. Who knows, maybe len calculation 446 /* Don't die. Who knows, maybe len calculation
447 * was botched somewhere. After all, crc matched! */ 447 * was botched somewhere. After all, crc matched! */
448 bb_error_msg("bad length"); 448 bb_simple_error_msg("bad length");
449 } 449 }
450} 450}
451 451
@@ -453,7 +453,7 @@ static void my_fgets80(char *buf80)
453{ 453{
454 fflush_all(); 454 fflush_all();
455 if (!fgets(buf80, 80, stdin)) { 455 if (!fgets(buf80, 80, stdin)) {
456 bb_perror_msg_and_die("can't read standard input"); 456 bb_simple_perror_msg_and_die("can't read standard input");
457 } 457 }
458} 458}
459 459
diff --git a/console-tools/loadfont.c b/console-tools/loadfont.c
index b5d4e8f43..caad7d9ac 100644
--- a/console-tools/loadfont.c
+++ b/console-tools/loadfont.c
@@ -225,7 +225,7 @@ static void do_loadtable(int fd, unsigned char *inbuf, int tailsz, int fontsize,
225 if (unicode == PSF2_SEPARATOR) { 225 if (unicode == PSF2_SEPARATOR) {
226 break; 226 break;
227 } else if (unicode == PSF2_STARTSEQ) { 227 } else if (unicode == PSF2_STARTSEQ) {
228 bb_error_msg_and_die("unicode sequences not implemented"); 228 bb_simple_error_msg_and_die("unicode sequences not implemented");
229 } else if (unicode >= 0xC0) { 229 } else if (unicode >= 0xC0) {
230 if (unicode >= 0xFC) 230 if (unicode >= 0xFC)
231 unicode &= 0x01, maxct = 5; 231 unicode &= 0x01, maxct = 5;
@@ -239,12 +239,12 @@ static void do_loadtable(int fd, unsigned char *inbuf, int tailsz, int fontsize,
239 unicode &= 0x1F, maxct = 1; 239 unicode &= 0x1F, maxct = 1;
240 do { 240 do {
241 if (tailsz <= 0 || *inbuf < 0x80 || *inbuf > 0xBF) 241 if (tailsz <= 0 || *inbuf < 0x80 || *inbuf > 0xBF)
242 bb_error_msg_and_die("illegal UTF-8 character"); 242 bb_simple_error_msg_and_die("illegal UTF-8 character");
243 --tailsz; 243 --tailsz;
244 unicode = (unicode << 6) + (*inbuf++ & 0x3F); 244 unicode = (unicode << 6) + (*inbuf++ & 0x3F);
245 } while (--maxct > 0); 245 } while (--maxct > 0);
246 } else if (unicode >= 0x80) { 246 } else if (unicode >= 0x80) {
247 bb_error_msg_and_die("illegal UTF-8 character"); 247 bb_simple_error_msg_and_die("illegal UTF-8 character");
248 } 248 }
249#else 249#else
250 return; 250 return;
@@ -281,7 +281,7 @@ static void do_load(int fd, unsigned char *buffer, size_t len)
281 281
282 if (len >= sizeof(struct psf1_header) && PSF1_MAGIC_OK(psf1h(buffer))) { 282 if (len >= sizeof(struct psf1_header) && PSF1_MAGIC_OK(psf1h(buffer))) {
283 if (psf1h(buffer)->mode > PSF1_MAXMODE) 283 if (psf1h(buffer)->mode > PSF1_MAXMODE)
284 bb_error_msg_and_die("unsupported psf file mode"); 284 bb_simple_error_msg_and_die("unsupported psf file mode");
285 if (psf1h(buffer)->mode & PSF1_MODE512) 285 if (psf1h(buffer)->mode & PSF1_MODE512)
286 fontsize = 512; 286 fontsize = 512;
287 if (psf1h(buffer)->mode & PSF1_MODEHASTAB) 287 if (psf1h(buffer)->mode & PSF1_MODEHASTAB)
@@ -292,7 +292,7 @@ static void do_load(int fd, unsigned char *buffer, size_t len)
292#if ENABLE_FEATURE_LOADFONT_PSF2 292#if ENABLE_FEATURE_LOADFONT_PSF2
293 if (len >= sizeof(struct psf2_header) && PSF2_MAGIC_OK(psf2h(buffer))) { 293 if (len >= sizeof(struct psf2_header) && PSF2_MAGIC_OK(psf2h(buffer))) {
294 if (psf2h(buffer)->version > PSF2_MAXVERSION) 294 if (psf2h(buffer)->version > PSF2_MAXVERSION)
295 bb_error_msg_and_die("unsupported psf file version"); 295 bb_simple_error_msg_and_die("unsupported psf file version");
296 fontsize = psf2h(buffer)->length; 296 fontsize = psf2h(buffer)->length;
297 if (psf2h(buffer)->flags & PSF2_HAS_UNICODE_TABLE) 297 if (psf2h(buffer)->flags & PSF2_HAS_UNICODE_TABLE)
298 has_table = 2; 298 has_table = 2;
@@ -311,19 +311,19 @@ static void do_load(int fd, unsigned char *buffer, size_t len)
311 } else 311 } else
312#endif 312#endif
313 { 313 {
314 bb_error_msg_and_die("input file: bad length or unsupported font type"); 314 bb_simple_error_msg_and_die("input file: bad length or unsupported font type");
315 } 315 }
316 316
317#if !defined(PIO_FONTX) || defined(__sparc__) 317#if !defined(PIO_FONTX) || defined(__sparc__)
318 if (fontsize != 256) 318 if (fontsize != 256)
319 bb_error_msg_and_die("only fontsize 256 supported"); 319 bb_simple_error_msg_and_die("only fontsize 256 supported");
320#endif 320#endif
321 321
322 table = font + fontsize * charsize; 322 table = font + fontsize * charsize;
323 buffer += len; 323 buffer += len;
324 324
325 if (table > buffer || (!has_table && table != buffer)) 325 if (table > buffer || (!has_table && table != buffer))
326 bb_error_msg_and_die("input file: bad length"); 326 bb_simple_error_msg_and_die("input file: bad length");
327 327
328 do_loadfont(fd, font, height, width, charsize, fontsize); 328 do_loadfont(fd, font, height, width, charsize, fontsize);
329 329
@@ -361,7 +361,7 @@ int loadfont_main(int argc UNUSED_PARAM, char **argv)
361 buffer = xmalloc_read(STDIN_FILENO, &len); 361 buffer = xmalloc_read(STDIN_FILENO, &len);
362 // xmalloc_open_zipped_read_close(filename, &len); 362 // xmalloc_open_zipped_read_close(filename, &len);
363 if (!buffer) 363 if (!buffer)
364 bb_perror_msg_and_die("error reading input font"); 364 bb_simple_perror_msg_and_die("error reading input font");
365 do_load(get_console_fd_or_die(), buffer, len); 365 do_load(get_console_fd_or_die(), buffer, len);
366 366
367 return EXIT_SUCCESS; 367 return EXIT_SUCCESS;
@@ -502,7 +502,7 @@ int setfont_main(int argc UNUSED_PARAM, char **argv)
502 if (a < 0 || a >= E_TABSZ 502 if (a < 0 || a >= E_TABSZ
503 || b < 0 || b > 65535 503 || b < 0 || b > 65535
504 ) { 504 ) {
505 bb_error_msg_and_die("map format"); 505 bb_simple_error_msg_and_die("map format");
506 } 506 }
507 // patch map 507 // patch map
508 unicodes[a] = b; 508 unicodes[a] = b;
diff --git a/console-tools/loadkmap.c b/console-tools/loadkmap.c
index d4981ad21..91ef50884 100644
--- a/console-tools/loadkmap.c
+++ b/console-tools/loadkmap.c
@@ -69,7 +69,7 @@ int loadkmap_main(int argc UNUSED_PARAM, char **argv)
69 69
70 xread(STDIN_FILENO, flags, 7); 70 xread(STDIN_FILENO, flags, 7);
71 if (!is_prefixed_with(flags, BINARY_KEYMAP_MAGIC)) 71 if (!is_prefixed_with(flags, BINARY_KEYMAP_MAGIC))
72 bb_error_msg_and_die("not a valid binary keymap"); 72 bb_simple_error_msg_and_die("not a valid binary keymap");
73 73
74 xread(STDIN_FILENO, flags, MAX_NR_KEYMAPS); 74 xread(STDIN_FILENO, flags, MAX_NR_KEYMAPS);
75 75
diff --git a/console-tools/openvt.c b/console-tools/openvt.c
index b01229a56..9e6cffecc 100644
--- a/console-tools/openvt.c
+++ b/console-tools/openvt.c
@@ -87,7 +87,7 @@ static int get_vt_fd(void)
87 fd = open(DEV_CONSOLE, O_RDONLY | O_NONBLOCK); 87 fd = open(DEV_CONSOLE, O_RDONLY | O_NONBLOCK);
88 if (fd >= 0 && !not_vt_fd(fd)) 88 if (fd >= 0 && !not_vt_fd(fd))
89 return fd; 89 return fd;
90 bb_error_msg_and_die("can't find open VT"); 90 bb_simple_error_msg_and_die("can't find open VT");
91} 91}
92 92
93static int find_free_vtno(void) 93static int find_free_vtno(void)
@@ -98,7 +98,7 @@ static int find_free_vtno(void)
98 errno = 0; 98 errno = 0;
99 /*xfunc_error_retval = 3; - do we need compat? */ 99 /*xfunc_error_retval = 3; - do we need compat? */
100 if (ioctl(fd, VT_OPENQRY, &vtno) != 0 || vtno <= 0) 100 if (ioctl(fd, VT_OPENQRY, &vtno) != 0 || vtno <= 0)
101 bb_perror_msg_and_die("can't find open VT"); 101 bb_simple_perror_msg_and_die("can't find open VT");
102// Not really needed, grep for DAEMON_CLOSE_EXTRA_FDS 102// Not really needed, grep for DAEMON_CLOSE_EXTRA_FDS
103// if (fd > 2) 103// if (fd > 2)
104// close(fd); 104// close(fd);
diff --git a/console-tools/showkey.c b/console-tools/showkey.c
index c322ce99d..8f0e9d938 100644
--- a/console-tools/showkey.c
+++ b/console-tools/showkey.c
@@ -56,7 +56,7 @@ static void xset1(struct termios *t)
56{ 56{
57 int ret = tcsetattr(STDIN_FILENO, TCSAFLUSH, t); 57 int ret = tcsetattr(STDIN_FILENO, TCSAFLUSH, t);
58 if (ret) { 58 if (ret) {
59 bb_perror_msg("can't tcsetattr for stdin"); 59 bb_simple_perror_msg("can't tcsetattr for stdin");
60 } 60 }
61} 61}
62 62
diff --git a/coreutils/cp.c b/coreutils/cp.c
index 59e3d2f80..cfeb19fc4 100644
--- a/coreutils/cp.c
+++ b/coreutils/cp.c
@@ -217,7 +217,7 @@ int cp_main(int argc, char **argv)
217 // flags, FILEUTILS_RMDEST, OPT_parents); 217 // flags, FILEUTILS_RMDEST, OPT_parents);
218 if (flags & OPT_parents) { 218 if (flags & OPT_parents) {
219 if (!(d_flags & 2)) { 219 if (!(d_flags & 2)) {
220 bb_error_msg_and_die("with --parents, the destination must be a directory"); 220 bb_simple_error_msg_and_die("with --parents, the destination must be a directory");
221 } 221 }
222 } 222 }
223 if (flags & FILEUTILS_RMDEST) { 223 if (flags & FILEUTILS_RMDEST) {
@@ -236,7 +236,7 @@ int cp_main(int argc, char **argv)
236 goto DO_COPY; /* NB: argc==2 -> *++argv==last */ 236 goto DO_COPY; /* NB: argc==2 -> *++argv==last */
237 } 237 }
238 } else if (flags & FILEUTILS_NO_TARGET_DIR) { 238 } else if (flags & FILEUTILS_NO_TARGET_DIR) {
239 bb_error_msg_and_die("too many arguments"); 239 bb_simple_error_msg_and_die("too many arguments");
240 } 240 }
241 241
242 while (1) { 242 while (1) {
diff --git a/coreutils/cut.c b/coreutils/cut.c
index e952dc17b..1acbb513e 100644
--- a/coreutils/cut.c
+++ b/coreutils/cut.c
@@ -209,11 +209,11 @@ int cut_main(int argc UNUSED_PARAM, char **argv)
209// argc -= optind; 209// argc -= optind;
210 argv += optind; 210 argv += optind;
211 if (!(opt & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS))) 211 if (!(opt & (CUT_OPT_BYTE_FLGS | CUT_OPT_CHAR_FLGS | CUT_OPT_FIELDS_FLGS)))
212 bb_error_msg_and_die("expected a list of bytes, characters, or fields"); 212 bb_simple_error_msg_and_die("expected a list of bytes, characters, or fields");
213 213
214 if (opt & CUT_OPT_DELIM_FLGS) { 214 if (opt & CUT_OPT_DELIM_FLGS) {
215 if (ltok[0] && ltok[1]) { /* more than 1 char? */ 215 if (ltok[0] && ltok[1]) { /* more than 1 char? */
216 bb_error_msg_and_die("the delimiter must be a single character"); 216 bb_simple_error_msg_and_die("the delimiter must be a single character");
217 } 217 }
218 delim = ltok[0]; 218 delim = ltok[0];
219 } 219 }
@@ -288,7 +288,7 @@ int cut_main(int argc UNUSED_PARAM, char **argv)
288 288
289 /* make sure we got some cut positions out of all that */ 289 /* make sure we got some cut positions out of all that */
290 if (nlists == 0) 290 if (nlists == 0)
291 bb_error_msg_and_die("missing list of positions"); 291 bb_simple_error_msg_and_die("missing list of positions");
292 292
293 /* now that the lists are parsed, we need to sort them to make life 293 /* now that the lists are parsed, we need to sort them to make life
294 * easier on us when it comes time to print the chars / fields / lines 294 * easier on us when it comes time to print the chars / fields / lines
diff --git a/coreutils/date.c b/coreutils/date.c
index 3414d38ae..feb400430 100644
--- a/coreutils/date.c
+++ b/coreutils/date.c
@@ -304,7 +304,7 @@ int date_main(int argc UNUSED_PARAM, char **argv)
304 304
305 /* if setting time, set it */ 305 /* if setting time, set it */
306 if ((opt & OPT_SET) && stime(&ts.tv_sec) < 0) { 306 if ((opt & OPT_SET) && stime(&ts.tv_sec) < 0) {
307 bb_perror_msg("can't set date"); 307 bb_simple_perror_msg("can't set date");
308 } 308 }
309 } 309 }
310 310
diff --git a/coreutils/df.c b/coreutils/df.c
index f6d66e4b6..debb86867 100644
--- a/coreutils/df.c
+++ b/coreutils/df.c
@@ -178,7 +178,7 @@ int df_main(int argc UNUSED_PARAM, char **argv)
178 if (!argv[0]) { 178 if (!argv[0]) {
179 mount_table = setmntent(bb_path_mtab_file, "r"); 179 mount_table = setmntent(bb_path_mtab_file, "r");
180 if (!mount_table) 180 if (!mount_table)
181 bb_perror_msg_and_die(bb_path_mtab_file); 181 bb_simple_perror_msg_and_die(bb_path_mtab_file);
182 } 182 }
183 183
184 while (1) { 184 while (1) {
diff --git a/coreutils/echo.c b/coreutils/echo.c
index 5dc5be072..b3828894c 100644
--- a/coreutils/echo.c
+++ b/coreutils/echo.c
@@ -188,7 +188,7 @@ int echo_main(int argc UNUSED_PARAM, char **argv)
188 /*r =*/ full_write(STDOUT_FILENO, buffer, out - buffer); 188 /*r =*/ full_write(STDOUT_FILENO, buffer, out - buffer);
189 free(buffer); 189 free(buffer);
190 if (/*WRONG:r < 0*/ errno) { 190 if (/*WRONG:r < 0*/ errno) {
191 bb_perror_msg(bb_msg_write_error); 191 bb_simple_perror_msg(bb_msg_write_error);
192 return 1; 192 return 1;
193 } 193 }
194 return 0; 194 return 0;
diff --git a/coreutils/env.c b/coreutils/env.c
index 878068f09..c37c0c2df 100644
--- a/coreutils/env.c
+++ b/coreutils/env.c
@@ -79,7 +79,7 @@ int env_main(int argc UNUSED_PARAM, char **argv)
79 79
80 while (*argv && (strchr(*argv, '=') != NULL)) { 80 while (*argv && (strchr(*argv, '=') != NULL)) {
81 if (putenv(*argv) < 0) { 81 if (putenv(*argv) < 0) {
82 bb_perror_msg_and_die("putenv"); 82 bb_simple_perror_msg_and_die("putenv");
83 } 83 }
84 ++argv; 84 ++argv;
85 } 85 }
diff --git a/coreutils/expand.c b/coreutils/expand.c
index f7e4619f9..4fa974df8 100644
--- a/coreutils/expand.c
+++ b/coreutils/expand.c
@@ -63,33 +63,62 @@ enum {
63 OPT_ALL = 1 << 2, 63 OPT_ALL = 1 << 2,
64}; 64};
65 65
66//FIXME: does not work properly with input containing NULs
67//coreutils 8.30 preserves NULs but treats them as chars of width zero:
68//AB<nul><tab>C will expand <tab> to 6 spaces, not 5.
69
66#if ENABLE_EXPAND 70#if ENABLE_EXPAND
67static void expand(FILE *file, unsigned tab_size, unsigned opt) 71static void expand(FILE *file, unsigned tab_size, unsigned opt)
68{ 72{
69 char *line;
70 73
71 while ((line = xmalloc_fgets(file)) != NULL) { 74 for (;;) {
72 unsigned char c; 75 char *line;
73 char *ptr; 76 char *ptr;
74 char *ptr_strbeg; 77 char *ptr_strbeg;
75 78//commented-out code handles NULs, +90 bytes of code, not tested much
79// size_t linelen;
80// unsigned len = 0;
81
82// linelen = 1024 * 1024;
83// line = xmalloc_fgets_str_len(file, "\n", &linelen);
84 line = xmalloc_fgets(file); //
85 if (!line)
86 break;
76 ptr = ptr_strbeg = line; 87 ptr = ptr_strbeg = line;
77 while ((c = *ptr) != '\0') { 88 for (;;) {
89 unsigned char c = *ptr;
90 if (c == '\0') {
91// size_t rem = line + linelen - ptr;
92// if (rem > 0) {
93//# if ENABLE_UNICODE_SUPPORT
94// len += unicode_strwidth(ptr_strbeg);
95//# else
96// len += ptr - ptr_strbeg;
97//# endif
98// printf("%s%c", ptr_strbeg, '\0');
99// memmove(ptr, ptr + 1, rem + 1);
100// ptr_strbeg = ptr;
101// linelen--;
102// continue;
103// }
104 break;
105 }
78 if ((opt & OPT_INITIAL) && !isblank(c)) { 106 if ((opt & OPT_INITIAL) && !isblank(c)) {
79 /* not space or tab */ 107 /* not space or tab */
80 break; 108 break;
81 } 109 }
82 if (c == '\t') { 110 if (c == '\t') {
83 unsigned len; 111 unsigned len = 0; //
84 *ptr = '\0'; 112 *ptr = '\0';
85# if ENABLE_UNICODE_SUPPORT 113# if ENABLE_UNICODE_SUPPORT
86 len = unicode_strwidth(ptr_strbeg); 114 len += unicode_strwidth(ptr_strbeg);
87# else 115# else
88 len = ptr - ptr_strbeg; 116 len += ptr - ptr_strbeg;
89# endif 117# endif
90 len = tab_size - (len % tab_size); 118 len = tab_size - (len % tab_size);
91 /*while (ptr[1] == '\t') { ptr++; len += tab_size; } - can handle many tabs at once */ 119 /*while (ptr[1] == '\t') { ptr++; len += tab_size; } - can handle many tabs at once */
92 printf("%s%*s", ptr_strbeg, len, ""); 120 printf("%s%*s", ptr_strbeg, len, "");
121// len = 0;
93 ptr_strbeg = ptr + 1; 122 ptr_strbeg = ptr + 1;
94 } 123 }
95 ptr++; 124 ptr++;
@@ -218,7 +247,7 @@ int expand_main(int argc UNUSED_PARAM, char **argv)
218 /* Now close stdin also */ 247 /* Now close stdin also */
219 /* (if we didn't read from it, it's a no-op) */ 248 /* (if we didn't read from it, it's a no-op) */
220 if (fclose(stdin)) 249 if (fclose(stdin))
221 bb_perror_msg_and_die(bb_msg_standard_input); 250 bb_simple_perror_msg_and_die(bb_msg_standard_input);
222 251
223 fflush_stdout_and_exit(exit_status); 252 fflush_stdout_and_exit(exit_status);
224} 253}
diff --git a/coreutils/expr.c b/coreutils/expr.c
index 900248103..c11505d13 100644
--- a/coreutils/expr.c
+++ b/coreutils/expr.c
@@ -249,7 +249,7 @@ static arith_t arithmetic_common(VALUE *l, VALUE *r, int op)
249 arith_t li, ri; 249 arith_t li, ri;
250 250
251 if (!toarith(l) || !toarith(r)) 251 if (!toarith(l) || !toarith(r))
252 bb_error_msg_and_die("non-numeric argument"); 252 bb_simple_error_msg_and_die("non-numeric argument");
253 li = l->u.i; 253 li = l->u.i;
254 ri = r->u.i; 254 ri = r->u.i;
255 if (op == '+') 255 if (op == '+')
@@ -259,7 +259,7 @@ static arith_t arithmetic_common(VALUE *l, VALUE *r, int op)
259 if (op == '*') 259 if (op == '*')
260 return li * ri; 260 return li * ri;
261 if (ri == 0) 261 if (ri == 0)
262 bb_error_msg_and_die("division by zero"); 262 bb_simple_error_msg_and_die("division by zero");
263 if (op == '/') 263 if (op == '/')
264 return li / ri; 264 return li / ri;
265 return li % ri; 265 return li % ri;
@@ -319,19 +319,19 @@ static VALUE *eval7(void)
319 VALUE *v; 319 VALUE *v;
320 320
321 if (!*G.args) 321 if (!*G.args)
322 bb_error_msg_and_die("syntax error"); 322 bb_simple_error_msg_and_die("syntax error");
323 323
324 if (nextarg("(")) { 324 if (nextarg("(")) {
325 G.args++; 325 G.args++;
326 v = eval(); 326 v = eval();
327 if (!nextarg(")")) 327 if (!nextarg(")"))
328 bb_error_msg_and_die("syntax error"); 328 bb_simple_error_msg_and_die("syntax error");
329 G.args++; 329 G.args++;
330 return v; 330 return v;
331 } 331 }
332 332
333 if (nextarg(")")) 333 if (nextarg(")"))
334 bb_error_msg_and_die("syntax error"); 334 bb_simple_error_msg_and_die("syntax error");
335 335
336 return str_value(*G.args++); 336 return str_value(*G.args++);
337} 337}
@@ -353,7 +353,7 @@ static VALUE *eval6(void)
353 G.args++; /* We have a valid token, so get the next argument. */ 353 G.args++; /* We have a valid token, so get the next argument. */
354 if (key == 1) { /* quote */ 354 if (key == 1) { /* quote */
355 if (!*G.args) 355 if (!*G.args)
356 bb_error_msg_and_die("syntax error"); 356 bb_simple_error_msg_and_die("syntax error");
357 return str_value(*G.args++); 357 return str_value(*G.args++);
358 } 358 }
359 if (key == 2) { /* length */ 359 if (key == 2) { /* length */
@@ -546,11 +546,11 @@ int expr_main(int argc UNUSED_PARAM, char **argv)
546 xfunc_error_retval = 2; /* coreutils compat */ 546 xfunc_error_retval = 2; /* coreutils compat */
547 G.args = argv + 1; 547 G.args = argv + 1;
548 if (*G.args == NULL) { 548 if (*G.args == NULL) {
549 bb_error_msg_and_die("too few arguments"); 549 bb_simple_error_msg_and_die("too few arguments");
550 } 550 }
551 v = eval(); 551 v = eval();
552 if (*G.args) 552 if (*G.args)
553 bb_error_msg_and_die("syntax error"); 553 bb_simple_error_msg_and_die("syntax error");
554 if (v->type == INTEGER) 554 if (v->type == INTEGER)
555 printf("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i); 555 printf("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i);
556 else 556 else
diff --git a/coreutils/id.c b/coreutils/id.c
index 00c0cd8ab..f20cd7d09 100644
--- a/coreutils/id.c
+++ b/coreutils/id.c
@@ -231,7 +231,7 @@ int id_main(int argc UNUSED_PARAM, char **argv)
231 } 231 }
232 } else if (n < 0) { /* error in get_groups() */ 232 } else if (n < 0) { /* error in get_groups() */
233 if (ENABLE_DESKTOP) 233 if (ENABLE_DESKTOP)
234 bb_error_msg_and_die("can't get groups"); 234 bb_simple_error_msg_and_die("can't get groups");
235 return EXIT_FAILURE; 235 return EXIT_FAILURE;
236 } 236 }
237 if (ENABLE_FEATURE_CLEAN_UP) 237 if (ENABLE_FEATURE_CLEAN_UP)
diff --git a/coreutils/install.c b/coreutils/install.c
index 8270490bd..c0f1c538a 100644
--- a/coreutils/install.c
+++ b/coreutils/install.c
@@ -238,7 +238,7 @@ int install_main(int argc, char **argv)
238 args[2] = dest; 238 args[2] = dest;
239 args[3] = NULL; 239 args[3] = NULL;
240 if (spawn_and_wait(args)) { 240 if (spawn_and_wait(args)) {
241 bb_perror_msg("strip"); 241 bb_simple_perror_msg("strip");
242 ret = EXIT_FAILURE; 242 ret = EXIT_FAILURE;
243 } 243 }
244 } 244 }
diff --git a/coreutils/ln.c b/coreutils/ln.c
index afeb0d72d..ea2d10eab 100644
--- a/coreutils/ln.c
+++ b/coreutils/ln.c
@@ -69,7 +69,7 @@ int ln_main(int argc, char **argv)
69 argc -= optind; 69 argc -= optind;
70 70
71 if ((opts & LN_LINKFILE) && argc > 2) { 71 if ((opts & LN_LINKFILE) && argc > 2) {
72 bb_error_msg_and_die("-T accepts 2 args max"); 72 bb_simple_error_msg_and_die("-T accepts 2 args max");
73 } 73 }
74 74
75 if (!argv[1]) { 75 if (!argv[1]) {
diff --git a/coreutils/logname.c b/coreutils/logname.c
index 31ce61f0c..06bbe1b0e 100644
--- a/coreutils/logname.c
+++ b/coreutils/logname.c
@@ -56,5 +56,5 @@ int logname_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
56 return fflush_all(); 56 return fflush_all();
57 } 57 }
58 58
59 bb_perror_msg_and_die("getlogin"); 59 bb_simple_perror_msg_and_die("getlogin");
60} 60}
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c
index 538df251b..ba26c985a 100644
--- a/coreutils/md5_sha1_sum.c
+++ b/coreutils/md5_sha1_sum.c
@@ -300,7 +300,7 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv)
300 } 300 }
301 if (filename_ptr == NULL) { 301 if (filename_ptr == NULL) {
302 if (flags & FLAG_WARN) { 302 if (flags & FLAG_WARN) {
303 bb_error_msg("invalid format"); 303 bb_simple_error_msg("invalid format");
304 } 304 }
305 count_failed++; 305 count_failed++;
306 return_value = EXIT_FAILURE; 306 return_value = EXIT_FAILURE;
diff --git a/coreutils/od_bloaty.c b/coreutils/od_bloaty.c
index 75e14ef7d..ea1ab9de8 100644
--- a/coreutils/od_bloaty.c
+++ b/coreutils/od_bloaty.c
@@ -543,7 +543,7 @@ check_and_close(void)
543 } 543 }
544 544
545 if (ferror(stdout)) { 545 if (ferror(stdout)) {
546 bb_error_msg_and_die(bb_msg_write_error); 546 bb_simple_error_msg_and_die(bb_msg_write_error);
547 } 547 }
548} 548}
549 549
@@ -848,7 +848,7 @@ skip(off_t n_skip)
848 } 848 }
849 849
850 if (n_skip) 850 if (n_skip)
851 bb_error_msg_and_die("can't skip past end of combined input"); 851 bb_simple_error_msg_and_die("can't skip past end of combined input");
852} 852}
853 853
854 854
@@ -1315,10 +1315,10 @@ int od_main(int argc UNUSED_PARAM, char **argv)
1315 pseudo_start = o2; 1315 pseudo_start = o2;
1316 argv[1] = NULL; 1316 argv[1] = NULL;
1317 } else { 1317 } else {
1318 bb_error_msg_and_die("the last two arguments must be offsets"); 1318 bb_simple_error_msg_and_die("the last two arguments must be offsets");
1319 } 1319 }
1320 } else { /* >3 args */ 1320 } else { /* >3 args */
1321 bb_error_msg_and_die("too many arguments"); 1321 bb_simple_error_msg_and_die("too many arguments");
1322 } 1322 }
1323 1323
1324 if (pseudo_start >= 0) { 1324 if (pseudo_start >= 0) {
@@ -1339,7 +1339,7 @@ int od_main(int argc UNUSED_PARAM, char **argv)
1339 if (option_mask32 & OPT_N) { 1339 if (option_mask32 & OPT_N) {
1340 end_offset = n_bytes_to_skip + max_bytes_to_format; 1340 end_offset = n_bytes_to_skip + max_bytes_to_format;
1341 if (end_offset < n_bytes_to_skip) 1341 if (end_offset < n_bytes_to_skip)
1342 bb_error_msg_and_die("SKIP + SIZE is too large"); 1342 bb_simple_error_msg_and_die("SKIP + SIZE is too large");
1343 } 1343 }
1344 1344
1345 if (G.n_specs == 0) { 1345 if (G.n_specs == 0) {
@@ -1396,7 +1396,7 @@ int od_main(int argc UNUSED_PARAM, char **argv)
1396 dump(n_bytes_to_skip, end_offset); 1396 dump(n_bytes_to_skip, end_offset);
1397 1397
1398 if (fclose(stdin)) 1398 if (fclose(stdin))
1399 bb_perror_msg_and_die(bb_msg_standard_input); 1399 bb_simple_perror_msg_and_die(bb_msg_standard_input);
1400 1400
1401 return G.exit_code; 1401 return G.exit_code;
1402} 1402}
diff --git a/coreutils/paste.c b/coreutils/paste.c
index 3d81a5f1a..11743297a 100644
--- a/coreutils/paste.c
+++ b/coreutils/paste.c
@@ -116,7 +116,7 @@ int paste_main(int argc UNUSED_PARAM, char **argv)
116 116
117 if (opt & PASTE_OPT_DELIMITERS) { 117 if (opt & PASTE_OPT_DELIMITERS) {
118 if (!delims[0]) 118 if (!delims[0])
119 bb_error_msg_and_die("-d '' is not supported"); 119 bb_simple_error_msg_and_die("-d '' is not supported");
120 /* unknown mappings are not changed: "\z" -> '\\' 'z' */ 120 /* unknown mappings are not changed: "\z" -> '\\' 'z' */
121 /* trailing backslash, if any, is preserved */ 121 /* trailing backslash, if any, is preserved */
122 del_cnt = strcpy_and_process_escape_sequences(delims, delims) - delims; 122 del_cnt = strcpy_and_process_escape_sequences(delims, delims) - delims;
diff --git a/coreutils/printf.c b/coreutils/printf.c
index 5cf518699..a20fc3301 100644
--- a/coreutils/printf.c
+++ b/coreutils/printf.c
@@ -430,7 +430,7 @@ int printf_main(int argc UNUSED_PARAM, char **argv)
430 if (ENABLE_ASH_PRINTF 430 if (ENABLE_ASH_PRINTF
431 && applet_name[0] != 'p' 431 && applet_name[0] != 'p'
432 ) { 432 ) {
433 bb_error_msg("usage: printf FORMAT [ARGUMENT...]"); 433 bb_simple_error_msg("usage: printf FORMAT [ARGUMENT...]");
434 return 2; /* bash compat */ 434 return 2; /* bash compat */
435 } 435 }
436 bb_show_usage(); 436 bb_show_usage();
diff --git a/coreutils/rm.c b/coreutils/rm.c
index fd94bb5c4..d000129d9 100644
--- a/coreutils/rm.c
+++ b/coreutils/rm.c
@@ -62,7 +62,7 @@ int rm_main(int argc UNUSED_PARAM, char **argv)
62 const char *base = bb_get_last_path_component_strip(*argv); 62 const char *base = bb_get_last_path_component_strip(*argv);
63 63
64 if (DOT_OR_DOTDOT(base)) { 64 if (DOT_OR_DOTDOT(base)) {
65 bb_error_msg("can't remove '.' or '..'"); 65 bb_simple_error_msg("can't remove '.' or '..'");
66 } else if (remove_file(*argv, flags) >= 0) { 66 } else if (remove_file(*argv, flags) >= 0) {
67 continue; 67 continue;
68 } 68 }
diff --git a/coreutils/sort.c b/coreutils/sort.c
index f04c6067b..07c327645 100644
--- a/coreutils/sort.c
+++ b/coreutils/sort.c
@@ -277,7 +277,7 @@ static int compare_keys(const void *xarg, const void *yarg)
277 /* Perform actual comparison */ 277 /* Perform actual comparison */
278 switch (flags & (FLAG_n | FLAG_g | FLAG_M | FLAG_V)) { 278 switch (flags & (FLAG_n | FLAG_g | FLAG_M | FLAG_V)) {
279 default: 279 default:
280 bb_error_msg_and_die("unknown sort type"); 280 bb_simple_error_msg_and_die("unknown sort type");
281 break; 281 break;
282#if defined(HAVE_STRVERSCMP) && HAVE_STRVERSCMP == 1 282#if defined(HAVE_STRVERSCMP) && HAVE_STRVERSCMP == 1
283 case FLAG_V: 283 case FLAG_V:
@@ -398,10 +398,10 @@ static unsigned str2u(char **str)
398{ 398{
399 unsigned long lu; 399 unsigned long lu;
400 if (!isdigit((*str)[0])) 400 if (!isdigit((*str)[0]))
401 bb_error_msg_and_die("bad field specification"); 401 bb_simple_error_msg_and_die("bad field specification");
402 lu = strtoul(*str, str, 10); 402 lu = strtoul(*str, str, 10);
403 if ((sizeof(long) > sizeof(int) && lu > INT_MAX) || !lu) 403 if ((sizeof(long) > sizeof(int) && lu > INT_MAX) || !lu)
404 bb_error_msg_and_die("bad field specification"); 404 bb_simple_error_msg_and_die("bad field specification");
405 return lu; 405 return lu;
406} 406}
407#endif 407#endif
@@ -461,7 +461,7 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
461#if ENABLE_FEATURE_SORT_BIG 461#if ENABLE_FEATURE_SORT_BIG
462 if (opts & FLAG_t) { 462 if (opts & FLAG_t) {
463 if (!str_t[0] || str_t[1]) 463 if (!str_t[0] || str_t[1])
464 bb_error_msg_and_die("bad -t parameter"); 464 bb_simple_error_msg_and_die("bad -t parameter");
465 key_separator = str_t[0]; 465 key_separator = str_t[0];
466 } 466 }
467 /* note: below this point we use option_mask32, not opts, 467 /* note: below this point we use option_mask32, not opts,
@@ -504,10 +504,10 @@ int sort_main(int argc UNUSED_PARAM, char **argv)
504 because comma isn't in OPT_STR */ 504 because comma isn't in OPT_STR */
505 idx = strchr(OPT_STR, *str_k); 505 idx = strchr(OPT_STR, *str_k);
506 if (!idx) 506 if (!idx)
507 bb_error_msg_and_die("unknown key option"); 507 bb_simple_error_msg_and_die("unknown key option");
508 flag = 1 << (idx - OPT_STR); 508 flag = 1 << (idx - OPT_STR);
509 if (flag & ~FLAG_allowed_for_k) 509 if (flag & ~FLAG_allowed_for_k)
510 bb_error_msg_and_die("unknown sort type"); 510 bb_simple_error_msg_and_die("unknown sort type");
511 /* b after ',' means strip _trailing_ space */ 511 /* b after ',' means strip _trailing_ space */
512 if (i && flag == FLAG_b) 512 if (i && flag == FLAG_b)
513 flag = FLAG_bb; 513 flag = FLAG_bb;
diff --git a/coreutils/split.c b/coreutils/split.c
index c1e4ceab2..ecbc9d2d8 100644
--- a/coreutils/split.c
+++ b/coreutils/split.c
@@ -127,7 +127,7 @@ int split_main(int argc UNUSED_PARAM, char **argv)
127 } 127 }
128 128
129 if (NAME_MAX < strlen(sfx) + suffix_len) 129 if (NAME_MAX < strlen(sfx) + suffix_len)
130 bb_error_msg_and_die("suffix too long"); 130 bb_simple_error_msg_and_die("suffix too long");
131 131
132 { 132 {
133 char *char_p = xzalloc(suffix_len + 1); 133 char *char_p = xzalloc(suffix_len + 1);
@@ -147,7 +147,7 @@ int split_main(int argc UNUSED_PARAM, char **argv)
147 do { 147 do {
148 if (!remaining) { 148 if (!remaining) {
149 if (!pfx) 149 if (!pfx)
150 bb_error_msg_and_die("suffixes exhausted"); 150 bb_simple_error_msg_and_die("suffixes exhausted");
151 xmove_fd(xopen(pfx, O_WRONLY | O_CREAT | O_TRUNC), 1); 151 xmove_fd(xopen(pfx, O_WRONLY | O_CREAT | O_TRUNC), 1);
152 pfx = next_file(pfx, suffix_len); 152 pfx = next_file(pfx, suffix_len);
153 remaining = cnt; 153 remaining = cnt;
diff --git a/coreutils/stat.c b/coreutils/stat.c
index d9287b34e..c332e5dc8 100644
--- a/coreutils/stat.c
+++ b/coreutils/stat.c
@@ -149,20 +149,16 @@ static const char *file_type(const struct stat *st)
149 return "weird file"; 149 return "weird file";
150} 150}
151 151
152static const char *human_time(time_t t) 152static const char *human_time(struct timespec *ts)
153{ 153{
154 /* Old 154 char fmt[sizeof("%Y-%m-%d %H:%M:%S.123456789 %z") + /*paranoia*/ 8];
155 static char *str; 155
156 str = ctime(&t); 156 /* coreutils 6.3 compat */
157 str[strlen(str)-1] = '\0';
158 return str;
159 */
160 /* coreutils 6.3 compat: */
161
162 /*static char buf[sizeof("YYYY-MM-DD HH:MM:SS.000000000")] ALIGN1;*/
163#define buf bb_common_bufsiz1 157#define buf bb_common_bufsiz1
164 setup_common_bufsiz(); 158 setup_common_bufsiz();
165 strcpy(strftime_YYYYMMDDHHMMSS(buf, COMMON_BUFSIZE, &t), ".000000000"); 159
160 sprintf(stpcpy(fmt, "%Y-%m-%d %H:%M:%S"), ".%09u %%z", (unsigned)ts->tv_nsec);
161 strftime(buf, COMMON_BUFSIZE, fmt, localtime(&ts->tv_sec));
166 return buf; 162 return buf;
167#undef buf 163#undef buf
168} 164}
@@ -388,19 +384,19 @@ static void FAST_FUNC print_stat(char *pformat, const char m,
388 strcat(pformat, "lu"); 384 strcat(pformat, "lu");
389 printf(pformat, (unsigned long) statbuf->st_blksize); 385 printf(pformat, (unsigned long) statbuf->st_blksize);
390 } else if (m == 'x') { 386 } else if (m == 'x') {
391 printfs(pformat, human_time(statbuf->st_atime)); 387 printfs(pformat, human_time(&statbuf->st_atim));
392 } else if (m == 'X') { 388 } else if (m == 'X') {
393 strcat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu"); 389 strcat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu");
394 /* note: (unsigned long) would be wrong: 390 /* note: (unsigned long) would be wrong:
395 * imagine (unsigned long64)int32 */ 391 * imagine (unsigned long64)int32 */
396 printf(pformat, (long) statbuf->st_atime); 392 printf(pformat, (long) statbuf->st_atime);
397 } else if (m == 'y') { 393 } else if (m == 'y') {
398 printfs(pformat, human_time(statbuf->st_mtime)); 394 printfs(pformat, human_time(&statbuf->st_mtim));
399 } else if (m == 'Y') { 395 } else if (m == 'Y') {
400 strcat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu"); 396 strcat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu");
401 printf(pformat, (long) statbuf->st_mtime); 397 printf(pformat, (long) statbuf->st_mtime);
402 } else if (m == 'z') { 398 } else if (m == 'z') {
403 printfs(pformat, human_time(statbuf->st_ctime)); 399 printfs(pformat, human_time(&statbuf->st_ctim));
404 } else if (m == 'Z') { 400 } else if (m == 'Z') {
405 strcat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu"); 401 strcat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu");
406 printf(pformat, (long) statbuf->st_ctime); 402 printf(pformat, (long) statbuf->st_ctime);
@@ -505,7 +501,7 @@ static bool do_statfs(const char *filename, const char *format)
505 if (format == NULL) { 501 if (format == NULL) {
506# if !ENABLE_SELINUX 502# if !ENABLE_SELINUX
507 format = (option_mask32 & OPT_TERSE 503 format = (option_mask32 & OPT_TERSE
508 ? "%n %i %l %t %s %b %f %a %c %d\n" 504 ? "%n %i %l %t %s %b %f %a %c %d"
509 : " File: \"%n\"\n" 505 : " File: \"%n\"\n"
510 " ID: %-8i Namelen: %-7l Type: %T\n" 506 " ID: %-8i Namelen: %-7l Type: %T\n"
511 "Block size: %-10s\n" 507 "Block size: %-10s\n"
@@ -513,25 +509,26 @@ static bool do_statfs(const char *filename, const char *format)
513 "Inodes: Total: %-10c Free: %d"); 509 "Inodes: Total: %-10c Free: %d");
514# else 510# else
515 format = (option_mask32 & OPT_TERSE 511 format = (option_mask32 & OPT_TERSE
516 ? (option_mask32 & OPT_SELINUX ? "%n %i %l %t %s %b %f %a %c %d %C\n": 512 ? (option_mask32 & OPT_SELINUX
517 "%n %i %l %t %s %b %f %a %c %d\n") 513 ? "%n %i %l %t %s %b %f %a %c %d %C"
518 : (option_mask32 & OPT_SELINUX ? 514 : "%n %i %l %t %s %b %f %a %c %d")
519 " File: \"%n\"\n" 515 : (option_mask32 & OPT_SELINUX
520 " ID: %-8i Namelen: %-7l Type: %T\n" 516 ? " File: \"%n\"\n"
521 "Block size: %-10s\n" 517 " ID: %-8i Namelen: %-7l Type: %T\n"
522 "Blocks: Total: %-10b Free: %-10f Available: %a\n" 518 "Block size: %-10s\n"
523 "Inodes: Total: %-10c Free: %d" 519 "Blocks: Total: %-10b Free: %-10f Available: %a\n"
524 " S_context: %C\n": 520 "Inodes: Total: %-10c Free: %d"
525 " File: \"%n\"\n" 521 " S_context: %C"
526 " ID: %-8i Namelen: %-7l Type: %T\n" 522 : " File: \"%n\"\n"
527 "Block size: %-10s\n" 523 " ID: %-8i Namelen: %-7l Type: %T\n"
528 "Blocks: Total: %-10b Free: %-10f Available: %a\n" 524 "Block size: %-10s\n"
529 "Inodes: Total: %-10c Free: %d\n") 525 "Blocks: Total: %-10b Free: %-10f Available: %a\n"
526 "Inodes: Total: %-10c Free: %d")
530 ); 527 );
531# endif /* SELINUX */ 528# endif /* SELINUX */
532 } 529 }
533 print_it(format, filename, print_statfs, &statfsbuf IF_SELINUX(, scontext)); 530 print_it(format, filename, print_statfs, &statfsbuf IF_SELINUX(, scontext));
534#else /* FEATURE_STAT_FORMAT */ 531#else /* !FEATURE_STAT_FORMAT */
535 format = (option_mask32 & OPT_TERSE 532 format = (option_mask32 & OPT_TERSE
536 ? "%s %llx %lu " 533 ? "%s %llx %lu "
537 : " File: \"%s\"\n" 534 : " File: \"%s\"\n"
@@ -628,14 +625,14 @@ static bool do_stat(const char *filename, const char *format)
628 "Device: %Dh/%dd\tInode: %-10i Links: %-5h" 625 "Device: %Dh/%dd\tInode: %-10i Links: %-5h"
629 " Device type: %t,%T\n" 626 " Device type: %t,%T\n"
630 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" 627 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
631 "Access: %x\n" "Modify: %y\n" "Change: %z\n"; 628 "Access: %x\n" "Modify: %y\n" "Change: %z";
632 } else { 629 } else {
633 format = 630 format =
634 " File: %N\n" 631 " File: %N\n"
635 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" 632 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
636 "Device: %Dh/%dd\tInode: %-10i Links: %h\n" 633 "Device: %Dh/%dd\tInode: %-10i Links: %h\n"
637 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" 634 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
638 "Access: %x\n" "Modify: %y\n" "Change: %z\n"; 635 "Access: %x\n" "Modify: %y\n" "Change: %z";
639 } 636 }
640 } 637 }
641# else 638# else
@@ -654,14 +651,14 @@ static bool do_stat(const char *filename, const char *format)
654 " Device type: %t,%T\n" 651 " Device type: %t,%T\n"
655 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" 652 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
656 " S_Context: %C\n" 653 " S_Context: %C\n"
657 "Access: %x\n" "Modify: %y\n" "Change: %z\n" 654 "Access: %x\n" "Modify: %y\n" "Change: %z"
658 : 655 :
659 " File: %N\n" 656 " File: %N\n"
660 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" 657 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
661 "Device: %Dh/%dd\tInode: %-10i Links: %-5h" 658 "Device: %Dh/%dd\tInode: %-10i Links: %-5h"
662 " Device type: %t,%T\n" 659 " Device type: %t,%T\n"
663 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" 660 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
664 "Access: %x\n" "Modify: %y\n" "Change: %z\n" 661 "Access: %x\n" "Modify: %y\n" "Change: %z"
665 ); 662 );
666 } else { 663 } else {
667 format = (option_mask32 & OPT_SELINUX ? 664 format = (option_mask32 & OPT_SELINUX ?
@@ -670,13 +667,13 @@ static bool do_stat(const char *filename, const char *format)
670 "Device: %Dh/%dd\tInode: %-10i Links: %h\n" 667 "Device: %Dh/%dd\tInode: %-10i Links: %h\n"
671 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" 668 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
672 "S_Context: %C\n" 669 "S_Context: %C\n"
673 "Access: %x\n" "Modify: %y\n" "Change: %z\n" 670 "Access: %x\n" "Modify: %y\n" "Change: %z"
674 : 671 :
675 " File: %N\n" 672 " File: %N\n"
676 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" 673 " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
677 "Device: %Dh/%dd\tInode: %-10i Links: %h\n" 674 "Device: %Dh/%dd\tInode: %-10i Links: %h\n"
678 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" 675 "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n"
679 "Access: %x\n" "Modify: %y\n" "Change: %z\n" 676 "Access: %x\n" "Modify: %y\n" "Change: %z"
680 ); 677 );
681 } 678 }
682 } 679 }
@@ -757,9 +754,9 @@ static bool do_stat(const char *filename, const char *format)
757 if (option_mask32 & OPT_SELINUX) 754 if (option_mask32 & OPT_SELINUX)
758 printf(" S_Context: %s\n", scontext); 755 printf(" S_Context: %s\n", scontext);
759# endif 756# endif
760 printf("Access: %s\n", human_time(statbuf.st_atime)); 757 printf("Access: %s\n", human_time(&statbuf.st_atim));
761 printf("Modify: %s\n", human_time(statbuf.st_mtime)); 758 printf("Modify: %s\n", human_time(&statbuf.st_mtim));
762 printf("Change: %s\n", human_time(statbuf.st_ctime)); 759 printf("Change: %s\n", human_time(&statbuf.st_ctim));
763 } 760 }
764#endif /* FEATURE_STAT_FORMAT */ 761#endif /* FEATURE_STAT_FORMAT */
765 return 1; 762 return 1;
diff --git a/coreutils/stty.c b/coreutils/stty.c
index d1309f9aa..40e812799 100644
--- a/coreutils/stty.c
+++ b/coreutils/stty.c
@@ -1320,7 +1320,7 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1320 break; 1320 break;
1321 case 'F': 1321 case 'F':
1322 if (file_name) 1322 if (file_name)
1323 bb_error_msg_and_die("only one device may be specified"); 1323 bb_simple_error_msg_and_die("only one device may be specified");
1324 file_name = &arg[i+1]; /* "-Fdevice" ? */ 1324 file_name = &arg[i+1]; /* "-Fdevice" ? */
1325 if (!file_name[0]) { /* nope, "-F device" */ 1325 if (!file_name[0]) { /* nope, "-F device" */
1326 int p = k+1; /* argv[p] is argnext */ 1326 int p = k+1; /* argv[p] is argnext */
@@ -1405,13 +1405,13 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1405 if ((stty_state & (STTY_verbose_output | STTY_recoverable_output)) == 1405 if ((stty_state & (STTY_verbose_output | STTY_recoverable_output)) ==
1406 (STTY_verbose_output | STTY_recoverable_output) 1406 (STTY_verbose_output | STTY_recoverable_output)
1407 ) { 1407 ) {
1408 bb_error_msg_and_die("-a and -g are mutually exclusive"); 1408 bb_simple_error_msg_and_die("-a and -g are mutually exclusive");
1409 } 1409 }
1410 /* Specifying -a or -g with non-options is an error */ 1410 /* Specifying -a or -g with non-options is an error */
1411 if ((stty_state & (STTY_verbose_output | STTY_recoverable_output)) 1411 if ((stty_state & (STTY_verbose_output | STTY_recoverable_output))
1412 && !(stty_state & STTY_noargs) 1412 && !(stty_state & STTY_noargs)
1413 ) { 1413 ) {
1414 bb_error_msg_and_die("modes may not be set when -a or -g is used"); 1414 bb_simple_error_msg_and_die("modes may not be set when -a or -g is used");
1415 } 1415 }
1416 1416
1417 /* Now it is safe to start doing things */ 1417 /* Now it is safe to start doing things */
diff --git a/coreutils/tail.c b/coreutils/tail.c
index 14ed85d16..1f458f9ed 100644
--- a/coreutils/tail.c
+++ b/coreutils/tail.c
@@ -89,7 +89,7 @@ static ssize_t tail_read(int fd, char *buf, size_t count)
89 89
90 r = full_read(fd, buf, count); 90 r = full_read(fd, buf, count);
91 if (r < 0) { 91 if (r < 0) {
92 bb_perror_msg(bb_msg_read_error); 92 bb_simple_perror_msg(bb_msg_read_error);
93 G.exitcode = EXIT_FAILURE; 93 G.exitcode = EXIT_FAILURE;
94 } 94 }
95 95
@@ -186,7 +186,7 @@ int tail_main(int argc, char **argv)
186 } while (++i < argc); 186 } while (++i < argc);
187 187
188 if (!nfiles) 188 if (!nfiles)
189 bb_error_msg_and_die("no files"); 189 bb_simple_error_msg_and_die("no files");
190 190
191 /* prepare the buffer */ 191 /* prepare the buffer */
192 tailbufsize = BUFSIZ; 192 tailbufsize = BUFSIZ;
diff --git a/coreutils/test.c b/coreutils/test.c
index 8d7dac025..868ffbecb 100644
--- a/coreutils/test.c
+++ b/coreutils/test.c
@@ -832,12 +832,12 @@ int test_main(int argc, char **argv)
832 --argc; 832 --argc;
833 if (!arg0[1]) { /* "[" ? */ 833 if (!arg0[1]) { /* "[" ? */
834 if (NOT_LONE_CHAR(argv[argc], ']')) { 834 if (NOT_LONE_CHAR(argv[argc], ']')) {
835 bb_error_msg("missing ]"); 835 bb_simple_error_msg("missing ]");
836 return 2; 836 return 2;
837 } 837 }
838 } else { /* assuming "[[" */ 838 } else { /* assuming "[[" */
839 if (strcmp(argv[argc], "]]") != 0) { 839 if (strcmp(argv[argc], "]]") != 0) {
840 bb_error_msg("missing ]]"); 840 bb_simple_error_msg("missing ]]");
841 return 2; 841 return 2;
842 } 842 }
843 } 843 }
diff --git a/coreutils/tr.c b/coreutils/tr.c
index ae35a9ee3..1e402dfdb 100644
--- a/coreutils/tr.c
+++ b/coreutils/tr.c
@@ -308,7 +308,7 @@ int tr_main(int argc UNUSED_PARAM, char **argv)
308 str1_length = complement(str1, str1_length); 308 str1_length = complement(str1, str1_length);
309 if (*argv) { 309 if (*argv) {
310 if (argv[0][0] == '\0') 310 if (argv[0][0] == '\0')
311 bb_error_msg_and_die("STRING2 cannot be empty"); 311 bb_simple_error_msg_and_die("STRING2 cannot be empty");
312 str2_length = expand(*argv, &str2); 312 str2_length = expand(*argv, &str2);
313 map(vector, str1, str1_length, 313 map(vector, str1, str1_length,
314 str2, str2_length); 314 str2, str2_length);
@@ -333,7 +333,7 @@ int tr_main(int argc UNUSED_PARAM, char **argv)
333 read_chars = safe_read(STDIN_FILENO, str1, TR_BUFSIZ); 333 read_chars = safe_read(STDIN_FILENO, str1, TR_BUFSIZ);
334 if (read_chars <= 0) { 334 if (read_chars <= 0) {
335 if (read_chars < 0) 335 if (read_chars < 0)
336 bb_perror_msg_and_die(bb_msg_read_error); 336 bb_simple_perror_msg_and_die(bb_msg_read_error);
337 break; 337 break;
338 } 338 }
339 in_index = 0; 339 in_index = 0;
diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c
index 5f69e62b3..dc8ef5cca 100644
--- a/coreutils/uudecode.c
+++ b/coreutils/uudecode.c
@@ -82,7 +82,7 @@ static void FAST_FUNC read_stduu(FILE *src_stream, FILE *dst_stream, int flags U
82 continue; 82 continue;
83 } 83 }
84 if (encoded_len > 60) { 84 if (encoded_len > 60) {
85 bb_error_msg_and_die("line too long"); 85 bb_simple_error_msg_and_die("line too long");
86 } 86 }
87 87
88 dst = line; 88 dst = line;
@@ -108,7 +108,7 @@ static void FAST_FUNC read_stduu(FILE *src_stream, FILE *dst_stream, int flags U
108 fwrite(line, 1, dst - line, dst_stream); 108 fwrite(line, 1, dst - line, dst_stream);
109 free(line); 109 free(line);
110 } 110 }
111 bb_error_msg_and_die("short file"); 111 bb_simple_error_msg_and_die("short file");
112} 112}
113#endif 113#endif
114 114
@@ -166,7 +166,7 @@ int uudecode_main(int argc UNUSED_PARAM, char **argv)
166 /* fclose_if_not_stdin(src_stream); - redundant */ 166 /* fclose_if_not_stdin(src_stream); - redundant */
167 return EXIT_SUCCESS; 167 return EXIT_SUCCESS;
168 } 168 }
169 bb_error_msg_and_die("no 'begin' line"); 169 bb_simple_error_msg_and_die("no 'begin' line");
170} 170}
171#endif 171#endif
172 172
@@ -216,7 +216,7 @@ int base64_main(int argc UNUSED_PARAM, char **argv)
216 if (!size) 216 if (!size)
217 break; 217 break;
218 if ((ssize_t)size < 0) 218 if ((ssize_t)size < 0)
219 bb_perror_msg_and_die(bb_msg_read_error); 219 bb_simple_perror_msg_and_die(bb_msg_read_error);
220 /* Encode the buffer we just read in */ 220 /* Encode the buffer we just read in */
221 bb_uuencode(dst_buf, src_buf, size, bb_uuenc_tbl_base64); 221 bb_uuencode(dst_buf, src_buf, size, bb_uuenc_tbl_base64);
222 xwrite(STDOUT_FILENO, dst_buf, 4 * ((size + 2) / 3)); 222 xwrite(STDOUT_FILENO, dst_buf, 4 * ((size + 2) / 3));
diff --git a/coreutils/uuencode.c b/coreutils/uuencode.c
index 2807ef82a..db49ec80a 100644
--- a/coreutils/uuencode.c
+++ b/coreutils/uuencode.c
@@ -66,7 +66,7 @@ int uuencode_main(int argc UNUSED_PARAM, char **argv)
66 if (!size) 66 if (!size)
67 break; 67 break;
68 if ((ssize_t)size < 0) 68 if ((ssize_t)size < 0)
69 bb_perror_msg_and_die(bb_msg_read_error); 69 bb_simple_perror_msg_and_die(bb_msg_read_error);
70 /* Encode the buffer we just read in */ 70 /* Encode the buffer we just read in */
71 bb_uuencode(dst_buf, src_buf, size, tbl); 71 bb_uuencode(dst_buf, src_buf, size, tbl);
72 bb_putchar('\n'); 72 bb_putchar('\n');
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c
index 72642ae74..68df44ae9 100644
--- a/debianutils/start_stop_daemon.c
+++ b/debianutils/start_stop_daemon.c
@@ -317,7 +317,7 @@ static void do_procinit(void)
317 } 317 }
318 closedir(procdir); 318 closedir(procdir);
319 if (!pid) 319 if (!pid)
320 bb_error_msg_and_die("nothing in /proc - not mounted?"); 320 bb_simple_error_msg_and_die("nothing in /proc - not mounted?");
321} 321}
322 322
323static int do_stop(void) 323static int do_stop(void)
@@ -337,7 +337,7 @@ static int do_stop(void)
337 } else if (userspec) { 337 } else if (userspec) {
338 what = xasprintf("process(es) owned by '%s'", userspec); 338 what = xasprintf("process(es) owned by '%s'", userspec);
339 } else { 339 } else {
340 bb_error_msg_and_die("internal error, please report"); 340 bb_simple_error_msg_and_die("internal error, please report");
341 } 341 }
342 342
343 if (!G.found_procs) { 343 if (!G.found_procs) {
@@ -537,6 +537,15 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv)
537 /* User wants _us_ to make the pidfile */ 537 /* User wants _us_ to make the pidfile */
538 write_pidfile(pidfile); 538 write_pidfile(pidfile);
539 } 539 }
540#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
541 if (opt & OPT_NICELEVEL) {
542 /* Set process priority (must be before OPT_c) */
543 int prio = getpriority(PRIO_PROCESS, 0) + xatoi_range(opt_N, INT_MIN/2, INT_MAX/2);
544 if (setpriority(PRIO_PROCESS, 0, prio) < 0) {
545 bb_perror_msg_and_die("setpriority(%d)", prio);
546 }
547 }
548#endif
540 if (opt & OPT_c) { 549 if (opt & OPT_c) {
541 struct bb_uidgid_t ugid; 550 struct bb_uidgid_t ugid;
542 parse_chown_usergroup_or_die(&ugid, chuid); 551 parse_chown_usergroup_or_die(&ugid, chuid);
@@ -551,15 +560,6 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv)
551 setgroups(1, &ugid.gid); 560 setgroups(1, &ugid.gid);
552 } 561 }
553 } 562 }
554#if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
555 if (opt & OPT_NICELEVEL) {
556 /* Set process priority */
557 int prio = getpriority(PRIO_PROCESS, 0) + xatoi_range(opt_N, INT_MIN/2, INT_MAX/2);
558 if (setpriority(PRIO_PROCESS, 0, prio) < 0) {
559 bb_perror_msg_and_die("setpriority(%d)", prio);
560 }
561 }
562#endif
563 /* Try: 563 /* Try:
564 * strace -oLOG start-stop-daemon -S -x /bin/usleep -a qwerty 500000 564 * strace -oLOG start-stop-daemon -S -x /bin/usleep -a qwerty 500000
565 * should exec "/bin/usleep", but argv[0] should be "qwerty": 565 * should exec "/bin/usleep", but argv[0] should be "qwerty":
diff --git a/e2fsprogs/chattr.c b/e2fsprogs/chattr.c
index c93e209b5..c37469021 100644
--- a/e2fsprogs/chattr.c
+++ b/e2fsprogs/chattr.c
@@ -196,11 +196,11 @@ int chattr_main(int argc UNUSED_PARAM, char **argv)
196 196
197 /* run sanity checks on all the arguments given us */ 197 /* run sanity checks on all the arguments given us */
198 if ((g.flags & OPT_SET) && (g.flags & (OPT_ADD|OPT_REM))) 198 if ((g.flags & OPT_SET) && (g.flags & (OPT_ADD|OPT_REM)))
199 bb_error_msg_and_die("= is incompatible with - and +"); 199 bb_simple_error_msg_and_die("= is incompatible with - and +");
200 if (g.rf & g.af) 200 if (g.rf & g.af)
201 bb_error_msg_and_die("can't set and unset a flag"); 201 bb_simple_error_msg_and_die("can't set and unset a flag");
202 if (!g.flags) 202 if (!g.flags)
203 bb_error_msg_and_die("must use '-v', =, - or +"); 203 bb_simple_error_msg_and_die("must use '-v', =, - or +");
204 204
205 /* now run chattr on all the files passed to us */ 205 /* now run chattr on all the files passed to us */
206 do change_attributes(*argv, &g); while (*++argv); 206 do change_attributes(*argv, &g); while (*++argv);
diff --git a/e2fsprogs/fsck.c b/e2fsprogs/fsck.c
index 8a14b3bdc..fc53a9043 100644
--- a/e2fsprogs/fsck.c
+++ b/e2fsprogs/fsck.c
@@ -431,10 +431,10 @@ static int wait_one(int flags)
431 if (errno == EINTR) 431 if (errno == EINTR)
432 continue; 432 continue;
433 if (errno == ECHILD) { /* paranoia */ 433 if (errno == ECHILD) { /* paranoia */
434 bb_error_msg("wait: no more children"); 434 bb_simple_error_msg("wait: no more children");
435 return -1; 435 return -1;
436 } 436 }
437 bb_perror_msg("wait"); 437 bb_simple_perror_msg("wait");
438 continue; 438 continue;
439 } 439 }
440 prev = NULL; 440 prev = NULL;
@@ -919,7 +919,7 @@ static void compile_fs_type(char *fs_type)
919 if (G.fs_type_negated == -1) 919 if (G.fs_type_negated == -1)
920 G.fs_type_negated = negate; 920 G.fs_type_negated = negate;
921 if (G.fs_type_negated != negate) 921 if (G.fs_type_negated != negate)
922 bb_error_msg_and_die( 922 bb_simple_error_msg_and_die(
923"either all or none of the filesystem types passed to -t must be prefixed " 923"either all or none of the filesystem types passed to -t must be prefixed "
924"with 'no' or '!'"); 924"with 'no' or '!'");
925 } 925 }
diff --git a/editors/awk.c b/editors/awk.c
index c4553728d..d1fedb572 100644
--- a/editors/awk.c
+++ b/editors/awk.c
@@ -2652,7 +2652,7 @@ static var *evaluate(node *op, var *res)
2652 if (opn == '|') { 2652 if (opn == '|') {
2653 rsm->F = popen(R.s, "w"); 2653 rsm->F = popen(R.s, "w");
2654 if (rsm->F == NULL) 2654 if (rsm->F == NULL)
2655 bb_perror_msg_and_die("popen"); 2655 bb_simple_perror_msg_and_die("popen");
2656 rsm->is_pipe = 1; 2656 rsm->is_pipe = 1;
2657 } else { 2657 } else {
2658 rsm->F = xfopen(R.s, opn=='w' ? "w" : "a"); 2658 rsm->F = xfopen(R.s, opn=='w' ? "w" : "a");
@@ -3265,7 +3265,7 @@ int awk_main(int argc UNUSED_PARAM, char **argv)
3265 argv += optind; 3265 argv += optind;
3266 //argc -= optind; 3266 //argc -= optind;
3267 if (opt & OPT_W) 3267 if (opt & OPT_W)
3268 bb_error_msg("warning: option -W is ignored"); 3268 bb_simple_error_msg("warning: option -W is ignored");
3269 if (opt & OPT_F) { 3269 if (opt & OPT_F) {
3270 unescape_string_in_place(opt_F); 3270 unescape_string_in_place(opt_F);
3271 setvar_s(intvar[FS], opt_F); 3271 setvar_s(intvar[FS], opt_F);
diff --git a/editors/diff.c b/editors/diff.c
index cf531460f..093e7b498 100644
--- a/editors/diff.c
+++ b/editors/diff.c
@@ -1027,7 +1027,7 @@ int diff_main(int argc UNUSED_PARAM, char **argv)
1027 xfunc_error_retval = 1; 1027 xfunc_error_retval = 1;
1028 1028
1029 if (gotstdin && (S_ISDIR(stb[0].st_mode) || S_ISDIR(stb[1].st_mode))) 1029 if (gotstdin && (S_ISDIR(stb[0].st_mode) || S_ISDIR(stb[1].st_mode)))
1030 bb_error_msg_and_die("can't compare stdin to a directory"); 1030 bb_simple_error_msg_and_die("can't compare stdin to a directory");
1031 1031
1032 /* Compare metadata to check if the files are the same physical file. 1032 /* Compare metadata to check if the files are the same physical file.
1033 * 1033 *
@@ -1063,7 +1063,7 @@ int diff_main(int argc UNUSED_PARAM, char **argv)
1063#if ENABLE_FEATURE_DIFF_DIR 1063#if ENABLE_FEATURE_DIFF_DIR
1064 diffdir(file, s_start); 1064 diffdir(file, s_start);
1065#else 1065#else
1066 bb_error_msg_and_die("no support for directory comparison"); 1066 bb_simple_error_msg_and_die("no support for directory comparison");
1067#endif 1067#endif
1068 } else { 1068 } else {
1069 bool dirfile = S_ISDIR(stb[0].st_mode) || S_ISDIR(stb[1].st_mode); 1069 bool dirfile = S_ISDIR(stb[0].st_mode) || S_ISDIR(stb[1].st_mode);
diff --git a/editors/ed.c b/editors/ed.c
index 1a36add39..d3ae8da92 100644
--- a/editors/ed.c
+++ b/editors/ed.c
@@ -165,7 +165,7 @@ static NOINLINE int searchLines(const char *str, int num1, int num2)
165 165
166 if (*str == '\0') { 166 if (*str == '\0') {
167 if (searchString[0] == '\0') { 167 if (searchString[0] == '\0') {
168 bb_error_msg("no previous search string"); 168 bb_simple_error_msg("no previous search string");
169 return 0; 169 return 0;
170 } 170 }
171 str = searchString; 171 str = searchString;
@@ -228,7 +228,7 @@ static const char* getNum(const char *cp, smallint *retHaveNum, int *retNum)
228 case '\'': 228 case '\'':
229 cp++; 229 cp++;
230 if ((unsigned)(*cp - 'a') >= 26) { 230 if ((unsigned)(*cp - 'a') >= 26) {
231 bb_error_msg("bad mark name"); 231 bb_simple_error_msg("bad mark name");
232 return NULL; 232 return NULL;
233 } 233 }
234 haveNum = TRUE; 234 haveNum = TRUE;
@@ -314,7 +314,7 @@ static int insertLine(int num, const char *data, int len)
314 LINE *newLp, *lp; 314 LINE *newLp, *lp;
315 315
316 if ((num < 1) || (num > lastNum + 1)) { 316 if ((num < 1) || (num > lastNum + 1)) {
317 bb_error_msg("inserting at bad line number"); 317 bb_simple_error_msg("inserting at bad line number");
318 return FALSE; 318 return FALSE;
319 } 319 }
320 320
@@ -384,7 +384,7 @@ static int readLines(const char *file, int num)
384 char *cp; 384 char *cp;
385 385
386 if ((num < 1) || (num > lastNum + 1)) { 386 if ((num < 1) || (num > lastNum + 1)) {
387 bb_error_msg("bad line for read"); 387 bb_simple_error_msg("bad line for read");
388 return FALSE; 388 return FALSE;
389 } 389 }
390 390
@@ -629,7 +629,7 @@ static void subCommand(const char *cmd, int num1, int num2)
629 cp = buf; 629 cp = buf;
630 630
631 if (isblank(*cp) || (*cp == '\0')) { 631 if (isblank(*cp) || (*cp == '\0')) {
632 bb_error_msg("bad delimiter for substitute"); 632 bb_simple_error_msg("bad delimiter for substitute");
633 return; 633 return;
634 } 634 }
635 635
@@ -638,7 +638,7 @@ static void subCommand(const char *cmd, int num1, int num2)
638 638
639 cp = strchr(cp, delim); 639 cp = strchr(cp, delim);
640 if (cp == NULL) { 640 if (cp == NULL) {
641 bb_error_msg("missing 2nd delimiter for substitute"); 641 bb_simple_error_msg("missing 2nd delimiter for substitute");
642 return; 642 return;
643 } 643 }
644 644
@@ -660,13 +660,13 @@ static void subCommand(const char *cmd, int num1, int num2)
660 printFlag = TRUE; 660 printFlag = TRUE;
661 break; 661 break;
662 default: 662 default:
663 bb_error_msg("unknown option for substitute"); 663 bb_simple_error_msg("unknown option for substitute");
664 return; 664 return;
665 } 665 }
666 666
667 if (*oldStr == '\0') { 667 if (*oldStr == '\0') {
668 if (searchString[0] == '\0') { 668 if (searchString[0] == '\0') {
669 bb_error_msg("no previous search string"); 669 bb_simple_error_msg("no previous search string");
670 return; 670 return;
671 } 671 }
672 oldStr = searchString; 672 oldStr = searchString;
@@ -846,7 +846,7 @@ static void doCommands(void)
846 846
847 case 'f': 847 case 'f':
848 if (*cp != '\0' && *cp != ' ') { 848 if (*cp != '\0' && *cp != ' ') {
849 bb_error_msg("bad file command"); 849 bb_simple_error_msg("bad file command");
850 break; 850 break;
851 } 851 }
852 cp = skip_whitespace(cp); 852 cp = skip_whitespace(cp);
@@ -870,7 +870,7 @@ static void doCommands(void)
870 case 'k': 870 case 'k':
871 cp = skip_whitespace(cp); 871 cp = skip_whitespace(cp);
872 if ((unsigned)(*cp - 'a') >= 26 || cp[1]) { 872 if ((unsigned)(*cp - 'a') >= 26 || cp[1]) {
873 bb_error_msg("bad mark name"); 873 bb_simple_error_msg("bad mark name");
874 break; 874 break;
875 } 875 }
876 marks[(unsigned)(*cp - 'a')] = num2; 876 marks[(unsigned)(*cp - 'a')] = num2;
@@ -887,7 +887,7 @@ static void doCommands(void)
887 case 'q': 887 case 'q':
888 cp = skip_whitespace(cp); 888 cp = skip_whitespace(cp);
889 if (have1 || *cp) { 889 if (have1 || *cp) {
890 bb_error_msg("bad quit command"); 890 bb_simple_error_msg("bad quit command");
891 break; 891 break;
892 } 892 }
893 if (!dirty) 893 if (!dirty)
@@ -903,12 +903,12 @@ static void doCommands(void)
903 903
904 case 'r': 904 case 'r':
905 if (*cp != '\0' && *cp != ' ') { 905 if (*cp != '\0' && *cp != ' ') {
906 bb_error_msg("bad read command"); 906 bb_simple_error_msg("bad read command");
907 break; 907 break;
908 } 908 }
909 cp = skip_whitespace(cp); 909 cp = skip_whitespace(cp);
910 if (*cp == '\0') { 910 if (*cp == '\0') {
911 bb_error_msg("no file name"); 911 bb_simple_error_msg("no file name");
912 break; 912 break;
913 } 913 }
914 if (!have1) 914 if (!have1)
@@ -925,14 +925,14 @@ static void doCommands(void)
925 925
926 case 'w': 926 case 'w':
927 if (*cp != '\0' && *cp != ' ') { 927 if (*cp != '\0' && *cp != ' ') {
928 bb_error_msg("bad write command"); 928 bb_simple_error_msg("bad write command");
929 break; 929 break;
930 } 930 }
931 cp = skip_whitespace(cp); 931 cp = skip_whitespace(cp);
932 if (*cp == '\0') { 932 if (*cp == '\0') {
933 cp = fileName; 933 cp = fileName;
934 if (!cp) { 934 if (!cp) {
935 bb_error_msg("no file name specified"); 935 bb_simple_error_msg("no file name specified");
936 break; 936 break;
937 } 937 }
938 } 938 }
@@ -960,7 +960,7 @@ static void doCommands(void)
960 960
961 case '.': 961 case '.':
962 if (have1) { 962 if (have1) {
963 bb_error_msg("no arguments allowed"); 963 bb_simple_error_msg("no arguments allowed");
964 break; 964 break;
965 } 965 }
966 printLines(curNum, curNum, FALSE); 966 printLines(curNum, curNum, FALSE);
@@ -984,7 +984,7 @@ static void doCommands(void)
984 break; 984 break;
985 985
986 default: 986 default:
987 bb_error_msg("unimplemented command"); 987 bb_simple_error_msg("unimplemented command");
988 break; 988 break;
989 } 989 }
990 } 990 }
diff --git a/editors/patch_bbox.c b/editors/patch_bbox.c
index 8e09ef488..d1f1ee2d6 100644
--- a/editors/patch_bbox.c
+++ b/editors/patch_bbox.c
@@ -30,7 +30,7 @@ static unsigned copy_lines(FILE *src_stream, FILE *dst_stream, unsigned lines_co
30 break; 30 break;
31 } 31 }
32 if (fputs(line, dst_stream) == EOF) { 32 if (fputs(line, dst_stream) == EOF) {
33 bb_perror_msg_and_die("error writing to new file"); 33 bb_simple_perror_msg_and_die("error writing to new file");
34 } 34 }
35 free(line); 35 free(line);
36 lines_count--; 36 lines_count--;
@@ -148,7 +148,7 @@ int patch_main(int argc UNUSED_PARAM, char **argv)
148 148
149 new_filename = extract_filename(patch_line, patch_level, "+++ "); 149 new_filename = extract_filename(patch_line, patch_level, "+++ ");
150 if (!new_filename) { 150 if (!new_filename) {
151 bb_error_msg_and_die("invalid patch"); 151 bb_simple_error_msg_and_die("invalid patch");
152 } 152 }
153 153
154 /* Get access rights from the file to be patched */ 154 /* Get access rights from the file to be patched */
@@ -209,7 +209,7 @@ int patch_main(int argc UNUSED_PARAM, char **argv)
209 /* src_beg_line will be 0 if it's a new file */ 209 /* src_beg_line will be 0 if it's a new file */
210 count = src_beg_line - src_cur_line; 210 count = src_beg_line - src_cur_line;
211 if (copy_lines(src_stream, dst_stream, count)) { 211 if (copy_lines(src_stream, dst_stream, count)) {
212 bb_error_msg_and_die("bad src file"); 212 bb_simple_error_msg_and_die("bad src file");
213 } 213 }
214 src_cur_line += count; 214 src_cur_line += count;
215 dst_cur_line += count; 215 dst_cur_line += count;
diff --git a/editors/patch_toybox.c b/editors/patch_toybox.c
index 3ffbf9084..aebab8132 100644
--- a/editors/patch_toybox.c
+++ b/editors/patch_toybox.c
@@ -200,7 +200,7 @@ int copy_tempfile(int fdin, char *name, char **tempname)
200 200
201 *tempname = xasprintf("%sXXXXXX", name); 201 *tempname = xasprintf("%sXXXXXX", name);
202 fd = mkstemp(*tempname); 202 fd = mkstemp(*tempname);
203 if(-1 == fd) bb_perror_msg_and_die("no temp file"); 203 if(-1 == fd) bb_simple_perror_msg_and_die("no temp file");
204 204
205 // Set permissions of output file 205 // Set permissions of output file
206 fstat(fdin, &statbuf); 206 fstat(fdin, &statbuf);
diff --git a/editors/sed.c b/editors/sed.c
index a93e5494a..b269b58d8 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -321,7 +321,7 @@ static int parse_regex_delim(const char *cmdstr, char **match, char **replace)
321 /* verify that the 's' or 'y' is followed by something. That something 321 /* verify that the 's' or 'y' is followed by something. That something
322 * (typically a 'slash') is now our regexp delimiter... */ 322 * (typically a 'slash') is now our regexp delimiter... */
323 if (*cmdstr == '\0') 323 if (*cmdstr == '\0')
324 bb_error_msg_and_die("bad format in substitution expression"); 324 bb_simple_error_msg_and_die("bad format in substitution expression");
325 delimiter = *cmdstr_ptr++; 325 delimiter = *cmdstr_ptr++;
326 326
327 /* save the match string */ 327 /* save the match string */
@@ -366,7 +366,7 @@ static int get_address(const char *my_str, int *linenum, regex_t ** regex)
366 } else { 366 } else {
367 *regex = G.previous_regex_ptr; 367 *regex = G.previous_regex_ptr;
368 if (!G.previous_regex_ptr) 368 if (!G.previous_regex_ptr)
369 bb_error_msg_and_die("no previous regexp"); 369 bb_simple_error_msg_and_die("no previous regexp");
370 } 370 }
371 /* Move position to next character after last delimiter */ 371 /* Move position to next character after last delimiter */
372 pos += (next+1); 372 pos += (next+1);
@@ -384,7 +384,7 @@ static int parse_file_cmd(/*sed_cmd_t *sed_cmd,*/ const char *filecmdstr, char *
384 start = skip_whitespace(filecmdstr); 384 start = skip_whitespace(filecmdstr);
385 eol = strchrnul(start, '\n'); 385 eol = strchrnul(start, '\n');
386 if (eol == start) 386 if (eol == start)
387 bb_error_msg_and_die("empty filename"); 387 bb_simple_error_msg_and_die("empty filename");
388 388
389 if (*eol) { 389 if (*eol) {
390 /* If lines glued together, put backslash back. */ 390 /* If lines glued together, put backslash back. */
@@ -474,7 +474,7 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, const char *substr)
474 goto out; 474 goto out;
475 default: 475 default:
476 dbg("s bad flags:'%s'", substr + idx); 476 dbg("s bad flags:'%s'", substr + idx);
477 bb_error_msg_and_die("bad option in substitution expression"); 477 bb_simple_error_msg_and_die("bad option in substitution expression");
478 } 478 }
479 } 479 }
480 out: 480 out:
@@ -694,7 +694,7 @@ static void add_cmd(const char *cmdstr)
694 idx--; /* if 0, trigger error check below */ 694 idx--; /* if 0, trigger error check below */
695 } 695 }
696 if (idx < 0) 696 if (idx < 0)
697 bb_error_msg_and_die("no address after comma"); 697 bb_simple_error_msg_and_die("no address after comma");
698 sed_cmd->end_line_orig = sed_cmd->end_line; 698 sed_cmd->end_line_orig = sed_cmd->end_line;
699 } 699 }
700 700
@@ -712,7 +712,7 @@ static void add_cmd(const char *cmdstr)
712 712
713 /* last part (mandatory) will be a command */ 713 /* last part (mandatory) will be a command */
714 if (!*cmdstr) 714 if (!*cmdstr)
715 bb_error_msg_and_die("missing command"); 715 bb_simple_error_msg_and_die("missing command");
716 sed_cmd->cmd = *cmdstr++; 716 sed_cmd->cmd = *cmdstr++;
717 cmdstr = parse_cmd_args(sed_cmd, cmdstr); 717 cmdstr = parse_cmd_args(sed_cmd, cmdstr);
718 718
@@ -797,7 +797,7 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line_p)
797 if (!current_regex) { 797 if (!current_regex) {
798 current_regex = G.previous_regex_ptr; 798 current_regex = G.previous_regex_ptr;
799 if (!current_regex) 799 if (!current_regex)
800 bb_error_msg_and_die("no previous regexp"); 800 bb_simple_error_msg_and_die("no previous regexp");
801 } 801 }
802 G.previous_regex_ptr = current_regex; 802 G.previous_regex_ptr = current_regex;
803 803
@@ -968,7 +968,7 @@ static void puts_maybe_newline(char *s, FILE *file, char *last_puts_char, char l
968 968
969 if (ferror(file)) { 969 if (ferror(file)) {
970 xfunc_error_retval = 4; /* It's what gnu sed exits with... */ 970 xfunc_error_retval = 4; /* It's what gnu sed exits with... */
971 bb_error_msg_and_die(bb_msg_write_error); 971 bb_simple_error_msg_and_die(bb_msg_write_error);
972 } 972 }
973 *last_puts_char = lpc; 973 *last_puts_char = lpc;
974} 974}
@@ -1203,7 +1203,7 @@ static void process_files(void)
1203 } 1203 }
1204 sed_cmd = sed_cmd->next; 1204 sed_cmd = sed_cmd->next;
1205 if (!sed_cmd) 1205 if (!sed_cmd)
1206 bb_error_msg_and_die("unterminated {"); 1206 bb_simple_error_msg_and_die("unterminated {");
1207 } 1207 }
1208 } 1208 }
1209 continue; 1209 continue;
diff --git a/editors/vi.c b/editors/vi.c
index 70c8f3daf..4676db2b2 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -1067,7 +1067,7 @@ static int readit(void) // read (maybe cursor) key from stdin
1067 goto again; 1067 goto again;
1068 go_bottom_and_clear_to_eol(); 1068 go_bottom_and_clear_to_eol();
1069 cookmode(); // terminal to "cooked" 1069 cookmode(); // terminal to "cooked"
1070 bb_error_msg_and_die("can't read user input"); 1070 bb_simple_error_msg_and_die("can't read user input");
1071 } 1071 }
1072 return c; 1072 return c;
1073} 1073}
@@ -1360,7 +1360,7 @@ static char what_reg(void)
1360 char c; 1360 char c;
1361 1361
1362 c = 'D'; // default to D-reg 1362 c = 'D'; // default to D-reg
1363 if (0 <= YDreg && YDreg <= 25) 1363 if (YDreg <= 25)
1364 c = 'a' + (char) YDreg; 1364 c = 'a' + (char) YDreg;
1365 if (YDreg == 26) 1365 if (YDreg == 26)
1366 c = 'D'; 1366 c = 'D';
@@ -2616,7 +2616,7 @@ static void colon(char *buf)
2616 free(reg[Ureg]); // free orig line reg- for 'U' 2616 free(reg[Ureg]); // free orig line reg- for 'U'
2617 reg[Ureg] = NULL; 2617 reg[Ureg] = NULL;
2618 } 2618 }
2619 if (YDreg >= 0 && YDreg < 28) { 2619 /*if (YDreg < 28) - always true*/ {
2620 free(reg[YDreg]); // free default yank/delete register 2620 free(reg[YDreg]); // free default yank/delete register
2621 reg[YDreg] = NULL; 2621 reg[YDreg] = NULL;
2622 } 2622 }
diff --git a/findutils/find.c b/findutils/find.c
index 8706e2cf3..66ad36283 100644
--- a/findutils/find.c
+++ b/findutils/find.c
@@ -1245,7 +1245,7 @@ static action*** parse_params(char **argv)
1245 * coreutils expects {} to appear only once in "-exec +" 1245 * coreutils expects {} to appear only once in "-exec +"
1246 */ 1246 */
1247 if (all_subst != 1 && ap->filelist) 1247 if (all_subst != 1 && ap->filelist)
1248 bb_error_msg_and_die("only one '{}' allowed for -exec +"); 1248 bb_simple_error_msg_and_die("only one '{}' allowed for -exec +");
1249# endif 1249# endif
1250 } 1250 }
1251#endif 1251#endif
@@ -1259,7 +1259,7 @@ static action*** parse_params(char **argv)
1259 endarg = argv; 1259 endarg = argv;
1260 while (1) { 1260 while (1) {
1261 if (!*++endarg) 1261 if (!*++endarg)
1262 bb_error_msg_and_die("unpaired '('"); 1262 bb_simple_error_msg_and_die("unpaired '('");
1263 if (LONE_CHAR(*endarg, '(')) 1263 if (LONE_CHAR(*endarg, '('))
1264 nested++; 1264 nested++;
1265 else if (LONE_CHAR(*endarg, ')') && !--nested) { 1265 else if (LONE_CHAR(*endarg, ')') && !--nested) {
diff --git a/findutils/xargs.c b/findutils/xargs.c
index 8331931bc..e0dbcbc7a 100644
--- a/findutils/xargs.c
+++ b/findutils/xargs.c
@@ -756,7 +756,7 @@ int xargs_main(int argc UNUSED_PARAM, char **argv)
756 } 756 }
757 /* Sanity check */ 757 /* Sanity check */
758 if (n_max_chars <= 0) { 758 if (n_max_chars <= 0) {
759 bb_error_msg_and_die("can't fit single argument within argument list size limit"); 759 bb_simple_error_msg_and_die("can't fit single argument within argument list size limit");
760 } 760 }
761 761
762 buf = xzalloc(n_max_chars + 1); 762 buf = xzalloc(n_max_chars + 1);
@@ -807,7 +807,7 @@ int xargs_main(int argc UNUSED_PARAM, char **argv)
807 807
808 if (!G.args[initial_idx]) { /* not even one ARG was added? */ 808 if (!G.args[initial_idx]) { /* not even one ARG was added? */
809 if (*rem != '\0') 809 if (*rem != '\0')
810 bb_error_msg_and_die("argument line too long"); 810 bb_simple_error_msg_and_die("argument line too long");
811 if (opt & OPT_NO_EMPTY) 811 if (opt & OPT_NO_EMPTY)
812 break; 812 break;
813 } 813 }
diff --git a/include/libbb.h b/include/libbb.h
index 9da94638b..84811c4f2 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -727,6 +727,7 @@ int xsocket_stream(len_and_sockaddr **lsap) FAST_FUNC;
727/* NB: these set SO_REUSEADDR before bind */ 727/* NB: these set SO_REUSEADDR before bind */
728int create_and_bind_stream_or_die(const char *bindaddr, int port) FAST_FUNC; 728int create_and_bind_stream_or_die(const char *bindaddr, int port) FAST_FUNC;
729int create_and_bind_dgram_or_die(const char *bindaddr, int port) FAST_FUNC; 729int create_and_bind_dgram_or_die(const char *bindaddr, int port) FAST_FUNC;
730int create_and_bind_to_netlink(int proto, int grp, unsigned rcvbuf) FAST_FUNC;
730/* Create client TCP socket connected to peer:port. Peer cannot be NULL. 731/* Create client TCP socket connected to peer:port. Peer cannot be NULL.
731 * Peer can be numeric IP ("N.N.N.N"), numeric IPv6 address or hostname, 732 * Peer can be numeric IP ("N.N.N.N"), numeric IPv6 address or hostname,
732 * and can have ":PORT" suffix (for IPv6 use "[X:X:...:X]:PORT"). 733 * and can have ":PORT" suffix (for IPv6 use "[X:X:...:X]:PORT").
@@ -1176,7 +1177,7 @@ void exec_prog_or_SHELL(char **argv) NORETURN FAST_FUNC;
1176({ \ 1177({ \
1177 pid_t bb__xvfork_pid = vfork(); \ 1178 pid_t bb__xvfork_pid = vfork(); \
1178 if (bb__xvfork_pid < 0) \ 1179 if (bb__xvfork_pid < 0) \
1179 bb_perror_msg_and_die("vfork"); \ 1180 bb_simple_perror_msg_and_die("vfork"); \
1180 bb__xvfork_pid; \ 1181 bb__xvfork_pid; \
1181}) 1182})
1182#else 1183#else
@@ -1366,13 +1367,17 @@ extern void (*die_func)(void);
1366void xfunc_die(void) NORETURN FAST_FUNC; 1367void xfunc_die(void) NORETURN FAST_FUNC;
1367void bb_show_usage(void) NORETURN FAST_FUNC; 1368void bb_show_usage(void) NORETURN FAST_FUNC;
1368void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; 1369void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
1370void bb_simple_error_msg(const char *s) FAST_FUNC;
1369void bb_error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC; 1371void bb_error_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;
1372void bb_simple_error_msg_and_die(const char *s) NORETURN FAST_FUNC;
1370void bb_perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; 1373void bb_perror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
1371void bb_simple_perror_msg(const char *s) FAST_FUNC; 1374void bb_simple_perror_msg(const char *s) FAST_FUNC;
1372void bb_perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC; 1375void bb_perror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;
1373void bb_simple_perror_msg_and_die(const char *s) NORETURN FAST_FUNC; 1376void bb_simple_perror_msg_and_die(const char *s) NORETURN FAST_FUNC;
1374void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; 1377void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
1378void bb_simple_herror_msg(const char *s) FAST_FUNC;
1375void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC; 1379void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC;
1380void bb_simple_herror_msg_and_die(const char *s) NORETURN FAST_FUNC;
1376void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC; 1381void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC;
1377void bb_perror_nomsg(void) FAST_FUNC; 1382void bb_perror_nomsg(void) FAST_FUNC;
1378void bb_verror_msg(const char *s, va_list p, const char *strerr) FAST_FUNC; 1383void bb_verror_msg(const char *s, va_list p, const char *strerr) FAST_FUNC;
@@ -1381,12 +1386,51 @@ void bb_logenv_override(void) FAST_FUNC;
1381 1386
1382#if ENABLE_FEATURE_SYSLOG_INFO 1387#if ENABLE_FEATURE_SYSLOG_INFO
1383void bb_info_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; 1388void bb_info_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
1389void bb_simple_info_msg(const char *s) FAST_FUNC;
1384void bb_vinfo_msg(const char *s, va_list p) FAST_FUNC; 1390void bb_vinfo_msg(const char *s, va_list p) FAST_FUNC;
1385#else 1391#else
1386#define bb_info_msg bb_error_msg 1392#define bb_info_msg bb_error_msg
1393#define bb_simple_info_msg bb_simple_error_msg
1387#define bb_vinfo_msg(s,p) bb_verror_msg(s,p,NULL) 1394#define bb_vinfo_msg(s,p) bb_verror_msg(s,p,NULL)
1388#endif 1395#endif
1389 1396
1397#if ENABLE_WARN_SIMPLE_MSG
1398/* If enabled, cause calls to bb_error_msg() et al that only take a single
1399 * parameter to generate a warning.
1400 */
1401static inline void __attribute__ ((deprecated("use bb_simple_error_msg instead")))
1402 bb_not_simple_error_msg(const char *s) { bb_simple_error_msg(s); }
1403static inline void __attribute__ ((deprecated("use bb_simple_error_msg_and_die instead"))) NORETURN
1404 bb_not_simple_error_msg_and_die(const char *s) { bb_simple_error_msg_and_die(s); }
1405static inline void __attribute__ ((deprecated("use bb_simple_perror_msg instead")))
1406 bb_not_simple_perror_msg(const char *s) { bb_simple_perror_msg(s); }
1407static inline void __attribute__ ((deprecated("use bb_simple_perror_msg_and_die instead"))) NORETURN
1408 bb_not_simple_perror_msg_and_die(const char *s) { bb_simple_perror_msg_and_die(s); }
1409static inline void __attribute__ ((deprecated("use bb_simple_herror_msg instead")))
1410 bb_not_simple_herror_msg(const char *s) { bb_simple_herror_msg(s); }
1411static inline void __attribute__ ((deprecated("use bb_simple_herror_msg_and_die instead"))) NORETURN
1412 bb_not_simple_herror_msg_and_die(const char *s) { bb_simple_herror_msg_and_die(s); }
1413static inline void __attribute__ ((deprecated("use bb_simple_info_msg instead")))
1414 bb_not_simple_info_msg(const char *s) { bb_simple_info_msg(s); }
1415/* Override bb_error_msg() and related functions with macros that will
1416 * substitute them for the equivalent bb_not_simple_error_msg() function when
1417 * they are used with only a single parameter. Macro approach inspired by
1418 * https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments and
1419 * https://gustedt.wordpress.com/2010/06/03/default-arguments-for-c99
1420 */
1421#define _ARG18(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, ...) _17
1422#define BB_MSG_KIND(...) _ARG18(__VA_ARGS__, , , , , , , , , , , , , , , , , _not_simple)
1423#define _BB_MSG(name, kind, ...) bb##kind##name(__VA_ARGS__)
1424#define BB_MSG(name, kind, ...) _BB_MSG(name, kind, __VA_ARGS__)
1425#define bb_error_msg(...) BB_MSG(_error_msg, BB_MSG_KIND(__VA_ARGS__), __VA_ARGS__)
1426#define bb_error_msg_and_die(...) BB_MSG(_error_msg_and_die, BB_MSG_KIND(__VA_ARGS__), __VA_ARGS__)
1427#define bb_perror_msg(...) BB_MSG(_perror_msg, BB_MSG_KIND(__VA_ARGS__), __VA_ARGS__)
1428#define bb_perror_msg_and_die(...) BB_MSG(_perror_msg_and_die, BB_MSG_KIND(__VA_ARGS__), __VA_ARGS__)
1429#define bb_herror_msg(...) BB_MSG(_herror_msg, BB_MSG_KIND(__VA_ARGS__), __VA_ARGS__)
1430#define bb_herror_msg_and_die(...) BB_MSG(_herror_msg_and_die, BB_MSG_KIND(__VA_ARGS__), __VA_ARGS__)
1431#define bb_info_msg(...) BB_MSG(_info_msg, BB_MSG_KIND(__VA_ARGS__), __VA_ARGS__)
1432#endif
1433
1390/* We need to export XXX_main from libbusybox 1434/* We need to export XXX_main from libbusybox
1391 * only if we build "individual" binaries 1435 * only if we build "individual" binaries
1392 */ 1436 */
@@ -1503,17 +1547,19 @@ extern void bb_warn_ignoring_args(char *arg) FAST_FUNC;
1503 1547
1504extern int get_linux_version_code(void) FAST_FUNC; 1548extern int get_linux_version_code(void) FAST_FUNC;
1505 1549
1506extern char *query_loop(const char *device) FAST_FUNC; 1550char *query_loop(const char *device) FAST_FUNC;
1507extern int del_loop(const char *device) FAST_FUNC; 1551int get_free_loop(void) FAST_FUNC;
1552int del_loop(const char *device) FAST_FUNC;
1508/* 1553/*
1509 * If *devname is not NULL, use that name, otherwise try to find free one, 1554 * If *devname is not NULL, use that name, otherwise try to find free one,
1510 * malloc and return it in *devname. 1555 * malloc and return it in *devname.
1511 * return value is the opened fd to the loop device, or < on error 1556 * return value is the opened fd to the loop device, or < on error
1512 */ 1557 */
1513extern int set_loop(char **devname, const char *file, unsigned long long offset, unsigned flags) FAST_FUNC; 1558int set_loop(char **devname, const char *file, unsigned long long offset, unsigned flags) FAST_FUNC;
1514/* These constants match linux/loop.h (without BB_ prefix): */ 1559/* These constants match linux/loop.h (without BB_ prefix): */
1515#define BB_LO_FLAGS_READ_ONLY 1 1560#define BB_LO_FLAGS_READ_ONLY 1
1516#define BB_LO_FLAGS_AUTOCLEAR 4 1561#define BB_LO_FLAGS_AUTOCLEAR 4
1562#define BB_LO_FLAGS_PARTSCAN 8
1517 1563
1518/* Returns malloced str */ 1564/* Returns malloced str */
1519char *bb_ask_noecho(int fd, int timeout, const char *prompt) FAST_FUNC; 1565char *bb_ask_noecho(int fd, int timeout, const char *prompt) FAST_FUNC;
diff --git a/init/bootchartd.c b/init/bootchartd.c
index 4377d90e3..750f67356 100644
--- a/init/bootchartd.c
+++ b/init/bootchartd.c
@@ -208,7 +208,7 @@ static char *make_tempdir(void)
208 bb_perror_msg_and_die("can't %smount tmpfs", "un"); 208 bb_perror_msg_and_die("can't %smount tmpfs", "un");
209 } 209 }
210#else 210#else
211 bb_perror_msg_and_die("can't create temporary directory"); 211 bb_simple_perror_msg_and_die("can't create temporary directory");
212#endif 212#endif
213 } else { 213 } else {
214 xchdir(tempdir); 214 xchdir(tempdir);
diff --git a/init/init.c b/init/init.c
index 87086b48b..0f3c5fa4d 100644
--- a/init/init.c
+++ b/init/init.c
@@ -1086,7 +1086,7 @@ int init_main(int argc UNUSED_PARAM, char **argv)
1086 if (getpid() != 1 1086 if (getpid() != 1
1087 && (!ENABLE_LINUXRC || applet_name[0] != 'l') /* not linuxrc? */ 1087 && (!ENABLE_LINUXRC || applet_name[0] != 'l') /* not linuxrc? */
1088 ) { 1088 ) {
1089 bb_error_msg_and_die("must be run as PID 1"); 1089 bb_simple_error_msg_and_die("must be run as PID 1");
1090 } 1090 }
1091#ifdef RB_DISABLE_CAD 1091#ifdef RB_DISABLE_CAD
1092 /* Turn off rebooting via CTL-ALT-DEL - we get a 1092 /* Turn off rebooting via CTL-ALT-DEL - we get a
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index 1f1a18aab..ef7d1ccd9 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -650,7 +650,7 @@ static void check_suid(int applet_no)
650 /* same group / in group */ 650 /* same group / in group */
651 m >>= 3; 651 m >>= 3;
652 if (!(m & S_IXOTH)) /* is x bit not set? */ 652 if (!(m & S_IXOTH)) /* is x bit not set? */
653 bb_error_msg_and_die("you have no permission to run this applet"); 653 bb_simple_error_msg_and_die("you have no permission to run this applet");
654 654
655 /* We set effective AND saved ids. If saved-id is not set 655 /* We set effective AND saved ids. If saved-id is not set
656 * like we do below, seteuid(0) can still later succeed! */ 656 * like we do below, seteuid(0) can still later succeed! */
@@ -662,7 +662,7 @@ static void check_suid(int applet_no)
662 rgid = sct->m_ugid.gid; 662 rgid = sct->m_ugid.gid;
663 /* else: we will set egid = rgid, thus dropping sgid effect */ 663 /* else: we will set egid = rgid, thus dropping sgid effect */
664 if (setresgid(-1, rgid, rgid)) 664 if (setresgid(-1, rgid, rgid))
665 bb_perror_msg_and_die("setresgid"); 665 bb_simple_perror_msg_and_die("setresgid");
666 666
667 /* Are we directed to change uid 667 /* Are we directed to change uid
668 * (APPLET = s** USER.GROUP or APPLET = S** USER.GROUP)? 668 * (APPLET = s** USER.GROUP or APPLET = S** USER.GROUP)?
@@ -672,7 +672,7 @@ static void check_suid(int applet_no)
672 uid = sct->m_ugid.uid; 672 uid = sct->m_ugid.uid;
673 /* else: we will set euid = ruid, thus dropping suid effect */ 673 /* else: we will set euid = ruid, thus dropping suid effect */
674 if (setresuid(-1, uid, uid)) 674 if (setresuid(-1, uid, uid))
675 bb_perror_msg_and_die("setresuid"); 675 bb_simple_perror_msg_and_die("setresuid");
676 676
677 goto ret; 677 goto ret;
678 } 678 }
@@ -682,7 +682,7 @@ static void check_suid(int applet_no)
682 682
683 if (!onetime) { 683 if (!onetime) {
684 onetime = 1; 684 onetime = 1;
685 bb_error_msg("using fallback suid method"); 685 bb_simple_error_msg("using fallback suid method");
686 } 686 }
687 } 687 }
688# endif 688# endif
@@ -692,7 +692,7 @@ static void check_suid(int applet_no)
692 /* Real uid is not 0. If euid isn't 0 too, suid bit 692 /* Real uid is not 0. If euid isn't 0 too, suid bit
693 * is most probably not set on our executable */ 693 * is most probably not set on our executable */
694 if (geteuid()) 694 if (geteuid())
695 bb_error_msg_and_die("must be suid to work properly"); 695 bb_simple_error_msg_and_die("must be suid to work properly");
696 } else if (APPLET_SUID(applet_no) == BB_SUID_DROP) { 696 } else if (APPLET_SUID(applet_no) == BB_SUID_DROP) {
697 /* 697 /*
698 * Drop all privileges. 698 * Drop all privileges.
diff --git a/libbb/bb_getgroups.c b/libbb/bb_getgroups.c
index 59ae53738..5d83c729a 100644
--- a/libbb/bb_getgroups.c
+++ b/libbb/bb_getgroups.c
@@ -38,7 +38,7 @@ gid_t* FAST_FUNC bb_getgroups(int *ngroups, gid_t *group_array)
38 continue; 38 continue;
39 } 39 }
40 /* Some other error (should never happen on Linux) */ 40 /* Some other error (should never happen on Linux) */
41 bb_perror_msg_and_die("getgroups"); 41 bb_simple_perror_msg_and_die("getgroups");
42 } 42 }
43 43
44 if (ngroups) 44 if (ngroups)
diff --git a/libbb/bbunit.c b/libbb/bbunit.c
index 5f8d980a3..ccd909d78 100644
--- a/libbb/bbunit.c
+++ b/libbb/bbunit.c
@@ -60,6 +60,6 @@ int unit_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
60 return EXIT_FAILURE; 60 return EXIT_FAILURE;
61 } 61 }
62 62
63 bb_error_msg("All tests passed"); 63 bb_simple_error_msg("All tests passed");
64 return EXIT_SUCCESS; 64 return EXIT_SUCCESS;
65} 65}
diff --git a/libbb/capability.c b/libbb/capability.c
index d0ae78b91..23afd8eb9 100644
--- a/libbb/capability.c
+++ b/libbb/capability.c
@@ -119,7 +119,7 @@ void FAST_FUNC getcaps(void *arg)
119 caps->u32s = _LINUX_CAPABILITY_U32S_3; 119 caps->u32s = _LINUX_CAPABILITY_U32S_3;
120 break; 120 break;
121 default: 121 default:
122 bb_error_msg_and_die("unsupported capability version"); 122 bb_simple_error_msg_and_die("unsupported capability version");
123 } 123 }
124 124
125 if (capget(&caps->header, caps->data) != 0) 125 if (capget(&caps->header, caps->data) != 0)
diff --git a/libbb/change_identity.c b/libbb/change_identity.c
index 20d7c5f2d..9ff741234 100644
--- a/libbb/change_identity.c
+++ b/libbb/change_identity.c
@@ -51,7 +51,7 @@ void FAST_FUNC change_identity(const struct passwd *pw)
51 return; 51 return;
52 } 52 }
53 53
54 bb_perror_msg_and_die("can't set groups"); 54 bb_simple_perror_msg_and_die("can't set groups");
55 } 55 }
56 56
57 xsetgid(pw->pw_gid); 57 xsetgid(pw->pw_gid);
diff --git a/libbb/copy_file.c b/libbb/copy_file.c
index 1dc515b07..9b10dda1f 100644
--- a/libbb/copy_file.c
+++ b/libbb/copy_file.c
@@ -333,7 +333,7 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags)
333 ) { 333 ) {
334 security_context_t con; 334 security_context_t con;
335 if (getfscreatecon(&con) == -1) { 335 if (getfscreatecon(&con) == -1) {
336 bb_perror_msg("getfscreatecon"); 336 bb_simple_perror_msg("getfscreatecon");
337 return -1; 337 return -1;
338 } 338 }
339 if (con) { 339 if (con) {
diff --git a/libbb/copyfd.c b/libbb/copyfd.c
index dd0517cd6..ae5c26999 100644
--- a/libbb/copyfd.c
+++ b/libbb/copyfd.c
@@ -87,7 +87,7 @@ static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size)
87 rd = safe_read(src_fd, buffer, 87 rd = safe_read(src_fd, buffer,
88 size > buffer_size ? buffer_size : size); 88 size > buffer_size ? buffer_size : size);
89 if (rd < 0) { 89 if (rd < 0) {
90 bb_perror_msg(bb_msg_read_error); 90 bb_simple_perror_msg(bb_msg_read_error);
91 break; 91 break;
92 } 92 }
93 read_ok: 93 read_ok:
@@ -100,7 +100,7 @@ static off_t bb_full_fd_action(int src_fd, int dst_fd, off_t size)
100 ssize_t wr = full_write(dst_fd, buffer, rd); 100 ssize_t wr = full_write(dst_fd, buffer, rd);
101 if (wr < rd) { 101 if (wr < rd) {
102 if (!continue_on_write_error) { 102 if (!continue_on_write_error) {
103 bb_perror_msg(bb_msg_write_error); 103 bb_simple_perror_msg(bb_msg_write_error);
104 break; 104 break;
105 } 105 }
106 dst_fd = -1; 106 dst_fd = -1;
@@ -151,7 +151,7 @@ void FAST_FUNC bb_copyfd_exact_size(int fd1, int fd2, off_t size)
151 if (sz == (size >= 0 ? size : -size)) 151 if (sz == (size >= 0 ? size : -size))
152 return; 152 return;
153 if (sz != -1) 153 if (sz != -1)
154 bb_error_msg_and_die("short read"); 154 bb_simple_error_msg_and_die("short read");
155 /* if sz == -1, bb_copyfd_XX already complained */ 155 /* if sz == -1, bb_copyfd_XX already complained */
156 xfunc_die(); 156 xfunc_die();
157} 157}
diff --git a/libbb/die_if_bad_username.c b/libbb/die_if_bad_username.c
index 46f103340..e5e1160c4 100644
--- a/libbb/die_if_bad_username.c
+++ b/libbb/die_if_bad_username.c
@@ -57,5 +57,5 @@ void FAST_FUNC die_if_bad_username(const char *name)
57 * including the terminating null byte. 57 * including the terminating null byte.
58 */ 58 */
59 if (name - start >= LOGIN_NAME_MAX) 59 if (name - start >= LOGIN_NAME_MAX)
60 bb_error_msg_and_die("name is too long"); 60 bb_simple_error_msg_and_die("name is too long");
61} 61}
diff --git a/libbb/dump.c b/libbb/dump.c
index b4b49d709..8029cca0e 100644
--- a/libbb/dump.c
+++ b/libbb/dump.c
@@ -199,7 +199,7 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs)
199 pr->bcnt = fu->bcnt; 199 pr->bcnt = fu->bcnt;
200 if (fu->bcnt == 0) { 200 if (fu->bcnt == 0) {
201 if (!prec) 201 if (!prec)
202 bb_error_msg_and_die("%%s needs precision or byte count"); 202 bb_simple_error_msg_and_die("%%s needs precision or byte count");
203 pr->bcnt = atoi(prec); 203 pr->bcnt = atoi(prec);
204 } 204 }
205 } else 205 } else
@@ -266,7 +266,7 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs)
266 266
267 /* only one conversion character if byte count */ 267 /* only one conversion character if byte count */
268 if (!(pr->flags & F_ADDRESS) && fu->bcnt && nconv++) { 268 if (!(pr->flags & F_ADDRESS) && fu->bcnt && nconv++) {
269 bb_error_msg_and_die("byte count with multiple conversion characters"); 269 bb_simple_error_msg_and_die("byte count with multiple conversion characters");
270 } 270 }
271 } 271 }
272 /* 272 /*
diff --git a/libbb/fflush_stdout_and_exit.c b/libbb/fflush_stdout_and_exit.c
index 4c689c0fb..5df74170e 100644
--- a/libbb/fflush_stdout_and_exit.c
+++ b/libbb/fflush_stdout_and_exit.c
@@ -15,7 +15,7 @@ void FAST_FUNC fflush_stdout_and_exit(int retval)
15{ 15{
16 xfunc_error_retval = retval; 16 xfunc_error_retval = retval;
17 if (fflush(stdout)) 17 if (fflush(stdout))
18 bb_perror_msg_and_die(bb_msg_standard_output); 18 bb_simple_perror_msg_and_die(bb_msg_standard_output);
19 /* In case we are in NOFORK applet. Do not exit() directly, 19 /* In case we are in NOFORK applet. Do not exit() directly,
20 * but use xfunc_die() */ 20 * but use xfunc_die() */
21 xfunc_die(); 21 xfunc_die();
diff --git a/libbb/find_pid_by_name.c b/libbb/find_pid_by_name.c
index 52debb171..0b6d5a206 100644
--- a/libbb/find_pid_by_name.c
+++ b/libbb/find_pid_by_name.c
@@ -95,7 +95,11 @@ pid_t* FAST_FUNC find_pid_by_name(const char *procName)
95 /* or we require argv0 to match (essential for matching reexeced /proc/self/exe)*/ 95 /* or we require argv0 to match (essential for matching reexeced /proc/self/exe)*/
96 || (p->argv0 && strcmp(bb_basename(p->argv0), procName) == 0) 96 || (p->argv0 && strcmp(bb_basename(p->argv0), procName) == 0)
97 /* or we require /proc/PID/exe link to match */ 97 /* or we require /proc/PID/exe link to match */
98 || (p->exe && strcmp(bb_basename(p->exe), procName) == 0) 98 || (p->exe && strcmp(
99 procName[0] == '/' ? p->exe /* support "pidof /path/to/binary" case too */
100 : bb_basename(p->exe),
101 procName
102 ) == 0)
99#endif 103#endif
100 ) { 104 ) {
101 pidList = xrealloc_vector(pidList, 2, i); 105 pidList = xrealloc_vector(pidList, 2, i);
diff --git a/libbb/get_console.c b/libbb/get_console.c
index 0b53524aa..7f2c75332 100644
--- a/libbb/get_console.c
+++ b/libbb/get_console.c
@@ -62,7 +62,7 @@ int FAST_FUNC get_console_fd_or_die(void)
62 } 62 }
63 } 63 }
64 64
65 bb_error_msg_and_die("can't open console"); 65 bb_simple_error_msg_and_die("can't open console");
66} 66}
67 67
68/* From <linux/vt.h> */ 68/* From <linux/vt.h> */
diff --git a/libbb/get_volsize.c b/libbb/get_volsize.c
index 241ceda9b..087efb3c7 100644
--- a/libbb/get_volsize.c
+++ b/libbb/get_volsize.c
@@ -18,7 +18,7 @@ uoff_t FAST_FUNC get_volume_size_in_bytes(int fd,
18 if (override) { 18 if (override) {
19 result = XATOOFF(override); 19 result = XATOOFF(override);
20 if (result >= (uoff_t)(MAXINT(off_t)) / override_units) 20 if (result >= (uoff_t)(MAXINT(off_t)) / override_units)
21 bb_error_msg_and_die("image size is too big"); 21 bb_simple_error_msg_and_die("image size is too big");
22 result *= override_units; 22 result *= override_units;
23 /* seek past end fails on block devices but works on files */ 23 /* seek past end fails on block devices but works on files */
24 if (lseek(fd, result - 1, SEEK_SET) != (off_t)-1) { 24 if (lseek(fd, result - 1, SEEK_SET) != (off_t)-1) {
@@ -42,7 +42,7 @@ uoff_t FAST_FUNC get_volume_size_in_bytes(int fd,
42 * 42 *
43 * Picked 16k arbitrarily: */ 43 * Picked 16k arbitrarily: */
44 if (result < 16*1024) 44 if (result < 16*1024)
45 bb_error_msg_and_die("image is too small"); 45 bb_simple_error_msg_and_die("image is too small");
46 46
47 return result; 47 return result;
48} 48}
diff --git a/libbb/getpty.c b/libbb/getpty.c
index 5d24ca930..9ec6265ad 100644
--- a/libbb/getpty.c
+++ b/libbb/getpty.c
@@ -23,14 +23,14 @@ int FAST_FUNC xgetpty(char *line)
23 const char *name; 23 const char *name;
24 name = ptsname(p); /* find out the name of slave pty */ 24 name = ptsname(p); /* find out the name of slave pty */
25 if (!name) { 25 if (!name) {
26 bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)"); 26 bb_simple_perror_msg_and_die("ptsname error (is /dev/pts mounted?)");
27 } 27 }
28 safe_strncpy(line, name, GETPTY_BUFSIZE); 28 safe_strncpy(line, name, GETPTY_BUFSIZE);
29 } 29 }
30# else 30# else
31 /* find out the name of slave pty */ 31 /* find out the name of slave pty */
32 if (ptsname_r(p, line, GETPTY_BUFSIZE-1) != 0) { 32 if (ptsname_r(p, line, GETPTY_BUFSIZE-1) != 0) {
33 bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)"); 33 bb_simple_perror_msg_and_die("ptsname error (is /dev/pts mounted?)");
34 } 34 }
35 line[GETPTY_BUFSIZE-1] = '\0'; 35 line[GETPTY_BUFSIZE-1] = '\0';
36# endif 36# endif
@@ -61,5 +61,5 @@ int FAST_FUNC xgetpty(char *line)
61 } 61 }
62 } 62 }
63#endif /* FEATURE_DEVPTS */ 63#endif /* FEATURE_DEVPTS */
64 bb_error_msg_and_die("can't find free pty"); 64 bb_simple_error_msg_and_die("can't find free pty");
65} 65}
diff --git a/libbb/herror_msg.c b/libbb/herror_msg.c
index d041076e0..a7dd98679 100644
--- a/libbb/herror_msg.c
+++ b/libbb/herror_msg.c
@@ -26,3 +26,13 @@ void FAST_FUNC bb_herror_msg_and_die(const char *s, ...)
26 va_end(p); 26 va_end(p);
27 xfunc_die(); 27 xfunc_die();
28} 28}
29
30void FAST_FUNC bb_simple_herror_msg(const char *s)
31{
32 bb_herror_msg("%s", s);
33}
34
35void FAST_FUNC bb_simple_herror_msg_and_die(const char *s)
36{
37 bb_herror_msg_and_die("%s", s);
38}
diff --git a/libbb/loop.c b/libbb/loop.c
index c78535a20..ada0c7638 100644
--- a/libbb/loop.c
+++ b/libbb/loop.c
@@ -78,6 +78,24 @@ int FAST_FUNC del_loop(const char *device)
78 return rc; 78 return rc;
79} 79}
80 80
81/* Obtain an unused loop device number */
82int FAST_FUNC get_free_loop(void)
83{
84 int fd;
85 int loopdevno;
86
87 fd = open("/dev/loop-control", O_RDWR | O_CLOEXEC);
88 if (fd == -1)
89 return fd - 1; /* -2: "no /dev/loop-control" */
90
91#ifndef LOOP_CTL_GET_FREE
92# define LOOP_CTL_GET_FREE 0x4C82
93#endif
94 loopdevno = ioctl(fd, LOOP_CTL_GET_FREE);
95 close(fd);
96 return loopdevno; /* can be -1 if error */
97}
98
81/* Returns opened fd to the loop device, <0 on error. 99/* Returns opened fd to the loop device, <0 on error.
82 * *device is loop device to use, or if *device==NULL finds a loop device to 100 * *device is loop device to use, or if *device==NULL finds a loop device to
83 * mount it on and sets *device to a strdup of that loop device name. This 101 * mount it on and sets *device to a strdup of that loop device name. This
@@ -106,12 +124,24 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse
106 return -errno; 124 return -errno;
107 } 125 }
108 126
109//TODO: use LOOP_CTL_GET_FREE instead of trying every loopN in sequence? a-la: 127 try = *device;
110// fd = open("/dev/loop-control", O_RDWR); 128 if (!try) {
111// loopN = ioctl(fd, LOOP_CTL_GET_FREE); 129 i = get_free_loop();
112// 130 if (i == -2) { /* no /dev/loop-control */
131 i = 0;
132 try = dev;
133 goto old_style;
134 }
135 if (i == -1) {
136 close(ffd);
137 return -1; /* no free loop devices */
138 }
139 try = *device = xasprintf(LOOP_FORMAT, i);
140 goto try_to_open;
141 }
142
143 old_style:
113 /* Find a loop device. */ 144 /* Find a loop device. */
114 try = *device ? *device : dev;
115 /* 1048575 (0xfffff) is a max possible minor number in Linux circa 2010 */ 145 /* 1048575 (0xfffff) is a max possible minor number in Linux circa 2010 */
116 for (i = 0; rc && i < 1048576; i++) { 146 for (i = 0; rc && i < 1048576; i++) {
117 sprintf(dev, LOOP_FORMAT, i); 147 sprintf(dev, LOOP_FORMAT, i);
@@ -170,7 +200,7 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse
170 rc = ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo); 200 rc = ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo);
171 } 201 }
172 if (rc != 0) { 202 if (rc != 0) {
173 ioctl(dfd, LOOP_CLR_FD, 0); 203 ioctl(dfd, LOOP_CLR_FD, 0); // actually, 0 param is unnecessary
174 } 204 }
175 } 205 }
176 } else { 206 } else {
diff --git a/libbb/mtab.c b/libbb/mtab.c
index 131705ddb..aa1a2a103 100644
--- a/libbb/mtab.c
+++ b/libbb/mtab.c
@@ -21,7 +21,7 @@ void FAST_FUNC erase_mtab(const char *name)
21 /* Bummer. Fall back on trying the /proc filesystem */ 21 /* Bummer. Fall back on trying the /proc filesystem */
22 if (!mountTable) mountTable = setmntent("/proc/mounts", "r"); 22 if (!mountTable) mountTable = setmntent("/proc/mounts", "r");
23 if (!mountTable) { 23 if (!mountTable) {
24 bb_perror_msg(bb_path_mtab_file); 24 bb_simple_perror_msg(bb_path_mtab_file);
25 return; 25 return;
26 } 26 }
27 27
@@ -49,6 +49,6 @@ void FAST_FUNC erase_mtab(const char *name)
49 } 49 }
50 endmntent(mountTable); 50 endmntent(mountTable);
51 } else if (errno != EROFS) 51 } else if (errno != EROFS)
52 bb_perror_msg(bb_path_mtab_file); 52 bb_simple_perror_msg(bb_path_mtab_file);
53} 53}
54#endif 54#endif
diff --git a/libbb/perror_nomsg.c b/libbb/perror_nomsg.c
index a2a11cc8e..d7d53de44 100644
--- a/libbb/perror_nomsg.c
+++ b/libbb/perror_nomsg.c
@@ -12,11 +12,11 @@
12 * instead of including libbb.h */ 12 * instead of including libbb.h */
13//#include "libbb.h" 13//#include "libbb.h"
14#include "platform.h" 14#include "platform.h"
15extern void bb_perror_msg(const char *s, ...) FAST_FUNC; 15extern void bb_simple_perror_msg(const char *s) FAST_FUNC;
16 16
17/* suppress gcc "no previous prototype" warning */ 17/* suppress gcc "no previous prototype" warning */
18void FAST_FUNC bb_perror_nomsg(void); 18void FAST_FUNC bb_perror_nomsg(void);
19void FAST_FUNC bb_perror_nomsg(void) 19void FAST_FUNC bb_perror_nomsg(void)
20{ 20{
21 bb_perror_msg(0); 21 bb_simple_perror_msg(0);
22} 22}
diff --git a/libbb/perror_nomsg_and_die.c b/libbb/perror_nomsg_and_die.c
index 543ff5178..bea5f25a5 100644
--- a/libbb/perror_nomsg_and_die.c
+++ b/libbb/perror_nomsg_and_die.c
@@ -12,11 +12,11 @@
12 * instead of including libbb.h */ 12 * instead of including libbb.h */
13//#include "libbb.h" 13//#include "libbb.h"
14#include "platform.h" 14#include "platform.h"
15extern void bb_perror_msg_and_die(const char *s, ...) FAST_FUNC; 15extern void bb_simple_perror_msg_and_die(const char *s) FAST_FUNC;
16 16
17/* suppress gcc "no previous prototype" warning */ 17/* suppress gcc "no previous prototype" warning */
18void FAST_FUNC bb_perror_nomsg_and_die(void); 18void FAST_FUNC bb_perror_nomsg_and_die(void);
19void FAST_FUNC bb_perror_nomsg_and_die(void) 19void FAST_FUNC bb_perror_nomsg_and_die(void)
20{ 20{
21 bb_perror_msg_and_die(0); 21 bb_simple_perror_msg_and_die(0);
22} 22}
diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c
index 86455cd0d..47c20690f 100644
--- a/libbb/pw_encrypt.c
+++ b/libbb/pw_encrypt.c
@@ -6,7 +6,9 @@
6 * 6 *
7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
8 */ 8 */
9#if !ENABLE_USE_BB_CRYPT
9#include <crypt.h> 10#include <crypt.h>
11#endif
10#include "libbb.h" 12#include "libbb.h"
11 13
12/* static const uint8_t ascii64[] ALIGN1 = 14/* static const uint8_t ascii64[] ALIGN1 =
diff --git a/libbb/read_printf.c b/libbb/read_printf.c
index 1e67d6542..379dd2448 100644
--- a/libbb/read_printf.c
+++ b/libbb/read_printf.c
@@ -222,7 +222,7 @@ void FAST_FUNC xread(int fd, void *buf, size_t count)
222 if (count) { 222 if (count) {
223 ssize_t size = full_read(fd, buf, count); 223 ssize_t size = full_read(fd, buf, count);
224 if ((size_t)size != count) 224 if ((size_t)size != count)
225 bb_error_msg_and_die("short read"); 225 bb_simple_error_msg_and_die("short read");
226 } 226 }
227} 227}
228 228
diff --git a/libbb/safe_poll.c b/libbb/safe_poll.c
index cf93a9774..a07e785f3 100644
--- a/libbb/safe_poll.c
+++ b/libbb/safe_poll.c
@@ -27,7 +27,7 @@ int FAST_FUNC safe_poll(struct pollfd *ufds, nfds_t nfds, int timeout)
27 /* I doubt many callers would handle this correctly! */ 27 /* I doubt many callers would handle this correctly! */
28 if (errno == ENOMEM) 28 if (errno == ENOMEM)
29 continue; 29 continue;
30 bb_perror_msg("poll"); 30 bb_simple_perror_msg("poll");
31 return n; 31 return n;
32 } 32 }
33} 33}
diff --git a/libbb/selinux_common.c b/libbb/selinux_common.c
index c2585557f..f917a1c6a 100644
--- a/libbb/selinux_common.c
+++ b/libbb/selinux_common.c
@@ -48,7 +48,7 @@ void FAST_FUNC selinux_preserve_fcontext(int fdesc)
48 if (fgetfilecon(fdesc, &context) < 0) { 48 if (fgetfilecon(fdesc, &context) < 0) {
49 if (errno == ENODATA || errno == ENOTSUP) 49 if (errno == ENODATA || errno == ENOTSUP)
50 return; 50 return;
51 bb_perror_msg_and_die("fgetfilecon failed"); 51 bb_simple_perror_msg_and_die("fgetfilecon failed");
52 } 52 }
53 setfscreatecon_or_die(context); 53 setfscreatecon_or_die(context);
54 freecon(context); 54 freecon(context);
diff --git a/libbb/time.c b/libbb/time.c
index f9b8da0b3..cab0ad602 100644
--- a/libbb/time.c
+++ b/libbb/time.c
@@ -258,7 +258,7 @@ char* FAST_FUNC strftime_YYYYMMDDHHMMSS(char *buf, unsigned len, time_t *tp)
258static void get_mono(struct timespec *ts) 258static void get_mono(struct timespec *ts)
259{ 259{
260 if (syscall(__NR_clock_gettime, CLOCK_MONOTONIC, ts)) 260 if (syscall(__NR_clock_gettime, CLOCK_MONOTONIC, ts))
261 bb_error_msg_and_die("clock_gettime(MONOTONIC) failed"); 261 bb_simple_error_msg_and_die("clock_gettime(MONOTONIC) failed");
262} 262}
263unsigned long long FAST_FUNC monotonic_ns(void) 263unsigned long long FAST_FUNC monotonic_ns(void)
264{ 264{
diff --git a/libbb/unicode.c b/libbb/unicode.c
index 89d42179b..79481f159 100644
--- a/libbb/unicode.c
+++ b/libbb/unicode.c
@@ -674,14 +674,20 @@ int FAST_FUNC wcwidth(unsigned ucs)
674 ( (/*ucs >= 0x1100 &&*/ ucs <= 0x115f) /* Hangul Jamo init. consonants */ 674 ( (/*ucs >= 0x1100 &&*/ ucs <= 0x115f) /* Hangul Jamo init. consonants */
675 || ucs == 0x2329 /* left-pointing angle bracket; also CJK punct. char */ 675 || ucs == 0x2329 /* left-pointing angle bracket; also CJK punct. char */
676 || ucs == 0x232a /* right-pointing angle bracket; also CJK punct. char */ 676 || ucs == 0x232a /* right-pointing angle bracket; also CJK punct. char */
677# if CONFIG_LAST_SUPPORTED_WCHAR >= 0x2e80
677 || (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) /* CJK ... Yi */ 678 || (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) /* CJK ... Yi */
679# endif
678# if CONFIG_LAST_SUPPORTED_WCHAR >= 0xac00 680# if CONFIG_LAST_SUPPORTED_WCHAR >= 0xac00
679 || (ucs >= 0xac00 && ucs <= 0xd7a3) /* Hangul Syllables */ 681 || (ucs >= 0xac00 && ucs <= 0xd7a3) /* Hangul Syllables */
682# endif
683# if CONFIG_LAST_SUPPORTED_WCHAR >= 0xf900
680 || (ucs >= 0xf900 && ucs <= 0xfaff) /* CJK Compatibility Ideographs */ 684 || (ucs >= 0xf900 && ucs <= 0xfaff) /* CJK Compatibility Ideographs */
681 || (ucs >= 0xfe10 && ucs <= 0xfe19) /* Vertical forms */ 685 || (ucs >= 0xfe10 && ucs <= 0xfe19) /* Vertical forms */
682 || (ucs >= 0xfe30 && ucs <= 0xfe6f) /* CJK Compatibility Forms */ 686 || (ucs >= 0xfe30 && ucs <= 0xfe6f) /* CJK Compatibility Forms */
683 || (ucs >= 0xff00 && ucs <= 0xff60) /* Fullwidth Forms */ 687 || (ucs >= 0xff00 && ucs <= 0xff60) /* Fullwidth Forms */
684 || (ucs >= 0xffe0 && ucs <= 0xffe6) 688 || (ucs >= 0xffe0 && ucs <= 0xffe6)
689# endif
690# if CONFIG_LAST_SUPPORTED_WCHAR >= 0x20000
685 || ((ucs >> 17) == (2 >> 1)) /* 20000..3ffff: Supplementary and Tertiary Ideographic Planes */ 691 || ((ucs >> 17) == (2 >> 1)) /* 20000..3ffff: Supplementary and Tertiary Ideographic Planes */
686# endif 692# endif
687 ); 693 );
diff --git a/libbb/update_passwd.c b/libbb/update_passwd.c
index 95423d19b..c605c4c64 100644
--- a/libbb/update_passwd.c
+++ b/libbb/update_passwd.c
@@ -25,7 +25,7 @@ static void check_selinux_update_passwd(const char *username)
25 return; /* No need to check */ 25 return; /* No need to check */
26 26
27 if (getprevcon_raw(&context) < 0) 27 if (getprevcon_raw(&context) < 0)
28 bb_perror_msg_and_die("getprevcon failed"); 28 bb_simple_perror_msg_and_die("getprevcon failed");
29 seuser = strtok(context, ":"); 29 seuser = strtok(context, ":");
30 if (!seuser) 30 if (!seuser)
31 bb_error_msg_and_die("invalid context '%s'", context); 31 bb_error_msg_and_die("invalid context '%s'", context);
@@ -42,7 +42,7 @@ static void check_selinux_update_passwd(const char *username)
42 42
43 if (selinux_check_passwd_access(av) != 0) 43 if (selinux_check_passwd_access(av) != 0)
44 die: 44 die:
45 bb_error_msg_and_die("SELinux: access denied"); 45 bb_simple_error_msg_and_die("SELinux: access denied");
46 } 46 }
47 if (ENABLE_FEATURE_CLEAN_UP) 47 if (ENABLE_FEATURE_CLEAN_UP)
48 freecon(context); 48 freecon(context);
@@ -270,10 +270,16 @@ int FAST_FUNC update_passwd(const char *filename,
270 if (shadow && *cp == ':') { 270 if (shadow && *cp == ':') {
271 /* /etc/shadow's field 3 (passwd change date) needs updating */ 271 /* /etc/shadow's field 3 (passwd change date) needs updating */
272 /* move past old change date */ 272 /* move past old change date */
273 unsigned time_days = (unsigned long)(time(NULL)) / (24*60*60);
274
275 if (time_days == 0) {
276 /* 0 as change date has special meaning, avoid it */
277 time_days = 1;
278 }
273 cp = strchrnul(cp + 1, ':'); 279 cp = strchrnul(cp + 1, ':');
274 /* "name:" + "new_passwd" + ":" + "change date" + ":rest of line" */ 280 /* "name:" + "new_passwd" + ":" + "change date" + ":rest of line" */
275 fprintf(new_fp, "%s%s:%u%s\n", name_colon, new_passwd, 281 fprintf(new_fp, "%s%s:%u%s\n", name_colon, new_passwd,
276 (unsigned)(time(NULL)) / (24*60*60), cp); 282 time_days, cp);
277 } else { 283 } else {
278 /* "name:" + "new_passwd" + ":rest of line" */ 284 /* "name:" + "new_passwd" + ":rest of line" */
279 fprintf(new_fp, "%s%s%s\n", name_colon, new_passwd, cp); 285 fprintf(new_fp, "%s%s%s\n", name_colon, new_passwd, cp);
diff --git a/libbb/uuencode.c b/libbb/uuencode.c
index f32a3da7d..d36b34f63 100644
--- a/libbb/uuencode.c
+++ b/libbb/uuencode.c
@@ -213,7 +213,7 @@ void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags)
213 if (*in_tail == '\0') 213 if (*in_tail == '\0')
214 return; 214 return;
215 /* No */ 215 /* No */
216 bb_error_msg_and_die("truncated base64 input"); 216 bb_simple_error_msg_and_die("truncated base64 input");
217 } 217 }
218 218
219 /* It was partial decode */ 219 /* It was partial decode */
diff --git a/libbb/verror_msg.c b/libbb/verror_msg.c
index 6d3459905..71512aee2 100644
--- a/libbb/verror_msg.c
+++ b/libbb/verror_msg.c
@@ -197,4 +197,19 @@ void FAST_FUNC bb_info_msg(const char *s, ...)
197 bb_vinfo_msg(s, p); 197 bb_vinfo_msg(s, p);
198 va_end(p); 198 va_end(p);
199} 199}
200
201void FAST_FUNC bb_simple_info_msg(const char *s)
202{
203 bb_info_msg("%s", s);
204}
200#endif 205#endif
206
207void FAST_FUNC bb_simple_error_msg(const char *s)
208{
209 bb_error_msg("%s", s);
210}
211
212void FAST_FUNC bb_simple_error_msg_and_die(const char *s)
213{
214 bb_error_msg_and_die("%s", s);
215}
diff --git a/libbb/warn_ignoring_args.c b/libbb/warn_ignoring_args.c
index 3f3025c03..b24546e41 100644
--- a/libbb/warn_ignoring_args.c
+++ b/libbb/warn_ignoring_args.c
@@ -12,7 +12,7 @@
12void FAST_FUNC bb_warn_ignoring_args(char *arg) 12void FAST_FUNC bb_warn_ignoring_args(char *arg)
13{ 13{
14 if (arg) { 14 if (arg) {
15 bb_error_msg("ignoring all arguments"); 15 bb_simple_error_msg("ignoring all arguments");
16 } 16 }
17} 17}
18#endif 18#endif
diff --git a/libbb/xconnect.c b/libbb/xconnect.c
index a6127508b..38faef38e 100644
--- a/libbb/xconnect.c
+++ b/libbb/xconnect.c
@@ -11,6 +11,9 @@
11#include <netinet/in.h> 11#include <netinet/in.h>
12#include <net/if.h> 12#include <net/if.h>
13#include <sys/un.h> 13#include <sys/un.h>
14#if ENABLE_IFPLUGD || ENABLE_FEATURE_MDEV_DAEMON || ENABLE_UEVENT
15# include <linux/netlink.h>
16#endif
14#include "libbb.h" 17#include "libbb.h"
15 18
16int FAST_FUNC setsockopt_int(int fd, int level, int optname, int optval) 19int FAST_FUNC setsockopt_int(int fd, int level, int optname, int optval)
@@ -63,7 +66,7 @@ int FAST_FUNC setsockopt_bindtodevice(int fd, const char *iface)
63int FAST_FUNC setsockopt_bindtodevice(int fd UNUSED_PARAM, 66int FAST_FUNC setsockopt_bindtodevice(int fd UNUSED_PARAM,
64 const char *iface UNUSED_PARAM) 67 const char *iface UNUSED_PARAM)
65{ 68{
66 bb_error_msg("SO_BINDTODEVICE is not supported on this system"); 69 bb_simple_error_msg("SO_BINDTODEVICE is not supported on this system");
67 return -1; 70 return -1;
68} 71}
69#endif 72#endif
@@ -108,7 +111,7 @@ void FAST_FUNC xconnect(int s, const struct sockaddr *saddr, socklen_t addrlen)
108 bb_perror_msg_and_die("%s (%s)", 111 bb_perror_msg_and_die("%s (%s)",
109 "can't connect to remote host", 112 "can't connect to remote host",
110 inet_ntoa(((struct sockaddr_in *)saddr)->sin_addr)); 113 inet_ntoa(((struct sockaddr_in *)saddr)->sin_addr));
111 bb_perror_msg_and_die("can't connect to remote host"); 114 bb_simple_perror_msg_and_die("can't connect to remote host");
112 } 115 }
113} 116}
114 117
@@ -132,6 +135,7 @@ unsigned FAST_FUNC bb_lookup_port(const char *port, const char *protocol, unsign
132 port_nr = default_port; 135 port_nr = default_port;
133 if (tserv) 136 if (tserv)
134 port_nr = ntohs(tserv->s_port); 137 port_nr = ntohs(tserv->s_port);
138//FIXME: else: port string was garbage, but we don't report that???
135 } 139 }
136 errno = old_errno; 140 errno = old_errno;
137 } 141 }
@@ -418,6 +422,38 @@ int FAST_FUNC create_and_bind_dgram_or_die(const char *bindaddr, int port)
418} 422}
419 423
420 424
425#if ENABLE_IFPLUGD || ENABLE_FEATURE_MDEV_DAEMON || ENABLE_UEVENT
426int FAST_FUNC create_and_bind_to_netlink(int proto, int grp, unsigned rcvbuf)
427{
428 struct sockaddr_nl sa;
429 int fd;
430
431 memset(&sa, 0, sizeof(sa));
432 sa.nl_family = AF_NETLINK;
433 sa.nl_pid = getpid();
434 sa.nl_groups = grp;
435 fd = xsocket(AF_NETLINK, SOCK_DGRAM, proto);
436 xbind(fd, (struct sockaddr *) &sa, sizeof(sa));
437 close_on_exec_on(fd);
438
439 if (rcvbuf != 0) {
440 // SO_RCVBUFFORCE (root only) can go above net.core.rmem_max sysctl
441 setsockopt_SOL_SOCKET_int(fd, SO_RCVBUF, rcvbuf);
442 setsockopt_SOL_SOCKET_int(fd, SO_RCVBUFFORCE, rcvbuf);
443# if 0
444 {
445 int z;
446 socklen_t zl = sizeof(z);
447 getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &z, &zl);
448 bb_error_msg("SO_RCVBUF:%d", z);
449 }
450# endif
451 }
452
453 return fd;
454}
455#endif
456
421int FAST_FUNC create_and_connect_stream_or_die(const char *peer, int port) 457int FAST_FUNC create_and_connect_stream_or_die(const char *peer, int port)
422{ 458{
423 int fd; 459 int fd;
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c
index 57bda6204..c92436683 100644
--- a/libbb/xfuncs.c
+++ b/libbb/xfuncs.c
@@ -430,6 +430,6 @@ int FAST_FUNC wait_for_exitstatus(pid_t pid)
430 430
431 n = safe_waitpid(pid, &exit_status, 0); 431 n = safe_waitpid(pid, &exit_status, 0);
432 if (n < 0) 432 if (n < 0)
433 bb_perror_msg_and_die("waitpid"); 433 bb_simple_perror_msg_and_die("waitpid");
434 return exit_status; 434 return exit_status;
435} 435}
diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c
index a0db2b86e..cfe062a47 100644
--- a/libbb/xfuncs_printf.c
+++ b/libbb/xfuncs_printf.c
@@ -27,7 +27,7 @@
27 27
28void FAST_FUNC bb_die_memory_exhausted(void) 28void FAST_FUNC bb_die_memory_exhausted(void)
29{ 29{
30 bb_error_msg_and_die(bb_msg_memory_exhausted); 30 bb_simple_error_msg_and_die(bb_msg_memory_exhausted);
31} 31}
32 32
33#ifndef DMALLOC 33#ifndef DMALLOC
@@ -40,7 +40,7 @@ void* FAST_FUNC malloc_or_warn(size_t size)
40{ 40{
41 void *ptr = malloc(size); 41 void *ptr = malloc(size);
42 if (ptr == NULL && size != 0) 42 if (ptr == NULL && size != 0)
43 bb_error_msg(bb_msg_memory_exhausted); 43 bb_simple_error_msg(bb_msg_memory_exhausted);
44 return ptr; 44 return ptr;
45} 45}
46 46
@@ -97,7 +97,7 @@ char* FAST_FUNC xstrndup(const char *s, int n)
97 char *t; 97 char *t;
98 98
99 if (ENABLE_DEBUG && s == NULL) 99 if (ENABLE_DEBUG && s == NULL)
100 bb_error_msg_and_die("xstrndup bug"); 100 bb_simple_error_msg_and_die("xstrndup bug");
101 101
102 /* We can just xmalloc(n+1) and strncpy into it, */ 102 /* We can just xmalloc(n+1) and strncpy into it, */
103 /* but think about xstrndup("abc", 10000) wastage! */ 103 /* but think about xstrndup("abc", 10000) wastage! */
@@ -215,13 +215,13 @@ int FAST_FUNC rename_or_warn(const char *oldpath, const char *newpath)
215void FAST_FUNC xpipe(int filedes[2]) 215void FAST_FUNC xpipe(int filedes[2])
216{ 216{
217 if (pipe(filedes)) 217 if (pipe(filedes))
218 bb_perror_msg_and_die("can't create pipe"); 218 bb_simple_perror_msg_and_die("can't create pipe");
219} 219}
220 220
221void FAST_FUNC xdup2(int from, int to) 221void FAST_FUNC xdup2(int from, int to)
222{ 222{
223 if (dup2(from, to) != to) 223 if (dup2(from, to) != to)
224 bb_perror_msg_and_die("can't duplicate file descriptor"); 224 bb_simple_perror_msg_and_die("can't duplicate file descriptor");
225 // " %d to %d", from, to); 225 // " %d to %d", from, to);
226} 226}
227 227
@@ -245,7 +245,7 @@ void FAST_FUNC xwrite(int fd, const void *buf, size_t count)
245 * or some writes succeeded, then we hit an error. 245 * or some writes succeeded, then we hit an error.
246 * In either case, errno is set. 246 * In either case, errno is set.
247 */ 247 */
248 bb_perror_msg_and_die( 248 bb_simple_perror_msg_and_die(
249 size >= 0 ? "short write" : "write error" 249 size >= 0 ? "short write" : "write error"
250 ); 250 );
251 } 251 }
@@ -259,7 +259,7 @@ void FAST_FUNC xwrite_str(int fd, const char *str)
259void FAST_FUNC xclose(int fd) 259void FAST_FUNC xclose(int fd)
260{ 260{
261 if (close(fd)) 261 if (close(fd))
262 bb_perror_msg_and_die("close failed"); 262 bb_simple_perror_msg_and_die("close failed");
263} 263}
264 264
265// Die with an error message if we can't lseek to the right spot. 265// Die with an error message if we can't lseek to the right spot.
@@ -267,9 +267,7 @@ off_t FAST_FUNC xlseek(int fd, off_t offset, int whence)
267{ 267{
268 off_t off = lseek(fd, offset, whence); 268 off_t off = lseek(fd, offset, whence);
269 if (off == (off_t)-1) { 269 if (off == (off_t)-1) {
270 if (whence == SEEK_SET) 270 bb_perror_msg_and_die("lseek(%"OFF_FMT"u, %d)", offset, whence);
271 bb_perror_msg_and_die("lseek(%"OFF_FMT"u)", offset);
272 bb_perror_msg_and_die("lseek");
273 } 271 }
274 return off; 272 return off;
275} 273}
@@ -384,23 +382,23 @@ void FAST_FUNC bb_unsetenv_and_free(char *var)
384// setgid() will fail and we'll _still_be_root_, which is bad.) 382// setgid() will fail and we'll _still_be_root_, which is bad.)
385void FAST_FUNC xsetgid(gid_t gid) 383void FAST_FUNC xsetgid(gid_t gid)
386{ 384{
387 if (setgid(gid)) bb_perror_msg_and_die("setgid"); 385 if (setgid(gid)) bb_simple_perror_msg_and_die("setgid");
388} 386}
389 387
390// Die with an error message if we can't set uid. (See xsetgid() for why.) 388// Die with an error message if we can't set uid. (See xsetgid() for why.)
391void FAST_FUNC xsetuid(uid_t uid) 389void FAST_FUNC xsetuid(uid_t uid)
392{ 390{
393 if (setuid(uid)) bb_perror_msg_and_die("setuid"); 391 if (setuid(uid)) bb_simple_perror_msg_and_die("setuid");
394} 392}
395 393
396void FAST_FUNC xsetegid(gid_t egid) 394void FAST_FUNC xsetegid(gid_t egid)
397{ 395{
398 if (setegid(egid)) bb_perror_msg_and_die("setegid"); 396 if (setegid(egid)) bb_simple_perror_msg_and_die("setegid");
399} 397}
400 398
401void FAST_FUNC xseteuid(uid_t euid) 399void FAST_FUNC xseteuid(uid_t euid)
402{ 400{
403 if (seteuid(euid)) bb_perror_msg_and_die("seteuid"); 401 if (seteuid(euid)) bb_simple_perror_msg_and_die("seteuid");
404} 402}
405 403
406// Die if we can't chdir to a new path. 404// Die if we can't chdir to a new path.
@@ -413,7 +411,7 @@ void FAST_FUNC xchdir(const char *path)
413void FAST_FUNC xfchdir(int fd) 411void FAST_FUNC xfchdir(int fd)
414{ 412{
415 if (fchdir(fd)) 413 if (fchdir(fd))
416 bb_perror_msg_and_die("fchdir"); 414 bb_simple_perror_msg_and_die("fchdir");
417} 415}
418 416
419void FAST_FUNC xchroot(const char *path) 417void FAST_FUNC xchroot(const char *path)
@@ -463,7 +461,7 @@ int FAST_FUNC xsocket(int domain, int type, int protocol)
463IF_FEATURE_IPV6(if (domain == AF_INET6) s = "INET6";) 461IF_FEATURE_IPV6(if (domain == AF_INET6) s = "INET6";)
464 bb_perror_msg_and_die("socket(AF_%s,%d,%d)", s, type, protocol); 462 bb_perror_msg_and_die("socket(AF_%s,%d,%d)", s, type, protocol);
465#else 463#else
466 bb_perror_msg_and_die("socket"); 464 bb_simple_perror_msg_and_die("socket");
467#endif 465#endif
468 } 466 }
469 467
@@ -473,13 +471,13 @@ IF_FEATURE_IPV6(if (domain == AF_INET6) s = "INET6";)
473// Die with an error message if we can't bind a socket to an address. 471// Die with an error message if we can't bind a socket to an address.
474void FAST_FUNC xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) 472void FAST_FUNC xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen)
475{ 473{
476 if (bind(sockfd, my_addr, addrlen)) bb_perror_msg_and_die("bind"); 474 if (bind(sockfd, my_addr, addrlen)) bb_simple_perror_msg_and_die("bind");
477} 475}
478 476
479// Die with an error message if we can't listen for connections on a socket. 477// Die with an error message if we can't listen for connections on a socket.
480void FAST_FUNC xlisten(int s, int backlog) 478void FAST_FUNC xlisten(int s, int backlog)
481{ 479{
482 if (listen(s, backlog)) bb_perror_msg_and_die("listen"); 480 if (listen(s, backlog)) bb_simple_perror_msg_and_die("listen");
483} 481}
484 482
485/* Die with an error message if sendto failed. 483/* Die with an error message if sendto failed.
@@ -491,7 +489,7 @@ ssize_t FAST_FUNC xsendto(int s, const void *buf, size_t len, const struct socka
491 if (ret < 0) { 489 if (ret < 0) {
492 if (ENABLE_FEATURE_CLEAN_UP) 490 if (ENABLE_FEATURE_CLEAN_UP)
493 close(s); 491 close(s);
494 bb_perror_msg_and_die("sendto"); 492 bb_simple_perror_msg_and_die("sendto");
495 } 493 }
496 return ret; 494 return ret;
497} 495}
@@ -520,12 +518,12 @@ void FAST_FUNC selinux_or_die(void)
520#if ENABLE_SELINUX 518#if ENABLE_SELINUX
521 int rc = is_selinux_enabled(); 519 int rc = is_selinux_enabled();
522 if (rc == 0) { 520 if (rc == 0) {
523 bb_error_msg_and_die("SELinux is disabled"); 521 bb_simple_error_msg_and_die("SELinux is disabled");
524 } else if (rc < 0) { 522 } else if (rc < 0) {
525 bb_error_msg_and_die("is_selinux_enabled() failed"); 523 bb_simple_error_msg_and_die("is_selinux_enabled() failed");
526 } 524 }
527#else 525#else
528 bb_error_msg_and_die("SELinux support is disabled"); 526 bb_simple_error_msg_and_die("SELinux support is disabled");
529#endif 527#endif
530} 528}
531 529
@@ -676,7 +674,7 @@ pid_t FAST_FUNC xfork(void)
676 pid_t pid; 674 pid_t pid;
677 pid = fork(); 675 pid = fork();
678 if (pid < 0) /* wtf? */ 676 if (pid < 0) /* wtf? */
679 bb_perror_msg_and_die("vfork"+1); 677 bb_simple_perror_msg_and_die("vfork"+1);
680 return pid; 678 return pid;
681} 679}
682#endif 680#endif
diff --git a/libbb/xgetcwd.c b/libbb/xgetcwd.c
index 7f9088bda..f4e768982 100644
--- a/libbb/xgetcwd.c
+++ b/libbb/xgetcwd.c
@@ -33,7 +33,7 @@ xrealloc_getcwd_or_warn(char *cwd)
33 if (errno == ERANGE) 33 if (errno == ERANGE)
34 continue; 34 continue;
35 free(cwd); 35 free(cwd);
36 bb_perror_msg("getcwd"); 36 bb_simple_perror_msg("getcwd");
37 return NULL; 37 return NULL;
38 } 38 }
39 cwd = xrealloc(cwd, strlen(cwd) + 1); 39 cwd = xrealloc(cwd, strlen(cwd) + 1);
diff --git a/libbb/xgethostbyname.c b/libbb/xgethostbyname.c
index 89d0329cc..9446daba7 100644
--- a/libbb/xgethostbyname.c
+++ b/libbb/xgethostbyname.c
@@ -12,6 +12,6 @@ struct hostent* FAST_FUNC xgethostbyname(const char *name)
12{ 12{
13 struct hostent *retval = gethostbyname(name); 13 struct hostent *retval = gethostbyname(name);
14 if (!retval) 14 if (!retval)
15 bb_herror_msg_and_die("%s", name); 15 bb_simple_herror_msg_and_die(name);
16 return retval; 16 return retval;
17} 17}
diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c
index 9ae70de99..ca53e12d3 100644
--- a/libbb/xreadlink.c
+++ b/libbb/xreadlink.c
@@ -147,6 +147,35 @@ char* FAST_FUNC xmalloc_realpath_coreutils(const char *path)
147 buf[len++] = '/'; 147 buf[len++] = '/';
148 strcpy(buf + len, last_slash); 148 strcpy(buf + len, last_slash);
149 } 149 }
150 } else {
151 char *target = xmalloc_readlink(path);
152 if (target) {
153 char *cwd;
154 if (target[0] == '/') {
155 /*
156 * $ ln -s /bin/qwe symlink # note: /bin is a link to /usr/bin
157 * $ readlink -f symlink
158 * /usr/bin/qwe/target_does_not_exist
159 * $ realpath symlink
160 * /usr/bin/qwe/target_does_not_exist
161 */
162 buf = xmalloc_realpath_coreutils(target);
163 free(target);
164 return buf;
165 }
166 /*
167 * $ ln -s target_does_not_exist symlink
168 * $ readlink -f symlink
169 * /CURDIR/target_does_not_exist
170 * $ realpath symlink
171 * /CURDIR/target_does_not_exist
172 */
173 cwd = xrealloc_getcwd_or_warn(NULL);
174 buf = concat_path_file(cwd, target);
175 free(cwd);
176 free(target);
177 return buf;
178 }
150 } 179 }
151 } 180 }
152 181
diff --git a/loginutils/addgroup.c b/loginutils/addgroup.c
index baa961ff3..2a83c8a15 100644
--- a/loginutils/addgroup.c
+++ b/loginutils/addgroup.c
@@ -149,7 +149,7 @@ int addgroup_main(int argc UNUSED_PARAM, char **argv)
149 149
150 /* need to be root */ 150 /* need to be root */
151 if (geteuid()) { 151 if (geteuid()) {
152 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 152 bb_simple_error_msg_and_die(bb_msg_perm_denied_are_you_root);
153 } 153 }
154 /* Syntax: 154 /* Syntax:
155 * addgroup group 155 * addgroup group
diff --git a/loginutils/adduser.c b/loginutils/adduser.c
index 850c810c4..d3c795afa 100644
--- a/loginutils/adduser.c
+++ b/loginutils/adduser.c
@@ -159,7 +159,7 @@ static void passwd_wrapper(const char *login_name) NORETURN;
159static void passwd_wrapper(const char *login_name) 159static void passwd_wrapper(const char *login_name)
160{ 160{
161 BB_EXECLP("passwd", "passwd", "--", login_name, NULL); 161 BB_EXECLP("passwd", "passwd", "--", login_name, NULL);
162 bb_error_msg_and_die("can't execute passwd, you must set password manually"); 162 bb_simple_error_msg_and_die("can't execute passwd, you must set password manually");
163} 163}
164 164
165//FIXME: upstream adduser has no short options! NOT COMPATIBLE! 165//FIXME: upstream adduser has no short options! NOT COMPATIBLE!
@@ -193,7 +193,7 @@ int adduser_main(int argc UNUSED_PARAM, char **argv)
193 193
194 /* got root? */ 194 /* got root? */
195 if (geteuid()) { 195 if (geteuid()) {
196 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 196 bb_simple_error_msg_and_die(bb_msg_perm_denied_are_you_root);
197 } 197 }
198 198
199 pw.pw_gecos = (char *)"Linux User,,,"; 199 pw.pw_gecos = (char *)"Linux User,,,";
diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c
index dd0532c66..4e70b2557 100644
--- a/loginutils/chpasswd.c
+++ b/loginutils/chpasswd.c
@@ -63,7 +63,7 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv)
63 int opt; 63 int opt;
64 64
65 if (getuid() != 0) 65 if (getuid() != 0)
66 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 66 bb_simple_error_msg_and_die(bb_msg_perm_denied_are_you_root);
67 67
68 opt = getopt32long(argv, "^" "emc:R:" "\0" "m--ec:e--mc:c--em", 68 opt = getopt32long(argv, "^" "emc:R:" "\0" "m--ec:e--mc:c--em",
69 chpasswd_longopts, 69 chpasswd_longopts,
@@ -81,7 +81,7 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv)
81 81
82 pass = strchr(name, ':'); 82 pass = strchr(name, ':');
83 if (!pass) 83 if (!pass)
84 bb_error_msg_and_die("missing new password"); 84 bb_simple_error_msg_and_die("missing new password");
85 *pass++ = '\0'; 85 *pass++ = '\0';
86 86
87 xuname2uid(name); /* dies if there is no such user */ 87 xuname2uid(name); /* dies if there is no such user */
diff --git a/loginutils/deluser.c b/loginutils/deluser.c
index d7e9327ba..56bc7eaa6 100644
--- a/loginutils/deluser.c
+++ b/loginutils/deluser.c
@@ -76,7 +76,7 @@ int deluser_main(int argc, char **argv)
76#endif 76#endif
77 77
78 if (geteuid() != 0) 78 if (geteuid() != 0)
79 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 79 bb_simple_error_msg_and_die(bb_msg_perm_denied_are_you_root);
80 80
81 name = argv[1]; 81 name = argv[1];
82 member = NULL; 82 member = NULL;
diff --git a/loginutils/getty.c b/loginutils/getty.c
index 23e92bc77..7393a3d1c 100644
--- a/loginutils/getty.c
+++ b/loginutils/getty.c
@@ -168,7 +168,7 @@ static void parse_speeds(char *arg)
168 /* note: arg "0" turns into speed B0 */ 168 /* note: arg "0" turns into speed B0 */
169 G.numspeed++; 169 G.numspeed++;
170 if (G.numspeed > MAX_SPEED) 170 if (G.numspeed > MAX_SPEED)
171 bb_error_msg_and_die("too many alternate speeds"); 171 bb_simple_error_msg_and_die("too many alternate speeds");
172 } 172 }
173 debug("exiting parse_speeds\n"); 173 debug("exiting parse_speeds\n");
174} 174}
@@ -230,7 +230,7 @@ static void open_tty(void)
230 * Make sure it is open for read/write. 230 * Make sure it is open for read/write.
231 */ 231 */
232 if ((fcntl(0, F_GETFL) & (O_RDWR|O_RDONLY|O_WRONLY)) != O_RDWR) 232 if ((fcntl(0, F_GETFL) & (O_RDWR|O_RDONLY|O_WRONLY)) != O_RDWR)
233 bb_error_msg_and_die("stdin is not open for read/write"); 233 bb_simple_error_msg_and_die("stdin is not open for read/write");
234 234
235 /* Try to get real tty name instead of "-" */ 235 /* Try to get real tty name instead of "-" */
236 n = xmalloc_ttyname(0); 236 n = xmalloc_ttyname(0);
@@ -243,7 +243,7 @@ static void open_tty(void)
243static void set_tty_attrs(void) 243static void set_tty_attrs(void)
244{ 244{
245 if (tcsetattr_stdin_TCSANOW(&G.tty_attrs) < 0) 245 if (tcsetattr_stdin_TCSANOW(&G.tty_attrs) < 0)
246 bb_perror_msg_and_die("tcsetattr"); 246 bb_simple_perror_msg_and_die("tcsetattr");
247} 247}
248 248
249/* We manipulate tty_attrs this way: 249/* We manipulate tty_attrs this way:
@@ -485,7 +485,7 @@ static char *get_logname(void)
485 finalize_tty_attrs(); 485 finalize_tty_attrs();
486 if (errno == EINTR || errno == EIO) 486 if (errno == EINTR || errno == EIO)
487 exit(EXIT_SUCCESS); 487 exit(EXIT_SUCCESS);
488 bb_perror_msg_and_die(bb_msg_read_error); 488 bb_simple_perror_msg_and_die(bb_msg_read_error);
489 } 489 }
490 490
491 switch (c) { 491 switch (c) {
@@ -582,7 +582,7 @@ int getty_main(int argc UNUSED_PARAM, char **argv)
582 // " sid %d pgid %d", 582 // " sid %d pgid %d",
583 // pid, getppid(), 583 // pid, getppid(),
584 // getsid(0), getpgid(0)); 584 // getsid(0), getpgid(0));
585 bb_perror_msg_and_die("setsid"); 585 bb_simple_perror_msg_and_die("setsid");
586 /* 586 /*
587 * When we can end up here? 587 * When we can end up here?
588 * Example: setsid() fails when run alone in interactive shell: 588 * Example: setsid() fails when run alone in interactive shell:
@@ -651,13 +651,13 @@ int getty_main(int argc UNUSED_PARAM, char **argv)
651 tsid = tcgetsid(STDIN_FILENO); 651 tsid = tcgetsid(STDIN_FILENO);
652 if (tsid < 0 || pid != tsid) { 652 if (tsid < 0 || pid != tsid) {
653 if (ioctl(STDIN_FILENO, TIOCSCTTY, /*force:*/ (long)1) < 0) 653 if (ioctl(STDIN_FILENO, TIOCSCTTY, /*force:*/ (long)1) < 0)
654 bb_perror_msg_and_die("TIOCSCTTY"); 654 bb_simple_perror_msg_and_die("TIOCSCTTY");
655 } 655 }
656 656
657#ifdef __linux__ 657#ifdef __linux__
658 /* Make ourself a foreground process group within our session */ 658 /* Make ourself a foreground process group within our session */
659 if (tcsetpgrp(STDIN_FILENO, pid) < 0) 659 if (tcsetpgrp(STDIN_FILENO, pid) < 0)
660 bb_perror_msg_and_die("tcsetpgrp"); 660 bb_simple_perror_msg_and_die("tcsetpgrp");
661#endif 661#endif
662 662
663 /* 663 /*
@@ -669,7 +669,7 @@ int getty_main(int argc UNUSED_PARAM, char **argv)
669 * 5 seconds seems to be a good value. 669 * 5 seconds seems to be a good value.
670 */ 670 */
671 if (tcgetattr(STDIN_FILENO, &G.tty_attrs) < 0) 671 if (tcgetattr(STDIN_FILENO, &G.tty_attrs) < 0)
672 bb_perror_msg_and_die("tcgetattr"); 672 bb_simple_perror_msg_and_die("tcgetattr");
673 673
674 /* Update the utmp file. This tty is ours now! */ 674 /* Update the utmp file. This tty is ours now! */
675 update_utmp(pid, LOGIN_PROCESS, G.tty_name, "LOGIN", G.fakehost); 675 update_utmp(pid, LOGIN_PROCESS, G.tty_name, "LOGIN", G.fakehost);
diff --git a/loginutils/login.c b/loginutils/login.c
index a08642a34..4e65b3a19 100644
--- a/loginutils/login.c
+++ b/loginutils/login.c
@@ -358,7 +358,7 @@ int login_main(int argc UNUSED_PARAM, char **argv)
358 opt = getopt32(argv, "f:h:p", &opt_user, &opt_host); 358 opt = getopt32(argv, "f:h:p", &opt_user, &opt_host);
359 if (opt & LOGIN_OPT_f) { 359 if (opt & LOGIN_OPT_f) {
360 if (!run_by_root) 360 if (!run_by_root)
361 bb_error_msg_and_die("-f is for root only"); 361 bb_simple_error_msg_and_die("-f is for root only");
362 safe_strncpy(username, opt_user, sizeof(username)); 362 safe_strncpy(username, opt_user, sizeof(username));
363 } 363 }
364 argv += optind; 364 argv += optind;
@@ -529,7 +529,7 @@ int login_main(int argc UNUSED_PARAM, char **argv)
529 child_pid = vfork(); 529 child_pid = vfork();
530 if (child_pid != 0) { 530 if (child_pid != 0) {
531 if (child_pid < 0) 531 if (child_pid < 0)
532 bb_perror_msg("vfork"); 532 bb_simple_perror_msg("vfork");
533 else { 533 else {
534 wait_for_exitstatus(child_pid); 534 wait_for_exitstatus(child_pid);
535 update_utmp_DEAD_PROCESS(child_pid); 535 update_utmp_DEAD_PROCESS(child_pid);
diff --git a/loginutils/su.c b/loginutils/su.c
index 2e1b309b0..79edbc44a 100644
--- a/loginutils/su.c
+++ b/loginutils/su.c
@@ -148,7 +148,7 @@ int su_main(int argc UNUSED_PARAM, char **argv)
148 syslog(LOG_NOTICE, "%c %s %s:%s", 148 syslog(LOG_NOTICE, "%c %s %s:%s",
149 '-', tty, old_user, opt_username); 149 '-', tty, old_user, opt_username);
150 bb_do_delay(LOGIN_FAIL_DELAY); 150 bb_do_delay(LOGIN_FAIL_DELAY);
151 bb_error_msg_and_die("incorrect password"); 151 bb_simple_error_msg_and_die("incorrect password");
152 } 152 }
153 153
154 if (ENABLE_FEATURE_CLEAN_UP && ENABLE_FEATURE_SU_SYSLOG) { 154 if (ENABLE_FEATURE_CLEAN_UP && ENABLE_FEATURE_SU_SYSLOG) {
@@ -166,7 +166,7 @@ int su_main(int argc UNUSED_PARAM, char **argv)
166 * probably a uucp account or has restricted access. Don't 166 * probably a uucp account or has restricted access. Don't
167 * compromise the account by allowing access with a standard 167 * compromise the account by allowing access with a standard
168 * shell. */ 168 * shell. */
169 bb_error_msg("using restricted shell"); 169 bb_simple_error_msg("using restricted shell");
170 opt_shell = NULL; /* ignore -s PROG */ 170 opt_shell = NULL; /* ignore -s PROG */
171 } 171 }
172 /* else: user can run whatever he wants via "su -s PROG USER". 172 /* else: user can run whatever he wants via "su -s PROG USER".
diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c
index 9bb4d3613..099085340 100644
--- a/loginutils/sulogin.c
+++ b/loginutils/sulogin.c
@@ -56,7 +56,7 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv)
56 56
57 pwd = getpwuid(0); 57 pwd = getpwuid(0);
58 if (!pwd) { 58 if (!pwd) {
59 bb_error_msg_and_die("no password entry for root"); 59 bb_simple_error_msg_and_die("no password entry for root");
60 } 60 }
61 61
62 while (1) { 62 while (1) {
@@ -68,17 +68,17 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv)
68 ); 68 );
69 if (r < 0) { 69 if (r < 0) {
70 /* ^D, ^C, timeout, or read error */ 70 /* ^D, ^C, timeout, or read error */
71 bb_info_msg("normal startup"); 71 bb_simple_info_msg("normal startup");
72 return 0; 72 return 0;
73 } 73 }
74 if (r > 0) { 74 if (r > 0) {
75 break; 75 break;
76 } 76 }
77 bb_do_delay(LOGIN_FAIL_DELAY); 77 bb_do_delay(LOGIN_FAIL_DELAY);
78 bb_info_msg("Login incorrect"); 78 bb_simple_info_msg("Login incorrect");
79 } 79 }
80 80
81 bb_info_msg("starting shell for system maintenance"); 81 bb_simple_info_msg("starting shell for system maintenance");
82 82
83 IF_SELINUX(renew_current_security_context()); 83 IF_SELINUX(renew_current_security_context());
84 84
diff --git a/mailutils/mail.c b/mailutils/mail.c
index 6726654f7..3a1fd6949 100644
--- a/mailutils/mail.c
+++ b/mailutils/mail.c
@@ -15,7 +15,7 @@ static void signal_handler(int signo)
15{ 15{
16#define err signo 16#define err signo
17 if (SIGALRM == signo) { 17 if (SIGALRM == signo) {
18 bb_error_msg_and_die("timed out"); 18 bb_simple_error_msg_and_die("timed out");
19 } 19 }
20 20
21 // SIGCHLD. reap zombies 21 // SIGCHLD. reap zombies
@@ -128,7 +128,7 @@ static void encode_n_base64(const char *fname, const char *text, size_t len)
128 if (fname) { 128 if (fname) {
129 size = fread((char *)src_buf, 1, SRC_BUF_SIZE, fp); 129 size = fread((char *)src_buf, 1, SRC_BUF_SIZE, fp);
130 if ((ssize_t)size < 0) 130 if ((ssize_t)size < 0)
131 bb_perror_msg_and_die(bb_msg_read_error); 131 bb_simple_perror_msg_and_die(bb_msg_read_error);
132 } else { 132 } else {
133 size = len; 133 size = len;
134 if (len > SRC_BUF_SIZE) 134 if (len > SRC_BUF_SIZE)
@@ -179,5 +179,5 @@ void FAST_FUNC get_cred_or_die(int fd)
179 G.pass = xmalloc_reads(fd, /* maxsize: */ NULL); 179 G.pass = xmalloc_reads(fd, /* maxsize: */ NULL);
180 } 180 }
181 if (!G.user || !*G.user || !G.pass) 181 if (!G.user || !*G.user || !G.pass)
182 bb_error_msg_and_die("no username or password"); 182 bb_simple_error_msg_and_die("no username or password");
183} 183}
diff --git a/mailutils/popmaildir.c b/mailutils/popmaildir.c
index 589456715..6927e3a58 100644
--- a/mailutils/popmaildir.c
+++ b/mailutils/popmaildir.c
@@ -222,7 +222,7 @@ int popmaildir_main(int argc UNUSED_PARAM, char **argv)
222 fp = popen(delivery, "w"); 222 fp = popen(delivery, "w");
223 unsetenv("FILENAME"); 223 unsetenv("FILENAME");
224 if (!fp) { 224 if (!fp) {
225 bb_perror_msg("delivery helper"); 225 bb_simple_perror_msg("delivery helper");
226 break; 226 break;
227 } 227 }
228 } else 228 } else
diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c
index 32c50ba84..1bdc1c300 100644
--- a/mailutils/sendmail.c
+++ b/mailutils/sendmail.c
@@ -338,7 +338,7 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv)
338 smtp_check(NULL, 250); 338 smtp_check(NULL, 250);
339 else 339 else
340 if (code != 250) 340 if (code != 250)
341 bb_error_msg_and_die("SMTP init failed"); 341 bb_simple_error_msg_and_die("SMTP init failed");
342 } else { 342 } else {
343 // vanilla connection 343 // vanilla connection
344 int fd; 344 int fd;
diff --git a/miscutils/bc.c b/miscutils/bc.c
index 36e978ed8..7ac30dd53 100644
--- a/miscutils/bc.c
+++ b/miscutils/bc.c
@@ -893,7 +893,7 @@ static void fflush_and_check(void)
893{ 893{
894 fflush_all(); 894 fflush_all();
895 if (ferror(stdout) || ferror(stderr)) 895 if (ferror(stdout) || ferror(stderr))
896 bb_perror_msg_and_die("output error"); 896 bb_simple_perror_msg_and_die("output error");
897} 897}
898 898
899#if ENABLE_FEATURE_CLEAN_UP 899#if ENABLE_FEATURE_CLEAN_UP
@@ -908,7 +908,7 @@ static void quit(void) NORETURN;
908static void quit(void) 908static void quit(void)
909{ 909{
910 if (ferror(stdin)) 910 if (ferror(stdin))
911 bb_perror_msg_and_die("input error"); 911 bb_simple_perror_msg_and_die("input error");
912 fflush_and_check(); 912 fflush_and_check();
913 dbg_exec("quit(): exiting with exitcode SUCCESS"); 913 dbg_exec("quit(): exiting with exitcode SUCCESS");
914 exit(0); 914 exit(0);
@@ -997,10 +997,12 @@ static ERRORFUNC int bc_error_bad_character(char c)
997 IF_ERROR_RETURN_POSSIBLE(return) bc_error("NUL character"); 997 IF_ERROR_RETURN_POSSIBLE(return) bc_error("NUL character");
998 IF_ERROR_RETURN_POSSIBLE(return) bc_error_fmt("bad character '%c'", c); 998 IF_ERROR_RETURN_POSSIBLE(return) bc_error_fmt("bad character '%c'", c);
999} 999}
1000#if ENABLE_BC
1000static ERRORFUNC int bc_error_bad_function_definition(void) 1001static ERRORFUNC int bc_error_bad_function_definition(void)
1001{ 1002{
1002 IF_ERROR_RETURN_POSSIBLE(return) bc_error_at("bad function definition"); 1003 IF_ERROR_RETURN_POSSIBLE(return) bc_error_at("bad function definition");
1003} 1004}
1005#endif
1004static ERRORFUNC int bc_error_bad_expression(void) 1006static ERRORFUNC int bc_error_bad_expression(void)
1005{ 1007{
1006 IF_ERROR_RETURN_POSSIBLE(return) bc_error_at("bad expression"); 1008 IF_ERROR_RETURN_POSSIBLE(return) bc_error_at("bad expression");
@@ -1273,14 +1275,12 @@ static int bc_map_insert(BcVec *v, const void *ptr, size_t *i)
1273 return 1; // "was inserted" 1275 return 1; // "was inserted"
1274} 1276}
1275 1277
1276#if ENABLE_BC
1277static size_t bc_map_find_exact(const BcVec *v, const void *ptr) 1278static size_t bc_map_find_exact(const BcVec *v, const void *ptr)
1278{ 1279{
1279 size_t i = bc_map_find_ge(v, ptr); 1280 size_t i = bc_map_find_ge(v, ptr);
1280 if (i >= v->len) return BC_VEC_INVALID_IDX; 1281 if (i >= v->len) return BC_VEC_INVALID_IDX;
1281 return bc_id_cmp(ptr, bc_vec_item(v, i)) ? BC_VEC_INVALID_IDX : i; 1282 return bc_id_cmp(ptr, bc_vec_item(v, i)) ? BC_VEC_INVALID_IDX : i;
1282} 1283}
1283#endif
1284 1284
1285static void bc_num_setToZero(BcNum *n, size_t scale) 1285static void bc_num_setToZero(BcNum *n, size_t scale)
1286{ 1286{
@@ -2576,7 +2576,7 @@ static void xc_read_line(BcVec *vec, FILE *fp)
2576 goto get_char; 2576 goto get_char;
2577 if (c == EOF) { 2577 if (c == EOF) {
2578 if (ferror(fp)) 2578 if (ferror(fp))
2579 bb_perror_msg_and_die("input error"); 2579 bb_simple_perror_msg_and_die("input error");
2580 // Note: EOF does not append '\n' 2580 // Note: EOF does not append '\n'
2581 break; 2581 break;
2582 } 2582 }
@@ -6925,9 +6925,9 @@ static BC_STATUS zxc_vm_process(const char *text)
6925 ip = (void*)G.prog.exestack.v; 6925 ip = (void*)G.prog.exestack.v;
6926#if SANITY_CHECKS 6926#if SANITY_CHECKS
6927 if (G.prog.exestack.len != 1) // should have only main's IP 6927 if (G.prog.exestack.len != 1) // should have only main's IP
6928 bb_error_msg_and_die("BUG:call stack"); 6928 bb_simple_error_msg_and_die("BUG:call stack");
6929 if (ip->func != BC_PROG_MAIN) 6929 if (ip->func != BC_PROG_MAIN)
6930 bb_error_msg_and_die("BUG:not MAIN"); 6930 bb_simple_error_msg_and_die("BUG:not MAIN");
6931#endif 6931#endif
6932 f = xc_program_func_BC_PROG_MAIN(); 6932 f = xc_program_func_BC_PROG_MAIN();
6933 // bc discards strings, constants and code after each 6933 // bc discards strings, constants and code after each
@@ -6943,7 +6943,7 @@ static BC_STATUS zxc_vm_process(const char *text)
6943 if (IS_BC) { 6943 if (IS_BC) {
6944#if SANITY_CHECKS 6944#if SANITY_CHECKS
6945 if (G.prog.results.len != 0) // should be empty 6945 if (G.prog.results.len != 0) // should be empty
6946 bb_error_msg_and_die("BUG:data stack"); 6946 bb_simple_error_msg_and_die("BUG:data stack");
6947#endif 6947#endif
6948 IF_BC(bc_vec_pop_all(&f->strs);) 6948 IF_BC(bc_vec_pop_all(&f->strs);)
6949 IF_BC(bc_vec_pop_all(&f->consts);) 6949 IF_BC(bc_vec_pop_all(&f->consts);)
diff --git a/miscutils/chat.c b/miscutils/chat.c
index 5183d1369..a04565063 100644
--- a/miscutils/chat.c
+++ b/miscutils/chat.c
@@ -307,7 +307,7 @@ int chat_main(int argc UNUSED_PARAM, char **argv)
307 } else if (DIR_SAY == key) { 307 } else if (DIR_SAY == key) {
308 // just print argument verbatim 308 // just print argument verbatim
309 // TODO: should we use full_write() to avoid unistd/stdio conflict? 309 // TODO: should we use full_write() to avoid unistd/stdio conflict?
310 bb_error_msg("%s", arg); 310 bb_simple_error_msg(arg);
311 } 311 }
312 // next, please! 312 // next, please!
313 argv++; 313 argv++;
diff --git a/miscutils/crond.c b/miscutils/crond.c
index b533a3991..2e8ca8b68 100644
--- a/miscutils/crond.c
+++ b/miscutils/crond.c
@@ -731,7 +731,7 @@ fork_job(const char *user, int mailFd, CronLine *line, bool run_sendmail)
731 logmode = sv_logmode; 731 logmode = sv_logmode;
732 732
733 if (pid < 0) { 733 if (pid < 0) {
734 bb_perror_msg("vfork"); 734 bb_simple_perror_msg("vfork");
735 err: 735 err:
736 pid = 0; 736 pid = 0;
737 } /* else: PARENT, FORK SUCCESS */ 737 } /* else: PARENT, FORK SUCCESS */
@@ -861,7 +861,7 @@ static pid_t start_one_job(const char *user, CronLine *line)
861 bb_error_msg_and_die("can't execute '%s' for user %s", shell, user); 861 bb_error_msg_and_die("can't execute '%s' for user %s", shell, user);
862 } 862 }
863 if (pid < 0) { 863 if (pid < 0) {
864 bb_perror_msg("vfork"); 864 bb_simple_perror_msg("vfork");
865 err: 865 err:
866 pid = 0; 866 pid = 0;
867 } 867 }
diff --git a/miscutils/crontab.c b/miscutils/crontab.c
index 96dc4741a..c71d914fc 100644
--- a/miscutils/crontab.c
+++ b/miscutils/crontab.c
@@ -107,7 +107,7 @@ int crontab_main(int argc UNUSED_PARAM, char **argv)
107 if (sanitize_env_if_suid()) { /* Clears dangerous stuff, sets PATH */ 107 if (sanitize_env_if_suid()) { /* Clears dangerous stuff, sets PATH */
108 /* Run by non-root */ 108 /* Run by non-root */
109 if (opt_ler & (OPT_u|OPT_c)) 109 if (opt_ler & (OPT_u|OPT_c))
110 bb_error_msg_and_die(bb_msg_you_must_be_root); 110 bb_simple_error_msg_and_die(bb_msg_you_must_be_root);
111 } 111 }
112 112
113 if (opt_ler & OPT_u) { 113 if (opt_ler & OPT_u) {
diff --git a/miscutils/dc.c b/miscutils/dc.c
index c7ce2be0b..b6c6795b6 100644
--- a/miscutils/dc.c
+++ b/miscutils/dc.c
@@ -39,14 +39,14 @@ static unsigned check_under(void)
39{ 39{
40 unsigned p = pointer; 40 unsigned p = pointer;
41 if (p == 0) 41 if (p == 0)
42 bb_error_msg_and_die("stack underflow"); 42 bb_simple_error_msg_and_die("stack underflow");
43 return p - 1; 43 return p - 1;
44} 44}
45 45
46static void push(double a) 46static void push(double a)
47{ 47{
48 if (pointer >= STACK_SIZE) 48 if (pointer >= STACK_SIZE)
49 bb_error_msg_and_die("stack overflow"); 49 bb_simple_error_msg_and_die("stack overflow");
50 stack[pointer++] = a; 50 stack[pointer++] = a;
51} 51}
52 52
diff --git a/miscutils/devfsd.c b/miscutils/devfsd.c
index e4d104d0c..f3d935b2e 100644
--- a/miscutils/devfsd.c
+++ b/miscutils/devfsd.c
@@ -344,14 +344,19 @@ static const char bb_msg_variable_not_found[] ALIGN1 = "variable: %s not found";
344/* Busybox stuff */ 344/* Busybox stuff */
345#if ENABLE_DEVFSD_VERBOSE || ENABLE_DEBUG 345#if ENABLE_DEVFSD_VERBOSE || ENABLE_DEBUG
346#define info_logger(p, fmt, args...) bb_info_msg(fmt, ## args) 346#define info_logger(p, fmt, args...) bb_info_msg(fmt, ## args)
347#define simple_info_logger(p, msg) bb_simple_info_msg(msg)
347#define msg_logger(p, fmt, args...) bb_error_msg(fmt, ## args) 348#define msg_logger(p, fmt, args...) bb_error_msg(fmt, ## args)
349#define simple_msg_logger(p, msg) bb_simple_error_msg(msg)
348#define msg_logger_and_die(p, fmt, args...) bb_error_msg_and_die(fmt, ## args) 350#define msg_logger_and_die(p, fmt, args...) bb_error_msg_and_die(fmt, ## args)
351#define simple_msg_logger_and_die(p, msg) bb_simple_error_msg_and_die(msg)
349#define error_logger(p, fmt, args...) bb_perror_msg(fmt, ## args) 352#define error_logger(p, fmt, args...) bb_perror_msg(fmt, ## args)
350#define error_logger_and_die(p, fmt, args...) bb_perror_msg_and_die(fmt, ## args) 353#define error_logger_and_die(p, fmt, args...) bb_perror_msg_and_die(fmt, ## args)
351#else 354#else
352#define info_logger(p, fmt, args...) 355#define info_logger(p, fmt, args...)
353#define msg_logger(p, fmt, args...) 356#define msg_logger(p, fmt, args...)
357#define simple_msg_logger(p, msg)
354#define msg_logger_and_die(p, fmt, args...) exit(EXIT_FAILURE) 358#define msg_logger_and_die(p, fmt, args...) exit(EXIT_FAILURE)
359#define simple_msg_logger_and_die(p, msg) exit(EXIT_FAILURE)
355#define error_logger(p, fmt, args...) 360#define error_logger(p, fmt, args...)
356#define error_logger_and_die(p, fmt, args...) exit(EXIT_FAILURE) 361#define error_logger_and_die(p, fmt, args...) exit(EXIT_FAILURE)
357#endif 362#endif
@@ -727,7 +732,7 @@ static int do_servicing(int fd, unsigned long event_mask)
727 caught_sighup = FALSE; 732 caught_sighup = FALSE;
728 return c_sighup; 733 return c_sighup;
729 } 734 }
730 msg_logger_and_die(LOG_ERR, "read error on control file"); 735 simple_msg_logger_and_die(LOG_ERR, "read error on control file");
731} /* End Function do_servicing */ 736} /* End Function do_servicing */
732 737
733static void service_name(const struct devfsd_notify_struct *info) 738static void service_name(const struct devfsd_notify_struct *info)
@@ -786,7 +791,7 @@ static void service_name(const struct devfsd_notify_struct *info)
786 action_compat(info, entry->action.what); 791 action_compat(info, entry->action.what);
787 break; 792 break;
788 default: 793 default:
789 msg_logger_and_die(LOG_ERR, "Unknown action"); 794 simple_msg_logger_and_die(LOG_ERR, "Unknown action");
790 } 795 }
791 } 796 }
792} /* End Function service_name */ 797} /* End Function service_name */
@@ -1691,7 +1696,7 @@ int st_expr_expand(char *output, unsigned int length, const char *input,
1691 } 1696 }
1692 return FALSE; 1697 return FALSE;
1693st_expr_expand_out: 1698st_expr_expand_out:
1694 info_logger(LOG_INFO, bb_msg_small_buffer); 1699 simple_info_logger(LOG_INFO, bb_msg_small_buffer);
1695 return FALSE; 1700 return FALSE;
1696} /* End Function st_expr_expand */ 1701} /* End Function st_expr_expand */
1697 1702
@@ -1775,7 +1780,7 @@ static const char *expand_variable(char *buffer, unsigned int length,
1775 return input + len; 1780 return input + len;
1776 } 1781 }
1777 if (ch != ':' || ptr[1] != '-') { 1782 if (ch != ':' || ptr[1] != '-') {
1778 info_logger(LOG_INFO, "illegal char in var name"); 1783 simple_info_logger(LOG_INFO, "illegal char in var name");
1779 return NULL; 1784 return NULL;
1780 } 1785 }
1781 /* It's that handy "${var:-word}" expression. Check if var is defined */ 1786 /* It's that handy "${var:-word}" expression. Check if var is defined */
@@ -1838,7 +1843,7 @@ static const char *expand_variable(char *buffer, unsigned int length,
1838 *out_pos += len; 1843 *out_pos += len;
1839 return input; 1844 return input;
1840expand_variable_out: 1845expand_variable_out:
1841 info_logger(LOG_INFO, bb_msg_small_buffer); 1846 simple_info_logger(LOG_INFO, bb_msg_small_buffer);
1842 return NULL; 1847 return NULL;
1843} /* End Function expand_variable */ 1848} /* End Function expand_variable */
1844 1849
diff --git a/miscutils/devmem.c b/miscutils/devmem.c
index 51ac3f22f..e8dce5225 100644
--- a/miscutils/devmem.c
+++ b/miscutils/devmem.c
@@ -89,7 +89,7 @@ int devmem_main(int argc UNUSED_PARAM, char **argv)
89 fd, 89 fd,
90 target & ~(off_t)(page_size - 1)); 90 target & ~(off_t)(page_size - 1));
91 if (map_base == MAP_FAILED) 91 if (map_base == MAP_FAILED)
92 bb_perror_msg_and_die("mmap"); 92 bb_simple_perror_msg_and_die("mmap");
93 93
94// printf("Memory mapped at address %p.\n", map_base); 94// printf("Memory mapped at address %p.\n", map_base);
95 95
@@ -110,7 +110,7 @@ int devmem_main(int argc UNUSED_PARAM, char **argv)
110 read_result = *(volatile uint64_t*)virt_addr; 110 read_result = *(volatile uint64_t*)virt_addr;
111 break; 111 break;
112 default: 112 default:
113 bb_error_msg_and_die("bad width"); 113 bb_simple_error_msg_and_die("bad width");
114 } 114 }
115// printf("Value at address 0x%"OFF_FMT"X (%p): 0x%llX\n", 115// printf("Value at address 0x%"OFF_FMT"X (%p): 0x%llX\n",
116// target, virt_addr, 116// target, virt_addr,
@@ -136,7 +136,7 @@ int devmem_main(int argc UNUSED_PARAM, char **argv)
136// read_result = *(volatile uint64_t*)virt_addr; 136// read_result = *(volatile uint64_t*)virt_addr;
137 break; 137 break;
138 default: 138 default:
139 bb_error_msg_and_die("bad width"); 139 bb_simple_error_msg_and_die("bad width");
140 } 140 }
141// printf("Written 0x%llX; readback 0x%llX\n", 141// printf("Written 0x%llX; readback 0x%llX\n",
142// (unsigned long long)writeval, 142// (unsigned long long)writeval,
@@ -145,7 +145,7 @@ int devmem_main(int argc UNUSED_PARAM, char **argv)
145 145
146 if (ENABLE_FEATURE_CLEAN_UP) { 146 if (ENABLE_FEATURE_CLEAN_UP) {
147 if (munmap(map_base, mapped_size) == -1) 147 if (munmap(map_base, mapped_size) == -1)
148 bb_perror_msg_and_die("munmap"); 148 bb_simple_perror_msg_and_die("munmap");
149 close(fd); 149 close(fd);
150 } 150 }
151 151
diff --git a/miscutils/fbsplash.c b/miscutils/fbsplash.c
index bba22d6d1..141957809 100644
--- a/miscutils/fbsplash.c
+++ b/miscutils/fbsplash.c
@@ -183,7 +183,7 @@ static void fb_open(const char *strfb_device)
183 (G.scr_var.yres_virtual ?: G.scr_var.yres) * G.scr_fix.line_length, 183 (G.scr_var.yres_virtual ?: G.scr_var.yres) * G.scr_fix.line_length,
184 PROT_WRITE, MAP_SHARED, fbfd, 0); 184 PROT_WRITE, MAP_SHARED, fbfd, 0);
185 if (G.addr == MAP_FAILED) 185 if (G.addr == MAP_FAILED)
186 bb_perror_msg_and_die("mmap"); 186 bb_simple_perror_msg_and_die("mmap");
187 187
188 // point to the start of the visible screen 188 // point to the start of the visible screen
189 G.addr += G.scr_var.yoffset * G.scr_fix.line_length + G.scr_var.xoffset * G.bytes_per_pixel; 189 G.addr += G.scr_var.yoffset * G.scr_fix.line_length + G.scr_var.xoffset * G.bytes_per_pixel;
diff --git a/miscutils/flash_eraseall.c b/miscutils/flash_eraseall.c
index a3dabdadb..c76d9a699 100644
--- a/miscutils/flash_eraseall.c
+++ b/miscutils/flash_eraseall.c
@@ -120,7 +120,7 @@ int flash_eraseall_main(int argc UNUSED_PARAM, char **argv)
120 if (clmlen > 8) 120 if (clmlen > 8)
121 clmlen = 8; 121 clmlen = 8;
122 if (clmlen == 0) 122 if (clmlen == 0)
123 bb_error_msg_and_die("autoplacement selected and no empty space in oob"); 123 bb_simple_error_msg_and_die("autoplacement selected and no empty space in oob");
124 } else { 124 } else {
125 /* Legacy mode */ 125 /* Legacy mode */
126 switch (meminfo.oobsize) { 126 switch (meminfo.oobsize) {
@@ -168,9 +168,9 @@ int flash_eraseall_main(int argc UNUSED_PARAM, char **argv)
168 if (errno == EOPNOTSUPP) { 168 if (errno == EOPNOTSUPP) {
169 flags |= OPTION_N; 169 flags |= OPTION_N;
170 if (flags & IS_NAND) 170 if (flags & IS_NAND)
171 bb_error_msg_and_die("bad block check not available"); 171 bb_simple_error_msg_and_die("bad block check not available");
172 } else { 172 } else {
173 bb_perror_msg_and_die("MEMGETBADBLOCK error"); 173 bb_simple_perror_msg_and_die("MEMGETBADBLOCK error");
174 } 174 }
175 } 175 }
176 } 176 }
diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c
index 342e240fa..b453efba9 100644
--- a/miscutils/hdparm.c
+++ b/miscutils/hdparm.c
@@ -810,7 +810,7 @@ static void identify(uint16_t *val)
810 like_std = 3; 810 like_std = 3;
811 } else 811 } else
812 /* "Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n" */ 812 /* "Unknown device type:\n\tbits 15&14 of general configuration word 0 both set to 1.\n" */
813 bb_error_msg_and_die("unknown device type"); 813 bb_simple_error_msg_and_die("unknown device type");
814 814
815 printf("%sremovable media\n", !(val[GEN_CONFIG] & MEDIA_REMOVABLE) ? "non-" : ""); 815 printf("%sremovable media\n", !(val[GEN_CONFIG] & MEDIA_REMOVABLE) ? "non-" : "");
816 /* Info from the specific configuration word says whether or not the 816 /* Info from the specific configuration word says whether or not the
@@ -1440,7 +1440,7 @@ static void flush_buffer_cache(/*int fd*/ void)
1440 sleep(1); 1440 sleep(1);
1441 if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) { /* await completion */ 1441 if (ioctl(fd, HDIO_DRIVE_CMD, NULL) && errno != EINVAL) { /* await completion */
1442 if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */ 1442 if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1443 bb_perror_msg("HDIO_DRIVE_CMD"); 1443 bb_simple_perror_msg("HDIO_DRIVE_CMD");
1444 else 1444 else
1445 bb_perror_msg("ioctl %#x failed", HDIO_DRIVE_CMD); 1445 bb_perror_msg("ioctl %#x failed", HDIO_DRIVE_CMD);
1446 } 1446 }
@@ -1506,7 +1506,7 @@ static void do_time(int cache /*,int fd*/)
1506 char *buf = xmalloc(TIMING_BUF_BYTES); 1506 char *buf = xmalloc(TIMING_BUF_BYTES);
1507 1507
1508 if (mlock(buf, TIMING_BUF_BYTES)) 1508 if (mlock(buf, TIMING_BUF_BYTES))
1509 bb_perror_msg_and_die("mlock"); 1509 bb_simple_perror_msg_and_die("mlock");
1510 1510
1511 /* Clear out the device request queues & give them time to complete. 1511 /* Clear out the device request queues & give them time to complete.
1512 * NB: *small* delay. User is expected to have a clue and to not run 1512 * NB: *small* delay. User is expected to have a clue and to not run
@@ -1857,7 +1857,7 @@ static void process_dev(char *devname)
1857 char buf[512]; 1857 char buf[512];
1858 flush_buffer_cache(); 1858 flush_buffer_cache();
1859 if (-1 == read(fd, buf, sizeof(buf))) 1859 if (-1 == read(fd, buf, sizeof(buf)))
1860 bb_perror_msg("read of 512 bytes failed"); 1860 bb_simple_perror_msg("read of 512 bytes failed");
1861 } 1861 }
1862#endif /* HDIO_DRIVE_CMD */ 1862#endif /* HDIO_DRIVE_CMD */
1863 if (getset_mult || get_identity) { 1863 if (getset_mult || get_identity) {
@@ -1865,7 +1865,7 @@ static void process_dev(char *devname)
1865 if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) { 1865 if (ioctl(fd, HDIO_GET_MULTCOUNT, &multcount)) {
1866 /* To be coherent with ioctl_or_warn. */ 1866 /* To be coherent with ioctl_or_warn. */
1867 if (getset_mult && ENABLE_IOCTL_HEX2STR_ERROR) 1867 if (getset_mult && ENABLE_IOCTL_HEX2STR_ERROR)
1868 bb_perror_msg("HDIO_GET_MULTCOUNT"); 1868 bb_simple_perror_msg("HDIO_GET_MULTCOUNT");
1869 else 1869 else
1870 bb_perror_msg("ioctl %#x failed", HDIO_GET_MULTCOUNT); 1870 bb_perror_msg("ioctl %#x failed", HDIO_GET_MULTCOUNT);
1871 } else if (getset_mult) { 1871 } else if (getset_mult) {
@@ -1985,7 +1985,7 @@ static void process_dev(char *devname)
1985 } else if (errno == -ENOMSG) 1985 } else if (errno == -ENOMSG)
1986 puts(" no identification info available"); 1986 puts(" no identification info available");
1987 else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */ 1987 else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */
1988 bb_perror_msg("HDIO_GET_IDENTITY"); 1988 bb_simple_perror_msg("HDIO_GET_IDENTITY");
1989 else 1989 else
1990 bb_perror_msg("ioctl %#x failed", HDIO_GET_IDENTITY); 1990 bb_perror_msg("ioctl %#x failed", HDIO_GET_IDENTITY);
1991 } 1991 }
diff --git a/miscutils/hexedit.c b/miscutils/hexedit.c
index 5c2f4a555..898d77376 100644
--- a/miscutils/hexedit.c
+++ b/miscutils/hexedit.c
@@ -193,7 +193,7 @@ static int remap(unsigned cur_pos)
193 ); 193 );
194 if (G.baseaddr == MAP_FAILED) { 194 if (G.baseaddr == MAP_FAILED) {
195 restore_term(); 195 restore_term();
196 bb_perror_msg_and_die("mmap"); 196 bb_simple_perror_msg_and_die("mmap");
197 } 197 }
198 198
199 G.current_byte = G.baseaddr + cur_pos; 199 G.current_byte = G.baseaddr + cur_pos;
diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c
index 7a2e8534a..82a559f74 100644
--- a/miscutils/i2c_tools.c
+++ b/miscutils/i2c_tools.c
@@ -344,7 +344,7 @@ static void get_funcs_matrix(int fd, unsigned long *funcs)
344static void check_funcs_test_end(int funcs, int pec, const char *err) 344static void check_funcs_test_end(int funcs, int pec, const char *err)
345{ 345{
346 if (pec && !(funcs & (I2C_FUNC_SMBUS_PEC | I2C_FUNC_I2C))) 346 if (pec && !(funcs & (I2C_FUNC_SMBUS_PEC | I2C_FUNC_I2C)))
347 bb_error_msg("warning: adapter does not support PEC"); 347 bb_simple_error_msg("warning: adapter does not support PEC");
348 348
349 if (err) 349 if (err)
350 bb_error_msg_and_die( 350 bb_error_msg_and_die(
@@ -392,7 +392,7 @@ static void check_read_funcs(int fd, int mode, int data_addr, int pec)
392 break; 392 break;
393#endif /* ENABLE_I2CDUMP */ 393#endif /* ENABLE_I2CDUMP */
394 default: 394 default:
395 bb_error_msg_and_die("internal error"); 395 bb_simple_error_msg_and_die("internal error");
396 } 396 }
397 check_funcs_test_end(funcs, pec, err); 397 check_funcs_test_end(funcs, pec, err);
398} 398}
@@ -438,7 +438,7 @@ static void confirm_or_abort(void)
438{ 438{
439 fprintf(stderr, "Continue? [y/N] "); 439 fprintf(stderr, "Continue? [y/N] ");
440 if (!bb_ask_y_confirmation()) 440 if (!bb_ask_y_confirmation())
441 bb_error_msg_and_die("aborting"); 441 bb_simple_error_msg_and_die("aborting");
442} 442}
443 443
444/* 444/*
@@ -449,20 +449,20 @@ static void confirm_or_abort(void)
449 */ 449 */
450static void confirm_action(int bus_addr, int mode, int data_addr, int pec) 450static void confirm_action(int bus_addr, int mode, int data_addr, int pec)
451{ 451{
452 bb_error_msg("WARNING! This program can confuse your I2C bus"); 452 bb_simple_error_msg("WARNING! This program can confuse your I2C bus");
453 453
454 /* Don't let the user break his/her EEPROMs */ 454 /* Don't let the user break his/her EEPROMs */
455 if (bus_addr >= 0x50 && bus_addr <= 0x57 && pec) { 455 if (bus_addr >= 0x50 && bus_addr <= 0x57 && pec) {
456 bb_error_msg_and_die("this is I2C not smbus - using PEC on I2C " 456 bb_simple_error_msg_and_die("this is I2C not smbus - using PEC on I2C "
457 "devices may result in data loss, aborting"); 457 "devices may result in data loss, aborting");
458 } 458 }
459 459
460 if (mode == I2C_SMBUS_BYTE && data_addr >= 0 && pec) 460 if (mode == I2C_SMBUS_BYTE && data_addr >= 0 && pec)
461 bb_error_msg("WARNING! May interpret a write byte command " 461 bb_simple_error_msg("WARNING! May interpret a write byte command "
462 "with PEC as a write byte data command"); 462 "with PEC as a write byte data command");
463 463
464 if (pec) 464 if (pec)
465 bb_error_msg("PEC checking enabled"); 465 bb_simple_error_msg("PEC checking enabled");
466 466
467 confirm_or_abort(); 467 confirm_or_abort();
468} 468}
@@ -507,7 +507,7 @@ int i2cget_main(int argc UNUSED_PARAM, char **argv)
507 case 'w': mode = I2C_SMBUS_WORD_DATA; break; 507 case 'w': mode = I2C_SMBUS_WORD_DATA; break;
508 case 'c': mode = I2C_SMBUS_BYTE; break; 508 case 'c': mode = I2C_SMBUS_BYTE; break;
509 default: 509 default:
510 bb_error_msg("invalid mode"); 510 bb_simple_error_msg("invalid mode");
511 bb_show_usage(); 511 bb_show_usage();
512 } 512 }
513 pec = argv[3][1] == 'p'; 513 pec = argv[3][1] == 'p';
@@ -529,7 +529,7 @@ int i2cget_main(int argc UNUSED_PARAM, char **argv)
529 if (data_addr >= 0) { 529 if (data_addr >= 0) {
530 status = i2c_smbus_write_byte(fd, data_addr); 530 status = i2c_smbus_write_byte(fd, data_addr);
531 if (status < 0) 531 if (status < 0)
532 bb_error_msg("warning - write failed"); 532 bb_simple_error_msg("warning - write failed");
533 } 533 }
534 status = i2c_smbus_read_byte(fd); 534 status = i2c_smbus_read_byte(fd);
535 break; 535 break;
@@ -542,7 +542,7 @@ int i2cget_main(int argc UNUSED_PARAM, char **argv)
542 close(fd); 542 close(fd);
543 543
544 if (status < 0) 544 if (status < 0)
545 bb_perror_msg_and_die("read failed"); 545 bb_simple_perror_msg_and_die("read failed");
546 546
547 printf("0x%0*x\n", mode == I2C_SMBUS_WORD_DATA ? 4 : 2, status); 547 printf("0x%0*x\n", mode == I2C_SMBUS_WORD_DATA ? 4 : 2, status);
548 548
@@ -611,7 +611,7 @@ int i2cset_main(int argc, char **argv)
611 case 'i': mode = I2C_SMBUS_I2C_BLOCK_DATA; 611 case 'i': mode = I2C_SMBUS_I2C_BLOCK_DATA;
612 break; 612 break;
613 default: 613 default:
614 bb_error_msg("invalid mode"); 614 bb_simple_error_msg("invalid mode");
615 bb_show_usage(); 615 bb_show_usage();
616 } 616 }
617 617
@@ -620,11 +620,11 @@ int i2cset_main(int argc, char **argv)
620 || mode == I2C_SMBUS_I2C_BLOCK_DATA 620 || mode == I2C_SMBUS_I2C_BLOCK_DATA
621 ) { 621 ) {
622 if (pec && mode == I2C_SMBUS_I2C_BLOCK_DATA) 622 if (pec && mode == I2C_SMBUS_I2C_BLOCK_DATA)
623 bb_error_msg_and_die( 623 bb_simple_error_msg_and_die(
624 "PEC not supported for I2C " 624 "PEC not supported for I2C "
625 "block writes"); 625 "block writes");
626 if (opts & opt_m) 626 if (opts & opt_m)
627 bb_error_msg_and_die( 627 bb_simple_error_msg_and_die(
628 "mask not supported for block " 628 "mask not supported for block "
629 "writes"); 629 "writes");
630 } 630 }
@@ -685,7 +685,7 @@ int i2cset_main(int argc, char **argv)
685 } 685 }
686 686
687 if (tmpval < 0) 687 if (tmpval < 0)
688 bb_perror_msg_and_die("can't read old value"); 688 bb_simple_perror_msg_and_die("can't read old value");
689 689
690 val = (val & mask) | (tmpval & ~mask); 690 val = (val & mask) | (tmpval & ~mask);
691 691
@@ -724,7 +724,7 @@ int i2cset_main(int argc, char **argv)
724 break; 724 break;
725 } 725 }
726 if (status < 0) 726 if (status < 0)
727 bb_perror_msg_and_die("write failed"); 727 bb_simple_perror_msg_and_die("write failed");
728 728
729 if (pec) 729 if (pec)
730 i2c_set_pec(fd, 0); /* Clear PEC. */ 730 i2c_set_pec(fd, 0); /* Clear PEC. */
@@ -978,12 +978,12 @@ int i2cdump_main(int argc UNUSED_PARAM, char **argv)
978 case 's': mode = I2C_SMBUS_BLOCK_DATA; break; 978 case 's': mode = I2C_SMBUS_BLOCK_DATA; break;
979 case 'i': mode = I2C_SMBUS_I2C_BLOCK_DATA; break; 979 case 'i': mode = I2C_SMBUS_I2C_BLOCK_DATA; break;
980 default: 980 default:
981 bb_error_msg_and_die("invalid mode"); 981 bb_simple_error_msg_and_die("invalid mode");
982 } 982 }
983 983
984 if (argv[2][1] == 'p') { 984 if (argv[2][1] == 'p') {
985 if (argv[2][0] == 'W' || argv[2][0] == 'i') { 985 if (argv[2][0] == 'W' || argv[2][0] == 'i') {
986 bb_error_msg_and_die( 986 bb_simple_error_msg_and_die(
987 "pec not supported for -W and -i"); 987 "pec not supported for -W and -i");
988 } else { 988 } else {
989 pec = 1; 989 pec = 1;
@@ -994,7 +994,7 @@ int i2cdump_main(int argc UNUSED_PARAM, char **argv)
994 if (opts & opt_r) { 994 if (opts & opt_r) {
995 first = strtol(opt_r_str, &dash, 0); 995 first = strtol(opt_r_str, &dash, 0);
996 if (dash == opt_r_str || *dash != '-' || first > 0xff) 996 if (dash == opt_r_str || *dash != '-' || first > 0xff)
997 bb_error_msg_and_die("invalid range"); 997 bb_simple_error_msg_and_die("invalid range");
998 last = xstrtou_range(++dash, 0, first, 0xff); 998 last = xstrtou_range(++dash, 0, first, 0xff);
999 999
1000 /* Range is not available for every mode. */ 1000 /* Range is not available for every mode. */
@@ -1007,7 +1007,7 @@ int i2cdump_main(int argc UNUSED_PARAM, char **argv)
1007 break; 1007 break;
1008 /* Fall through */ 1008 /* Fall through */
1009 default: 1009 default:
1010 bb_error_msg_and_die( 1010 bb_simple_error_msg_and_die(
1011 "range not compatible with selected mode"); 1011 "range not compatible with selected mode");
1012 } 1012 }
1013 } 1013 }
@@ -1032,7 +1032,7 @@ int i2cdump_main(int argc UNUSED_PARAM, char **argv)
1032 if (mode == I2C_SMBUS_BYTE) { 1032 if (mode == I2C_SMBUS_BYTE) {
1033 res = i2c_smbus_write_byte(fd, first); 1033 res = i2c_smbus_write_byte(fd, first);
1034 if (res < 0) 1034 if (res < 0)
1035 bb_perror_msg_and_die("write start address"); 1035 bb_simple_perror_msg_and_die("write start address");
1036 } 1036 }
1037 1037
1038 dump_data(fd, mode, first, last, block, blen); 1038 dump_data(fd, mode, first, last, block, blen);
@@ -1398,7 +1398,7 @@ static void check_i2c_func(int fd)
1398 get_funcs_matrix(fd, &funcs); 1398 get_funcs_matrix(fd, &funcs);
1399 1399
1400 if (!(funcs & I2C_FUNC_I2C)) 1400 if (!(funcs & I2C_FUNC_I2C))
1401 bb_error_msg_and_die("adapter does not support I2C transfers"); 1401 bb_simple_error_msg_and_die("adapter does not support I2C transfers");
1402} 1402}
1403 1403
1404//usage:#define i2ctransfer_trivial_usage 1404//usage:#define i2ctransfer_trivial_usage
@@ -1451,7 +1451,7 @@ int i2ctransfer_main(int argc UNUSED_PARAM, char **argv)
1451 char *end; 1451 char *end;
1452 1452
1453 if (nmsgs >= I2C_RDWR_IOCTL_MAX_MSGS) 1453 if (nmsgs >= I2C_RDWR_IOCTL_MAX_MSGS)
1454 bb_error_msg_and_die("too many messages, max: "I2C_RDWR_IOCTL_MAX_MSGS_STR); 1454 bb_simple_error_msg_and_die("too many messages, max: "I2C_RDWR_IOCTL_MAX_MSGS_STR);
1455 1455
1456 flags = 0; 1456 flags = 0;
1457 arg_ptr = *argv; 1457 arg_ptr = *argv;
diff --git a/miscutils/inotifyd.c b/miscutils/inotifyd.c
index ec0321941..8bff86ae5 100644
--- a/miscutils/inotifyd.c
+++ b/miscutils/inotifyd.c
@@ -117,7 +117,7 @@ int inotifyd_main(int argc, char **argv)
117 // open inotify 117 // open inotify
118 pfd.fd = inotify_init(); 118 pfd.fd = inotify_init();
119 if (pfd.fd < 0) 119 if (pfd.fd < 0)
120 bb_perror_msg_and_die("no kernel support"); 120 bb_simple_perror_msg_and_die("no kernel support");
121 121
122 // setup watches 122 // setup watches
123 while (*++argv) { 123 while (*++argv) {
diff --git a/miscutils/nandwrite.c b/miscutils/nandwrite.c
index 09bcaaf63..f111c6363 100644
--- a/miscutils/nandwrite.c
+++ b/miscutils/nandwrite.c
@@ -101,7 +101,7 @@ static unsigned next_good_eraseblock(int fd, struct mtd_info_user *meminfo,
101 101
102 if (block_offset >= meminfo->size) { 102 if (block_offset >= meminfo->size) {
103 if (IS_NANDWRITE) 103 if (IS_NANDWRITE)
104 bb_error_msg_and_die("not enough space in MTD device"); 104 bb_simple_error_msg_and_die("not enough space in MTD device");
105 return block_offset; /* let the caller exit */ 105 return block_offset; /* let the caller exit */
106 } 106 }
107 offs = block_offset; 107 offs = block_offset;
@@ -174,7 +174,7 @@ int nandwrite_main(int argc UNUSED_PARAM, char **argv)
174 meminfo_writesize = meminfo.writesize; 174 meminfo_writesize = meminfo.writesize;
175 175
176 if (mtdoffset & (meminfo_writesize - 1)) 176 if (mtdoffset & (meminfo_writesize - 1))
177 bb_error_msg_and_die("start address is not page aligned"); 177 bb_simple_error_msg_and_die("start address is not page aligned");
178 178
179 filebuf = xmalloc(meminfo_writesize); 179 filebuf = xmalloc(meminfo_writesize);
180 oobbuf = xmalloc(meminfo.oobsize); 180 oobbuf = xmalloc(meminfo.oobsize);
@@ -248,9 +248,9 @@ int nandwrite_main(int argc UNUSED_PARAM, char **argv)
248 } 248 }
249 if (cnt < meminfo_writesize) { 249 if (cnt < meminfo_writesize) {
250 if (IS_NANDDUMP) 250 if (IS_NANDDUMP)
251 bb_error_msg_and_die("short read"); 251 bb_simple_error_msg_and_die("short read");
252 if (!(opts & OPT_p)) 252 if (!(opts & OPT_p))
253 bb_error_msg_and_die("input size is not rounded up to page size, " 253 bb_simple_error_msg_and_die("input size is not rounded up to page size, "
254 "use -p to zero pad"); 254 "use -p to zero pad");
255 /* zero pad to end of write block */ 255 /* zero pad to end of write block */
256 memset(filebuf + cnt, 0, meminfo_writesize - cnt); 256 memset(filebuf + cnt, 0, meminfo_writesize - cnt);
@@ -273,7 +273,7 @@ int nandwrite_main(int argc UNUSED_PARAM, char **argv)
273 /* We filled entire MTD, but did we reach EOF on input? */ 273 /* We filled entire MTD, but did we reach EOF on input? */
274 if (full_read(STDIN_FILENO, filebuf, meminfo_writesize) != 0) { 274 if (full_read(STDIN_FILENO, filebuf, meminfo_writesize) != 0) {
275 /* no */ 275 /* no */
276 bb_error_msg_and_die("not enough space in MTD device"); 276 bb_simple_error_msg_and_die("not enough space in MTD device");
277 } 277 }
278 } 278 }
279 279
diff --git a/miscutils/rfkill.c b/miscutils/rfkill.c
index 766bad8c7..db7c83750 100644
--- a/miscutils/rfkill.c
+++ b/miscutils/rfkill.c
@@ -88,7 +88,7 @@ int rfkill_main(int argc UNUSED_PARAM, char **argv)
88 88
89 rf_fd = device_open("/dev/rfkill", mode); 89 rf_fd = device_open("/dev/rfkill", mode);
90 if (rf_fd < 0) 90 if (rf_fd < 0)
91 bb_perror_msg_and_die("/dev/rfkill"); 91 bb_simple_perror_msg_and_die("/dev/rfkill");
92 92
93 if (rf_opt & OPT_l) { 93 if (rf_opt & OPT_l) {
94 while (full_read(rf_fd, &event, sizeof(event)) == RFKILL_EVENT_SIZE_V1) { 94 while (full_read(rf_fd, &event, sizeof(event)) == RFKILL_EVENT_SIZE_V1) {
diff --git a/miscutils/rx.c b/miscutils/rx.c
index 874a3f0a3..319ec1d49 100644
--- a/miscutils/rx.c
+++ b/miscutils/rx.c
@@ -120,7 +120,7 @@ static int receive(/*int read_fd, */int file_fd)
120 /* Write previously received block */ 120 /* Write previously received block */
121 errno = 0; 121 errno = 0;
122 if (full_write(file_fd, blockBuf, blockLength) != blockLength) { 122 if (full_write(file_fd, blockBuf, blockLength) != blockLength) {
123 bb_perror_msg(bb_msg_write_error); 123 bb_simple_perror_msg(bb_msg_write_error);
124 goto fatal; 124 goto fatal;
125 } 125 }
126 126
@@ -150,7 +150,7 @@ static int receive(/*int read_fd, */int file_fd)
150 goto timeout; 150 goto timeout;
151 151
152 if (blockNo != (255 - blockNoOnesCompl)) { 152 if (blockNo != (255 - blockNoOnesCompl)) {
153 bb_error_msg("bad block ones compl"); 153 bb_simple_error_msg("bad block ones compl");
154 goto error; 154 goto error;
155 } 155 }
156 156
@@ -229,7 +229,7 @@ static int receive(/*int read_fd, */int file_fd)
229 do_crc = 0; 229 do_crc = 0;
230 goto timeout; 230 goto timeout;
231 } 231 }
232 bb_error_msg("too many errors; giving up"); 232 bb_simple_error_msg("too many errors; giving up");
233 fatal: 233 fatal:
234 /* 5 CAN followed by 5 BS. Don't try too hard... */ 234 /* 5 CAN followed by 5 BS. Don't try too hard... */
235 safe_write(write_fd, "\030\030\030\030\030\010\010\010\010\010", 10); 235 safe_write(write_fd, "\030\030\030\030\030\010\010\010\010\010", 10);
diff --git a/miscutils/time.c b/miscutils/time.c
index 064888ab8..d15d363f3 100644
--- a/miscutils/time.c
+++ b/miscutils/time.c
@@ -88,7 +88,7 @@ static void resuse_end(pid_t pid, resource_t *resp)
88 * returns the child process, set the time the command finished. */ 88 * returns the child process, set the time the command finished. */
89 while ((caught = wait3(&resp->waitstatus, 0, &resp->ru)) != pid) { 89 while ((caught = wait3(&resp->waitstatus, 0, &resp->ru)) != pid) {
90 if (caught == -1 && errno != EINTR) { 90 if (caught == -1 && errno != EINTR) {
91 bb_perror_msg("wait"); 91 bb_simple_perror_msg("wait");
92 return; 92 return;
93 } 93 }
94 } 94 }
diff --git a/miscutils/ubi_tools.c b/miscutils/ubi_tools.c
index dc7af25a4..8318df0f9 100644
--- a/miscutils/ubi_tools.c
+++ b/miscutils/ubi_tools.c
@@ -234,10 +234,10 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv)
234 // bb_error_msg_and_die("%s invalid maximum size calculated", "UBI"); 234 // bb_error_msg_and_die("%s invalid maximum size calculated", "UBI");
235 } else 235 } else
236 if (!(opts & OPTION_s)) 236 if (!(opts & OPTION_s))
237 bb_error_msg_and_die("size not specified"); 237 bb_simple_error_msg_and_die("size not specified");
238 238
239 if (!(opts & OPTION_N)) 239 if (!(opts & OPTION_N))
240 bb_error_msg_and_die("name not specified"); 240 bb_simple_error_msg_and_die("name not specified");
241 241
242 /* the structure is memset(0) above */ 242 /* the structure is memset(0) above */
243 mkvol_req.vol_id = vol_id; 243 mkvol_req.vol_id = vol_id;
@@ -264,7 +264,7 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv)
264//usage: "\n -N VOLNAME Volume name" 264//usage: "\n -N VOLNAME Volume name"
265 if (do_rmvol) { 265 if (do_rmvol) {
266 if (!(opts & (OPTION_n|OPTION_N))) 266 if (!(opts & (OPTION_n|OPTION_N)))
267 bb_error_msg_and_die("volume id not specified"); 267 bb_simple_error_msg_and_die("volume id not specified");
268 268
269 if (opts & OPTION_N) { 269 if (opts & OPTION_N) {
270 unsigned num = ubi_devnum_from_devname(ubi_ctrl); 270 unsigned num = ubi_devnum_from_devname(ubi_ctrl);
@@ -288,9 +288,9 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv)
288//usage: "\n -s SIZE Size in bytes" 288//usage: "\n -s SIZE Size in bytes"
289 if (do_rsvol) { 289 if (do_rsvol) {
290 if (!(opts & OPTION_s)) 290 if (!(opts & OPTION_s))
291 bb_error_msg_and_die("size not specified"); 291 bb_simple_error_msg_and_die("size not specified");
292 if (!(opts & OPTION_n)) 292 if (!(opts & OPTION_n))
293 bb_error_msg_and_die("volume id not specified"); 293 bb_simple_error_msg_and_die("volume id not specified");
294 294
295 rsvol_req.bytes = size_bytes; /* signed int64_t */ 295 rsvol_req.bytes = size_bytes; /* signed int64_t */
296 rsvol_req.vol_id = vol_id; 296 rsvol_req.vol_id = vol_id;
diff --git a/miscutils/ubirename.c b/miscutils/ubirename.c
index 21bd10111..e7c56640c 100644
--- a/miscutils/ubirename.c
+++ b/miscutils/ubirename.c
@@ -72,7 +72,7 @@ int ubirename_main(int argc, char **argv)
72 rnvol = xzalloc(sizeof(*rnvol)); 72 rnvol = xzalloc(sizeof(*rnvol));
73 rnvol->count = --argc; 73 rnvol->count = --argc;
74 if (argc > ARRAY_SIZE(rnvol->ents)) 74 if (argc > ARRAY_SIZE(rnvol->ents))
75 bb_error_msg_and_die("too many renames requested"); 75 bb_simple_error_msg_and_die("too many renames requested");
76 76
77 ubi_devname = argv[1]; 77 ubi_devname = argv[1];
78 ubi_devnum = ubi_devnum_from_devname(ubi_devname); 78 ubi_devnum = ubi_devnum_from_devname(ubi_devname);
diff --git a/modutils/modutils-24.c b/modutils/modutils-24.c
index 1a30dd87c..ac8632481 100644
--- a/modutils/modutils-24.c
+++ b/modutils/modutils-24.c
@@ -2600,7 +2600,7 @@ static void new_get_kernel_symbols(void)
2600 module_names = xrealloc(module_names, bufsize); 2600 module_names = xrealloc(module_names, bufsize);
2601 goto retry_modules_load; 2601 goto retry_modules_load;
2602 } 2602 }
2603 bb_perror_msg_and_die("QM_MODULES"); 2603 bb_simple_perror_msg_and_die("QM_MODULES");
2604 } 2604 }
2605 2605
2606 n_ext_modules = nmod = ret; 2606 n_ext_modules = nmod = ret;
@@ -2661,7 +2661,7 @@ static void new_get_kernel_symbols(void)
2661 syms = xrealloc(syms, bufsize); 2661 syms = xrealloc(syms, bufsize);
2662 goto retry_kern_sym_load; 2662 goto retry_kern_sym_load;
2663 } 2663 }
2664 bb_perror_msg_and_die("kernel: QM_SYMBOLS"); 2664 bb_simple_perror_msg_and_die("kernel: QM_SYMBOLS");
2665 } 2665 }
2666 nksyms = nsyms = ret; 2666 nksyms = nsyms = ret;
2667 ksyms = syms; 2667 ksyms = syms;
@@ -3247,21 +3247,21 @@ static struct obj_file *obj_load(char *image, size_t image_size, int loadprogbit
3247 f->load_order_search_start = &f->load_order; 3247 f->load_order_search_start = &f->load_order;
3248 3248
3249 if (image_size < sizeof(f->header)) 3249 if (image_size < sizeof(f->header))
3250 bb_error_msg_and_die("error while loading ELF header"); 3250 bb_simple_error_msg_and_die("error while loading ELF header");
3251 memcpy(&f->header, image, sizeof(f->header)); 3251 memcpy(&f->header, image, sizeof(f->header));
3252 3252
3253 if (*(aliased_uint32_t*)(&f->header.e_ident) != ELFMAG_U32) { 3253 if (*(aliased_uint32_t*)(&f->header.e_ident) != ELFMAG_U32) {
3254 bb_error_msg_and_die("not an ELF file"); 3254 bb_simple_error_msg_and_die("not an ELF file");
3255 } 3255 }
3256 if (f->header.e_ident[EI_CLASS] != ELFCLASSM 3256 if (f->header.e_ident[EI_CLASS] != ELFCLASSM
3257 || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB) 3257 || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB)
3258 || f->header.e_ident[EI_VERSION] != EV_CURRENT 3258 || f->header.e_ident[EI_VERSION] != EV_CURRENT
3259 || !MATCH_MACHINE(f->header.e_machine) 3259 || !MATCH_MACHINE(f->header.e_machine)
3260 ) { 3260 ) {
3261 bb_error_msg_and_die("ELF file not for this architecture"); 3261 bb_simple_error_msg_and_die("ELF file not for this architecture");
3262 } 3262 }
3263 if (f->header.e_type != ET_REL) { 3263 if (f->header.e_type != ET_REL) {
3264 bb_error_msg_and_die("ELF file not a relocatable object"); 3264 bb_simple_error_msg_and_die("ELF file not a relocatable object");
3265 } 3265 }
3266 3266
3267 /* Read the section headers. */ 3267 /* Read the section headers. */
@@ -3280,7 +3280,7 @@ static struct obj_file *obj_load(char *image, size_t image_size, int loadprogbit
3280 3280
3281 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum); 3281 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum);
3282 if (image_size < f->header.e_shoff + sizeof(ElfW(Shdr)) * shnum) 3282 if (image_size < f->header.e_shoff + sizeof(ElfW(Shdr)) * shnum)
3283 bb_error_msg_and_die("error while loading section headers"); 3283 bb_simple_error_msg_and_die("error while loading section headers");
3284 memcpy(section_headers, image + f->header.e_shoff, sizeof(ElfW(Shdr)) * shnum); 3284 memcpy(section_headers, image + f->header.e_shoff, sizeof(ElfW(Shdr)) * shnum);
3285 3285
3286 /* Read the section data. */ 3286 /* Read the section data. */
@@ -3317,16 +3317,16 @@ static struct obj_file *obj_load(char *image, size_t image_size, int loadprogbit
3317 if (sec->header.sh_size > 0) { 3317 if (sec->header.sh_size > 0) {
3318 sec->contents = xmalloc(sec->header.sh_size); 3318 sec->contents = xmalloc(sec->header.sh_size);
3319 if (image_size < (sec->header.sh_offset + sec->header.sh_size)) 3319 if (image_size < (sec->header.sh_offset + sec->header.sh_size))
3320 bb_error_msg_and_die("error while loading section data"); 3320 bb_simple_error_msg_and_die("error while loading section data");
3321 memcpy(sec->contents, image + sec->header.sh_offset, sec->header.sh_size); 3321 memcpy(sec->contents, image + sec->header.sh_offset, sec->header.sh_size);
3322 } 3322 }
3323 break; 3323 break;
3324#if SHT_RELM == SHT_REL 3324#if SHT_RELM == SHT_REL
3325 case SHT_RELA: 3325 case SHT_RELA:
3326 bb_error_msg_and_die("RELA relocations not supported on this architecture"); 3326 bb_simple_error_msg_and_die("RELA relocations not supported on this architecture");
3327#else 3327#else
3328 case SHT_REL: 3328 case SHT_REL:
3329 bb_error_msg_and_die("REL relocations not supported on this architecture"); 3329 bb_simple_error_msg_and_die("REL relocations not supported on this architecture");
3330#endif 3330#endif
3331 default: 3331 default:
3332 if (sec->header.sh_type >= SHT_LOPROC) { 3332 if (sec->header.sh_type >= SHT_LOPROC) {
@@ -3447,7 +3447,7 @@ static int obj_load_progbits(char *image, size_t image_size, struct obj_file *f,
3447 continue; 3447 continue;
3448 sec->contents = imagebase + (sec->header.sh_addr - base); 3448 sec->contents = imagebase + (sec->header.sh_addr - base);
3449 if (image_size < (sec->header.sh_offset + sec->header.sh_size)) { 3449 if (image_size < (sec->header.sh_offset + sec->header.sh_size)) {
3450 bb_error_msg("error reading ELF section data"); 3450 bb_simple_error_msg("error reading ELF section data");
3451 return 0; /* need to delete half-loaded module! */ 3451 return 0; /* need to delete half-loaded module! */
3452 } 3452 }
3453 memcpy(sec->contents, image + sec->header.sh_offset, sec->header.sh_size); 3453 memcpy(sec->contents, image + sec->header.sh_offset, sec->header.sh_size);
@@ -3845,7 +3845,7 @@ int FAST_FUNC bb_init_module_24(const char *m_filename, const char *options)
3845 if (m_has_modinfo) { 3845 if (m_has_modinfo) {
3846 int m_version = new_get_module_version(f, m_strversion); 3846 int m_version = new_get_module_version(f, m_strversion);
3847 if (m_version == -1) { 3847 if (m_version == -1) {
3848 bb_error_msg_and_die("can't find the kernel version " 3848 bb_simple_error_msg_and_die("can't find the kernel version "
3849 "the module was compiled for"); 3849 "the module was compiled for");
3850 } 3850 }
3851 } 3851 }
@@ -3864,7 +3864,7 @@ int FAST_FUNC bb_init_module_24(const char *m_filename, const char *options)
3864#endif 3864#endif
3865 3865
3866 if (query_module(NULL, 0, NULL, 0, NULL)) 3866 if (query_module(NULL, 0, NULL, 0, NULL))
3867 bb_error_msg_and_die("old (unsupported) kernel"); 3867 bb_simple_error_msg_and_die("old (unsupported) kernel");
3868 new_get_kernel_symbols(); 3868 new_get_kernel_symbols();
3869 k_crcs = new_is_kernel_checksummed(); 3869 k_crcs = new_is_kernel_checksummed();
3870 3870
diff --git a/modutils/rmmod.c b/modutils/rmmod.c
index a3548879c..8d4639f50 100644
--- a/modutils/rmmod.c
+++ b/modutils/rmmod.c
@@ -52,7 +52,7 @@ int rmmod_main(int argc UNUSED_PARAM, char **argv)
52 /* Unload _all_ unused modules via NULL delete_module() call */ 52 /* Unload _all_ unused modules via NULL delete_module() call */
53 err = bb_delete_module(NULL, flags); 53 err = bb_delete_module(NULL, flags);
54 if (err && err != EFAULT) 54 if (err && err != EFAULT)
55 bb_perror_msg_and_die("rmmod"); 55 bb_simple_perror_msg_and_die("rmmod");
56 return EXIT_SUCCESS; 56 return EXIT_SUCCESS;
57 } 57 }
58 58
diff --git a/networking/arp.c b/networking/arp.c
index 71bfe3cbf..6519f8156 100644
--- a/networking/arp.c
+++ b/networking/arp.c
@@ -116,7 +116,7 @@ static int arp_del(char **args)
116 /* Resolve the host name. */ 116 /* Resolve the host name. */
117 host = *args; 117 host = *args;
118 if (ap->input(host, &sa) < 0) { 118 if (ap->input(host, &sa) < 0) {
119 bb_herror_msg_and_die("%s", host); 119 bb_simple_herror_msg_and_die(host);
120 } 120 }
121 121
122 /* If a host has more than one address, use the correct one! */ 122 /* If a host has more than one address, use the correct one! */
@@ -149,7 +149,7 @@ static int arp_del(char **args)
149#ifdef HAVE_ATF_DONTPUB 149#ifdef HAVE_ATF_DONTPUB
150 req.arp_flags |= ATF_DONTPUB; 150 req.arp_flags |= ATF_DONTPUB;
151#else 151#else
152 bb_error_msg("feature ATF_DONTPUB is not supported"); 152 bb_simple_error_msg("feature ATF_DONTPUB is not supported");
153#endif 153#endif
154 args++; 154 args++;
155 break; 155 break;
@@ -157,7 +157,7 @@ static int arp_del(char **args)
157#ifdef HAVE_ATF_MAGIC 157#ifdef HAVE_ATF_MAGIC
158 req.arp_flags |= ATF_MAGIC; 158 req.arp_flags |= ATF_MAGIC;
159#else 159#else
160 bb_error_msg("feature ATF_MAGIC is not supported"); 160 bb_simple_error_msg("feature ATF_MAGIC is not supported");
161#endif 161#endif
162 args++; 162 args++;
163 break; 163 break;
@@ -173,7 +173,7 @@ static int arp_del(char **args)
173 if (strcmp(*args, "255.255.255.255") != 0) { 173 if (strcmp(*args, "255.255.255.255") != 0) {
174 host = *args; 174 host = *args;
175 if (ap->input(host, &sa) < 0) { 175 if (ap->input(host, &sa) < 0) {
176 bb_herror_msg_and_die("%s", host); 176 bb_simple_herror_msg_and_die(host);
177 } 177 }
178 memcpy(&req.arp_netmask, &sa, sizeof(struct sockaddr)); 178 memcpy(&req.arp_netmask, &sa, sizeof(struct sockaddr));
179 req.arp_flags |= ATF_NETMASK; 179 req.arp_flags |= ATF_NETMASK;
@@ -195,7 +195,7 @@ static int arp_del(char **args)
195 /* Call the kernel. */ 195 /* Call the kernel. */
196 if (flags & 2) { 196 if (flags & 2) {
197 if (option_mask32 & ARP_OPT_v) 197 if (option_mask32 & ARP_OPT_v)
198 bb_error_msg("SIOCDARP(nopub)"); 198 bb_simple_error_msg("SIOCDARP(nopub)");
199 err = ioctl(sockfd, SIOCDARP, &req); 199 err = ioctl(sockfd, SIOCDARP, &req);
200 if (err < 0) { 200 if (err < 0) {
201 if (errno == ENXIO) { 201 if (errno == ENXIO) {
@@ -204,20 +204,20 @@ static int arp_del(char **args)
204 printf("No ARP entry for %s\n", host); 204 printf("No ARP entry for %s\n", host);
205 return -1; 205 return -1;
206 } 206 }
207 bb_perror_msg_and_die("SIOCDARP(priv)"); 207 bb_simple_perror_msg_and_die("SIOCDARP(priv)");
208 } 208 }
209 } 209 }
210 if ((flags & 1) && err) { 210 if ((flags & 1) && err) {
211 nopub: 211 nopub:
212 req.arp_flags |= ATF_PUBL; 212 req.arp_flags |= ATF_PUBL;
213 if (option_mask32 & ARP_OPT_v) 213 if (option_mask32 & ARP_OPT_v)
214 bb_error_msg("SIOCDARP(pub)"); 214 bb_simple_error_msg("SIOCDARP(pub)");
215 if (ioctl(sockfd, SIOCDARP, &req) < 0) { 215 if (ioctl(sockfd, SIOCDARP, &req) < 0) {
216 if (errno == ENXIO) { 216 if (errno == ENXIO) {
217 printf("No ARP entry for %s\n", host); 217 printf("No ARP entry for %s\n", host);
218 return -1; 218 return -1;
219 } 219 }
220 bb_perror_msg_and_die("SIOCDARP(pub)"); 220 bb_simple_perror_msg_and_die("SIOCDARP(pub)");
221 } 221 }
222 } 222 }
223 return 0; 223 return 0;
@@ -233,7 +233,7 @@ static void arp_getdevhw(char *ifname, struct sockaddr *sa)
233 ioctl_or_perror_and_die(sockfd, SIOCGIFHWADDR, &ifr, 233 ioctl_or_perror_and_die(sockfd, SIOCGIFHWADDR, &ifr,
234 "can't get HW-Address for '%s'", ifname); 234 "can't get HW-Address for '%s'", ifname);
235 if (hw_set && (ifr.ifr_hwaddr.sa_family != hw->type)) { 235 if (hw_set && (ifr.ifr_hwaddr.sa_family != hw->type)) {
236 bb_error_msg_and_die("protocol type mismatch"); 236 bb_simple_error_msg_and_die("protocol type mismatch");
237 } 237 }
238 memcpy(sa, &(ifr.ifr_hwaddr), sizeof(struct sockaddr)); 238 memcpy(sa, &(ifr.ifr_hwaddr), sizeof(struct sockaddr));
239 239
@@ -261,20 +261,20 @@ static int arp_set(char **args)
261 261
262 host = *args++; 262 host = *args++;
263 if (ap->input(host, &sa) < 0) { 263 if (ap->input(host, &sa) < 0) {
264 bb_herror_msg_and_die("%s", host); 264 bb_simple_herror_msg_and_die(host);
265 } 265 }
266 /* If a host has more than one address, use the correct one! */ 266 /* If a host has more than one address, use the correct one! */
267 memcpy(&req.arp_pa, &sa, sizeof(struct sockaddr)); 267 memcpy(&req.arp_pa, &sa, sizeof(struct sockaddr));
268 268
269 /* Fetch the hardware address. */ 269 /* Fetch the hardware address. */
270 if (*args == NULL) { 270 if (*args == NULL) {
271 bb_error_msg_and_die("need hardware address"); 271 bb_simple_error_msg_and_die("need hardware address");
272 } 272 }
273 if (option_mask32 & ARP_OPT_D) { 273 if (option_mask32 & ARP_OPT_D) {
274 arp_getdevhw(*args++, &req.arp_ha); 274 arp_getdevhw(*args++, &req.arp_ha);
275 } else { 275 } else {
276 if (hw->input(*args++, &req.arp_ha) < 0) { 276 if (hw->input(*args++, &req.arp_ha) < 0) {
277 bb_error_msg_and_die("invalid hardware address"); 277 bb_simple_error_msg_and_die("invalid hardware address");
278 } 278 }
279 } 279 }
280 280
@@ -302,7 +302,7 @@ static int arp_set(char **args)
302#ifdef HAVE_ATF_DONTPUB 302#ifdef HAVE_ATF_DONTPUB
303 flags |= ATF_DONTPUB; 303 flags |= ATF_DONTPUB;
304#else 304#else
305 bb_error_msg("feature ATF_DONTPUB is not supported"); 305 bb_simple_error_msg("feature ATF_DONTPUB is not supported");
306#endif 306#endif
307 args++; 307 args++;
308 break; 308 break;
@@ -310,7 +310,7 @@ static int arp_set(char **args)
310#ifdef HAVE_ATF_MAGIC 310#ifdef HAVE_ATF_MAGIC
311 flags |= ATF_MAGIC; 311 flags |= ATF_MAGIC;
312#else 312#else
313 bb_error_msg("feature ATF_MAGIC is not supported"); 313 bb_simple_error_msg("feature ATF_MAGIC is not supported");
314#endif 314#endif
315 args++; 315 args++;
316 break; 316 break;
@@ -326,7 +326,7 @@ static int arp_set(char **args)
326 if (strcmp(*args, "255.255.255.255") != 0) { 326 if (strcmp(*args, "255.255.255.255") != 0) {
327 host = *args; 327 host = *args;
328 if (ap->input(host, &sa) < 0) { 328 if (ap->input(host, &sa) < 0) {
329 bb_herror_msg_and_die("%s", host); 329 bb_simple_herror_msg_and_die(host);
330 } 330 }
331 memcpy(&req.arp_netmask, &sa, sizeof(struct sockaddr)); 331 memcpy(&req.arp_netmask, &sa, sizeof(struct sockaddr));
332 flags |= ATF_NETMASK; 332 flags |= ATF_NETMASK;
@@ -346,7 +346,7 @@ static int arp_set(char **args)
346 346
347 /* Call the kernel. */ 347 /* Call the kernel. */
348 if (option_mask32 & ARP_OPT_v) 348 if (option_mask32 & ARP_OPT_v)
349 bb_error_msg("SIOCSARP()"); 349 bb_simple_error_msg("SIOCSARP()");
350 xioctl(sockfd, SIOCSARP, &req); 350 xioctl(sockfd, SIOCSARP, &req);
351 return 0; 351 return 0;
352} 352}
@@ -422,7 +422,7 @@ static int arp_show(char *name)
422 if (name != NULL) { 422 if (name != NULL) {
423 /* Resolve the host name. */ 423 /* Resolve the host name. */
424 if (ap->input(name, &sa) < 0) { 424 if (ap->input(name, &sa) < 0) {
425 bb_herror_msg_and_die("%s", name); 425 bb_simple_herror_msg_and_die(name);
426 } 426 }
427 host = xstrdup(ap->sprint(&sa, 1)); 427 host = xstrdup(ap->sprint(&sa, 1));
428 } 428 }
@@ -530,7 +530,7 @@ int arp_main(int argc UNUSED_PARAM, char **argv)
530 /* Now see what we have to do here... */ 530 /* Now see what we have to do here... */
531 if (opts & (ARP_OPT_d | ARP_OPT_s)) { 531 if (opts & (ARP_OPT_d | ARP_OPT_s)) {
532 if (argv[0] == NULL) 532 if (argv[0] == NULL)
533 bb_error_msg_and_die("need host name"); 533 bb_simple_error_msg_and_die("need host name");
534 if (opts & ARP_OPT_s) 534 if (opts & ARP_OPT_s)
535 return arp_set(argv); 535 return arp_set(argv);
536 return arp_del(argv); 536 return arp_del(argv);
diff --git a/networking/arping.c b/networking/arping.c
index 901578b68..2a256aaa0 100644
--- a/networking/arping.c
+++ b/networking/arping.c
@@ -375,7 +375,7 @@ int arping_main(int argc UNUSED_PARAM, char **argv)
375 xconnect(probe_fd, (struct sockaddr *) &G.probe_saddr, sizeof(G.probe_saddr)); 375 xconnect(probe_fd, (struct sockaddr *) &G.probe_saddr, sizeof(G.probe_saddr));
376 bb_getsockname(probe_fd, (struct sockaddr *) &G.probe_saddr, sizeof(G.probe_saddr)); 376 bb_getsockname(probe_fd, (struct sockaddr *) &G.probe_saddr, sizeof(G.probe_saddr));
377 if (G.probe_saddr.sin_family != AF_INET) 377 if (G.probe_saddr.sin_family != AF_INET)
378 bb_error_msg_and_die("no IP address configured"); 378 bb_simple_error_msg_and_die("no IP address configured");
379 src = G.probe_saddr.sin_addr; 379 src = G.probe_saddr.sin_addr;
380 } 380 }
381 close(probe_fd); 381 close(probe_fd);
@@ -430,7 +430,7 @@ int arping_main(int argc UNUSED_PARAM, char **argv)
430 /* Don't allow SIGALRMs while we process the reply */ 430 /* Don't allow SIGALRMs while we process the reply */
431 sigprocmask(SIG_BLOCK, &G.sset, NULL); 431 sigprocmask(SIG_BLOCK, &G.sset, NULL);
432 if (cc < 0) { 432 if (cc < 0) {
433 bb_perror_msg("recvfrom"); 433 bb_simple_perror_msg("recvfrom");
434 continue; 434 continue;
435 } 435 }
436 recv_pack(G.packet, cc, &from); 436 recv_pack(G.packet, cc, &from);
diff --git a/networking/brctl.c b/networking/brctl.c
index f44ad9c8d..586ca9b0c 100644
--- a/networking/brctl.c
+++ b/networking/brctl.c
@@ -107,6 +107,7 @@ static unsigned str_to_jiffies(const char *time_str)
107 107
108#define filedata bb_common_bufsiz1 108#define filedata bb_common_bufsiz1
109 109
110#if ENABLE_FEATURE_BRCTL_SHOW
110static int read_file(const char *name) 111static int read_file(const char *name)
111{ 112{
112 int n = open_read_close(name, filedata, COMMON_BUFSIZE - 1); 113 int n = open_read_close(name, filedata, COMMON_BUFSIZE - 1);
@@ -176,7 +177,9 @@ static int show_bridge(const char *name, int need_hdr)
176 bb_putchar('\n'); 177 bb_putchar('\n');
177 return 0; 178 return 0;
178} 179}
180#endif
179 181
182#if ENABLE_FEATURE_BRCTL_FANCY
180static void write_uint(const char *name, const char *leaf, unsigned val) 183static void write_uint(const char *name, const char *leaf, unsigned val)
181{ 184{
182 char pathbuf[IFNAMSIZ + sizeof("/bridge/bridge_id") + 32]; 185 char pathbuf[IFNAMSIZ + sizeof("/bridge/bridge_id") + 32];
@@ -193,6 +196,7 @@ static void write_uint(const char *name, const char *leaf, unsigned val)
193 bb_simple_perror_msg_and_die(name); 196 bb_simple_perror_msg_and_die(name);
194 close(fd); 197 close(fd);
195} 198}
199#endif
196 200
197int brctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 201int brctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
198int brctl_main(int argc UNUSED_PARAM, char **argv) 202int brctl_main(int argc UNUSED_PARAM, char **argv)
diff --git a/networking/dnsd.c b/networking/dnsd.c
index f2c6bddc6..0ff0290fb 100644
--- a/networking/dnsd.c
+++ b/networking/dnsd.c
@@ -395,11 +395,11 @@ static int process_packet(struct dns_entry *conf_data,
395 395
396 head = (struct dns_head *)buf; 396 head = (struct dns_head *)buf;
397 if (head->nquer == 0) { 397 if (head->nquer == 0) {
398 bb_error_msg("packet has 0 queries, ignored"); 398 bb_simple_error_msg("packet has 0 queries, ignored");
399 return 0; /* don't reply */ 399 return 0; /* don't reply */
400 } 400 }
401 if (head->flags & htons(0x8000)) { /* QR bit */ 401 if (head->flags & htons(0x8000)) { /* QR bit */
402 bb_error_msg("response packet, ignored"); 402 bb_simple_error_msg("response packet, ignored");
403 return 0; /* don't reply */ 403 return 0; /* don't reply */
404 } 404 }
405 /* QR = 1 "response", RCODE = 4 "Not Implemented" */ 405 /* QR = 1 "response", RCODE = 4 "Not Implemented" */
@@ -474,7 +474,7 @@ static int process_packet(struct dns_entry *conf_data,
474 * RCODE = 0 "success" 474 * RCODE = 0 "success"
475 */ 475 */
476 if (OPT_verbose) 476 if (OPT_verbose)
477 bb_info_msg("returning positive reply"); 477 bb_simple_info_msg("returning positive reply");
478 outr_flags = htons(0x8000 | 0x0400 | 0); 478 outr_flags = htons(0x8000 | 0x0400 | 0);
479 /* we have one answer */ 479 /* we have one answer */
480 head->nansw = htons(1); 480 head->nansw = htons(1);
@@ -557,7 +557,7 @@ int dnsd_main(int argc UNUSED_PARAM, char **argv)
557 continue; 557 continue;
558 } 558 }
559 if (OPT_verbose) 559 if (OPT_verbose)
560 bb_info_msg("got UDP packet"); 560 bb_simple_info_msg("got UDP packet");
561 buf[r] = '\0'; /* paranoia */ 561 buf[r] = '\0'; /* paranoia */
562 r = process_packet(conf_data, conf_ttl, buf); 562 r = process_packet(conf_data, conf_ttl, buf);
563 if (r <= 0) 563 if (r <= 0)
diff --git a/networking/ether-wake.c b/networking/ether-wake.c
index acaac16f8..f45d43609 100644
--- a/networking/ether-wake.c
+++ b/networking/ether-wake.c
@@ -182,7 +182,7 @@ static int get_wol_pw(const char *ethoptarg, unsigned char *wol_passwd)
182 byte_cnt = sscanf(ethoptarg, "%u.%u.%u.%u", 182 byte_cnt = sscanf(ethoptarg, "%u.%u.%u.%u",
183 &passwd[0], &passwd[1], &passwd[2], &passwd[3]); 183 &passwd[0], &passwd[1], &passwd[2], &passwd[3]);
184 if (byte_cnt < 4) { 184 if (byte_cnt < 4) {
185 bb_error_msg("can't read Wake-On-LAN pass"); 185 bb_simple_error_msg("can't read Wake-On-LAN pass");
186 return 0; 186 return 0;
187 } 187 }
188// TODO: check invalid numbers >255?? 188// TODO: check invalid numbers >255??
@@ -266,7 +266,7 @@ int ether_wake_main(int argc UNUSED_PARAM, char **argv)
266 /* This is necessary for broadcasts to work */ 266 /* This is necessary for broadcasts to work */
267 if (flags /* & 1 OPT_BROADCAST */) { 267 if (flags /* & 1 OPT_BROADCAST */) {
268 if (setsockopt_broadcast(s) != 0) 268 if (setsockopt_broadcast(s) != 0)
269 bb_perror_msg("SO_BROADCAST"); 269 bb_simple_perror_msg("SO_BROADCAST");
270 } 270 }
271 271
272#if defined(PF_PACKET) 272#if defined(PF_PACKET)
diff --git a/networking/ftpgetput.c b/networking/ftpgetput.c
index bff90538f..7b6b89057 100644
--- a/networking/ftpgetput.c
+++ b/networking/ftpgetput.c
@@ -220,7 +220,7 @@ int ftp_receive(const char *local_path, char *server_path)
220 struct stat sbuf; 220 struct stat sbuf;
221 /* lstat would be wrong here! */ 221 /* lstat would be wrong here! */
222 if (stat(local_path, &sbuf) < 0) { 222 if (stat(local_path, &sbuf) < 0) {
223 bb_perror_msg_and_die("stat"); 223 bb_simple_perror_msg_and_die("stat");
224 } 224 }
225 if (sbuf.st_size > 0) { 225 if (sbuf.st_size > 0) {
226 beg_range = sbuf.st_size; 226 beg_range = sbuf.st_size;
diff --git a/networking/hostname.c b/networking/hostname.c
index 248d8b65a..f96daed95 100644
--- a/networking/hostname.c
+++ b/networking/hostname.c
@@ -61,7 +61,7 @@ static void do_sethostname(char *s, int isfile)
61 } else if (sethostname(s, strlen(s))) { 61 } else if (sethostname(s, strlen(s))) {
62// if (errno == EPERM) 62// if (errno == EPERM)
63// bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 63// bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
64 bb_perror_msg_and_die("sethostname"); 64 bb_simple_perror_msg_and_die("sethostname");
65 } 65 }
66} 66}
67 67
diff --git a/networking/httpd.c b/networking/httpd.c
index 3f1e02ec8..1757e09c9 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -1025,7 +1025,7 @@ static void log_and_exit(void)
1025 */ 1025 */
1026 1026
1027 if (verbose > 2) 1027 if (verbose > 2)
1028 bb_error_msg("closed"); 1028 bb_simple_error_msg("closed");
1029 _exit(xfunc_error_retval); 1029 _exit(xfunc_error_retval);
1030} 1030}
1031 1031
@@ -1220,7 +1220,7 @@ static void send_headers(unsigned responseNum)
1220 } 1220 }
1221 if (full_write(STDOUT_FILENO, iobuf, len) != len) { 1221 if (full_write(STDOUT_FILENO, iobuf, len) != len) {
1222 if (verbose > 1) 1222 if (verbose > 1)
1223 bb_perror_msg("error"); 1223 bb_simple_perror_msg("error");
1224 log_and_exit(); 1224 log_and_exit();
1225 } 1225 }
1226} 1226}
@@ -1726,8 +1726,10 @@ static NOINLINE void send_file_and_exit(const char *url, int what)
1726 ".jpg.jpeg\0" "image/jpeg\0" 1726 ".jpg.jpeg\0" "image/jpeg\0"
1727 ".gif\0" "image/gif\0" 1727 ".gif\0" "image/gif\0"
1728 ".png\0" "image/png\0" 1728 ".png\0" "image/png\0"
1729 ".svg\0" "image/svg+xml\0"
1729 /* .css line must be after .c line */ 1730 /* .css line must be after .c line */
1730 ".css\0" "text/css\0" 1731 ".css\0" "text/css\0"
1732 ".js\0" "application/javascript\0"
1731 ".wav\0" "audio/wav\0" 1733 ".wav\0" "audio/wav\0"
1732 ".avi\0" "video/x-msvideo\0" 1734 ".avi\0" "video/x-msvideo\0"
1733 ".qt.mov\0" "video/quicktime\0" 1735 ".qt.mov\0" "video/quicktime\0"
@@ -1836,7 +1838,7 @@ static NOINLINE void send_file_and_exit(const char *url, int what)
1836 if (count < 0) { 1838 if (count < 0) {
1837 IF_FEATURE_USE_SENDFILE(fin:) 1839 IF_FEATURE_USE_SENDFILE(fin:)
1838 if (verbose > 1) 1840 if (verbose > 1)
1839 bb_perror_msg("error"); 1841 bb_simple_perror_msg("error");
1840 } 1842 }
1841 log_and_exit(); 1843 log_and_exit();
1842} 1844}
@@ -2147,7 +2149,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2147 if (rmt_ip_str) 2149 if (rmt_ip_str)
2148 applet_name = rmt_ip_str; 2150 applet_name = rmt_ip_str;
2149 if (verbose > 2) 2151 if (verbose > 2)
2150 bb_error_msg("connected"); 2152 bb_simple_error_msg("connected");
2151 } 2153 }
2152 if_ip_denied_send_HTTP_FORBIDDEN_and_exit(remote_ip); 2154 if_ip_denied_send_HTTP_FORBIDDEN_and_exit(remote_ip);
2153 2155
@@ -2744,7 +2746,7 @@ int httpd_main(int argc UNUSED_PARAM, char **argv)
2744 if (opt & OPT_SETUID) { 2746 if (opt & OPT_SETUID) {
2745 if (ugid.gid != (gid_t)-1) { 2747 if (ugid.gid != (gid_t)-1) {
2746 if (setgroups(1, &ugid.gid) == -1) 2748 if (setgroups(1, &ugid.gid) == -1)
2747 bb_perror_msg_and_die("setgroups"); 2749 bb_simple_perror_msg_and_die("setgroups");
2748 xsetgid(ugid.gid); 2750 xsetgid(ugid.gid);
2749 } 2751 }
2750 xsetuid(ugid.uid); 2752 xsetuid(ugid.uid);
diff --git a/networking/ifconfig.c b/networking/ifconfig.c
index 5c47abc16..b566d91a9 100644
--- a/networking/ifconfig.c
+++ b/networking/ifconfig.c
@@ -361,7 +361,7 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv)
361#if ENABLE_FEATURE_IFCONFIG_STATUS 361#if ENABLE_FEATURE_IFCONFIG_STATUS
362 return display_interfaces(argv[0] ? argv[0] : show_all_param); 362 return display_interfaces(argv[0] ? argv[0] : show_all_param);
363#else 363#else
364 bb_error_msg_and_die("no support for status display"); 364 bb_simple_error_msg_and_die("no support for status display");
365#endif 365#endif
366 } 366 }
367 367
diff --git a/networking/ifplugd.c b/networking/ifplugd.c
index 1426709cb..fa18edd57 100644
--- a/networking/ifplugd.c
+++ b/networking/ifplugd.c
@@ -365,7 +365,7 @@ static void up_iface(void)
365 if (!(ifrequest.ifr_flags & IFF_UP)) { 365 if (!(ifrequest.ifr_flags & IFF_UP)) {
366 ifrequest.ifr_flags |= IFF_UP; 366 ifrequest.ifr_flags |= IFF_UP;
367 /* Let user know we mess up with interface */ 367 /* Let user know we mess up with interface */
368 bb_info_msg("upping interface"); 368 bb_simple_info_msg("upping interface");
369 if (network_ioctl(SIOCSIFFLAGS, &ifrequest, "setting interface flags") < 0) { 369 if (network_ioctl(SIOCSIFFLAGS, &ifrequest, "setting interface flags") < 0) {
370 if (errno != ENODEV && errno != EADDRNOTAVAIL) 370 if (errno != ENODEV && errno != EADDRNOTAVAIL)
371 xfunc_die(); 371 xfunc_die();
@@ -461,7 +461,7 @@ static smallint detect_link(void)
461 else if (option_mask32 & FLAG_IGNORE_FAIL_POSITIVE) 461 else if (option_mask32 & FLAG_IGNORE_FAIL_POSITIVE)
462 status = IFSTATUS_UP; 462 status = IFSTATUS_UP;
463 else if (G.api_mode[0] == 'a') 463 else if (G.api_mode[0] == 'a')
464 bb_error_msg("can't detect link status"); 464 bb_simple_error_msg("can't detect link status");
465 } 465 }
466 466
467 if (status != G.iface_last_status) { 467 if (status != G.iface_last_status) {
@@ -493,14 +493,14 @@ static NOINLINE int check_existence_through_netlink(void)
493 goto ret; 493 goto ret;
494 if (errno == EINTR) 494 if (errno == EINTR)
495 continue; 495 continue;
496 bb_perror_msg("netlink: recv"); 496 bb_simple_perror_msg("netlink: recv");
497 return -1; 497 return -1;
498 } 498 }
499 499
500 mhdr = (struct nlmsghdr*)replybuf; 500 mhdr = (struct nlmsghdr*)replybuf;
501 while (bytes > 0) { 501 while (bytes > 0) {
502 if (!NLMSG_OK(mhdr, bytes)) { 502 if (!NLMSG_OK(mhdr, bytes)) {
503 bb_error_msg("netlink packet too small or truncated"); 503 bb_simple_error_msg("netlink packet too small or truncated");
504 return -1; 504 return -1;
505 } 505 }
506 506
@@ -509,7 +509,7 @@ static NOINLINE int check_existence_through_netlink(void)
509 int attr_len; 509 int attr_len;
510 510
511 if (mhdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg))) { 511 if (mhdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct ifinfomsg))) {
512 bb_error_msg("netlink packet too small or truncated"); 512 bb_simple_error_msg("netlink packet too small or truncated");
513 return -1; 513 return -1;
514 } 514 }
515 515
@@ -591,7 +591,7 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv)
591 } 591 }
592 592
593 if (pid_from_pidfile > 0 && kill(pid_from_pidfile, 0) == 0) 593 if (pid_from_pidfile > 0 && kill(pid_from_pidfile, 0) == 0)
594 bb_error_msg_and_die("daemon already running"); 594 bb_simple_error_msg_and_die("daemon already running");
595#endif 595#endif
596 596
597 api_mode_found = strchr(api_modes, G.api_mode[0]); 597 api_mode_found = strchr(api_modes, G.api_mode[0]);
@@ -604,15 +604,7 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv)
604 604
605 xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), ioctl_fd); 605 xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), ioctl_fd);
606 if (opts & FLAG_MONITOR) { 606 if (opts & FLAG_MONITOR) {
607 struct sockaddr_nl addr; 607 int fd = create_and_bind_to_netlink(NETLINK_ROUTE, RTMGRP_LINK, 0);
608 int fd = xsocket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
609
610 memset(&addr, 0, sizeof(addr));
611 addr.nl_family = AF_NETLINK;
612 addr.nl_groups = RTMGRP_LINK;
613 addr.nl_pid = getpid();
614
615 xbind(fd, (struct sockaddr*)&addr, sizeof(addr));
616 xmove_fd(fd, netlink_fd); 608 xmove_fd(fd, netlink_fd);
617 } 609 }
618 610
@@ -698,7 +690,7 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv)
698 ) { 690 ) {
699 if (errno == EINTR) 691 if (errno == EINTR)
700 continue; 692 continue;
701 bb_perror_msg("poll"); 693 bb_simple_perror_msg("poll");
702 goto exiting; 694 goto exiting;
703 } 695 }
704 696
@@ -771,5 +763,5 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv)
771 763
772 exiting: 764 exiting:
773 remove_pidfile(pidfile_name); 765 remove_pidfile(pidfile_name);
774 bb_error_msg_and_die("exiting"); 766 bb_simple_error_msg_and_die("exiting");
775} 767}
diff --git a/networking/ifupdown.c b/networking/ifupdown.c
index 5327b0979..60ceb5a1f 100644
--- a/networking/ifupdown.c
+++ b/networking/ifupdown.c
@@ -665,7 +665,7 @@ static int FAST_FUNC dhcp_up(struct interface_defn_t *ifd, execfn *exec)
665 if (executable_exists(ext_dhcp_clients[i].name)) 665 if (executable_exists(ext_dhcp_clients[i].name))
666 return execute(ext_dhcp_clients[i].startcmd, ifd, exec); 666 return execute(ext_dhcp_clients[i].startcmd, ifd, exec);
667 } 667 }
668 bb_error_msg("no dhcp clients found"); 668 bb_simple_error_msg("no dhcp clients found");
669 return 0; 669 return 0;
670} 670}
671# elif ENABLE_UDHCPC 671# elif ENABLE_UDHCPC
@@ -707,7 +707,7 @@ static int FAST_FUNC dhcp_down(struct interface_defn_t *ifd, execfn *exec)
707 } 707 }
708 708
709 if (!result) 709 if (!result)
710 bb_error_msg("warning: no dhcp clients found and stopped"); 710 bb_simple_error_msg("warning: no dhcp clients found and stopped");
711 711
712 /* Sleep a bit, otherwise static_down tries to bring down interface too soon, 712 /* Sleep a bit, otherwise static_down tries to bring down interface too soon,
713 and it may come back up because udhcpc is still shutting down */ 713 and it may come back up because udhcpc is still shutting down */
diff --git a/networking/inetd.c b/networking/inetd.c
index da6551174..3cd2b11f0 100644
--- a/networking/inetd.c
+++ b/networking/inetd.c
@@ -504,7 +504,7 @@ static void register_rpc(servtab_t *sep)
504 504
505 if (bb_getsockname(sep->se_fd, (struct sockaddr *) &ir_sin, sizeof(ir_sin)) < 0) { 505 if (bb_getsockname(sep->se_fd, (struct sockaddr *) &ir_sin, sizeof(ir_sin)) < 0) {
506//TODO: verify that such failure is even possible in Linux kernel 506//TODO: verify that such failure is even possible in Linux kernel
507 bb_perror_msg("getsockname"); 507 bb_simple_perror_msg("getsockname");
508 return; 508 return;
509 } 509 }
510 510
@@ -544,7 +544,7 @@ static void bump_nofile(void)
544 } 544 }
545 545
546 if (setrlimit(RLIMIT_NOFILE, &rl) < 0) { 546 if (setrlimit(RLIMIT_NOFILE, &rl) < 0) {
547 bb_perror_msg("setrlimit"); 547 bb_simple_perror_msg("setrlimit");
548 return; 548 return;
549 } 549 }
550 550
@@ -599,7 +599,7 @@ static void prepare_socket_fd(servtab_t *sep)
599 599
600 fd = socket(sep->se_family, sep->se_socktype, 0); 600 fd = socket(sep->se_family, sep->se_socktype, 0);
601 if (fd < 0) { 601 if (fd < 0) {
602 bb_perror_msg("socket"); 602 bb_simple_perror_msg("socket");
603 return; 603 return;
604 } 604 }
605 setsockopt_reuseaddr(fd); 605 setsockopt_reuseaddr(fd);
@@ -815,7 +815,7 @@ static NOINLINE servtab_t *parse_one_line(void)
815 n = bb_strtou(p, &p, 10); 815 n = bb_strtou(p, &p, 10);
816 if (n > INT_MAX) { 816 if (n > INT_MAX) {
817 bad_ver_spec: 817 bad_ver_spec:
818 bb_error_msg("bad rpc version"); 818 bb_simple_error_msg("bad rpc version");
819 goto parse_err; 819 goto parse_err;
820 } 820 }
821 sep->se_rpcver_lo = sep->se_rpcver_hi = n; 821 sep->se_rpcver_lo = sep->se_rpcver_hi = n;
@@ -829,7 +829,7 @@ static NOINLINE servtab_t *parse_one_line(void)
829 if (*p != '\0') 829 if (*p != '\0')
830 goto bad_ver_spec; 830 goto bad_ver_spec;
831#else 831#else
832 bb_error_msg("no support for rpc services"); 832 bb_simple_error_msg("no support for rpc services");
833 goto parse_err; 833 goto parse_err;
834#endif 834#endif
835 } 835 }
@@ -1235,7 +1235,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv)
1235 if (argv[0]) 1235 if (argv[0])
1236 config_filename = argv[0]; 1236 config_filename = argv[0];
1237 if (config_filename == NULL) 1237 if (config_filename == NULL)
1238 bb_error_msg_and_die("non-root must specify config file"); 1238 bb_simple_error_msg_and_die("non-root must specify config file");
1239 if (!(opt & 2)) 1239 if (!(opt & 2))
1240 bb_daemonize_or_rexec(0, argv - optind); 1240 bb_daemonize_or_rexec(0, argv - optind);
1241 else 1241 else
@@ -1304,7 +1304,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv)
1304 ready_fd_cnt = select(maxsock + 1, &readable, NULL, NULL, NULL); 1304 ready_fd_cnt = select(maxsock + 1, &readable, NULL, NULL, NULL);
1305 if (ready_fd_cnt < 0) { 1305 if (ready_fd_cnt < 0) {
1306 if (errno != EINTR) { 1306 if (errno != EINTR) {
1307 bb_perror_msg("select"); 1307 bb_simple_perror_msg("select");
1308 sleep(1); 1308 sleep(1);
1309 } 1309 }
1310 continue; 1310 continue;
@@ -1405,7 +1405,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv)
1405 pid = vfork(); 1405 pid = vfork();
1406 1406
1407 if (pid < 0) { /* fork error */ 1407 if (pid < 0) { /* fork error */
1408 bb_perror_msg("vfork"+1); 1408 bb_simple_perror_msg("vfork"+1);
1409 sleep(1); 1409 sleep(1);
1410 restore_sigmask(&omask); 1410 restore_sigmask(&omask);
1411 maybe_close(new_udp_fd); 1411 maybe_close(new_udp_fd);
@@ -1488,7 +1488,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv)
1488 } 1488 }
1489 if (real_uid != 0 && real_uid != pwd->pw_uid) { 1489 if (real_uid != 0 && real_uid != pwd->pw_uid) {
1490 /* a user running private inetd */ 1490 /* a user running private inetd */
1491 bb_error_msg("non-root must run services as himself"); 1491 bb_simple_error_msg("non-root must run services as himself");
1492 goto do_exit1; 1492 goto do_exit1;
1493 } 1493 }
1494 if (pwd->pw_uid != real_uid) { 1494 if (pwd->pw_uid != real_uid) {
@@ -1502,7 +1502,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv)
1502 } 1502 }
1503 if (rlim_ofile.rlim_cur != rlim_ofile_cur) 1503 if (rlim_ofile.rlim_cur != rlim_ofile_cur)
1504 if (setrlimit(RLIMIT_NOFILE, &rlim_ofile) < 0) 1504 if (setrlimit(RLIMIT_NOFILE, &rlim_ofile) < 0)
1505 bb_perror_msg("setrlimit"); 1505 bb_simple_perror_msg("setrlimit");
1506 1506
1507 /* closelog(); - WRONG. we are after vfork, 1507 /* closelog(); - WRONG. we are after vfork,
1508 * this may confuse syslog() internal state. 1508 * this may confuse syslog() internal state.
diff --git a/networking/ipcalc.c b/networking/ipcalc.c
index 67f768836..09b146872 100644
--- a/networking/ipcalc.c
+++ b/networking/ipcalc.c
@@ -183,7 +183,7 @@ int ipcalc_main(int argc UNUSED_PARAM, char **argv)
183 183
184 if (argv[1]) { 184 if (argv[1]) {
185 if (ENABLE_FEATURE_IPCALC_FANCY && have_netmask) { 185 if (ENABLE_FEATURE_IPCALC_FANCY && have_netmask) {
186 bb_error_msg_and_die("use prefix or netmask, not both"); 186 bb_simple_error_msg_and_die("use prefix or netmask, not both");
187 } 187 }
188 if (inet_aton(argv[1], &s_netmask) == 0) { 188 if (inet_aton(argv[1], &s_netmask) == 0) {
189 bb_error_msg_and_die("bad netmask: %s", argv[1]); 189 bb_error_msg_and_die("bad netmask: %s", argv[1]);
diff --git a/networking/isrv.c b/networking/isrv.c
index 97f5c6d4e..0e3f10f9a 100644
--- a/networking/isrv.c
+++ b/networking/isrv.c
@@ -185,7 +185,7 @@ static void handle_accept(isrv_state_t *state, int fd)
185 /* Most probably someone gave us wrong fd type 185 /* Most probably someone gave us wrong fd type
186 * (for example, non-socket). Don't want 186 * (for example, non-socket). Don't want
187 * to loop forever. */ 187 * to loop forever. */
188 bb_perror_msg_and_die("accept"); 188 bb_simple_perror_msg_and_die("accept");
189 } 189 }
190 190
191 DPRINTF("new_peer(%d)", newfd); 191 DPRINTF("new_peer(%d)", newfd);
@@ -311,7 +311,7 @@ void isrv_run(
311 311
312 if (n < 0) { 312 if (n < 0) {
313 if (errno != EINTR) 313 if (errno != EINTR)
314 bb_perror_msg("select"); 314 bb_simple_perror_msg("select");
315 continue; 315 continue;
316 } 316 }
317 317
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
index 7b7e0154b..86cf3beea 100644
--- a/networking/libiproute/ipaddress.c
+++ b/networking/libiproute/ipaddress.c
@@ -119,7 +119,7 @@ static NOINLINE int print_linkinfo(const struct nlmsghdr *n)
119 //memset(tb, 0, sizeof(tb)); - parse_rtattr does this 119 //memset(tb, 0, sizeof(tb)); - parse_rtattr does this
120 parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); 120 parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
121 if (tb[IFLA_IFNAME] == NULL) { 121 if (tb[IFLA_IFNAME] == NULL) {
122 bb_error_msg("nil ifname"); 122 bb_simple_error_msg("nil ifname");
123 return -1; 123 return -1;
124 } 124 }
125 if (G_filter.label 125 if (G_filter.label
@@ -205,7 +205,7 @@ static NOINLINE int print_linkinfo(const struct nlmsghdr *n)
205static int flush_update(void) 205static int flush_update(void)
206{ 206{
207 if (rtnl_send_check(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) { 207 if (rtnl_send_check(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) {
208 bb_perror_msg("can't send flush request"); 208 bb_simple_perror_msg("can't send flush request");
209 return -1; 209 return -1;
210 } 210 }
211 G_filter.flushp = 0; 211 G_filter.flushp = 0;
@@ -439,7 +439,7 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush)
439 bb_error_msg_and_die(bb_msg_requires_arg, "flush"); 439 bb_error_msg_and_die(bb_msg_requires_arg, "flush");
440 } 440 }
441 if (G_filter.family == AF_PACKET) { 441 if (G_filter.family == AF_PACKET) {
442 bb_error_msg_and_die("can't flush link addresses"); 442 bb_simple_error_msg_and_die("can't flush link addresses");
443 } 443 }
444 } 444 }
445 445
@@ -700,7 +700,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
700 700
701 if (!d) { 701 if (!d) {
702 /* There was no "dev IFACE", but we need that */ 702 /* There was no "dev IFACE", but we need that */
703 bb_error_msg_and_die("need \"dev IFACE\""); 703 bb_simple_error_msg_and_die("need \"dev IFACE\"");
704 } 704 }
705 if (l && !is_prefixed_with(l, d)) { 705 if (l && !is_prefixed_with(l, d)) {
706 bb_error_msg_and_die("\"dev\" (%s) must match \"label\" (%s)", d, l); 706 bb_error_msg_and_die("\"dev\" (%s) must match \"label\" (%s)", d, l);
@@ -717,7 +717,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
717 inet_prefix brd; 717 inet_prefix brd;
718 int i; 718 int i;
719 if (req.ifa.ifa_family != AF_INET) { 719 if (req.ifa.ifa_family != AF_INET) {
720 bb_error_msg_and_die("broadcast can be set only for IPv4 addresses"); 720 bb_simple_error_msg_and_die("broadcast can be set only for IPv4 addresses");
721 } 721 }
722 brd = peer; 722 brd = peer;
723 if (brd.bitlen <= 30) { 723 if (brd.bitlen <= 30) {
diff --git a/networking/libiproute/ipneigh.c b/networking/libiproute/ipneigh.c
index 984dd4bdd..b9b4f4b31 100644
--- a/networking/libiproute/ipneigh.c
+++ b/networking/libiproute/ipneigh.c
@@ -49,7 +49,7 @@ typedef struct filter_t filter_t;
49static int flush_update(void) 49static int flush_update(void)
50{ 50{
51 if (rtnl_send_check(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) { 51 if (rtnl_send_check(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) {
52 bb_perror_msg("can't send flush request"); 52 bb_simple_perror_msg("can't send flush request");
53 return -1; 53 return -1;
54 } 54 }
55 G_filter.flushp = 0; 55 G_filter.flushp = 0;
@@ -305,7 +305,7 @@ static int FAST_FUNC ipneigh_list_or_flush(char **argv, int flush)
305 xrtnl_wilddump_request(&rth, G_filter.family, RTM_GETNEIGH); 305 xrtnl_wilddump_request(&rth, G_filter.family, RTM_GETNEIGH);
306 G_filter.flushed = 0; 306 G_filter.flushed = 0;
307 if (xrtnl_dump_filter(&rth, print_neigh, NULL) < 0) { 307 if (xrtnl_dump_filter(&rth, print_neigh, NULL) < 0) {
308 bb_perror_msg_and_die("flush terminated"); 308 bb_simple_perror_msg_and_die("flush terminated");
309 } 309 }
310 if (G_filter.flushed == 0) { 310 if (G_filter.flushed == 0) {
311 if (round == 0) 311 if (round == 0)
@@ -325,11 +325,11 @@ static int FAST_FUNC ipneigh_list_or_flush(char **argv, int flush)
325 ndm.ndm_family = G_filter.family; 325 ndm.ndm_family = G_filter.family;
326 326
327 if (rtnl_dump_request(&rth, RTM_GETNEIGH, &ndm, sizeof(struct ndmsg)) < 0) { 327 if (rtnl_dump_request(&rth, RTM_GETNEIGH, &ndm, sizeof(struct ndmsg)) < 0) {
328 bb_perror_msg_and_die("can't send dump request"); 328 bb_simple_perror_msg_and_die("can't send dump request");
329 } 329 }
330 330
331 if (xrtnl_dump_filter(&rth, print_neigh, NULL) < 0) { 331 if (xrtnl_dump_filter(&rth, print_neigh, NULL) < 0) {
332 bb_error_msg_and_die("dump terminated"); 332 bb_simple_error_msg_and_die("dump terminated");
333 } 333 }
334 334
335 return 0; 335 return 0;
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c
index b11078ed5..5a972f8b2 100644
--- a/networking/libiproute/iproute.c
+++ b/networking/libiproute/iproute.c
@@ -57,7 +57,7 @@ typedef struct filter_t filter_t;
57static int flush_update(void) 57static int flush_update(void)
58{ 58{
59 if (rtnl_send_check(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) { 59 if (rtnl_send_check(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) {
60 bb_perror_msg("can't send flush request"); 60 bb_simple_perror_msg("can't send flush request");
61 return -1; 61 return -1;
62 } 62 }
63 G_filter.flushp = 0; 63 G_filter.flushp = 0;
@@ -756,7 +756,7 @@ static void iproute_flush_cache(void)
756 } 756 }
757 757
758 if (write(flush_fd, "-1", 2) < 2) { 758 if (write(flush_fd, "-1", 2) < 2) {
759 bb_perror_msg("can't flush routing cache"); 759 bb_simple_perror_msg("can't flush routing cache");
760 return; 760 return;
761 } 761 }
762 close(flush_fd); 762 close(flush_fd);
@@ -948,7 +948,7 @@ static int iproute_list_or_flush(char **argv, int flush)
948 if (G_filter.tb != -1) { 948 if (G_filter.tb != -1) {
949 xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE); 949 xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
950 } else if (rtnl_rtcache_request(&rth, do_ipv6) < 0) { 950 } else if (rtnl_rtcache_request(&rth, do_ipv6) < 0) {
951 bb_perror_msg_and_die("can't send dump request"); 951 bb_simple_perror_msg_and_die("can't send dump request");
952 } 952 }
953 xrtnl_dump_filter(&rth, print_route, NULL); 953 xrtnl_dump_filter(&rth, print_route, NULL);
954 954
@@ -1041,7 +1041,7 @@ static int iproute_get(char **argv)
1041 } 1041 }
1042 1042
1043 if (req.r.rtm_dst_len == 0) { 1043 if (req.r.rtm_dst_len == 0) {
1044 bb_error_msg_and_die("need at least destination address"); 1044 bb_simple_error_msg_and_die("need at least destination address");
1045 } 1045 }
1046 1046
1047 xrtnl_open(&rth); 1047 xrtnl_open(&rth);
@@ -1077,7 +1077,7 @@ static int iproute_get(char **argv)
1077 print_route(NULL, &req.n, NULL); 1077 print_route(NULL, &req.n, NULL);
1078 1078
1079 if (req.n.nlmsg_type != RTM_NEWROUTE) { 1079 if (req.n.nlmsg_type != RTM_NEWROUTE) {
1080 bb_error_msg_and_die("not a route?"); 1080 bb_simple_error_msg_and_die("not a route?");
1081 } 1081 }
1082 len -= NLMSG_LENGTH(sizeof(*r)); 1082 len -= NLMSG_LENGTH(sizeof(*r));
1083 if (len < 0) { 1083 if (len < 0) {
@@ -1091,7 +1091,7 @@ static int iproute_get(char **argv)
1091 tb[RTA_PREFSRC]->rta_type = RTA_SRC; 1091 tb[RTA_PREFSRC]->rta_type = RTA_SRC;
1092 r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]); 1092 r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]);
1093 } else if (!tb[RTA_SRC]) { 1093 } else if (!tb[RTA_SRC]) {
1094 bb_error_msg_and_die("can't connect the route"); 1094 bb_simple_error_msg_and_die("can't connect the route");
1095 } 1095 }
1096 if (!odev && tb[RTA_OIF]) { 1096 if (!odev && tb[RTA_OIF]) {
1097 tb[RTA_OIF]->rta_type = 0; 1097 tb[RTA_OIF]->rta_type = 0;
diff --git a/networking/libiproute/iptunnel.c b/networking/libiproute/iptunnel.c
index 4002feb78..c9fa632f3 100644
--- a/networking/libiproute/iptunnel.c
+++ b/networking/libiproute/iptunnel.c
@@ -338,7 +338,7 @@ static void parse_args(char **argv, int cmd, struct ip_tunnel_parm *p)
338 338
339 if (p->iph.protocol == IPPROTO_IPIP || p->iph.protocol == IPPROTO_IPV6) { 339 if (p->iph.protocol == IPPROTO_IPIP || p->iph.protocol == IPPROTO_IPV6) {
340 if ((p->i_flags & GRE_KEY) || (p->o_flags & GRE_KEY)) { 340 if ((p->i_flags & GRE_KEY) || (p->o_flags & GRE_KEY)) {
341 bb_error_msg_and_die("keys are not allowed with ipip and sit"); 341 bb_simple_error_msg_and_die("keys are not allowed with ipip and sit");
342 } 342 }
343 } 343 }
344 344
@@ -355,7 +355,7 @@ static void parse_args(char **argv, int cmd, struct ip_tunnel_parm *p)
355 p->o_flags |= GRE_KEY; 355 p->o_flags |= GRE_KEY;
356 } 356 }
357 if (IN_MULTICAST(ntohl(p->iph.daddr)) && !p->iph.saddr) { 357 if (IN_MULTICAST(ntohl(p->iph.daddr)) && !p->iph.saddr) {
358 bb_error_msg_and_die("broadcast tunnel requires a source address"); 358 bb_simple_error_msg_and_die("broadcast tunnel requires a source address");
359 } 359 }
360} 360}
361 361
@@ -367,7 +367,7 @@ static int do_add(int cmd, char **argv)
367 parse_args(argv, cmd, &p); 367 parse_args(argv, cmd, &p);
368 368
369 if (p.iph.ttl && p.iph.frag_off == 0) { 369 if (p.iph.ttl && p.iph.frag_off == 0) {
370 bb_error_msg_and_die("ttl != 0 and noptmudisc are incompatible"); 370 bb_simple_error_msg_and_die("ttl != 0 and noptmudisc are incompatible");
371 } 371 }
372 372
373 switch (p.iph.protocol) { 373 switch (p.iph.protocol) {
@@ -378,7 +378,7 @@ static int do_add(int cmd, char **argv)
378 case IPPROTO_IPV6: 378 case IPPROTO_IPV6:
379 return do_add_ioctl(cmd, "sit0", &p); 379 return do_add_ioctl(cmd, "sit0", &p);
380 default: 380 default:
381 bb_error_msg_and_die("can't determine tunnel mode (ipip, gre or sit)"); 381 bb_simple_error_msg_and_die("can't determine tunnel mode (ipip, gre or sit)");
382 } 382 }
383} 383}
384 384
@@ -485,7 +485,7 @@ static void do_tunnels_list(struct ip_tunnel_parm *p)
485 if (ptr == NULL || 485 if (ptr == NULL ||
486 (*ptr++ = 0, sscanf(buf, "%s", name) != 1) 486 (*ptr++ = 0, sscanf(buf, "%s", name) != 1)
487 ) { 487 ) {
488 bb_error_msg("wrong format of /proc/net/dev"); 488 bb_simple_error_msg("wrong format of /proc/net/dev");
489 return; 489 return;
490 } 490 }
491 if (sscanf(ptr, "%lu%lu%lu%lu%lu%lu%lu%*d%lu%lu%lu%lu%lu%lu%lu", 491 if (sscanf(ptr, "%lu%lu%lu%lu%lu%lu%lu%*d%lu%lu%lu%lu%lu%lu%lu",
diff --git a/networking/libiproute/libnetlink.c b/networking/libiproute/libnetlink.c
index b0d4166ac..7e3473a1c 100644
--- a/networking/libiproute/libnetlink.c
+++ b/networking/libiproute/libnetlink.c
@@ -79,7 +79,7 @@ int FAST_FUNC rtnl_send_check(struct rtnl_handle *rth, const void *buf, int len)
79 if (h->nlmsg_type == NLMSG_ERROR) { 79 if (h->nlmsg_type == NLMSG_ERROR) {
80 struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); 80 struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
81 if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) 81 if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr)))
82 bb_error_msg("ERROR truncated"); 82 bb_simple_error_msg("ERROR truncated");
83 else 83 else
84 errno = -err->error; 84 errno = -err->error;
85 return -1; 85 return -1;
@@ -149,11 +149,11 @@ static int rtnl_dump_filter(struct rtnl_handle *rth,
149 if (status < 0) { 149 if (status < 0) {
150 if (errno == EINTR) 150 if (errno == EINTR)
151 continue; 151 continue;
152 bb_perror_msg("OVERRUN"); 152 bb_simple_perror_msg("OVERRUN");
153 continue; 153 continue;
154 } 154 }
155 if (status == 0) { 155 if (status == 0) {
156 bb_error_msg("EOF on netlink"); 156 bb_simple_error_msg("EOF on netlink");
157 goto ret; 157 goto ret;
158 } 158 }
159 if (msg.msg_namelen != sizeof(nladdr)) { 159 if (msg.msg_namelen != sizeof(nladdr)) {
@@ -184,10 +184,10 @@ static int rtnl_dump_filter(struct rtnl_handle *rth,
184 if (h->nlmsg_type == NLMSG_ERROR) { 184 if (h->nlmsg_type == NLMSG_ERROR) {
185 struct nlmsgerr *l_err = (struct nlmsgerr*)NLMSG_DATA(h); 185 struct nlmsgerr *l_err = (struct nlmsgerr*)NLMSG_DATA(h);
186 if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) { 186 if (h->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr))) {
187 bb_error_msg("ERROR truncated"); 187 bb_simple_error_msg("ERROR truncated");
188 } else { 188 } else {
189 errno = -l_err->error; 189 errno = -l_err->error;
190 bb_perror_msg("RTNETLINK answers"); 190 bb_simple_perror_msg("RTNETLINK answers");
191 } 191 }
192 goto ret; 192 goto ret;
193 } 193 }
@@ -201,7 +201,7 @@ static int rtnl_dump_filter(struct rtnl_handle *rth,
201 h = NLMSG_NEXT(h, status); 201 h = NLMSG_NEXT(h, status);
202 } 202 }
203 if (msg.msg_flags & MSG_TRUNC) { 203 if (msg.msg_flags & MSG_TRUNC) {
204 bb_error_msg("message truncated"); 204 bb_simple_error_msg("message truncated");
205 continue; 205 continue;
206 } 206 }
207 if (status) { 207 if (status) {
@@ -221,7 +221,7 @@ int FAST_FUNC xrtnl_dump_filter(struct rtnl_handle *rth,
221{ 221{
222 int ret = rtnl_dump_filter(rth, filter, arg1/*, NULL, NULL*/); 222 int ret = rtnl_dump_filter(rth, filter, arg1/*, NULL, NULL*/);
223 if (ret < 0) 223 if (ret < 0)
224 bb_error_msg_and_die("dump terminated"); 224 bb_simple_error_msg_and_die("dump terminated");
225 return ret; 225 return ret;
226} 226}
227 227
@@ -266,7 +266,7 @@ int FAST_FUNC rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
266 status = sendmsg(rtnl->fd, &msg, 0); 266 status = sendmsg(rtnl->fd, &msg, 0);
267 267
268 if (status < 0) { 268 if (status < 0) {
269 bb_perror_msg("can't talk to rtnetlink"); 269 bb_simple_perror_msg("can't talk to rtnetlink");
270 goto ret; 270 goto ret;
271 } 271 }
272 272
@@ -280,11 +280,11 @@ int FAST_FUNC rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
280 if (errno == EINTR) { 280 if (errno == EINTR) {
281 continue; 281 continue;
282 } 282 }
283 bb_perror_msg("OVERRUN"); 283 bb_simple_perror_msg("OVERRUN");
284 continue; 284 continue;
285 } 285 }
286 if (status == 0) { 286 if (status == 0) {
287 bb_error_msg("EOF on netlink"); 287 bb_simple_error_msg("EOF on netlink");
288 goto ret; 288 goto ret;
289 } 289 }
290 if (msg.msg_namelen != sizeof(nladdr)) { 290 if (msg.msg_namelen != sizeof(nladdr)) {
@@ -297,7 +297,7 @@ int FAST_FUNC rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
297 297
298 if (l < 0 || len > status) { 298 if (l < 0 || len > status) {
299 if (msg.msg_flags & MSG_TRUNC) { 299 if (msg.msg_flags & MSG_TRUNC) {
300 bb_error_msg("truncated message"); 300 bb_simple_error_msg("truncated message");
301 goto ret; 301 goto ret;
302 } 302 }
303 bb_error_msg_and_die("malformed message: len=%d!", len); 303 bb_error_msg_and_die("malformed message: len=%d!", len);
@@ -320,7 +320,7 @@ int FAST_FUNC rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
320 if (h->nlmsg_type == NLMSG_ERROR) { 320 if (h->nlmsg_type == NLMSG_ERROR) {
321 struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h); 321 struct nlmsgerr *err = (struct nlmsgerr*)NLMSG_DATA(h);
322 if (l < (int)sizeof(struct nlmsgerr)) { 322 if (l < (int)sizeof(struct nlmsgerr)) {
323 bb_error_msg("ERROR truncated"); 323 bb_simple_error_msg("ERROR truncated");
324 } else { 324 } else {
325 errno = - err->error; 325 errno = - err->error;
326 if (errno == 0) { 326 if (errno == 0) {
@@ -329,7 +329,7 @@ int FAST_FUNC rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
329 } 329 }
330 goto ret_0; 330 goto ret_0;
331 } 331 }
332 bb_perror_msg("RTNETLINK answers"); 332 bb_simple_perror_msg("RTNETLINK answers");
333 } 333 }
334 goto ret; 334 goto ret;
335 } 335 }
@@ -338,13 +338,13 @@ int FAST_FUNC rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n,
338 goto ret_0; 338 goto ret_0;
339 } 339 }
340 340
341 bb_error_msg("unexpected reply!"); 341 bb_simple_error_msg("unexpected reply!");
342 342
343 status -= NLMSG_ALIGN(len); 343 status -= NLMSG_ALIGN(len);
344 h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len)); 344 h = (struct nlmsghdr*)((char*)h + NLMSG_ALIGN(len));
345 } 345 }
346 if (msg.msg_flags & MSG_TRUNC) { 346 if (msg.msg_flags & MSG_TRUNC) {
347 bb_error_msg("message truncated"); 347 bb_simple_error_msg("message truncated");
348 continue; 348 continue;
349 } 349 }
350 if (status) { 350 if (status) {
diff --git a/networking/libiproute/utils.c b/networking/libiproute/utils.c
index bf053a54b..4ce230356 100644
--- a/networking/libiproute/utils.c
+++ b/networking/libiproute/utils.c
@@ -230,7 +230,7 @@ uint32_t FAST_FUNC get_addr32(char *name)
230char** FAST_FUNC next_arg(char **argv) 230char** FAST_FUNC next_arg(char **argv)
231{ 231{
232 if (!*++argv) 232 if (!*++argv)
233 bb_error_msg_and_die("command line is not complete, try \"help\""); 233 bb_simple_error_msg_and_die("command line is not complete, try \"help\"");
234 return argv; 234 return argv;
235} 235}
236 236
diff --git a/networking/nbd-client.c b/networking/nbd-client.c
index 0dc8d0c43..3db3b46f9 100644
--- a/networking/nbd-client.c
+++ b/networking/nbd-client.c
@@ -179,7 +179,7 @@ int nbdclient_main(int argc, char **argv)
179 if (memcmp(&nbd_header.magic1, "NBDMAGIC", 179 if (memcmp(&nbd_header.magic1, "NBDMAGIC",
180 sizeof(nbd_header.magic1)) != 0 180 sizeof(nbd_header.magic1)) != 0
181 ) { 181 ) {
182 bb_error_msg_and_die("login failed"); 182 bb_simple_error_msg_and_die("login failed");
183 } 183 }
184 if (memcmp(&nbd_header.magic2, 184 if (memcmp(&nbd_header.magic2,
185 "\x00\x00\x42\x02\x81\x86\x12\x53", 185 "\x00\x00\x42\x02\x81\x86\x12\x53",
@@ -189,7 +189,7 @@ int nbdclient_main(int argc, char **argv)
189 } else if (memcmp(&nbd_header.magic2, "IHAVEOPT", 8) == 0) { 189 } else if (memcmp(&nbd_header.magic2, "IHAVEOPT", 8) == 0) {
190 proto_new = 1; 190 proto_new = 1;
191 } else { 191 } else {
192 bb_error_msg_and_die("login failed"); 192 bb_simple_error_msg_and_die("login failed");
193 } 193 }
194 194
195 if (!proto_new) { 195 if (!proto_new) {
@@ -240,17 +240,17 @@ int nbdclient_main(int argc, char **argv)
240 } 240 }
241 241
242 if (ioctl(nbd, BLKROSET, &ro) < 0) { 242 if (ioctl(nbd, BLKROSET, &ro) < 0) {
243 bb_perror_msg_and_die("BLKROSET"); 243 bb_simple_perror_msg_and_die("BLKROSET");
244 } 244 }
245 245
246 if (timeout) { 246 if (timeout) {
247 if (ioctl(nbd, NBD_SET_TIMEOUT, (unsigned long) timeout)) { 247 if (ioctl(nbd, NBD_SET_TIMEOUT, (unsigned long) timeout)) {
248 bb_perror_msg_and_die("NBD_SET_TIMEOUT"); 248 bb_simple_perror_msg_and_die("NBD_SET_TIMEOUT");
249 } 249 }
250 } 250 }
251 251
252 if (ioctl(nbd, NBD_SET_SOCK, sock)) { 252 if (ioctl(nbd, NBD_SET_SOCK, sock)) {
253 bb_perror_msg_and_die("NBD_SET_SOCK"); 253 bb_simple_perror_msg_and_die("NBD_SET_SOCK");
254 } 254 }
255 255
256 //if (swap) mlockall(MCL_CURRENT|MCL_FUTURE); 256 //if (swap) mlockall(MCL_CURRENT|MCL_FUTURE);
diff --git a/networking/nc.c b/networking/nc.c
index 3e122b787..3dce6a528 100644
--- a/networking/nc.c
+++ b/networking/nc.c
@@ -113,7 +113,7 @@
113#if ENABLE_NC_EXTRA 113#if ENABLE_NC_EXTRA
114static void timeout(int signum UNUSED_PARAM) 114static void timeout(int signum UNUSED_PARAM)
115{ 115{
116 bb_error_msg_and_die("timed out"); 116 bb_simple_error_msg_and_die("timed out");
117} 117}
118#endif 118#endif
119 119
@@ -215,7 +215,7 @@ int nc_main(int argc, char **argv)
215 IF_NC_EXTRA(accept_again:) 215 IF_NC_EXTRA(accept_again:)
216 cfd = accept(sfd, NULL, 0); 216 cfd = accept(sfd, NULL, 0);
217 if (cfd < 0) 217 if (cfd < 0)
218 bb_perror_msg_and_die("accept"); 218 bb_simple_perror_msg_and_die("accept");
219 if (!execparam) 219 if (!execparam)
220 close(sfd); 220 close(sfd);
221 } else { 221 } else {
@@ -267,7 +267,7 @@ int nc_main(int argc, char **argv)
267 testfds = readfds; 267 testfds = readfds;
268 268
269 if (select(cfd + 1, &testfds, NULL, NULL, NULL) < 0) 269 if (select(cfd + 1, &testfds, NULL, NULL, NULL) < 0)
270 bb_perror_msg_and_die("select"); 270 bb_simple_perror_msg_and_die("select");
271 271
272 fd = STDIN_FILENO; 272 fd = STDIN_FILENO;
273 while (1) { 273 while (1) {
diff --git a/networking/nc_bloaty.c b/networking/nc_bloaty.c
index 42c84de45..034e03d21 100644
--- a/networking/nc_bloaty.c
+++ b/networking/nc_bloaty.c
@@ -198,8 +198,8 @@ enum {
198#define Debug(...) do { } while (0) 198#define Debug(...) do { } while (0)
199#endif 199#endif
200 200
201#define holler_error(...) do { if (o_verbose) bb_error_msg(__VA_ARGS__); } while (0) 201#define holler_error(msg) do { if (o_verbose) bb_simple_error_msg(msg); } while (0)
202#define holler_perror(...) do { if (o_verbose) bb_perror_msg(__VA_ARGS__); } while (0) 202#define holler_perror(msg) do { if (o_verbose) bb_simple_perror_msg(msg); } while (0)
203 203
204/* catch: no-brainer interrupt handler */ 204/* catch: no-brainer interrupt handler */
205static void catch(int sig) 205static void catch(int sig)
@@ -361,10 +361,10 @@ static void dolisten(int is_persistent, char **proggie)
361 rr = recv_from_to(netfd, NULL, 0, MSG_PEEK, /*was bigbuf_net, BIGSIZ*/ 361 rr = recv_from_to(netfd, NULL, 0, MSG_PEEK, /*was bigbuf_net, BIGSIZ*/
362 &remend.u.sa, &ouraddr->u.sa, ouraddr->len); 362 &remend.u.sa, &ouraddr->u.sa, ouraddr->len);
363 if (rr < 0) 363 if (rr < 0)
364 bb_perror_msg_and_die("recvfrom"); 364 bb_simple_perror_msg_and_die("recvfrom");
365 unarm(); 365 unarm();
366 } else 366 } else
367 bb_error_msg_and_die("timeout"); 367 bb_simple_error_msg_and_die("timeout");
368/* Now we learned *to which IP* peer has connected, and we want to anchor 368/* Now we learned *to which IP* peer has connected, and we want to anchor
369our socket on it, so that our outbound packets will have correct local IP. 369our socket on it, so that our outbound packets will have correct local IP.
370Unfortunately, bind() on already bound socket will fail now (EINVAL): 370Unfortunately, bind() on already bound socket will fail now (EINVAL):
@@ -382,7 +382,7 @@ create new one, and bind() it. TODO */
382 remend.len = LSA_SIZEOF_SA; 382 remend.len = LSA_SIZEOF_SA;
383 rr = accept(netfd, &remend.u.sa, &remend.len); 383 rr = accept(netfd, &remend.u.sa, &remend.len);
384 if (rr < 0) 384 if (rr < 0)
385 bb_perror_msg_and_die("accept"); 385 bb_simple_perror_msg_and_die("accept");
386 if (themaddr) { 386 if (themaddr) {
387 int sv_port, port, r; 387 int sv_port, port, r;
388 388
@@ -409,7 +409,7 @@ create new one, and bind() it. TODO */
409 } 409 }
410 unarm(); 410 unarm();
411 } else 411 } else
412 bb_error_msg_and_die("timeout"); 412 bb_simple_error_msg_and_die("timeout");
413 413
414 if (is_persistent && proggie) { 414 if (is_persistent && proggie) {
415 /* -l -k -e PROG */ 415 /* -l -k -e PROG */
@@ -494,7 +494,7 @@ static int udptest(void)
494 494
495 rr = write(netfd, bigbuf_in, 1); 495 rr = write(netfd, bigbuf_in, 1);
496 if (rr != 1) 496 if (rr != 1)
497 bb_perror_msg("udptest first write"); 497 bb_simple_perror_msg("udptest first write");
498 498
499 if (o_wait) 499 if (o_wait)
500 sleep(o_wait); // can be interrupted! while (t) nanosleep(&t)? 500 sleep(o_wait); // can be interrupted! while (t) nanosleep(&t)?
@@ -644,7 +644,7 @@ static int readwrite(void)
644 if (rr <= 0) { 644 if (rr <= 0) {
645 if (rr < 0 && o_verbose > 1) { 645 if (rr < 0 && o_verbose > 1) {
646 /* nc 1.10 doesn't do this */ 646 /* nc 1.10 doesn't do this */
647 bb_perror_msg("net read"); 647 bb_simple_perror_msg("net read");
648 } 648 }
649 pfds[1].fd = -1; /* don't poll for netfd anymore */ 649 pfds[1].fd = -1; /* don't poll for netfd anymore */
650 fds_open--; 650 fds_open--;
@@ -869,7 +869,7 @@ int nc_main(int argc UNUSED_PARAM, char **argv)
869 /* apparently UDP can listen ON "port 0", 869 /* apparently UDP can listen ON "port 0",
870 but that's not useful */ 870 but that's not useful */
871 if (!o_lport) 871 if (!o_lport)
872 bb_error_msg_and_die("UDP listen needs nonzero -p port"); 872 bb_simple_error_msg_and_die("UDP listen needs nonzero -p port");
873 } 873 }
874#endif 874#endif
875 875
diff --git a/networking/netstat.c b/networking/netstat.c
index f6bcd44ba..29b891cdc 100644
--- a/networking/netstat.c
+++ b/networking/netstat.c
@@ -343,9 +343,9 @@ static void prg_cache_load(void)
343 return; 343 return;
344 344
345 if (prg_cache_loaded == 1) 345 if (prg_cache_loaded == 1)
346 bb_error_msg("can't scan /proc - are you root?"); 346 bb_simple_error_msg("can't scan /proc - are you root?");
347 else 347 else
348 bb_error_msg("showing only processes with your user ID"); 348 bb_simple_error_msg("showing only processes with your user ID");
349} 349}
350 350
351#else 351#else
diff --git a/networking/nslookup.c b/networking/nslookup.c
index 24e09d4f0..8adde14b8 100644
--- a/networking/nslookup.c
+++ b/networking/nslookup.c
@@ -549,7 +549,7 @@ static int send_queries(struct ns *ns)
549 549
550 recvlen = read(pfd.fd, reply, sizeof(reply)); 550 recvlen = read(pfd.fd, reply, sizeof(reply));
551 if (recvlen < 0) { 551 if (recvlen < 0) {
552 bb_perror_msg("read"); 552 bb_simple_perror_msg("read");
553 next: 553 next:
554 tcur = monotonic_ms(); 554 tcur = monotonic_ms();
555 continue; 555 continue;
diff --git a/networking/ntpd.c b/networking/ntpd.c
index cd6da2b38..48dc1c379 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -905,7 +905,7 @@ do_sendto(int fd,
905 ret = send_to_from(fd, msg, len, MSG_DONTWAIT, to, from, addrlen); 905 ret = send_to_from(fd, msg, len, MSG_DONTWAIT, to, from, addrlen);
906 } 906 }
907 if (ret != len) { 907 if (ret != len) {
908 bb_perror_msg("send failed"); 908 bb_simple_perror_msg("send failed");
909 return -1; 909 return -1;
910 } 910 }
911 return 0; 911 return 0;
@@ -1121,7 +1121,7 @@ step_time(double offset)
1121 dtime = tvc.tv_sec + (1.0e-6 * tvc.tv_usec) + offset; 1121 dtime = tvc.tv_sec + (1.0e-6 * tvc.tv_usec) + offset;
1122 d_to_tv(dtime, &tvn); 1122 d_to_tv(dtime, &tvn);
1123 if (settimeofday(&tvn, NULL) == -1) 1123 if (settimeofday(&tvn, NULL) == -1)
1124 bb_perror_msg_and_die("settimeofday"); 1124 bb_simple_perror_msg_and_die("settimeofday");
1125 1125
1126 VERB2 { 1126 VERB2 {
1127 tval = tvc.tv_sec; 1127 tval = tvc.tv_sec;
@@ -1494,7 +1494,7 @@ select_and_cluster(void)
1494 /* Starting from 1 is ok here */ 1494 /* Starting from 1 is ok here */
1495 for (i = 1; i < num_survivors; i++) { 1495 for (i = 1; i < num_survivors; i++) {
1496 if (G.last_update_peer == survivor[i].p) { 1496 if (G.last_update_peer == survivor[i].p) {
1497 VERB5 bb_error_msg("keeping old synced peer"); 1497 VERB5 bb_simple_error_msg("keeping old synced peer");
1498 p = G.last_update_peer; 1498 p = G.last_update_peer;
1499 goto keep_old; 1499 goto keep_old;
1500 } 1500 }
@@ -1702,7 +1702,7 @@ update_local_clock(peer_t *p)
1702#else 1702#else
1703 set_new_values(STATE_SYNC, offset, recv_time); 1703 set_new_values(STATE_SYNC, offset, recv_time);
1704#endif 1704#endif
1705 VERB4 bb_error_msg("transitioning to FREQ, datapoint ignored"); 1705 VERB4 bb_simple_error_msg("transitioning to FREQ, datapoint ignored");
1706 return 0; /* "leave poll interval as is" */ 1706 return 0; /* "leave poll interval as is" */
1707 1707
1708#if 0 /* this is dead code for now */ 1708#if 0 /* this is dead code for now */
@@ -1796,7 +1796,7 @@ update_local_clock(peer_t *p)
1796 VERB4 { 1796 VERB4 {
1797 memset(&tmx, 0, sizeof(tmx)); 1797 memset(&tmx, 0, sizeof(tmx));
1798 if (adjtimex(&tmx) < 0) 1798 if (adjtimex(&tmx) < 0)
1799 bb_perror_msg_and_die("adjtimex"); 1799 bb_simple_perror_msg_and_die("adjtimex");
1800 bb_error_msg("p adjtimex freq:%ld offset:%+ld status:0x%x tc:%ld", 1800 bb_error_msg("p adjtimex freq:%ld offset:%+ld status:0x%x tc:%ld",
1801 tmx.freq, tmx.offset, tmx.status, tmx.constant); 1801 tmx.freq, tmx.offset, tmx.status, tmx.constant);
1802 } 1802 }
@@ -1906,7 +1906,7 @@ update_local_clock(peer_t *p)
1906 //tmx.maxerror = (uint32_t)((sys_rootdelay / 2 + sys_rootdisp) * 1e6); 1906 //tmx.maxerror = (uint32_t)((sys_rootdelay / 2 + sys_rootdisp) * 1e6);
1907 rc = adjtimex(&tmx); 1907 rc = adjtimex(&tmx);
1908 if (rc < 0) 1908 if (rc < 0)
1909 bb_perror_msg_and_die("adjtimex"); 1909 bb_simple_perror_msg_and_die("adjtimex");
1910 /* NB: here kernel returns constant == G.poll_exp, not == G.poll_exp - 4. 1910 /* NB: here kernel returns constant == G.poll_exp, not == G.poll_exp - 4.
1911 * Not sure why. Perhaps it is normal. 1911 * Not sure why. Perhaps it is normal.
1912 */ 1912 */
@@ -2018,7 +2018,7 @@ recv_and_process_peer_pkt(peer_t *p)
2018 2018
2019#if ENABLE_FEATURE_NTP_AUTH 2019#if ENABLE_FEATURE_NTP_AUTH
2020 if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH && size != NTP_MSGSIZE_SHA1_AUTH) { 2020 if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH && size != NTP_MSGSIZE_SHA1_AUTH) {
2021 bb_error_msg("malformed packet received from %s", p->p_dotted); 2021 bb_error_msg("malformed packet received from %s: size %u", p->p_dotted, (int)size);
2022 return; 2022 return;
2023 } 2023 }
2024 if (p->key_entry && hashes_differ(p, &msg)) { 2024 if (p->key_entry && hashes_differ(p, &msg)) {
@@ -2027,7 +2027,7 @@ recv_and_process_peer_pkt(peer_t *p)
2027 } 2027 }
2028#else 2028#else
2029 if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH) { 2029 if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH) {
2030 bb_error_msg("malformed packet received from %s", p->p_dotted); 2030 bb_error_msg("malformed packet received from %s: size %u", p->p_dotted, (int)size);
2031 return; 2031 return;
2032 } 2032 }
2033#endif 2033#endif
@@ -2238,6 +2238,13 @@ recv_and_process_client_pkt(void /*int fd*/)
2238 from = xzalloc(to->len); 2238 from = xzalloc(to->len);
2239 2239
2240 size = recv_from_to(G_listen_fd, &msg, sizeof(msg), MSG_DONTWAIT, from, &to->u.sa, to->len); 2240 size = recv_from_to(G_listen_fd, &msg, sizeof(msg), MSG_DONTWAIT, from, &to->u.sa, to->len);
2241
2242 /* "ntpq -p" (4.2.8p13) sends a 12-byte NTPv2 request:
2243 * m_status is 0x16: leap:0 version:2 mode:6(reserved1)
2244 * https://docs.ntpsec.org/latest/mode6.html
2245 * We don't support this.
2246 */
2247
2241#if ENABLE_FEATURE_NTP_AUTH 2248#if ENABLE_FEATURE_NTP_AUTH
2242 if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH && size != NTP_MSGSIZE_SHA1_AUTH) 2249 if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH && size != NTP_MSGSIZE_SHA1_AUTH)
2243#else 2250#else
@@ -2248,7 +2255,7 @@ recv_and_process_client_pkt(void /*int fd*/)
2248 if (size < 0) { 2255 if (size < 0) {
2249 if (errno == EAGAIN) 2256 if (errno == EAGAIN)
2250 goto bail; 2257 goto bail;
2251 bb_perror_msg_and_die("recv"); 2258 bb_simple_perror_msg_and_die("recv");
2252 } 2259 }
2253 addr = xmalloc_sockaddr2dotted_noport(from); 2260 addr = xmalloc_sockaddr2dotted_noport(from);
2254 bb_error_msg("malformed packet received from %s: size %u", addr, (int)size); 2261 bb_error_msg("malformed packet received from %s: size %u", addr, (int)size);
@@ -2415,7 +2422,7 @@ static NOINLINE void ntp_init(char **argv)
2415 srand(getpid()); 2422 srand(getpid());
2416 2423
2417 if (getuid()) 2424 if (getuid())
2418 bb_error_msg_and_die(bb_msg_you_must_be_root); 2425 bb_simple_error_msg_and_die(bb_msg_you_must_be_root);
2419 2426
2420 /* Set some globals */ 2427 /* Set some globals */
2421 G.discipline_jitter = G_precision_sec; 2428 G.discipline_jitter = G_precision_sec;
@@ -2436,7 +2443,8 @@ static NOINLINE void ntp_init(char **argv)
2436 "d" /* compat */ 2443 "d" /* compat */
2437 "46aAbgL" /* compat, ignored */ 2444 "46aAbgL" /* compat, ignored */
2438 "\0" 2445 "\0"
2439 "dd:wn" /* -d: counter; -p: list; -w implies -n */ 2446 "=0" /* should have no arguments */
2447 ":dd:wn" /* -d: counter; -p: list; -w implies -n */
2440 IF_FEATURE_NTPD_SERVER(":Il") /* -I implies -l */ 2448 IF_FEATURE_NTPD_SERVER(":Il") /* -I implies -l */
2441 IF_FEATURE_NTP_AUTH(, &key_file_path) 2449 IF_FEATURE_NTP_AUTH(, &key_file_path)
2442 , &peers, &G.script_name 2450 , &peers, &G.script_name
@@ -2490,7 +2498,7 @@ static NOINLINE void ntp_init(char **argv)
2490 /* supports 'sha' and 'sha1' formats */ 2498 /* supports 'sha' and 'sha1' formats */
2491 hash_type = HASH_SHA1; 2499 hash_type = HASH_SHA1;
2492 else 2500 else
2493 bb_error_msg_and_die("only MD5 and SHA1 keys supported"); 2501 bb_simple_error_msg_and_die("only MD5 and SHA1 keys supported");
2494/* man ntp.keys: 2502/* man ntp.keys:
2495 * MD5 The key is 1 to 16 printable characters terminated by an EOL, 2503 * MD5 The key is 1 to 16 printable characters terminated by an EOL,
2496 * whitespace, or a # (which is the "start of comment" character). 2504 * whitespace, or a # (which is the "start of comment" character).
@@ -2673,7 +2681,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
2673 if (p->p_fd == -1) { 2681 if (p->p_fd == -1) {
2674 /* Time to send new req */ 2682 /* Time to send new req */
2675 if (--cnt == 0) { 2683 if (--cnt == 0) {
2676 VERB4 bb_error_msg("disabling burst mode"); 2684 VERB4 bb_simple_error_msg("disabling burst mode");
2677 G.polladj_count = 0; 2685 G.polladj_count = 0;
2678 G.poll_exp = MINPOLL; 2686 G.poll_exp = MINPOLL;
2679 } 2687 }
diff --git a/networking/ping.c b/networking/ping.c
index b534c74c7..a47342fee 100644
--- a/networking/ping.c
+++ b/networking/ping.c
@@ -184,8 +184,8 @@ create_icmp_socket(void)
184 sock = socket(AF_INET, SOCK_RAW, 1); /* 1 == ICMP */ 184 sock = socket(AF_INET, SOCK_RAW, 1); /* 1 == ICMP */
185 if (sock < 0) { 185 if (sock < 0) {
186 if (errno == EPERM) 186 if (errno == EPERM)
187 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 187 bb_simple_error_msg_and_die(bb_msg_perm_denied_are_you_root);
188 bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket); 188 bb_simple_perror_msg_and_die(bb_msg_can_not_create_raw_socket);
189 } 189 }
190 190
191 xmove_fd(sock, pingsock); 191 xmove_fd(sock, pingsock);
@@ -235,7 +235,7 @@ static void ping4(len_and_sockaddr *lsa)
235#endif 235#endif
236 if (c < 0) { 236 if (c < 0) {
237 if (errno != EINTR) 237 if (errno != EINTR)
238 bb_perror_msg("recvfrom"); 238 bb_simple_perror_msg("recvfrom");
239 continue; 239 continue;
240 } 240 }
241 if (c >= 76) { /* ip + icmp */ 241 if (c >= 76) { /* ip + icmp */
@@ -280,7 +280,7 @@ static void ping6(len_and_sockaddr *lsa)
280#endif 280#endif
281 if (c < 0) { 281 if (c < 0) {
282 if (errno != EINTR) 282 if (errno != EINTR)
283 bb_perror_msg("recvfrom"); 283 bb_simple_perror_msg("recvfrom");
284 continue; 284 continue;
285 } 285 }
286 if (c >= ICMP_MINLEN) { /* icmp6_hdr */ 286 if (c >= ICMP_MINLEN) { /* icmp6_hdr */
@@ -482,7 +482,7 @@ static void sendping_tail(void (*sp)(int), int size_pkt)
482 * it doesn't matter */ 482 * it doesn't matter */
483 sz = xsendto(pingsock, G.snd_packet, size_pkt, &pingaddr.sa, sizeof(pingaddr)); 483 sz = xsendto(pingsock, G.snd_packet, size_pkt, &pingaddr.sa, sizeof(pingaddr));
484 if (sz != size_pkt) 484 if (sz != size_pkt)
485 bb_error_msg_and_die(bb_msg_write_error); 485 bb_simple_error_msg_and_die(bb_msg_write_error);
486 486
487 if (pingcount == 0 || G.ntransmitted < pingcount) { 487 if (pingcount == 0 || G.ntransmitted < pingcount) {
488 /* Didn't send all pings yet - schedule next in -i SEC interval */ 488 /* Didn't send all pings yet - schedule next in -i SEC interval */
@@ -723,7 +723,7 @@ static void ping4(len_and_sockaddr *lsa)
723 if (source_lsa) { 723 if (source_lsa) {
724 if (setsockopt(pingsock, IPPROTO_IP, IP_MULTICAST_IF, 724 if (setsockopt(pingsock, IPPROTO_IP, IP_MULTICAST_IF,
725 &source_lsa->u.sa, source_lsa->len)) 725 &source_lsa->u.sa, source_lsa->len))
726 bb_error_msg_and_die("can't set multicast source interface"); 726 bb_simple_error_msg_and_die("can't set multicast source interface");
727 xbind(pingsock, &source_lsa->u.sa, source_lsa->len); 727 xbind(pingsock, &source_lsa->u.sa, source_lsa->len);
728 } 728 }
729 729
@@ -757,7 +757,7 @@ static void ping4(len_and_sockaddr *lsa)
757 (struct sockaddr *) &from, &fromlen); 757 (struct sockaddr *) &from, &fromlen);
758 if (c < 0) { 758 if (c < 0) {
759 if (errno != EINTR) 759 if (errno != EINTR)
760 bb_perror_msg("recvfrom"); 760 bb_simple_perror_msg("recvfrom");
761 continue; 761 continue;
762 } 762 }
763 c = unpack4(G.rcv_packet, c, &from); 763 c = unpack4(G.rcv_packet, c, &from);
@@ -838,7 +838,7 @@ static void ping6(len_and_sockaddr *lsa)
838 c = recvmsg(pingsock, &msg, 0); 838 c = recvmsg(pingsock, &msg, 0);
839 if (c < 0) { 839 if (c < 0) {
840 if (errno != EINTR) 840 if (errno != EINTR)
841 bb_perror_msg("recvfrom"); 841 bb_simple_perror_msg("recvfrom");
842 continue; 842 continue;
843 } 843 }
844 for (mp = CMSG_FIRSTHDR(&msg); mp; mp = CMSG_NXTHDR(&msg, mp)) { 844 for (mp = CMSG_FIRSTHDR(&msg); mp; mp = CMSG_NXTHDR(&msg, mp)) {
diff --git a/networking/route.c b/networking/route.c
index ac1d94c28..a5d8d7cb9 100644
--- a/networking/route.c
+++ b/networking/route.c
@@ -336,7 +336,7 @@ static NOINLINE void INET_setroute(int action, char **args)
336 } 336 }
337 mask = ((struct sockaddr_in *) &rt->rt_dst)->sin_addr.s_addr; 337 mask = ((struct sockaddr_in *) &rt->rt_dst)->sin_addr.s_addr;
338 if (mask & ~(uint32_t)mask_in_addr(*rt)) { 338 if (mask & ~(uint32_t)mask_in_addr(*rt)) {
339 bb_error_msg_and_die("netmask and route address conflict"); 339 bb_simple_error_msg_and_die("netmask and route address conflict");
340 } 340 }
341 } 341 }
342 342
@@ -532,7 +532,7 @@ void FAST_FUNC bb_displayroutes(int noresolve, int netstatfmt)
532 if ((r < 0) && feof(fp)) { /* EOF with no (nonspace) chars read. */ 532 if ((r < 0) && feof(fp)) { /* EOF with no (nonspace) chars read. */
533 break; 533 break;
534 } 534 }
535 bb_perror_msg_and_die(bb_msg_read_error); 535 bb_simple_perror_msg_and_die(bb_msg_read_error);
536 } 536 }
537 537
538 if (!(flgs & RTF_UP)) { /* Skip interfaces that are down. */ 538 if (!(flgs & RTF_UP)) { /* Skip interfaces that are down. */
@@ -598,7 +598,7 @@ static void INET6_displayroutes(void)
598 break; 598 break;
599 } 599 }
600 ERROR: 600 ERROR:
601 bb_perror_msg_and_die(bb_msg_read_error); 601 bb_simple_perror_msg_and_die(bb_msg_read_error);
602 } 602 }
603 603
604 /* Do the addr6x shift-and-insert changes to ':'-delimit addresses. 604 /* Do the addr6x shift-and-insert changes to ':'-delimit addresses.
diff --git a/networking/slattach.c b/networking/slattach.c
index c6feca248..659822a91 100644
--- a/networking/slattach.c
+++ b/networking/slattach.c
@@ -56,7 +56,7 @@ static int tcsetattr_serial_or_warn(struct termios *state)
56 56
57 ret = tcsetattr(serial_fd, TCSANOW, state); 57 ret = tcsetattr(serial_fd, TCSANOW, state);
58 if (ret != 0) { 58 if (ret != 0) {
59 bb_perror_msg("tcsetattr"); 59 bb_simple_perror_msg("tcsetattr");
60 return 1; /* used as exitcode */ 60 return 1; /* used as exitcode */
61 } 61 }
62 return ret; /* 0 */ 62 return ret; /* 0 */
@@ -159,7 +159,7 @@ int slattach_main(int argc UNUSED_PARAM, char **argv)
159 159
160 /* Save current tty state */ 160 /* Save current tty state */
161 if (tcgetattr(serial_fd, &G.saved_state) != 0) 161 if (tcgetattr(serial_fd, &G.saved_state) != 0)
162 bb_perror_msg_and_die("tcgetattr"); 162 bb_simple_perror_msg_and_die("tcgetattr");
163 /* Save line discipline */ 163 /* Save line discipline */
164 xioctl(serial_fd, TIOCGETD, &G.saved_disc); 164 xioctl(serial_fd, TIOCGETD, &G.saved_disc);
165 165
diff --git a/networking/tcpudp.c b/networking/tcpudp.c
index a0af64981..8c4afabf6 100644
--- a/networking/tcpudp.c
+++ b/networking/tcpudp.c
@@ -325,7 +325,7 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
325 client = 0; 325 client = 0;
326 if ((getuid() == 0) && !(opts & OPT_u)) { 326 if ((getuid() == 0) && !(opts & OPT_u)) {
327 xfunc_error_retval = 100; 327 xfunc_error_retval = 100;
328 bb_error_msg_and_die(bb_msg_you_must_be_root); 328 bb_simple_error_msg_and_die(bb_msg_you_must_be_root);
329 } 329 }
330 if (opts & OPT_u) 330 if (opts & OPT_u)
331 if (!uidgid_get(&sslugid, ssluser, 1)) { 331 if (!uidgid_get(&sslugid, ssluser, 1)) {
@@ -419,7 +419,7 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
419 sig_block(SIGCHLD); 419 sig_block(SIGCHLD);
420 if (conn < 0) { 420 if (conn < 0) {
421 if (errno != EINTR) 421 if (errno != EINTR)
422 bb_perror_msg(tcp ? "accept" : "recv"); 422 bb_simple_perror_msg(tcp ? "accept" : "recv");
423 goto again2; 423 goto again2;
424 } 424 }
425 xmove_fd(tcp ? conn : sock, 0); 425 xmove_fd(tcp ? conn : sock, 0);
@@ -484,7 +484,7 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
484 484
485 pid = vfork(); 485 pid = vfork();
486 if (pid == -1) { 486 if (pid == -1) {
487 bb_perror_msg("vfork"); 487 bb_simple_perror_msg("vfork");
488 goto again; 488 goto again;
489 } 489 }
490 490
diff --git a/networking/telnetd.c b/networking/telnetd.c
index 6abecbde2..29f805de7 100644
--- a/networking/telnetd.c
+++ b/networking/telnetd.c
@@ -495,7 +495,7 @@ make_new_session(
495 free(ts); 495 free(ts);
496 close(fd); 496 close(fd);
497 /* sock will be closed by caller */ 497 /* sock will be closed by caller */
498 bb_perror_msg("vfork"); 498 bb_simple_perror_msg("vfork");
499 return NULL; 499 return NULL;
500 } 500 }
501 if (pid > 0) { 501 if (pid > 0) {
diff --git a/networking/tftp.c b/networking/tftp.c
index 5ebd22105..04bfe844f 100644
--- a/networking/tftp.c
+++ b/networking/tftp.c
@@ -31,6 +31,11 @@
31//config: default y 31//config: default y
32//config: depends on TFTP 32//config: depends on TFTP
33//config: 33//config:
34//config:config FEATURE_TFTP_HPA_COMPAT
35//config: bool "tftp-hpa compat (support -c get/put FILE)"
36//config: default y
37//config: depends on TFTP
38//config:
34//config:config TFTPD 39//config:config TFTPD
35//config: bool "tftpd (10 kb)" 40//config: bool "tftpd (10 kb)"
36//config: default y 41//config: default y
@@ -101,9 +106,10 @@
101//usage: IF_FEATURE_TFTP_BLOCKSIZE( 106//usage: IF_FEATURE_TFTP_BLOCKSIZE(
102//usage: "\n -b SIZE Transfer blocks of SIZE octets" 107//usage: "\n -b SIZE Transfer blocks of SIZE octets"
103//usage: ) 108//usage: )
109///////: "\n -m STR Accepted and ignored ('-m binary' compat with tftp-hpa 5.2)"
104//usage: 110//usage:
105//usage:#define tftpd_trivial_usage 111//usage:#define tftpd_trivial_usage
106//usage: "[-cr] [-u USER] [DIR]" 112//usage: "[-crl] [-u USER] [DIR]"
107//usage:#define tftpd_full_usage "\n\n" 113//usage:#define tftpd_full_usage "\n\n"
108//usage: "Transfer a file on tftp client's request\n" 114//usage: "Transfer a file on tftp client's request\n"
109//usage: "\n" 115//usage: "\n"
@@ -447,7 +453,7 @@ static int tftp_protocol(
447 /* fill in packet if the filename fits into xbuf */ 453 /* fill in packet if the filename fits into xbuf */
448 len = strlen(remote_file) + 1; 454 len = strlen(remote_file) + 1;
449 if (2 + len + sizeof("octet") >= io_bufsize) { 455 if (2 + len + sizeof("octet") >= io_bufsize) {
450 bb_error_msg("remote filename is too long"); 456 bb_simple_error_msg("remote filename is too long");
451 goto ret; 457 goto ret;
452 } 458 }
453 strcpy(cp, remote_file); 459 strcpy(cp, remote_file);
@@ -462,7 +468,7 @@ static int tftp_protocol(
462 468
463 /* Need to add option to pkt */ 469 /* Need to add option to pkt */
464 if ((&xbuf[io_bufsize - 1] - cp) < sizeof("blksize NNNNN tsize ") + sizeof(off_t)*3) { 470 if ((&xbuf[io_bufsize - 1] - cp) < sizeof("blksize NNNNN tsize ") + sizeof(off_t)*3) {
465 bb_error_msg("remote filename is too long"); 471 bb_simple_error_msg("remote filename is too long");
466 goto ret; 472 goto ret;
467 } 473 }
468 expect_OACK = 1; 474 expect_OACK = 1;
@@ -563,7 +569,7 @@ static int tftp_protocol(
563 retries--; 569 retries--;
564 if (retries == 0) { 570 if (retries == 0) {
565 tftp_progress_done(); 571 tftp_progress_done();
566 bb_error_msg("timeout"); 572 bb_simple_error_msg("timeout");
567 goto ret; /* no err packet sent */ 573 goto ret; /* no err packet sent */
568 } 574 }
569 575
@@ -668,7 +674,7 @@ static int tftp_protocol(
668 * must be ignored by the client and server 674 * must be ignored by the client and server
669 * as if it were never requested." */ 675 * as if it were never requested." */
670 if (blksize != TFTP_BLKSIZE_DEFAULT) 676 if (blksize != TFTP_BLKSIZE_DEFAULT)
671 bb_error_msg("falling back to blocksize "TFTP_BLKSIZE_DEFAULT_STR); 677 bb_simple_error_msg("falling back to blocksize "TFTP_BLKSIZE_DEFAULT_STR);
672 blksize = TFTP_BLKSIZE_DEFAULT; 678 blksize = TFTP_BLKSIZE_DEFAULT;
673 io_bufsize = TFTP_BLKSIZE_DEFAULT + 4; 679 io_bufsize = TFTP_BLKSIZE_DEFAULT + 4;
674 } 680 }
@@ -733,7 +739,7 @@ static int tftp_protocol(
733 strcpy(G_error_pkt_str, bb_msg_read_error); 739 strcpy(G_error_pkt_str, bb_msg_read_error);
734 send_err_pkt: 740 send_err_pkt:
735 if (G_error_pkt_str[0]) 741 if (G_error_pkt_str[0])
736 bb_error_msg("%s", G_error_pkt_str); 742 bb_simple_error_msg(G_error_pkt_str);
737 G.error_pkt[1] = TFTP_ERROR; 743 G.error_pkt[1] = TFTP_ERROR;
738 xsendto(socket_fd, G.error_pkt, 4 + 1 + strlen(G_error_pkt_str), 744 xsendto(socket_fd, G.error_pkt, 4 + 1 + strlen(G_error_pkt_str),
739 &peer_lsa->u.sa, peer_lsa->len); 745 &peer_lsa->u.sa, peer_lsa->len);
@@ -759,15 +765,54 @@ int tftp_main(int argc UNUSED_PARAM, char **argv)
759 765
760 INIT_G(); 766 INIT_G();
761 767
768 if (ENABLE_FEATURE_TFTP_HPA_COMPAT) {
769 /* As of 2019, common tftp client in Linux distros
770 * is one maintained by H. Peter Anvin:
771 * I've seen "tftp-hpa 5.2" version.
772 * Make the following command work:
773 * "tftp HOST [PORT] -m binary -c get/put FILE"
774 * by mangling it into "....... -g/-p -r FILE"
775 * and accepting and ignoring -m STR option.
776 */
777 unsigned i = 1;
778 while (argv[i]) {
779 /* Accept not only -c, but also
780 * -lc, -cl, -llcclcllcc etc:
781 * "-l Literal mode (do not recognize HOST:FILE)"
782 * since we do not recognize that syntax anyway,
783 * might as well allow the option.
784 */
785 if (argv[i][0] == '-' && strchr(argv[i], 'c')
786 /*&& argv[i][1+strspn(argv[i]+1, "lc")] == '\0'*/
787 ) {
788 if (!argv[++i])
789 break;
790 if (strcmp(argv[i], "get") == 0) {
791 argv[i-1] = (char*)"-g";
792 argv[i] = (char*)"-r";
793 break;
794 }
795 if (strcmp(argv[i], "put") == 0) {
796 argv[i-1] = (char*)"-p";
797 argv[i] = (char*)"-r";
798 break;
799 }
800 }
801 i++;
802 }
803 }
804
762 IF_GETPUT(opt =) getopt32(argv, "^" 805 IF_GETPUT(opt =) getopt32(argv, "^"
763 IF_FEATURE_TFTP_GET("g") IF_FEATURE_TFTP_PUT("p") 806 IF_FEATURE_TFTP_GET("g") IF_FEATURE_TFTP_PUT("p")
764 "l:r:" IF_FEATURE_TFTP_BLOCKSIZE("b:") 807 "l:r:" IF_FEATURE_TFTP_BLOCKSIZE("b:")
808 IF_FEATURE_TFTP_HPA_COMPAT("m:")
765 "\0" 809 "\0"
766 /* -p or -g is mandatory, and they are mutually exclusive */ 810 /* -p or -g is mandatory, and they are mutually exclusive */
767 IF_FEATURE_TFTP_GET("g:") IF_FEATURE_TFTP_PUT("p:") 811 IF_FEATURE_TFTP_GET("g:") IF_FEATURE_TFTP_PUT("p:")
768 IF_GETPUT("g--p:p--g:"), 812 IF_GETPUT("g--p:p--g:"),
769 &local_file, &remote_file 813 &local_file, &remote_file
770 IF_FEATURE_TFTP_BLOCKSIZE(, &blksize_str) 814 IF_FEATURE_TFTP_BLOCKSIZE(, &blksize_str)
815 IF_FEATURE_TFTP_HPA_COMPAT(, NULL)
771 ); 816 );
772 argv += optind; 817 argv += optind;
773 818
@@ -897,6 +942,7 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv)
897 mode = local_file + strlen(local_file) + 1; 942 mode = local_file + strlen(local_file) + 1;
898 /* RFC 1350 says mode string is case independent */ 943 /* RFC 1350 says mode string is case independent */
899 if (mode >= G.block_buf + result || strcasecmp(mode, "octet") != 0) { 944 if (mode >= G.block_buf + result || strcasecmp(mode, "octet") != 0) {
945 error_msg = "mode is not 'octet'";
900 goto err; 946 goto err;
901 } 947 }
902# if ENABLE_FEATURE_TFTP_BLOCKSIZE 948# if ENABLE_FEATURE_TFTP_BLOCKSIZE
@@ -944,7 +990,8 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv)
944 /* tftp_protocol() will create new one, bound to particular local IP */ 990 /* tftp_protocol() will create new one, bound to particular local IP */
945 result = tftp_protocol( 991 result = tftp_protocol(
946 our_lsa, peer_lsa, 992 our_lsa, peer_lsa,
947 local_file IF_TFTP(, NULL /*remote_file*/) 993 local_file
994 IF_TFTP(, NULL /*remote_file*/)
948 IF_FEATURE_TFTP_BLOCKSIZE(, want_transfer_size) 995 IF_FEATURE_TFTP_BLOCKSIZE(, want_transfer_size)
949 IF_FEATURE_TFTP_BLOCKSIZE(, blksize) 996 IF_FEATURE_TFTP_BLOCKSIZE(, blksize)
950 ); 997 );
diff --git a/networking/tls.c b/networking/tls.c
index d1a0204ed..9e81afbad 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -452,7 +452,7 @@ static void hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size,
452 // than INSIZE bytes will first hash the key using H and then use the 452 // than INSIZE bytes will first hash the key using H and then use the
453 // resultant OUTSIZE byte string as the actual key to HMAC." 453 // resultant OUTSIZE byte string as the actual key to HMAC."
454 if (key_size > SHA_INSIZE) { 454 if (key_size > SHA_INSIZE) {
455 bb_error_msg_and_die("HMAC key>64"); //does not happen (yet?) 455 bb_simple_error_msg_and_die("HMAC key>64"); //does not happen (yet?)
456// md5sha_ctx_t ctx; 456// md5sha_ctx_t ctx;
457// begin(&ctx); 457// begin(&ctx);
458// md5sha_hash(&ctx, key, key_size); 458// md5sha_hash(&ctx, key, key_size);
@@ -1138,7 +1138,7 @@ static int tls_xread_record(tls_state_t *tls, const char *expected)
1138 } 1138 }
1139 } 1139 }
1140 if (sz < 0) 1140 if (sz < 0)
1141 bb_error_msg_and_die("encrypted data too short"); 1141 bb_simple_error_msg_and_die("encrypted data too short");
1142 1142
1143 //dump_hex("<< %s\n", tls->inbuf, RECHDR_LEN + sz); 1143 //dump_hex("<< %s\n", tls->inbuf, RECHDR_LEN + sz);
1144 1144
@@ -1417,7 +1417,7 @@ static void find_key_in_der_cert(tls_state_t *tls, uint8_t *der, int len)
1417 dbg("ECDSA key\n"); 1417 dbg("ECDSA key\n");
1418 //UNUSED: tls->flags |= GOT_CERT_ECDSA_KEY_ALG; 1418 //UNUSED: tls->flags |= GOT_CERT_ECDSA_KEY_ALG;
1419 } else 1419 } else
1420 bb_error_msg_and_die("not RSA or ECDSA cert"); 1420 bb_simple_error_msg_and_die("not RSA or ECDSA cert");
1421 } 1421 }
1422 1422
1423 if (tls->flags & GOT_CERT_RSA_KEY_ALG) { 1423 if (tls->flags & GOT_CERT_RSA_KEY_ALG) {
@@ -1888,7 +1888,7 @@ static void process_server_key(tls_state_t *tls, int len)
1888 /* So far we only support curve_x25519 */ 1888 /* So far we only support curve_x25519 */
1889 move_from_unaligned32(t32, keybuf); 1889 move_from_unaligned32(t32, keybuf);
1890 if (t32 != htonl(0x03001d20)) 1890 if (t32 != htonl(0x03001d20))
1891 bb_error_msg_and_die("elliptic curve is not x25519"); 1891 bb_simple_error_msg_and_die("elliptic curve is not x25519");
1892 1892
1893 memcpy(tls->hsd->ecc_pub_key32, keybuf + 4, 32); 1893 memcpy(tls->hsd->ecc_pub_key32, keybuf + 4, 32);
1894 tls->flags |= GOT_EC_KEY; 1894 tls->flags |= GOT_EC_KEY;
@@ -1935,7 +1935,7 @@ static void send_client_key_exchange(tls_state_t *tls)
1935 if (!(tls->flags & NEED_EC_KEY)) { 1935 if (!(tls->flags & NEED_EC_KEY)) {
1936 /* RSA */ 1936 /* RSA */
1937 if (!(tls->flags & GOT_CERT_RSA_KEY_ALG)) 1937 if (!(tls->flags & GOT_CERT_RSA_KEY_ALG))
1938 bb_error_msg("server cert is not RSA"); 1938 bb_simple_error_msg("server cert is not RSA");
1939 1939
1940 tls_get_random(rsa_premaster, sizeof(rsa_premaster)); 1940 tls_get_random(rsa_premaster, sizeof(rsa_premaster));
1941 if (TLS_DEBUG_FIXED_SECRETS) 1941 if (TLS_DEBUG_FIXED_SECRETS)
@@ -1965,7 +1965,7 @@ static void send_client_key_exchange(tls_state_t *tls)
1965 uint8_t privkey[CURVE25519_KEYSIZE]; //[32] 1965 uint8_t privkey[CURVE25519_KEYSIZE]; //[32]
1966 1966
1967 if (!(tls->flags & GOT_EC_KEY)) 1967 if (!(tls->flags & GOT_EC_KEY))
1968 bb_error_msg("server did not provide EC key"); 1968 bb_simple_error_msg("server did not provide EC key");
1969 1969
1970 /* Generate random private key, see RFC 7748 */ 1970 /* Generate random private key, see RFC 7748 */
1971 tls_get_random(privkey, sizeof(privkey)); 1971 tls_get_random(privkey, sizeof(privkey));
@@ -2328,7 +2328,7 @@ void FAST_FUNC tls_run_copy_loop(tls_state_t *tls, unsigned flags)
2328 int nread; 2328 int nread;
2329 2329
2330 if (safe_poll(pfds, 2, -1) < 0) 2330 if (safe_poll(pfds, 2, -1) < 0)
2331 bb_perror_msg_and_die("poll"); 2331 bb_simple_perror_msg_and_die("poll");
2332 2332
2333 if (pfds[0].revents) { 2333 if (pfds[0].revents) {
2334 void *buf; 2334 void *buf;
diff --git a/networking/tls.h b/networking/tls.h
index 494ed78c4..d4ac1bef8 100644
--- a/networking/tls.h
+++ b/networking/tls.h
@@ -90,7 +90,7 @@ void xorbuf_aligned_AES_BLOCK_SIZE(void* buf, const void* mask) FAST_FUNC;
90#define matrixCryptoGetPrngData(buf, len, userPtr) (tls_get_random(buf, len), PS_SUCCESS) 90#define matrixCryptoGetPrngData(buf, len, userPtr) (tls_get_random(buf, len), PS_SUCCESS)
91 91
92#define psFree(p, pool) free(p) 92#define psFree(p, pool) free(p)
93#define psTraceCrypto(...) bb_error_msg_and_die(__VA_ARGS__) 93#define psTraceCrypto(msg) bb_simple_error_msg_and_die(msg)
94 94
95/* Secure zerofill */ 95/* Secure zerofill */
96#define memset_s(A,B,C,D) memset((A),(C),(D)) 96#define memset_s(A,B,C,D) memset((A),(C),(D))
diff --git a/networking/traceroute.c b/networking/traceroute.c
index bdf451186..0435d6ba6 100644
--- a/networking/traceroute.c
+++ b/networking/traceroute.c
@@ -875,7 +875,7 @@ common_traceroute_main(int op, char **argv)
875 * probe (e.g., on a multi-homed host). 875 * probe (e.g., on a multi-homed host).
876 */ 876 */
877 if (getuid() != 0) 877 if (getuid() != 0)
878 bb_error_msg_and_die(bb_msg_you_must_be_root); 878 bb_simple_error_msg_and_die(bb_msg_you_must_be_root);
879 } 879 }
880 if (op & OPT_WAITTIME) 880 if (op & OPT_WAITTIME)
881 waittime = xatou_range(waittime_str, 1, 24 * 60 * 60); 881 waittime = xatou_range(waittime_str, 1, 24 * 60 * 60);
@@ -1003,7 +1003,7 @@ common_traceroute_main(int op, char **argv)
1003 if (af == AF_INET) 1003 if (af == AF_INET)
1004 if (setsockopt(sndsock, IPPROTO_IP, IP_MULTICAST_IF, 1004 if (setsockopt(sndsock, IPPROTO_IP, IP_MULTICAST_IF,
1005 &source_lsa->u.sa, source_lsa->len)) 1005 &source_lsa->u.sa, source_lsa->len))
1006 bb_error_msg_and_die("can't set multicast source interface"); 1006 bb_simple_error_msg_and_die("can't set multicast source interface");
1007//TODO: we can query source port we bound to, 1007//TODO: we can query source port we bound to,
1008// and check it in replies... if we care enough 1008// and check it in replies... if we care enough
1009 xbind(sndsock, &source_lsa->u.sa, source_lsa->len); 1009 xbind(sndsock, &source_lsa->u.sa, source_lsa->len);
@@ -1025,7 +1025,7 @@ common_traceroute_main(int op, char **argv)
1025 /* read IP and port */ 1025 /* read IP and port */
1026 source_lsa = get_sock_lsa(probe_fd); 1026 source_lsa = get_sock_lsa(probe_fd);
1027 if (source_lsa == NULL) 1027 if (source_lsa == NULL)
1028 bb_error_msg_and_die("can't get probe addr"); 1028 bb_simple_error_msg_and_die("can't get probe addr");
1029 1029
1030 close(probe_fd); 1030 close(probe_fd);
1031 1031
diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src
index f16fc0a4f..8ef24748e 100644
--- a/networking/udhcp/Config.src
+++ b/networking/udhcp/Config.src
@@ -116,7 +116,7 @@ config FEATURE_UDHCP_PORT
116 116
117config UDHCP_DEBUG 117config UDHCP_DEBUG
118 int "Maximum verbosity level (0..9)" 118 int "Maximum verbosity level (0..9)"
119 default 9 119 default 2
120 range 0 9 120 range 0 9
121 depends on UDHCPD || UDHCPC || UDHCPC6 || DHCPRELAY 121 depends on UDHCPD || UDHCPC || UDHCPC6 || DHCPRELAY
122 help 122 help
diff --git a/networking/udhcp/arpping.c b/networking/udhcp/arpping.c
index 215d023ce..a395e838d 100644
--- a/networking/udhcp/arpping.c
+++ b/networking/udhcp/arpping.c
@@ -53,12 +53,12 @@ int FAST_FUNC arpping(uint32_t test_nip,
53 53
54 s = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP)); 54 s = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP));
55 if (s == -1) { 55 if (s == -1) {
56 bb_perror_msg(bb_msg_can_not_create_raw_socket); 56 bb_simple_perror_msg(bb_msg_can_not_create_raw_socket);
57 return -1; 57 return -1;
58 } 58 }
59 59
60 if (setsockopt_broadcast(s) == -1) { 60 if (setsockopt_broadcast(s) == -1) {
61 bb_perror_msg("can't enable bcast on raw socket"); 61 bb_simple_perror_msg("can't enable bcast on raw socket");
62 goto ret; 62 goto ret;
63 } 63 }
64 64
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c
index 62ad248ce..4a452cdb9 100644
--- a/networking/udhcp/common.c
+++ b/networking/udhcp/common.c
@@ -240,7 +240,7 @@ uint8_t* FAST_FUNC udhcp_get_option(struct dhcp_packet *packet, int code)
240 while (1) { 240 while (1) {
241 if (rem <= 0) { 241 if (rem <= 0) {
242 complain: 242 complain:
243 bb_error_msg("bad packet, malformed option field"); 243 bb_simple_error_msg("bad packet, malformed option field");
244 return NULL; 244 return NULL;
245 } 245 }
246 246
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h
index bba3d6037..60255eefa 100644
--- a/networking/udhcp/common.h
+++ b/networking/udhcp/common.h
@@ -267,26 +267,45 @@ struct option_set *udhcp_find_option(struct option_set *opt_list, uint8_t code)
267# define IF_UDHCP_VERBOSE(...) __VA_ARGS__ 267# define IF_UDHCP_VERBOSE(...) __VA_ARGS__
268extern unsigned dhcp_verbose; 268extern unsigned dhcp_verbose;
269# define log1(...) do { if (dhcp_verbose >= 1) bb_info_msg(__VA_ARGS__); } while (0) 269# define log1(...) do { if (dhcp_verbose >= 1) bb_info_msg(__VA_ARGS__); } while (0)
270# define log1s(msg) do { if (dhcp_verbose >= 1) bb_simple_info_msg(msg); } while (0)
270# if CONFIG_UDHCP_DEBUG >= 2 271# if CONFIG_UDHCP_DEBUG >= 2
271void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC; 272void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC;
272# define log2(...) do { if (dhcp_verbose >= 2) bb_info_msg(__VA_ARGS__); } while (0) 273# define log2(...) do { if (dhcp_verbose >= 2) bb_info_msg(__VA_ARGS__); } while (0)
274# define log2s(msg) do { if (dhcp_verbose >= 2) bb_simple_info_msg(msg); } while (0)
273# else 275# else
274# define udhcp_dump_packet(...) ((void)0) 276# define udhcp_dump_packet(...) ((void)0)
275# define log2(...) ((void)0) 277# define log2(...) ((void)0)
278# define log2s(msg) ((void)0)
276# endif 279# endif
277# if CONFIG_UDHCP_DEBUG >= 3 280# if CONFIG_UDHCP_DEBUG >= 3
278# define log3(...) do { if (dhcp_verbose >= 3) bb_info_msg(__VA_ARGS__); } while (0) 281# define log3(...) do { if (dhcp_verbose >= 3) bb_info_msg(__VA_ARGS__); } while (0)
282# define log3s(msg) do { if (dhcp_verbose >= 3) bb_simple_info_msg(msg); } while (0)
279# else 283# else
280# define log3(...) ((void)0) 284# define log3(...) ((void)0)
285# define log3s(msg) ((void)0)
281# endif 286# endif
282#else 287#else
283# define IF_UDHCP_VERBOSE(...) 288# define IF_UDHCP_VERBOSE(...)
284# define udhcp_dump_packet(...) ((void)0) 289# define udhcp_dump_packet(...) ((void)0)
285# define log1(...) ((void)0) 290# define log1(...) ((void)0)
291# define log1s(msg) ((void)0)
286# define log2(...) ((void)0) 292# define log2(...) ((void)0)
293# define log2s(msg) ((void)0)
287# define log3(...) ((void)0) 294# define log3(...) ((void)0)
295# define log3s(msg) ((void)0)
288#endif 296#endif
289 297
298#if defined(__mips__)
299/*
300 * The 'simple' message functions have a negative impact on the size of the
301 * DHCP code when compiled for MIPS, so don't use them in this case.
302 */
303#define bb_simple_info_msg bb_info_msg
304#define bb_simple_error_msg bb_error_msg
305#define bb_simple_perror_msg_and_die bb_perror_msg_and_die
306#undef log1s
307#define log1s log1
308#endif
290 309
291/*** Other shared functions ***/ 310/*** Other shared functions ***/
292 311
diff --git a/networking/udhcp/d6_common.h b/networking/udhcp/d6_common.h
index dee2558e2..688f5d6c7 100644
--- a/networking/udhcp/d6_common.h
+++ b/networking/udhcp/d6_common.h
@@ -34,7 +34,7 @@ struct d6_packet {
34 uint8_t d6_msg_type; 34 uint8_t d6_msg_type;
35 uint32_t d6_xid32; 35 uint32_t d6_xid32;
36 } d6_u; 36 } d6_u;
37 uint8_t d6_options[576 - sizeof(struct iphdr) - sizeof(struct udphdr) - 4 37 uint8_t d6_options[576 - sizeof(struct ip6_hdr) - sizeof(struct udphdr) - 4
38 + CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS]; 38 + CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS];
39} PACKED; 39} PACKED;
40#define d6_msg_type d6_u.d6_msg_type 40#define d6_msg_type d6_u.d6_msg_type
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c
index 15e9f3924..9d8e17c51 100644
--- a/networking/udhcp/d6_dhcpc.c
+++ b/networking/udhcp/d6_dhcpc.c
@@ -235,7 +235,7 @@ static char *string_option_to_env(const uint8_t *option,
235 found: 235 found:
236 val_len = (option[2] << 8) | option[3]; 236 val_len = (option[2] << 8) | option[3];
237 if (val_len + &option[D6_OPT_DATA] > option_end) { 237 if (val_len + &option[D6_OPT_DATA] > option_end) {
238 bb_error_msg("option data exceeds option length"); 238 bb_simple_error_msg("option data exceeds option length");
239 return NULL; 239 return NULL;
240 } 240 }
241 return xasprintf("%s=%.*s", name, val_len, (char*)option + 4); 241 return xasprintf("%s=%.*s", name, val_len, (char*)option + 4);
@@ -643,7 +643,7 @@ static NOINLINE int send_d6_discover(uint32_t xid, struct in6_addr *requested_ip
643 client6_data.ia_na = xzalloc(len); 643 client6_data.ia_na = xzalloc(len);
644 client6_data.ia_na->code = D6_OPT_IA_NA; 644 client6_data.ia_na->code = D6_OPT_IA_NA;
645 client6_data.ia_na->len = len - 4; 645 client6_data.ia_na->len = len - 4;
646 *(uint32_t*)client6_data.ia_na->data = rand(); /* IAID */ 646 *(bb__aliased_uint32_t*)client6_data.ia_na->data = rand(); /* IAID */
647 if (requested_ipv6) { 647 if (requested_ipv6) {
648 struct d6_option *iaaddr = (void*)(client6_data.ia_na->data + 4+4+4); 648 struct d6_option *iaaddr = (void*)(client6_data.ia_na->data + 4+4+4);
649 iaaddr->code = D6_OPT_IAADDR; 649 iaaddr->code = D6_OPT_IAADDR;
@@ -661,7 +661,7 @@ static NOINLINE int send_d6_discover(uint32_t xid, struct in6_addr *requested_ip
661 client6_data.ia_pd = xzalloc(len); 661 client6_data.ia_pd = xzalloc(len);
662 client6_data.ia_pd->code = D6_OPT_IA_PD; 662 client6_data.ia_pd->code = D6_OPT_IA_PD;
663 client6_data.ia_pd->len = len - 4; 663 client6_data.ia_pd->len = len - 4;
664 *(uint32_t*)client6_data.ia_pd->data = rand(); /* IAID */ 664 *(bb__aliased_uint32_t*)client6_data.ia_pd->data = rand(); /* IAID */
665 opt_ptr = mempcpy(opt_ptr, client6_data.ia_pd, len); 665 opt_ptr = mempcpy(opt_ptr, client6_data.ia_pd, len);
666 } 666 }
667 667
@@ -848,19 +848,19 @@ static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6, struct d6_pac
848 848
849 bytes = safe_read(fd, &packet, sizeof(packet)); 849 bytes = safe_read(fd, &packet, sizeof(packet));
850 if (bytes < 0) { 850 if (bytes < 0) {
851 log1("packet read error, ignoring"); 851 log1s("packet read error, ignoring");
852 /* NB: possible down interface, etc. Caller should pause. */ 852 /* NB: possible down interface, etc. Caller should pause. */
853 return bytes; /* returns -1 */ 853 return bytes; /* returns -1 */
854 } 854 }
855 855
856 if (bytes < (int) (sizeof(packet.ip6) + sizeof(packet.udp))) { 856 if (bytes < (int) (sizeof(packet.ip6) + sizeof(packet.udp))) {
857 log1("packet is too short, ignoring"); 857 log1s("packet is too short, ignoring");
858 return -2; 858 return -2;
859 } 859 }
860 860
861 if (bytes < sizeof(packet.ip6) + ntohs(packet.ip6.ip6_plen)) { 861 if (bytes < sizeof(packet.ip6) + ntohs(packet.ip6.ip6_plen)) {
862 /* packet is bigger than sizeof(packet), we did partial read */ 862 /* packet is bigger than sizeof(packet), we did partial read */
863 log1("oversized packet, ignoring"); 863 log1s("oversized packet, ignoring");
864 return -2; 864 return -2;
865 } 865 }
866 866
@@ -874,7 +874,7 @@ static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6, struct d6_pac
874 /* || bytes > (int) sizeof(packet) - can't happen */ 874 /* || bytes > (int) sizeof(packet) - can't happen */
875 || packet.udp.len != packet.ip6.ip6_plen 875 || packet.udp.len != packet.ip6.ip6_plen
876 ) { 876 ) {
877 log1("unrelated/bogus packet, ignoring"); 877 log1s("unrelated/bogus packet, ignoring");
878 return -2; 878 return -2;
879 } 879 }
880 880
@@ -981,7 +981,7 @@ static int d6_raw_socket(int ifindex)
981 log2("opening raw socket on ifindex %d", ifindex); 981 log2("opening raw socket on ifindex %d", ifindex);
982 982
983 fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6)); 983 fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6));
984 log2("got raw socket fd %d", fd); 984 log3("got raw socket fd %d", fd);
985 985
986 memset(&sock, 0, sizeof(sock)); /* let's be deterministic */ 986 memset(&sock, 0, sizeof(sock)); /* let's be deterministic */
987 sock.sll_family = AF_PACKET; 987 sock.sll_family = AF_PACKET;
@@ -1003,7 +1003,7 @@ static int d6_raw_socket(int ifindex)
1003 } 1003 }
1004#endif 1004#endif
1005 1005
1006 log1("created raw socket"); 1006 log1s("created raw socket");
1007 1007
1008 return fd; 1008 return fd;
1009} 1009}
@@ -1031,7 +1031,7 @@ static void change_listen_mode(int new_mode)
1031/* Called only on SIGUSR1 */ 1031/* Called only on SIGUSR1 */
1032static void perform_renew(void) 1032static void perform_renew(void)
1033{ 1033{
1034 bb_info_msg("performing DHCP renew"); 1034 bb_simple_info_msg("performing DHCP renew");
1035 switch (client_data.state) { 1035 switch (client_data.state) {
1036 case BOUND: 1036 case BOUND:
1037 change_listen_mode(LISTEN_KERNEL); 1037 change_listen_mode(LISTEN_KERNEL);
@@ -1059,10 +1059,10 @@ static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *ou
1059 || client_data.state == REBINDING 1059 || client_data.state == REBINDING
1060 || client_data.state == RENEW_REQUESTED 1060 || client_data.state == RENEW_REQUESTED
1061 ) { 1061 ) {
1062 bb_info_msg("unicasting a release"); 1062 bb_simple_info_msg("unicasting a release");
1063 send_d6_release(server_ipv6, our_cur_ipv6); /* unicast */ 1063 send_d6_release(server_ipv6, our_cur_ipv6); /* unicast */
1064 } 1064 }
1065 bb_info_msg("entering released state"); 1065 bb_simple_info_msg("entering released state");
1066/* 1066/*
1067 * We can be here on: SIGUSR2, 1067 * We can be here on: SIGUSR2,
1068 * or on exit (SIGTERM) and -R "release on quit" is specified. 1068 * or on exit (SIGTERM) and -R "release on quit" is specified.
@@ -1174,6 +1174,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1174 client_data.script = CONFIG_UDHCPC_DEFAULT_SCRIPT; 1174 client_data.script = CONFIG_UDHCPC_DEFAULT_SCRIPT;
1175 client_data.sockfd = -1; 1175 client_data.sockfd = -1;
1176 1176
1177 /* Make sure fd 0,1,2 are open */
1178 /* Set up the signal pipe on fds 3,4 - must be before openlog() */
1179 udhcp_sp_setup();
1180
1177 /* Parse command line */ 1181 /* Parse command line */
1178 opt = getopt32long(argv, "^" 1182 opt = getopt32long(argv, "^"
1179 /* O,x: list; -T,-t,-A take numeric param */ 1183 /* O,x: list; -T,-t,-A take numeric param */
@@ -1268,14 +1272,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1268 logmode |= LOGMODE_SYSLOG; 1272 logmode |= LOGMODE_SYSLOG;
1269 } 1273 }
1270 1274
1271 /* Make sure fd 0,1,2 are open */
1272 bb_sanitize_stdio();
1273 /* Create pidfile */ 1275 /* Create pidfile */
1274 write_pidfile(client_data.pidfile); 1276 write_pidfile(client_data.pidfile);
1275 /* Goes to stdout (unless NOMMU) and possibly syslog */ 1277 /* Goes to stdout (unless NOMMU) and possibly syslog */
1276 bb_info_msg("started, v"BB_VER); 1278 bb_simple_info_msg("started, v"BB_VER);
1277 /* Set up the signal pipe */
1278 udhcp_sp_setup();
1279 1279
1280 client_data.state = INIT_SELECTING; 1280 client_data.state = INIT_SELECTING;
1281 d6_run_script_no_option("deconfig"); 1281 d6_run_script_no_option("deconfig");
@@ -1321,7 +1321,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1321 continue; 1321 continue;
1322 } 1322 }
1323 /* Else: an error occured, panic! */ 1323 /* Else: an error occured, panic! */
1324 bb_perror_msg_and_die("poll"); 1324 bb_simple_perror_msg_and_die("poll");
1325 } 1325 }
1326 } 1326 }
1327 1327
@@ -1362,7 +1362,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1362 d6_run_script_no_option("leasefail"); 1362 d6_run_script_no_option("leasefail");
1363#if BB_MMU /* -b is not supported on NOMMU */ 1363#if BB_MMU /* -b is not supported on NOMMU */
1364 if (opt & OPT_b) { /* background if no lease */ 1364 if (opt & OPT_b) { /* background if no lease */
1365 bb_info_msg("no lease, forking to background"); 1365 bb_simple_info_msg("no lease, forking to background");
1366 client_background(); 1366 client_background();
1367 /* do not background again! */ 1367 /* do not background again! */
1368 opt = ((opt & ~(OPT_b|OPT_n)) | OPT_f); 1368 opt = ((opt & ~(OPT_b|OPT_n)) | OPT_f);
@@ -1375,7 +1375,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1375 } else 1375 } else
1376#endif 1376#endif
1377 if (opt & OPT_n) { /* abort if no lease */ 1377 if (opt & OPT_n) { /* abort if no lease */
1378 bb_info_msg("no lease, failing"); 1378 bb_simple_info_msg("no lease, failing");
1379 retval = 1; 1379 retval = 1;
1380 goto ret; 1380 goto ret;
1381 } 1381 }
@@ -1403,7 +1403,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1403 client_data.state = RENEWING; 1403 client_data.state = RENEWING;
1404 client_data.first_secs = 0; /* make secs field count from 0 */ 1404 client_data.first_secs = 0; /* make secs field count from 0 */
1405 change_listen_mode(LISTEN_KERNEL); 1405 change_listen_mode(LISTEN_KERNEL);
1406 log1("entering renew state"); 1406 log1s("entering renew state");
1407 /* fall right through */ 1407 /* fall right through */
1408 case RENEW_REQUESTED: /* manual (SIGUSR1) renew */ 1408 case RENEW_REQUESTED: /* manual (SIGUSR1) renew */
1409 case_RENEW_REQUESTED: 1409 case_RENEW_REQUESTED:
@@ -1423,7 +1423,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1423 continue; 1423 continue;
1424 } 1424 }
1425 /* Timed out, enter rebinding state */ 1425 /* Timed out, enter rebinding state */
1426 log1("entering rebinding state"); 1426 log1s("entering rebinding state");
1427 client_data.state = REBINDING; 1427 client_data.state = REBINDING;
1428 /* fall right through */ 1428 /* fall right through */
1429 case REBINDING: 1429 case REBINDING:
@@ -1438,7 +1438,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1438 continue; 1438 continue;
1439 } 1439 }
1440 /* Timed out, enter init state */ 1440 /* Timed out, enter init state */
1441 bb_info_msg("lease lost, entering init state"); 1441 bb_simple_info_msg("lease lost, entering init state");
1442 d6_run_script_no_option("deconfig"); 1442 d6_run_script_no_option("deconfig");
1443 client_data.state = INIT_SELECTING; 1443 client_data.state = INIT_SELECTING;
1444 client_data.first_secs = 0; /* make secs field count from 0 */ 1444 client_data.first_secs = 0; /* make secs field count from 0 */
@@ -1560,7 +1560,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1560 } 1560 }
1561 option = d6_copy_option(packet.d6_options, packet_end, D6_OPT_SERVERID); 1561 option = d6_copy_option(packet.d6_options, packet_end, D6_OPT_SERVERID);
1562 if (!option) { 1562 if (!option) {
1563 bb_info_msg("no server ID, ignoring packet"); 1563 bb_simple_info_msg("no server ID, ignoring packet");
1564 continue; 1564 continue;
1565 /* still selecting - this server looks bad */ 1565 /* still selecting - this server looks bad */
1566 } 1566 }
diff --git a/networking/udhcp/d6_packet.c b/networking/udhcp/d6_packet.c
index 01d1c930b..446497e15 100644
--- a/networking/udhcp/d6_packet.c
+++ b/networking/udhcp/d6_packet.c
@@ -35,12 +35,12 @@ int FAST_FUNC d6_recv_kernel_packet(struct in6_addr *peer_ipv6
35 memset(packet, 0, sizeof(*packet)); 35 memset(packet, 0, sizeof(*packet));
36 bytes = safe_read(fd, packet, sizeof(*packet)); 36 bytes = safe_read(fd, packet, sizeof(*packet));
37 if (bytes < 0) { 37 if (bytes < 0) {
38 log1("packet read error, ignoring"); 38 log1s("packet read error, ignoring");
39 return bytes; /* returns -1 */ 39 return bytes; /* returns -1 */
40 } 40 }
41 41
42 if (bytes < offsetof(struct d6_packet, d6_options)) { 42 if (bytes < offsetof(struct d6_packet, d6_options)) {
43 bb_info_msg("packet with bad magic, ignoring"); 43 bb_simple_info_msg("packet with bad magic, ignoring");
44 return -2; 44 return -2;
45 } 45 }
46 log1("received %s", "a packet"); 46 log1("received %s", "a packet");
diff --git a/networking/udhcp/d6_socket.c b/networking/udhcp/d6_socket.c
index 25e622d6f..8ddee5a8e 100644
--- a/networking/udhcp/d6_socket.c
+++ b/networking/udhcp/d6_socket.c
@@ -115,7 +115,7 @@ int FAST_FUNC d6_listen_socket(int port, const char *inf)
115 115
116 setsockopt_reuseaddr(fd); 116 setsockopt_reuseaddr(fd);
117 if (setsockopt_broadcast(fd) == -1) 117 if (setsockopt_broadcast(fd) == -1)
118 bb_perror_msg_and_die("SO_BROADCAST"); 118 bb_simple_perror_msg_and_die("SO_BROADCAST");
119 119
120 /* NB: bug 1032 says this doesn't work on ethernet aliases (ethN:M) */ 120 /* NB: bug 1032 says this doesn't work on ethernet aliases (ethN:M) */
121 if (setsockopt_bindtodevice(fd, inf)) 121 if (setsockopt_bindtodevice(fd, inf))
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index cb85fa9e3..656295ff7 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -449,15 +449,16 @@ static char **fill_envp(struct dhcp_packet *packet)
449 449
450 memset(found_opts, 0, sizeof(found_opts)); 450 memset(found_opts, 0, sizeof(found_opts));
451 451
452 /* We need 6 elements for: 452 /* We need 7 elements for:
453 * "interface=IFACE" 453 * "interface=IFACE"
454 * "ip=N.N.N.N" from packet->yiaddr 454 * "ip=N.N.N.N" from packet->yiaddr
455 * "giaddr=IP" from packet->gateway_nip (unless 0)
455 * "siaddr=IP" from packet->siaddr_nip (unless 0) 456 * "siaddr=IP" from packet->siaddr_nip (unless 0)
456 * "boot_file=FILE" from packet->file (unless overloaded) 457 * "boot_file=FILE" from packet->file (unless overloaded)
457 * "sname=SERVER_HOSTNAME" from packet->sname (unless overloaded) 458 * "sname=SERVER_HOSTNAME" from packet->sname (unless overloaded)
458 * terminating NULL 459 * terminating NULL
459 */ 460 */
460 envc = 6; 461 envc = 7;
461 /* +1 element for each option, +2 for subnet option: */ 462 /* +1 element for each option, +2 for subnet option: */
462 if (packet) { 463 if (packet) {
463 /* note: do not search for "pad" (0) and "end" (255) options */ 464 /* note: do not search for "pad" (0) and "end" (255) options */
@@ -493,9 +494,7 @@ static char **fill_envp(struct dhcp_packet *packet)
493 * uint16_t flags; // only one flag so far: bcast. Never set by server 494 * uint16_t flags; // only one flag so far: bcast. Never set by server
494 * uint32_t ciaddr; // client IP (usually == yiaddr. can it be different 495 * uint32_t ciaddr; // client IP (usually == yiaddr. can it be different
495 * // if during renew server wants to give us different IP?) 496 * // if during renew server wants to give us different IP?)
496 * uint32_t gateway_nip; // relay agent IP address
497 * uint8_t chaddr[16]; // link-layer client hardware address (MAC) 497 * uint8_t chaddr[16]; // link-layer client hardware address (MAC)
498 * TODO: export gateway_nip as $giaddr?
499 */ 498 */
500 /* Most important one: yiaddr as $ip */ 499 /* Most important one: yiaddr as $ip */
501 *curr = xmalloc(sizeof("ip=255.255.255.255")); 500 *curr = xmalloc(sizeof("ip=255.255.255.255"));
@@ -507,6 +506,12 @@ static char **fill_envp(struct dhcp_packet *packet)
507 sprint_nip(*curr, "siaddr=", (uint8_t *) &packet->siaddr_nip); 506 sprint_nip(*curr, "siaddr=", (uint8_t *) &packet->siaddr_nip);
508 putenv(*curr++); 507 putenv(*curr++);
509 } 508 }
509 if (packet->gateway_nip) {
510 /* IP address of DHCP relay agent */
511 *curr = xmalloc(sizeof("giaddr=255.255.255.255"));
512 sprint_nip(*curr, "giaddr=", (uint8_t *) &packet->gateway_nip);
513 putenv(*curr++);
514 }
510 if (!(overload & FILE_FIELD) && packet->file[0]) { 515 if (!(overload & FILE_FIELD) && packet->file[0]) {
511 /* watch out for invalid packets */ 516 /* watch out for invalid packets */
512 *curr = xasprintf("boot_file=%."DHCP_PKT_FILE_LEN_STR"s", packet->file); 517 *curr = xasprintf("boot_file=%."DHCP_PKT_FILE_LEN_STR"s", packet->file);
@@ -901,7 +906,7 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd)
901 if (bytes < 0) { 906 if (bytes < 0) {
902 if (errno == EINTR) 907 if (errno == EINTR)
903 continue; 908 continue;
904 log1("packet read error, ignoring"); 909 log1s("packet read error, ignoring");
905 /* NB: possible down interface, etc. Caller should pause. */ 910 /* NB: possible down interface, etc. Caller should pause. */
906 return bytes; /* returns -1 */ 911 return bytes; /* returns -1 */
907 } 912 }
@@ -909,13 +914,13 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd)
909 } 914 }
910 915
911 if (bytes < (int) (sizeof(packet.ip) + sizeof(packet.udp))) { 916 if (bytes < (int) (sizeof(packet.ip) + sizeof(packet.udp))) {
912 log1("packet is too short, ignoring"); 917 log1s("packet is too short, ignoring");
913 return -2; 918 return -2;
914 } 919 }
915 920
916 if (bytes < ntohs(packet.ip.tot_len)) { 921 if (bytes < ntohs(packet.ip.tot_len)) {
917 /* packet is bigger than sizeof(packet), we did partial read */ 922 /* packet is bigger than sizeof(packet), we did partial read */
918 log1("oversized packet, ignoring"); 923 log1s("oversized packet, ignoring");
919 return -2; 924 return -2;
920 } 925 }
921 926
@@ -930,7 +935,7 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd)
930 /* || bytes > (int) sizeof(packet) - can't happen */ 935 /* || bytes > (int) sizeof(packet) - can't happen */
931 || ntohs(packet.udp.len) != (uint16_t)(bytes - sizeof(packet.ip)) 936 || ntohs(packet.udp.len) != (uint16_t)(bytes - sizeof(packet.ip))
932 ) { 937 ) {
933 log1("unrelated/bogus packet, ignoring"); 938 log1s("unrelated/bogus packet, ignoring");
934 return -2; 939 return -2;
935 } 940 }
936 941
@@ -938,7 +943,7 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd)
938 check = packet.ip.check; 943 check = packet.ip.check;
939 packet.ip.check = 0; 944 packet.ip.check = 0;
940 if (check != inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip))) { 945 if (check != inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip))) {
941 log1("bad IP header checksum, ignoring"); 946 log1s("bad IP header checksum, ignoring");
942 return -2; 947 return -2;
943 } 948 }
944 949
@@ -963,13 +968,13 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd)
963 check = packet.udp.check; 968 check = packet.udp.check;
964 packet.udp.check = 0; 969 packet.udp.check = 0;
965 if (check && check != inet_cksum((uint16_t *)&packet, bytes)) { 970 if (check && check != inet_cksum((uint16_t *)&packet, bytes)) {
966 log1("packet with bad UDP checksum received, ignoring"); 971 log1s("packet with bad UDP checksum received, ignoring");
967 return -2; 972 return -2;
968 } 973 }
969 skip_udp_sum_check: 974 skip_udp_sum_check:
970 975
971 if (packet.data.cookie != htonl(DHCP_MAGIC)) { 976 if (packet.data.cookie != htonl(DHCP_MAGIC)) {
972 bb_info_msg("packet with bad magic, ignoring"); 977 bb_simple_info_msg("packet with bad magic, ignoring");
973 return -2; 978 return -2;
974 } 979 }
975 980
@@ -1017,7 +1022,7 @@ static int udhcp_raw_socket(int ifindex)
1017 * SOCK_DGRAM: remove link-layer headers on input (SOCK_RAW keeps them) 1022 * SOCK_DGRAM: remove link-layer headers on input (SOCK_RAW keeps them)
1018 * ETH_P_IP: want to receive only packets with IPv4 eth type 1023 * ETH_P_IP: want to receive only packets with IPv4 eth type
1019 */ 1024 */
1020 log2("got raw socket fd"); 1025 log3("got raw socket fd %d", fd);
1021 1026
1022 memset(&sock, 0, sizeof(sock)); /* let's be deterministic */ 1027 memset(&sock, 0, sizeof(sock)); /* let's be deterministic */
1023 sock.sll_family = AF_PACKET; 1028 sock.sll_family = AF_PACKET;
@@ -1084,10 +1089,10 @@ static int udhcp_raw_socket(int ifindex)
1084 1089
1085 if (setsockopt_1(fd, SOL_PACKET, PACKET_AUXDATA) != 0) { 1090 if (setsockopt_1(fd, SOL_PACKET, PACKET_AUXDATA) != 0) {
1086 if (errno != ENOPROTOOPT) 1091 if (errno != ENOPROTOOPT)
1087 log1("can't set PACKET_AUXDATA on raw socket"); 1092 log1s("can't set PACKET_AUXDATA on raw socket");
1088 } 1093 }
1089 1094
1090 log1("created raw socket"); 1095 log1s("created raw socket");
1091 1096
1092 return fd; 1097 return fd;
1093} 1098}
@@ -1115,7 +1120,7 @@ static void change_listen_mode(int new_mode)
1115/* Called only on SIGUSR1 */ 1120/* Called only on SIGUSR1 */
1116static void perform_renew(void) 1121static void perform_renew(void)
1117{ 1122{
1118 bb_info_msg("performing DHCP renew"); 1123 bb_simple_info_msg("performing DHCP renew");
1119 switch (client_data.state) { 1124 switch (client_data.state) {
1120 case BOUND: 1125 case BOUND:
1121 change_listen_mode(LISTEN_KERNEL); 1126 change_listen_mode(LISTEN_KERNEL);
@@ -1153,7 +1158,7 @@ static void perform_release(uint32_t server_addr, uint32_t requested_ip)
1153 inet_ntoa(temp_addr), buffer); 1158 inet_ntoa(temp_addr), buffer);
1154 send_release(server_addr, requested_ip); /* unicast */ 1159 send_release(server_addr, requested_ip); /* unicast */
1155 } 1160 }
1156 bb_info_msg("entering released state"); 1161 bb_simple_info_msg("entering released state");
1157/* 1162/*
1158 * We can be here on: SIGUSR2, 1163 * We can be here on: SIGUSR2,
1159 * or on exit (SIGTERM) and -R "release on quit" is specified. 1164 * or on exit (SIGTERM) and -R "release on quit" is specified.
@@ -1271,6 +1276,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1271 client_data.sockfd = -1; 1276 client_data.sockfd = -1;
1272 str_V = "udhcp "BB_VER; 1277 str_V = "udhcp "BB_VER;
1273 1278
1279 /* Make sure fd 0,1,2 are open */
1280 /* Set up the signal pipe on fds 3,4 - must be before openlog() */
1281 udhcp_sp_setup();
1282
1274 /* Parse command line */ 1283 /* Parse command line */
1275 opt = getopt32long(argv, "^" 1284 opt = getopt32long(argv, "^"
1276 /* O,x: list; -T,-t,-A take numeric param */ 1285 /* O,x: list; -T,-t,-A take numeric param */
@@ -1294,7 +1303,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1294 ); 1303 );
1295 if (opt & (OPT_h|OPT_H)) { 1304 if (opt & (OPT_h|OPT_H)) {
1296 //msg added 2011-11 1305 //msg added 2011-11
1297 bb_error_msg("option -h NAME is deprecated, use -x hostname:NAME"); 1306 bb_simple_error_msg("option -h NAME is deprecated, use -x hostname:NAME");
1298 client_data.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0); 1307 client_data.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0);
1299 } 1308 }
1300 if (opt & OPT_F) { 1309 if (opt & OPT_F) {
@@ -1385,14 +1394,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1385 logmode |= LOGMODE_SYSLOG; 1394 logmode |= LOGMODE_SYSLOG;
1386 } 1395 }
1387 1396
1388 /* Make sure fd 0,1,2 are open */
1389 bb_sanitize_stdio();
1390 /* Create pidfile */ 1397 /* Create pidfile */
1391 write_pidfile(client_data.pidfile); 1398 write_pidfile(client_data.pidfile);
1392 /* Goes to stdout (unless NOMMU) and possibly syslog */ 1399 /* Goes to stdout (unless NOMMU) and possibly syslog */
1393 bb_info_msg("started, v"BB_VER); 1400 bb_simple_info_msg("started, v"BB_VER);
1394 /* Set up the signal pipe */
1395 udhcp_sp_setup();
1396 /* We want random_xid to be random... */ 1401 /* We want random_xid to be random... */
1397 srand(monotonic_us()); 1402 srand(monotonic_us());
1398 1403
@@ -1439,7 +1444,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1439 continue; 1444 continue;
1440 } 1445 }
1441 /* Else: an error occurred, panic! */ 1446 /* Else: an error occurred, panic! */
1442 bb_perror_msg_and_die("poll"); 1447 bb_simple_perror_msg_and_die("poll");
1443 } 1448 }
1444 } 1449 }
1445 1450
@@ -1480,7 +1485,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1480 udhcp_run_script(NULL, "leasefail"); 1485 udhcp_run_script(NULL, "leasefail");
1481#if BB_MMU /* -b is not supported on NOMMU */ 1486#if BB_MMU /* -b is not supported on NOMMU */
1482 if (opt & OPT_b) { /* background if no lease */ 1487 if (opt & OPT_b) { /* background if no lease */
1483 bb_info_msg("no lease, forking to background"); 1488 bb_simple_info_msg("no lease, forking to background");
1484 client_background(); 1489 client_background();
1485 /* do not background again! */ 1490 /* do not background again! */
1486 opt = ((opt & ~(OPT_b|OPT_n)) | OPT_f); 1491 opt = ((opt & ~(OPT_b|OPT_n)) | OPT_f);
@@ -1493,7 +1498,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1493 } else 1498 } else
1494#endif 1499#endif
1495 if (opt & OPT_n) { /* abort if no lease */ 1500 if (opt & OPT_n) { /* abort if no lease */
1496 bb_info_msg("no lease, failing"); 1501 bb_simple_info_msg("no lease, failing");
1497 retval = 1; 1502 retval = 1;
1498 goto ret; 1503 goto ret;
1499 } 1504 }
@@ -1521,7 +1526,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1521 client_data.state = RENEWING; 1526 client_data.state = RENEWING;
1522 client_data.first_secs = 0; /* make secs field count from 0 */ 1527 client_data.first_secs = 0; /* make secs field count from 0 */
1523 change_listen_mode(LISTEN_KERNEL); 1528 change_listen_mode(LISTEN_KERNEL);
1524 log1("entering renew state"); 1529 log1s("entering renew state");
1525 /* fall right through */ 1530 /* fall right through */
1526 case RENEW_REQUESTED: /* manual (SIGUSR1) renew */ 1531 case RENEW_REQUESTED: /* manual (SIGUSR1) renew */
1527 case_RENEW_REQUESTED: 1532 case_RENEW_REQUESTED:
@@ -1554,7 +1559,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1554 */ 1559 */
1555 } 1560 }
1556 /* Timed out or error, enter rebinding state */ 1561 /* Timed out or error, enter rebinding state */
1557 log1("entering rebinding state"); 1562 log1s("entering rebinding state");
1558 client_data.state = REBINDING; 1563 client_data.state = REBINDING;
1559 /* fall right through */ 1564 /* fall right through */
1560 case REBINDING: 1565 case REBINDING:
@@ -1569,7 +1574,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1569 continue; 1574 continue;
1570 } 1575 }
1571 /* Timed out, enter init state */ 1576 /* Timed out, enter init state */
1572 bb_info_msg("lease lost, entering init state"); 1577 bb_simple_info_msg("lease lost, entering init state");
1573 udhcp_run_script(NULL, "deconfig"); 1578 udhcp_run_script(NULL, "deconfig");
1574 client_data.state = INIT_SELECTING; 1579 client_data.state = INIT_SELECTING;
1575 client_data.first_secs = 0; /* make secs field count from 0 */ 1580 client_data.first_secs = 0; /* make secs field count from 0 */
@@ -1655,13 +1660,13 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1655 || memcmp(packet.chaddr, client_data.client_mac, 6) != 0 1660 || memcmp(packet.chaddr, client_data.client_mac, 6) != 0
1656 ) { 1661 ) {
1657//FIXME: need to also check that last 10 bytes are zero 1662//FIXME: need to also check that last 10 bytes are zero
1658 log1("chaddr does not match, ignoring packet"); // log2? 1663 log1("chaddr does not match%s", ", ignoring packet"); // log2?
1659 continue; 1664 continue;
1660 } 1665 }
1661 1666
1662 message = udhcp_get_option(&packet, DHCP_MESSAGE_TYPE); 1667 message = udhcp_get_option(&packet, DHCP_MESSAGE_TYPE);
1663 if (message == NULL) { 1668 if (message == NULL) {
1664 bb_info_msg("no message type option, ignoring packet"); 1669 bb_info_msg("no message type option%s", ", ignoring packet");
1665 continue; 1670 continue;
1666 } 1671 }
1667 1672
@@ -1698,7 +1703,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1698 server_addr = 0; 1703 server_addr = 0;
1699 temp = udhcp_get_option32(&packet, DHCP_SERVER_ID); 1704 temp = udhcp_get_option32(&packet, DHCP_SERVER_ID);
1700 if (!temp) { 1705 if (!temp) {
1701 bb_info_msg("no server ID, using 0.0.0.0"); 1706 bb_simple_info_msg("no server ID, using 0.0.0.0");
1702 } else { 1707 } else {
1703 /* it IS unaligned sometimes, don't "optimize" */ 1708 /* it IS unaligned sometimes, don't "optimize" */
1704 move_from_unaligned32(server_addr, temp); 1709 move_from_unaligned32(server_addr, temp);
@@ -1725,7 +1730,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1725 1730
1726 temp = udhcp_get_option32(&packet, DHCP_LEASE_TIME); 1731 temp = udhcp_get_option32(&packet, DHCP_LEASE_TIME);
1727 if (!temp) { 1732 if (!temp) {
1728 bb_info_msg("no lease time with ACK, using 1 hour lease"); 1733 bb_simple_info_msg("no lease time with ACK, using 1 hour lease");
1729 lease_seconds = 60 * 60; 1734 lease_seconds = 60 * 60;
1730 } else { 1735 } else {
1731 /* it IS unaligned sometimes, don't "optimize" */ 1736 /* it IS unaligned sometimes, don't "optimize" */
@@ -1758,7 +1763,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1758 client_data.interface, 1763 client_data.interface,
1759 arpping_ms) 1764 arpping_ms)
1760 ) { 1765 ) {
1761 bb_info_msg("offered address is in use " 1766 bb_simple_info_msg("offered address is in use "
1762 "(got ARP reply), declining"); 1767 "(got ARP reply), declining");
1763 send_decline(/*xid,*/ server_addr, packet.yiaddr); 1768 send_decline(/*xid,*/ server_addr, packet.yiaddr);
1764 1769
@@ -1822,7 +1827,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1822 if (!temp) { 1827 if (!temp) {
1823 non_matching_svid: 1828 non_matching_svid:
1824 log1("received DHCP NAK with wrong" 1829 log1("received DHCP NAK with wrong"
1825 " server ID, ignoring packet"); 1830 " server ID%s", ", ignoring packet");
1826 continue; 1831 continue;
1827 } 1832 }
1828 move_from_unaligned32(svid, temp); 1833 move_from_unaligned32(svid, temp);
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index 058f86bca..3e08ec011 100644
--- a/networking/udhcp/dhcpd.c
+++ b/networking/udhcp/dhcpd.c
@@ -37,6 +37,8 @@
37//usage: IF_FEATURE_UDHCP_PORT( 37//usage: IF_FEATURE_UDHCP_PORT(
38//usage: "\n -P N Use port N (default 67)" 38//usage: "\n -P N Use port N (default 67)"
39//usage: ) 39//usage: )
40//usage: "\nSignals:"
41//usage: "\n USR1 Update lease file"
40 42
41#include <netinet/ether.h> 43#include <netinet/ether.h>
42#include <syslog.h> 44#include <syslog.h>
@@ -46,7 +48,7 @@
46 48
47/* globals */ 49/* globals */
48#define g_leases ((struct dyn_lease*)ptr_to_globals) 50#define g_leases ((struct dyn_lease*)ptr_to_globals)
49/* struct server_config_t server_config is in bb_common_bufsiz1 */ 51/* struct server_data_t server_data is in bb_common_bufsiz1 */
50 52
51struct static_lease { 53struct static_lease {
52 struct static_lease *next; 54 struct static_lease *next;
@@ -100,7 +102,7 @@ static void add_static_lease(struct static_lease **st_lease_pp,
100/* Find static lease IP by mac */ 102/* Find static lease IP by mac */
101static uint32_t get_static_nip_by_mac(void *mac) 103static uint32_t get_static_nip_by_mac(void *mac)
102{ 104{
103 struct static_lease *st_lease = server_config.static_leases; 105 struct static_lease *st_lease = server_data.static_leases;
104 106
105 while (st_lease) { 107 while (st_lease) {
106 if (memcmp(st_lease->mac, mac, 6) == 0) 108 if (memcmp(st_lease->mac, mac, 6) == 0)
@@ -113,7 +115,7 @@ static uint32_t get_static_nip_by_mac(void *mac)
113 115
114static int is_nip_reserved_as_static(uint32_t nip) 116static int is_nip_reserved_as_static(uint32_t nip)
115{ 117{
116 struct static_lease *st_lease = server_config.static_leases; 118 struct static_lease *st_lease = server_data.static_leases;
117 119
118 while (st_lease) { 120 while (st_lease) {
119 if (st_lease->nip == nip) 121 if (st_lease->nip == nip)
@@ -133,7 +135,7 @@ static struct dyn_lease *oldest_expired_lease(void)
133 135
134 /* Unexpired leases have g_leases[i].expires >= current time 136 /* Unexpired leases have g_leases[i].expires >= current time
135 * and therefore can't ever match */ 137 * and therefore can't ever match */
136 for (i = 0; i < server_config.max_leases; i++) { 138 for (i = 0; i < server_data.max_leases; i++) {
137 if (g_leases[i].expires == 0 /* empty entry */ 139 if (g_leases[i].expires == 0 /* empty entry */
138 || g_leases[i].expires < oldest_time 140 || g_leases[i].expires < oldest_time
139 ) { 141 ) {
@@ -151,7 +153,7 @@ static void clear_leases(const uint8_t *chaddr, uint32_t yiaddr)
151{ 153{
152 unsigned i; 154 unsigned i;
153 155
154 for (i = 0; i < server_config.max_leases; i++) { 156 for (i = 0; i < server_data.max_leases; i++) {
155 if ((chaddr && memcmp(g_leases[i].lease_mac, chaddr, 6) == 0) 157 if ((chaddr && memcmp(g_leases[i].lease_mac, chaddr, 6) == 0)
156 || (yiaddr && g_leases[i].lease_nip == yiaddr) 158 || (yiaddr && g_leases[i].lease_nip == yiaddr)
157 ) { 159 ) {
@@ -216,7 +218,7 @@ static struct dyn_lease *find_lease_by_mac(const uint8_t *mac)
216{ 218{
217 unsigned i; 219 unsigned i;
218 220
219 for (i = 0; i < server_config.max_leases; i++) 221 for (i = 0; i < server_data.max_leases; i++)
220 if (memcmp(g_leases[i].lease_mac, mac, 6) == 0) 222 if (memcmp(g_leases[i].lease_mac, mac, 6) == 0)
221 return &g_leases[i]; 223 return &g_leases[i];
222 224
@@ -228,7 +230,7 @@ static struct dyn_lease *find_lease_by_nip(uint32_t nip)
228{ 230{
229 unsigned i; 231 unsigned i;
230 232
231 for (i = 0; i < server_config.max_leases; i++) 233 for (i = 0; i < server_data.max_leases; i++)
232 if (g_leases[i].lease_nip == nip) 234 if (g_leases[i].lease_nip == nip)
233 return &g_leases[i]; 235 return &g_leases[i];
234 236
@@ -242,17 +244,17 @@ static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac, unsigne
242 int r; 244 int r;
243 245
244 r = arpping(nip, safe_mac, 246 r = arpping(nip, safe_mac,
245 server_config.server_nip, 247 server_data.server_nip,
246 server_config.server_mac, 248 server_data.server_mac,
247 server_config.interface, 249 server_data.interface,
248 arpping_ms); 250 arpping_ms);
249 if (r) 251 if (r)
250 return r; 252 return r;
251 253
252 temp.s_addr = nip; 254 temp.s_addr = nip;
253 bb_info_msg("%s belongs to someone, reserving it for %u seconds", 255 bb_info_msg("%s belongs to someone, reserving it for %u seconds",
254 inet_ntoa(temp), (unsigned)server_config.conflict_time); 256 inet_ntoa(temp), (unsigned)server_data.conflict_time);
255 add_lease(NULL, nip, server_config.conflict_time, NULL, 0); 257 add_lease(NULL, nip, server_data.conflict_time, NULL, 0);
256 return 0; 258 return 0;
257} 259}
258 260
@@ -274,12 +276,12 @@ static uint32_t find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arppi
274 hash += safe_mac[i] + (hash << 6) + (hash << 16) - hash; 276 hash += safe_mac[i] + (hash << 6) + (hash << 16) - hash;
275 277
276 /* pick a seed based on hwaddr then iterate until we find a free address. */ 278 /* pick a seed based on hwaddr then iterate until we find a free address. */
277 addr = server_config.start_ip 279 addr = server_data.start_ip
278 + (hash % (1 + server_config.end_ip - server_config.start_ip)); 280 + (hash % (1 + server_data.end_ip - server_data.start_ip));
279 stop = addr; 281 stop = addr;
280#else 282#else
281 addr = server_config.start_ip; 283 addr = server_data.start_ip;
282#define stop (server_config.end_ip + 1) 284#define stop (server_data.end_ip + 1)
283#endif 285#endif
284 do { 286 do {
285 uint32_t nip; 287 uint32_t nip;
@@ -293,7 +295,7 @@ static uint32_t find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arppi
293 goto next_addr; 295 goto next_addr;
294 nip = htonl(addr); 296 nip = htonl(addr);
295 /* skip our own address */ 297 /* skip our own address */
296 if (nip == server_config.server_nip) 298 if (nip == server_data.server_nip)
297 goto next_addr; 299 goto next_addr;
298 /* is this a static lease addr? */ 300 /* is this a static lease addr? */
299 if (is_nip_reserved_as_static(nip)) 301 if (is_nip_reserved_as_static(nip))
@@ -312,8 +314,8 @@ static uint32_t find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arppi
312 next_addr: 314 next_addr:
313 addr++; 315 addr++;
314#if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC 316#if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC
315 if (addr > server_config.end_ip) 317 if (addr > server_data.end_ip)
316 addr = server_config.start_ip; 318 addr = server_data.start_ip;
317#endif 319#endif
318 } while (addr != stop); 320 } while (addr != stop);
319 321
@@ -386,7 +388,7 @@ struct config_keyword {
386 const char *def; 388 const char *def;
387}; 389};
388 390
389#define OFS(field) offsetof(struct server_config_t, field) 391#define OFS(field) offsetof(struct server_data_t, field)
390 392
391static const struct config_keyword keywords[] = { 393static const struct config_keyword keywords[] = {
392 /* keyword handler variable address default */ 394 /* keyword handler variable address default */
@@ -422,17 +424,17 @@ static NOINLINE void read_config(const char *file)
422 char *token[2]; 424 char *token[2];
423 425
424 for (i = 0; i < KWS_WITH_DEFAULTS; i++) 426 for (i = 0; i < KWS_WITH_DEFAULTS; i++)
425 keywords[i].handler(keywords[i].def, (char*)&server_config + keywords[i].ofs); 427 keywords[i].handler(keywords[i].def, (char*)&server_data + keywords[i].ofs);
426 428
427 parser = config_open(file); 429 parser = config_open(file);
428 while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) { 430 while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) {
429 for (k = keywords, i = 0; i < ARRAY_SIZE(keywords); k++, i++) { 431 for (k = keywords, i = 0; i < ARRAY_SIZE(keywords); k++, i++) {
430 if (strcasecmp(token[0], k->keyword) == 0) { 432 if (strcasecmp(token[0], k->keyword) == 0) {
431 if (!k->handler(token[1], (char*)&server_config + k->ofs)) { 433 if (!k->handler(token[1], (char*)&server_data + k->ofs)) {
432 bb_error_msg("can't parse line %u in %s", 434 bb_error_msg("can't parse line %u in %s",
433 parser->lineno, file); 435 parser->lineno, file);
434 /* reset back to the default value */ 436 /* reset back to the default value */
435 k->handler(k->def, (char*)&server_config + k->ofs); 437 k->handler(k->def, (char*)&server_data + k->ofs);
436 } 438 }
437 break; 439 break;
438 } 440 }
@@ -440,8 +442,8 @@ static NOINLINE void read_config(const char *file)
440 } 442 }
441 config_close(parser); 443 config_close(parser);
442 444
443 server_config.start_ip = ntohl(server_config.start_ip); 445 server_data.start_ip = ntohl(server_data.start_ip);
444 server_config.end_ip = ntohl(server_config.end_ip); 446 server_data.end_ip = ntohl(server_data.end_ip);
445} 447}
446 448
447static void write_leases(void) 449static void write_leases(void)
@@ -451,7 +453,7 @@ static void write_leases(void)
451 leasetime_t curr; 453 leasetime_t curr;
452 int64_t written_at; 454 int64_t written_at;
453 455
454 fd = open_or_warn(server_config.lease_file, O_WRONLY|O_CREAT|O_TRUNC); 456 fd = open_or_warn(server_data.lease_file, O_WRONLY|O_CREAT|O_TRUNC);
455 if (fd < 0) 457 if (fd < 0)
456 return; 458 return;
457 459
@@ -460,7 +462,7 @@ static void write_leases(void)
460 written_at = SWAP_BE64(written_at); 462 written_at = SWAP_BE64(written_at);
461 full_write(fd, &written_at, sizeof(written_at)); 463 full_write(fd, &written_at, sizeof(written_at));
462 464
463 for (i = 0; i < server_config.max_leases; i++) { 465 for (i = 0; i < server_data.max_leases; i++) {
464 leasetime_t tmp_time; 466 leasetime_t tmp_time;
465 467
466 if (g_leases[i].lease_nip == 0) 468 if (g_leases[i].lease_nip == 0)
@@ -483,10 +485,10 @@ static void write_leases(void)
483 } 485 }
484 close(fd); 486 close(fd);
485 487
486 if (server_config.notify_file) { 488 if (server_data.notify_file) {
487 char *argv[3]; 489 char *argv[3];
488 argv[0] = server_config.notify_file; 490 argv[0] = server_data.notify_file;
489 argv[1] = server_config.lease_file; 491 argv[1] = server_data.lease_file;
490 argv[2] = NULL; 492 argv[2] = NULL;
491 spawn_and_wait(argv); 493 spawn_and_wait(argv);
492 } 494 }
@@ -517,7 +519,7 @@ static NOINLINE void read_leases(const char *file)
517 519
518 while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) { 520 while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) {
519 uint32_t y = ntohl(lease.lease_nip); 521 uint32_t y = ntohl(lease.lease_nip);
520 if (y >= server_config.start_ip && y <= server_config.end_ip) { 522 if (y >= server_data.start_ip && y <= server_data.end_ip) {
521 signed_leasetime_t expires = ntohl(lease.expires) - (signed_leasetime_t)time_passed; 523 signed_leasetime_t expires = ntohl(lease.expires) - (signed_leasetime_t)time_passed;
522 uint32_t static_nip; 524 uint32_t static_nip;
523 525
@@ -580,28 +582,28 @@ static void send_packet_to_client(struct dhcp_packet *dhcp_pkt, int force_broadc
580 || (dhcp_pkt->flags & htons(BROADCAST_FLAG)) 582 || (dhcp_pkt->flags & htons(BROADCAST_FLAG))
581 || dhcp_pkt->ciaddr == 0 583 || dhcp_pkt->ciaddr == 0
582 ) { 584 ) {
583 log1("broadcasting packet to client"); 585 log1s("broadcasting packet to client");
584 ciaddr = INADDR_BROADCAST; 586 ciaddr = INADDR_BROADCAST;
585 chaddr = MAC_BCAST_ADDR; 587 chaddr = MAC_BCAST_ADDR;
586 } else { 588 } else {
587 log1("unicasting packet to client ciaddr"); 589 log1s("unicasting packet to client ciaddr");
588 ciaddr = dhcp_pkt->ciaddr; 590 ciaddr = dhcp_pkt->ciaddr;
589 chaddr = dhcp_pkt->chaddr; 591 chaddr = dhcp_pkt->chaddr;
590 } 592 }
591 593
592 udhcp_send_raw_packet(dhcp_pkt, 594 udhcp_send_raw_packet(dhcp_pkt,
593 /*src*/ server_config.server_nip, SERVER_PORT, 595 /*src*/ server_data.server_nip, SERVER_PORT,
594 /*dst*/ ciaddr, CLIENT_PORT, chaddr, 596 /*dst*/ ciaddr, CLIENT_PORT, chaddr,
595 server_config.ifindex); 597 server_data.ifindex);
596} 598}
597 599
598/* Send a packet to gateway_nip using the kernel ip stack */ 600/* Send a packet to gateway_nip using the kernel ip stack */
599static void send_packet_to_relay(struct dhcp_packet *dhcp_pkt) 601static void send_packet_to_relay(struct dhcp_packet *dhcp_pkt)
600{ 602{
601 log1("forwarding packet to relay"); 603 log1s("forwarding packet to relay");
602 604
603 udhcp_send_kernel_packet(dhcp_pkt, 605 udhcp_send_kernel_packet(dhcp_pkt,
604 server_config.server_nip, SERVER_PORT, 606 server_data.server_nip, SERVER_PORT,
605 dhcp_pkt->gateway_nip, SERVER_PORT); 607 dhcp_pkt->gateway_nip, SERVER_PORT);
606} 608}
607 609
@@ -633,7 +635,7 @@ static void init_packet(struct dhcp_packet *packet, struct dhcp_packet *oldpacke
633 packet->flags = oldpacket->flags; 635 packet->flags = oldpacket->flags;
634 packet->gateway_nip = oldpacket->gateway_nip; 636 packet->gateway_nip = oldpacket->gateway_nip;
635 packet->ciaddr = oldpacket->ciaddr; 637 packet->ciaddr = oldpacket->ciaddr;
636 udhcp_add_simple_option(packet, DHCP_SERVER_ID, server_config.server_nip); 638 udhcp_add_simple_option(packet, DHCP_SERVER_ID, server_data.server_nip);
637} 639}
638 640
639/* Fill options field, siaddr_nip, and sname and boot_file fields. 641/* Fill options field, siaddr_nip, and sname and boot_file fields.
@@ -646,7 +648,7 @@ static void add_server_options(struct dhcp_packet *packet)
646 648
647 client_hostname_opt = NULL; 649 client_hostname_opt = NULL;
648 if (packet->yiaddr) { /* if we aren't from send_inform()... */ 650 if (packet->yiaddr) { /* if we aren't from send_inform()... */
649 struct static_lease *st_lease = server_config.static_leases; 651 struct static_lease *st_lease = server_data.static_leases;
650 while (st_lease) { 652 while (st_lease) {
651 if (st_lease->nip == packet->yiaddr) { 653 if (st_lease->nip == packet->yiaddr) {
652 if (st_lease->opt[0] != 0) 654 if (st_lease->opt[0] != 0)
@@ -657,7 +659,7 @@ static void add_server_options(struct dhcp_packet *packet)
657 } 659 }
658 } 660 }
659 661
660 config_opts = server_config.options; 662 config_opts = server_data.options;
661 while (config_opts) { 663 while (config_opts) {
662 if (config_opts->data[OPT_CODE] != DHCP_LEASE_TIME) { 664 if (config_opts->data[OPT_CODE] != DHCP_LEASE_TIME) {
663 /* ^^^^ 665 /* ^^^^
@@ -684,25 +686,25 @@ static void add_server_options(struct dhcp_packet *packet)
684 if (client_hostname_opt) 686 if (client_hostname_opt)
685 udhcp_add_binary_option(packet, client_hostname_opt); 687 udhcp_add_binary_option(packet, client_hostname_opt);
686 688
687 packet->siaddr_nip = server_config.siaddr_nip; 689 packet->siaddr_nip = server_data.siaddr_nip;
688 690
689 if (server_config.sname) 691 if (server_data.sname)
690 strncpy((char*)packet->sname, server_config.sname, sizeof(packet->sname) - 1); 692 strncpy((char*)packet->sname, server_data.sname, sizeof(packet->sname) - 1);
691 if (server_config.boot_file) 693 if (server_data.boot_file)
692 strncpy((char*)packet->file, server_config.boot_file, sizeof(packet->file) - 1); 694 strncpy((char*)packet->file, server_data.boot_file, sizeof(packet->file) - 1);
693} 695}
694 696
695static uint32_t select_lease_time(struct dhcp_packet *packet) 697static uint32_t select_lease_time(struct dhcp_packet *packet)
696{ 698{
697 uint32_t lease_time_sec = server_config.max_lease_sec; 699 uint32_t lease_time_sec = server_data.max_lease_sec;
698 uint8_t *lease_time_opt = udhcp_get_option32(packet, DHCP_LEASE_TIME); 700 uint8_t *lease_time_opt = udhcp_get_option32(packet, DHCP_LEASE_TIME);
699 if (lease_time_opt) { 701 if (lease_time_opt) {
700 move_from_unaligned32(lease_time_sec, lease_time_opt); 702 move_from_unaligned32(lease_time_sec, lease_time_opt);
701 lease_time_sec = ntohl(lease_time_sec); 703 lease_time_sec = ntohl(lease_time_sec);
702 if (lease_time_sec > server_config.max_lease_sec) 704 if (lease_time_sec > server_data.max_lease_sec)
703 lease_time_sec = server_config.max_lease_sec; 705 lease_time_sec = server_data.max_lease_sec;
704 if (lease_time_sec < server_config.min_lease_sec) 706 if (lease_time_sec < server_data.min_lease_sec)
705 lease_time_sec = server_config.min_lease_sec; 707 lease_time_sec = server_data.min_lease_sec;
706 } 708 }
707 return lease_time_sec; 709 return lease_time_sec;
708} 710}
@@ -737,8 +739,8 @@ static NOINLINE void send_offer(struct dhcp_packet *oldpacket,
737 /* Or: if client has requested an IP */ 739 /* Or: if client has requested an IP */
738 else if (requested_nip != 0 740 else if (requested_nip != 0
739 /* and the IP is in the lease range */ 741 /* and the IP is in the lease range */
740 && ntohl(requested_nip) >= server_config.start_ip 742 && ntohl(requested_nip) >= server_data.start_ip
741 && ntohl(requested_nip) <= server_config.end_ip 743 && ntohl(requested_nip) <= server_data.end_ip
742 /* and */ 744 /* and */
743 && ( !(lease = find_lease_by_nip(requested_nip)) /* is not already taken */ 745 && ( !(lease = find_lease_by_nip(requested_nip)) /* is not already taken */
744 || is_expired_lease(lease) /* or is taken, but expired */ 746 || is_expired_lease(lease) /* or is taken, but expired */
@@ -752,18 +754,18 @@ static NOINLINE void send_offer(struct dhcp_packet *oldpacket,
752 } 754 }
753 755
754 if (!packet.yiaddr) { 756 if (!packet.yiaddr) {
755 bb_error_msg("no free IP addresses. OFFER abandoned"); 757 bb_simple_error_msg("no free IP addresses. OFFER abandoned");
756 return; 758 return;
757 } 759 }
758 /* Reserve the IP for a short time hoping to get DHCPREQUEST soon */ 760 /* Reserve the IP for a short time hoping to get DHCPREQUEST soon */
759 p_host_name = (const char*) udhcp_get_option(oldpacket, DHCP_HOST_NAME); 761 p_host_name = (const char*) udhcp_get_option(oldpacket, DHCP_HOST_NAME);
760 lease = add_lease(packet.chaddr, packet.yiaddr, 762 lease = add_lease(packet.chaddr, packet.yiaddr,
761 server_config.offer_time, 763 server_data.offer_time,
762 p_host_name, 764 p_host_name,
763 p_host_name ? (unsigned char)p_host_name[OPT_LEN - OPT_DATA] : 0 765 p_host_name ? (unsigned char)p_host_name[OPT_LEN - OPT_DATA] : 0
764 ); 766 );
765 if (!lease) { 767 if (!lease) {
766 bb_error_msg("no free IP addresses. OFFER abandoned"); 768 bb_simple_error_msg("no free IP addresses. OFFER abandoned");
767 return; 769 return;
768 } 770 }
769 } 771 }
@@ -863,6 +865,10 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
863 IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) 865 IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;)
864 IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) 866 IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;)
865 867
868 /* Make sure fd 0,1,2 are open */
869 /* Setup the signal pipe on fds 3,4 - must be before openlog() */
870 udhcp_sp_setup();
871
866 opt = getopt32(argv, "^" 872 opt = getopt32(argv, "^"
867 "fSI:va:"IF_FEATURE_UDHCP_PORT("P:") 873 "fSI:va:"IF_FEATURE_UDHCP_PORT("P:")
868 "\0" 874 "\0"
@@ -886,7 +892,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
886 } 892 }
887 if (opt & 4) { /* -I */ 893 if (opt & 4) { /* -I */
888 len_and_sockaddr *lsa = xhost_and_af2sockaddr(str_I, 0, AF_INET); 894 len_and_sockaddr *lsa = xhost_and_af2sockaddr(str_I, 0, AF_INET);
889 server_config.server_nip = lsa->u.sin.sin_addr.s_addr; 895 server_data.server_nip = lsa->u.sin.sin_addr.s_addr;
890 free(lsa); 896 free(lsa);
891 } 897 }
892#if ENABLE_FEATURE_UDHCP_PORT 898#if ENABLE_FEATURE_UDHCP_PORT
@@ -901,52 +907,46 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
901 * otherwise NOMMU machines will parse config twice */ 907 * otherwise NOMMU machines will parse config twice */
902 read_config(argv[0] ? argv[0] : DHCPD_CONF_FILE); 908 read_config(argv[0] ? argv[0] : DHCPD_CONF_FILE);
903 /* prevent poll timeout overflow */ 909 /* prevent poll timeout overflow */
904 if (server_config.auto_time > INT_MAX / 1000) 910 if (server_data.auto_time > INT_MAX / 1000)
905 server_config.auto_time = INT_MAX / 1000; 911 server_data.auto_time = INT_MAX / 1000;
906
907 /* Make sure fd 0,1,2 are open */
908 bb_sanitize_stdio();
909 912
910 /* Create pidfile */ 913 /* Create pidfile */
911 write_pidfile(server_config.pidfile); 914 write_pidfile(server_data.pidfile);
912 /* if (!..) bb_perror_msg("can't create pidfile %s", pidfile); */ 915 /* if (!..) bb_perror_msg("can't create pidfile %s", pidfile); */
913 916
914 bb_info_msg("started, v"BB_VER); 917 bb_simple_info_msg("started, v"BB_VER);
915 918
916 option = udhcp_find_option(server_config.options, DHCP_LEASE_TIME); 919 option = udhcp_find_option(server_data.options, DHCP_LEASE_TIME);
917 server_config.max_lease_sec = DEFAULT_LEASE_TIME; 920 server_data.max_lease_sec = DEFAULT_LEASE_TIME;
918 if (option) { 921 if (option) {
919 move_from_unaligned32(server_config.max_lease_sec, option->data + OPT_DATA); 922 move_from_unaligned32(server_data.max_lease_sec, option->data + OPT_DATA);
920 server_config.max_lease_sec = ntohl(server_config.max_lease_sec); 923 server_data.max_lease_sec = ntohl(server_data.max_lease_sec);
921 } 924 }
922 925
923 /* Sanity check */ 926 /* Sanity check */
924 num_ips = server_config.end_ip - server_config.start_ip + 1; 927 num_ips = server_data.end_ip - server_data.start_ip + 1;
925 if (server_config.max_leases > num_ips) { 928 if (server_data.max_leases > num_ips) {
926 bb_error_msg("max_leases=%u is too big, setting to %u", 929 bb_error_msg("max_leases=%u is too big, setting to %u",
927 (unsigned)server_config.max_leases, num_ips); 930 (unsigned)server_data.max_leases, num_ips);
928 server_config.max_leases = num_ips; 931 server_data.max_leases = num_ips;
929 } 932 }
930 933
931 /* this sets g_leases */ 934 /* this sets g_leases */
932 SET_PTR_TO_GLOBALS(xzalloc(server_config.max_leases * sizeof(g_leases[0]))); 935 SET_PTR_TO_GLOBALS(xzalloc(server_data.max_leases * sizeof(g_leases[0])));
933 936
934 read_leases(server_config.lease_file); 937 read_leases(server_data.lease_file);
935 938
936 if (udhcp_read_interface(server_config.interface, 939 if (udhcp_read_interface(server_data.interface,
937 &server_config.ifindex, 940 &server_data.ifindex,
938 (server_config.server_nip == 0 ? &server_config.server_nip : NULL), 941 (server_data.server_nip == 0 ? &server_data.server_nip : NULL),
939 server_config.server_mac) 942 server_data.server_mac)
940 ) { 943 ) {
941 retval = 1; 944 retval = 1;
942 goto ret; 945 goto ret;
943 } 946 }
944 947
945 /* Setup the signal pipe */
946 udhcp_sp_setup();
947
948 continue_with_autotime: 948 continue_with_autotime:
949 timeout_end = monotonic_sec() + server_config.auto_time; 949 timeout_end = monotonic_sec() + server_data.auto_time;
950 while (1) { /* loop until universe collapses */ 950 while (1) { /* loop until universe collapses */
951 struct pollfd pfds[2]; 951 struct pollfd pfds[2];
952 struct dhcp_packet packet; 952 struct dhcp_packet packet;
@@ -960,14 +960,14 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
960 960
961 if (server_socket < 0) { 961 if (server_socket < 0) {
962 server_socket = udhcp_listen_socket(/*INADDR_ANY,*/ SERVER_PORT, 962 server_socket = udhcp_listen_socket(/*INADDR_ANY,*/ SERVER_PORT,
963 server_config.interface); 963 server_data.interface);
964 } 964 }
965 965
966 udhcp_sp_fd_set(pfds, server_socket); 966 udhcp_sp_fd_set(pfds, server_socket);
967 967
968 new_tv: 968 new_tv:
969 tv = -1; 969 tv = -1;
970 if (server_config.auto_time) { 970 if (server_data.auto_time) {
971 tv = timeout_end - monotonic_sec(); 971 tv = timeout_end - monotonic_sec();
972 if (tv <= 0) { 972 if (tv <= 0) {
973 write_leases: 973 write_leases:
@@ -985,7 +985,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
985 if (errno == EINTR) 985 if (errno == EINTR)
986 goto new_tv; 986 goto new_tv;
987 /* < 0 and not EINTR: should not happen */ 987 /* < 0 and not EINTR: should not happen */
988 bb_perror_msg_and_die("poll"); 988 bb_simple_perror_msg_and_die("poll");
989 } 989 }
990 990
991 if (pfds[0].revents) switch (udhcp_sp_read()) { 991 if (pfds[0].revents) switch (udhcp_sp_read()) {
@@ -1019,16 +1019,16 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
1019 continue; 1019 continue;
1020 } 1020 }
1021 if (packet.hlen != 6) { 1021 if (packet.hlen != 6) {
1022 bb_info_msg("MAC length != 6, ignoring packet"); 1022 bb_info_msg("MAC length != 6%s", ", ignoring packet");
1023 continue; 1023 continue;
1024 } 1024 }
1025 if (packet.op != BOOTREQUEST) { 1025 if (packet.op != BOOTREQUEST) {
1026 bb_info_msg("not a REQUEST, ignoring packet"); 1026 bb_info_msg("not a REQUEST%s", ", ignoring packet");
1027 continue; 1027 continue;
1028 } 1028 }
1029 state = udhcp_get_option(&packet, DHCP_MESSAGE_TYPE); 1029 state = udhcp_get_option(&packet, DHCP_MESSAGE_TYPE);
1030 if (state == NULL || state[0] < DHCP_MINTYPE || state[0] > DHCP_MAXTYPE) { 1030 if (state == NULL || state[0] < DHCP_MINTYPE || state[0] > DHCP_MAXTYPE) {
1031 bb_info_msg("no or bad message type option, ignoring packet"); 1031 bb_info_msg("no or bad message type option%s", ", ignoring packet");
1032 continue; 1032 continue;
1033 } 1033 }
1034 1034
@@ -1037,9 +1037,9 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
1037 if (server_id_opt) { 1037 if (server_id_opt) {
1038 uint32_t server_id_network_order; 1038 uint32_t server_id_network_order;
1039 move_from_unaligned32(server_id_network_order, server_id_opt); 1039 move_from_unaligned32(server_id_network_order, server_id_opt);
1040 if (server_id_network_order != server_config.server_nip) { 1040 if (server_id_network_order != server_data.server_nip) {
1041 /* client talks to somebody else */ 1041 /* client talks to somebody else */
1042 log1("server ID doesn't match, ignoring"); 1042 log1("server ID doesn't match%s", ", ignoring");
1043 continue; 1043 continue;
1044 } 1044 }
1045 } 1045 }
@@ -1162,7 +1162,7 @@ o DHCPREQUEST generated during REBINDING state:
1162 if (!requested_ip_opt) { 1162 if (!requested_ip_opt) {
1163 requested_nip = packet.ciaddr; 1163 requested_nip = packet.ciaddr;
1164 if (requested_nip == 0) { 1164 if (requested_nip == 0) {
1165 log1("no requested IP and no ciaddr, ignoring"); 1165 log1("no requested IP and no ciaddr%s", ", ignoring");
1166 break; 1166 break;
1167 } 1167 }
1168 } 1168 }
@@ -1204,7 +1204,7 @@ o DHCPREQUEST generated during REBINDING state:
1204 && requested_nip == lease->lease_nip 1204 && requested_nip == lease->lease_nip
1205 ) { 1205 ) {
1206 memset(lease->lease_mac, 0, sizeof(lease->lease_mac)); 1206 memset(lease->lease_mac, 0, sizeof(lease->lease_mac));
1207 lease->expires = time(NULL) + server_config.decline_time; 1207 lease->expires = time(NULL) + server_data.decline_time;
1208 } 1208 }
1209 break; 1209 break;
1210 1210
@@ -1235,7 +1235,7 @@ o DHCPREQUEST generated during REBINDING state:
1235 ret0: 1235 ret0:
1236 retval = 0; 1236 retval = 0;
1237 ret: 1237 ret:
1238 /*if (server_config.pidfile) - server_config.pidfile is never NULL */ 1238 /*if (server_data.pidfile) - server_data.pidfile is never NULL */
1239 remove_pidfile(server_config.pidfile); 1239 remove_pidfile(server_data.pidfile);
1240 return retval; 1240 return retval;
1241} 1241}
diff --git a/networking/udhcp/dhcpd.h b/networking/udhcp/dhcpd.h
index ba11d77e8..b42849bbb 100644
--- a/networking/udhcp/dhcpd.h
+++ b/networking/udhcp/dhcpd.h
@@ -17,7 +17,7 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
17 17
18struct static_lease; 18struct static_lease;
19 19
20struct server_config_t { 20struct server_data_t {
21 char *interface; /* interface to use */ 21 char *interface; /* interface to use */
22//TODO: ifindex, server_nip, server_mac 22//TODO: ifindex, server_nip, server_mac
23// are obtained from interface name. 23// are obtained from interface name.
@@ -53,12 +53,12 @@ struct server_config_t {
53 struct static_lease *static_leases; /* List of ip/mac pairs to assign static leases */ 53 struct static_lease *static_leases; /* List of ip/mac pairs to assign static leases */
54} FIX_ALIASING; 54} FIX_ALIASING;
55 55
56#define server_config (*(struct server_config_t*)bb_common_bufsiz1) 56#define server_data (*(struct server_data_t*)bb_common_bufsiz1)
57/* client_data sits in 2nd half of bb_common_bufsiz1 */ 57/* client_data sits in 2nd half of bb_common_bufsiz1 */
58 58
59#if ENABLE_FEATURE_UDHCP_PORT 59#if ENABLE_FEATURE_UDHCP_PORT
60#define SERVER_PORT (server_config.port) 60#define SERVER_PORT (server_data.port)
61#define SERVER_PORT6 (server_config.port) 61#define SERVER_PORT6 (server_data.port)
62#else 62#else
63#define SERVER_PORT 67 63#define SERVER_PORT 67
64#define SERVER_PORT6 547 64#define SERVER_PORT6 547
diff --git a/networking/udhcp/dhcprelay.c b/networking/udhcp/dhcprelay.c
index 86dcb1af0..ef9447b4b 100644
--- a/networking/udhcp/dhcprelay.c
+++ b/networking/udhcp/dhcprelay.c
@@ -186,7 +186,7 @@ static int sendto_ip4(int sock, const void *msg, int msg_len, struct sockaddr_in
186 err = sendto(sock, msg, msg_len, 0, (struct sockaddr*) to, sizeof(*to)); 186 err = sendto(sock, msg, msg_len, 0, (struct sockaddr*) to, sizeof(*to));
187 err -= msg_len; 187 err -= msg_len;
188 if (err) 188 if (err)
189 bb_perror_msg("sendto"); 189 bb_simple_perror_msg("sendto");
190 return err; 190 return err;
191} 191}
192 192
@@ -273,7 +273,7 @@ int dhcprelay_main(int argc UNUSED_PARAM, char **argv)
273 bb_show_usage(); 273 bb_show_usage();
274 if (argv[3]) { 274 if (argv[3]) {
275 if (!inet_aton(argv[3], &server_addr.sin_addr)) 275 if (!inet_aton(argv[3], &server_addr.sin_addr))
276 bb_perror_msg_and_die("bad server IP"); 276 bb_simple_perror_msg_and_die("bad server IP");
277 } 277 }
278 278
279 iface_list = make_iface_list(argv + 1, &num_sockets); 279 iface_list = make_iface_list(argv + 1, &num_sockets);
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c
index 64af802a3..6d4375237 100644
--- a/networking/udhcp/packet.c
+++ b/networking/udhcp/packet.c
@@ -85,14 +85,14 @@ int FAST_FUNC udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd)
85 memset(packet, 0, sizeof(*packet)); 85 memset(packet, 0, sizeof(*packet));
86 bytes = safe_read(fd, packet, sizeof(*packet)); 86 bytes = safe_read(fd, packet, sizeof(*packet));
87 if (bytes < 0) { 87 if (bytes < 0) {
88 log1("packet read error, ignoring"); 88 log1s("packet read error, ignoring");
89 return bytes; /* returns -1 */ 89 return bytes; /* returns -1 */
90 } 90 }
91 91
92 if (bytes < offsetof(struct dhcp_packet, options) 92 if (bytes < offsetof(struct dhcp_packet, options)
93 || packet->cookie != htonl(DHCP_MAGIC) 93 || packet->cookie != htonl(DHCP_MAGIC)
94 ) { 94 ) {
95 bb_info_msg("packet with bad magic, ignoring"); 95 bb_simple_info_msg("packet with bad magic, ignoring");
96 return -2; 96 return -2;
97 } 97 }
98 log1("received %s", "a packet"); 98 log1("received %s", "a packet");
diff --git a/networking/udhcp/signalpipe.c b/networking/udhcp/signalpipe.c
index 2ff78f0f2..7df671245 100644
--- a/networking/udhcp/signalpipe.c
+++ b/networking/udhcp/signalpipe.c
@@ -20,15 +20,15 @@
20 */ 20 */
21#include "common.h" 21#include "common.h"
22 22
23/* Global variable: we access it from signal handler */ 23#define READ_FD 3
24static struct fd_pair signal_pipe; 24#define WRITE_FD 4
25 25
26static void signal_handler(int sig) 26static void signal_handler(int sig)
27{ 27{
28 int sv = errno; 28 int sv = errno;
29 unsigned char ch = sig; /* use char, avoid dealing with partial writes */ 29 unsigned char ch = sig; /* use char, avoid dealing with partial writes */
30 if (write(signal_pipe.wr, &ch, 1) != 1) 30 if (write(WRITE_FD, &ch, 1) != 1)
31 bb_perror_msg("can't send signal"); 31 bb_simple_perror_msg("can't send signal");
32 errno = sv; 32 errno = sv;
33} 33}
34 34
@@ -36,12 +36,25 @@ static void signal_handler(int sig)
36 * and installs the signal handler */ 36 * and installs the signal handler */
37void FAST_FUNC udhcp_sp_setup(void) 37void FAST_FUNC udhcp_sp_setup(void)
38{ 38{
39 struct fd_pair signal_pipe;
40
41 /* All callers also want this, so... */
42 bb_sanitize_stdio();
43
39 /* was socketpair, but it needs AF_UNIX in kernel */ 44 /* was socketpair, but it needs AF_UNIX in kernel */
40 xpiped_pair(signal_pipe); 45 xpiped_pair(signal_pipe);
41 close_on_exec_on(signal_pipe.rd); 46
42 close_on_exec_on(signal_pipe.wr); 47 /* usually we get fds 3 and 4, but if we get higher ones... */
43 ndelay_on(signal_pipe.rd); 48 if (signal_pipe.rd != READ_FD)
44 ndelay_on(signal_pipe.wr); 49 xmove_fd(signal_pipe.rd, READ_FD);
50 if (signal_pipe.wr != WRITE_FD)
51 xmove_fd(signal_pipe.wr, WRITE_FD);
52
53 close_on_exec_on(READ_FD);
54 close_on_exec_on(WRITE_FD);
55 ndelay_on(READ_FD);
56 ndelay_on(WRITE_FD);
57
45 bb_signals(0 58 bb_signals(0
46 + (1 << SIGUSR1) 59 + (1 << SIGUSR1)
47 + (1 << SIGUSR2) 60 + (1 << SIGUSR2)
@@ -54,7 +67,7 @@ void FAST_FUNC udhcp_sp_setup(void)
54 */ 67 */
55void FAST_FUNC udhcp_sp_fd_set(struct pollfd pfds[2], int extra_fd) 68void FAST_FUNC udhcp_sp_fd_set(struct pollfd pfds[2], int extra_fd)
56{ 69{
57 pfds[0].fd = signal_pipe.rd; 70 pfds[0].fd = READ_FD;
58 pfds[0].events = POLLIN; 71 pfds[0].events = POLLIN;
59 pfds[1].fd = -1; 72 pfds[1].fd = -1;
60 if (extra_fd >= 0) { 73 if (extra_fd >= 0) {
@@ -74,7 +87,7 @@ int FAST_FUNC udhcp_sp_read(void)
74 unsigned char sig; 87 unsigned char sig;
75 88
76 /* Can't block here, fd is in nonblocking mode */ 89 /* Can't block here, fd is in nonblocking mode */
77 if (safe_read(signal_pipe.rd, &sig, 1) != 1) 90 if (safe_read(READ_FD, &sig, 1) != 1)
78 return 0; 91 return 0;
79 92
80 return sig; 93 return sig;
diff --git a/networking/udhcp/socket.c b/networking/udhcp/socket.c
index 34049c3ee..65a1a8ead 100644
--- a/networking/udhcp/socket.c
+++ b/networking/udhcp/socket.c
@@ -87,7 +87,7 @@ int FAST_FUNC udhcp_listen_socket(/*uint32_t ip,*/ int port, const char *inf)
87 87
88 setsockopt_reuseaddr(fd); 88 setsockopt_reuseaddr(fd);
89 if (setsockopt_broadcast(fd) == -1) 89 if (setsockopt_broadcast(fd) == -1)
90 bb_perror_msg_and_die("SO_BROADCAST"); 90 bb_simple_perror_msg_and_die("SO_BROADCAST");
91 91
92 /* SO_BINDTODEVICE doesn't work on ethernet aliases (ethN:M) */ 92 /* SO_BINDTODEVICE doesn't work on ethernet aliases (ethN:M) */
93 colon = strrchr(inf, ':'); 93 colon = strrchr(inf, ':');
diff --git a/networking/wget.c b/networking/wget.c
index 44cec2cb5..5b85cce1f 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -368,7 +368,7 @@ static void alarm_handler(int sig UNUSED_PARAM)
368{ 368{
369 /* This is theoretically unsafe (uses stdio and malloc in signal handler) */ 369 /* This is theoretically unsafe (uses stdio and malloc in signal handler) */
370 if (G.die_if_timed_out) 370 if (G.die_if_timed_out)
371 bb_error_msg_and_die("download timed out"); 371 bb_simple_error_msg_and_die("download timed out");
372} 372}
373static void set_alarm(void) 373static void set_alarm(void)
374{ 374{
@@ -452,7 +452,7 @@ static char fgets_trim_sanitize(FILE *fp, const char *fmt)
452 452
453 set_alarm(); 453 set_alarm();
454 if (fgets(G.wget_buf, sizeof(G.wget_buf), fp) == NULL) 454 if (fgets(G.wget_buf, sizeof(G.wget_buf), fp) == NULL)
455 bb_perror_msg_and_die("error getting response"); 455 bb_simple_perror_msg_and_die("error getting response");
456 clear_alarm(); 456 clear_alarm();
457 457
458 buf_ptr = strchrnul(G.wget_buf, '\n'); 458 buf_ptr = strchrnul(G.wget_buf, '\n');
@@ -639,7 +639,7 @@ static char *get_sanitized_hdr(FILE *fp)
639 639
640static void reset_beg_range_to_zero(void) 640static void reset_beg_range_to_zero(void)
641{ 641{
642 bb_error_msg("restart failed"); 642 bb_simple_error_msg("restart failed");
643 G.beg_range = 0; 643 G.beg_range = 0;
644 xlseek(G.output_fd, 0, SEEK_SET); 644 xlseek(G.output_fd, 0, SEEK_SET);
645 /* Done at the end instead: */ 645 /* Done at the end instead: */
@@ -657,7 +657,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port)
657 657
658 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) 658 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0)
659 /* Kernel can have AF_UNIX support disabled */ 659 /* Kernel can have AF_UNIX support disabled */
660 bb_perror_msg_and_die("socketpair"); 660 bb_simple_perror_msg_and_die("socketpair");
661 661
662 if (!strchr(host, ':')) 662 if (!strchr(host, ':'))
663 host = allocated = xasprintf("%s:%u", host, port); 663 host = allocated = xasprintf("%s:%u", host, port);
@@ -731,7 +731,7 @@ static void spawn_ssl_client(const char *host, int network_fd, int flags)
731 731
732 if (!(option_mask32 & WGET_OPT_NO_CHECK_CERT)) { 732 if (!(option_mask32 & WGET_OPT_NO_CHECK_CERT)) {
733 option_mask32 |= WGET_OPT_NO_CHECK_CERT; 733 option_mask32 |= WGET_OPT_NO_CHECK_CERT;
734 bb_error_msg("note: TLS certificate validation not implemented"); 734 bb_simple_error_msg("note: TLS certificate validation not implemented");
735 } 735 }
736 736
737 servername = xstrdup(host); 737 servername = xstrdup(host);
@@ -740,7 +740,7 @@ static void spawn_ssl_client(const char *host, int network_fd, int flags)
740 740
741 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) 741 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0)
742 /* Kernel can have AF_UNIX support disabled */ 742 /* Kernel can have AF_UNIX support disabled */
743 bb_perror_msg_and_die("socketpair"); 743 bb_simple_perror_msg_and_die("socketpair");
744 744
745 fflush_all(); 745 fflush_all();
746 pid = BB_MMU ? xfork() : xvfork(); 746 pid = BB_MMU ? xfork() : xvfork();
@@ -818,7 +818,7 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_
818#endif 818#endif
819 819
820 if (ftpcmd(NULL, NULL, sfp) != 220) 820 if (ftpcmd(NULL, NULL, sfp) != 220)
821 bb_error_msg_and_die("%s", G.wget_buf); 821 bb_simple_error_msg_and_die(G.wget_buf);
822 /* note: ftpcmd() sanitizes G.wget_buf, ok to print */ 822 /* note: ftpcmd() sanitizes G.wget_buf, ok to print */
823 823
824 /* Split username:password pair */ 824 /* Split username:password pair */
@@ -981,7 +981,7 @@ static void NOINLINE retrieve_file_data(FILE *dfp)
981 if (errno != EAGAIN) { 981 if (errno != EAGAIN) {
982 if (ferror(dfp)) { 982 if (ferror(dfp)) {
983 progress_meter(PROGRESS_END); 983 progress_meter(PROGRESS_END);
984 bb_perror_msg_and_die(bb_msg_read_error); 984 bb_simple_perror_msg_and_die(bb_msg_read_error);
985 } 985 }
986 break; /* EOF, not error */ 986 break; /* EOF, not error */
987 } 987 }
@@ -994,7 +994,7 @@ static void NOINLINE retrieve_file_data(FILE *dfp)
994# if ENABLE_FEATURE_WGET_TIMEOUT 994# if ENABLE_FEATURE_WGET_TIMEOUT
995 if (second_cnt != 0 && --second_cnt == 0) { 995 if (second_cnt != 0 && --second_cnt == 0) {
996 progress_meter(PROGRESS_END); 996 progress_meter(PROGRESS_END);
997 bb_error_msg_and_die("download timed out"); 997 bb_simple_error_msg_and_die("download timed out");
998 } 998 }
999# endif 999# endif
1000 /* We used to loop back to poll here, 1000 /* We used to loop back to poll here,
@@ -1047,7 +1047,7 @@ static void NOINLINE retrieve_file_data(FILE *dfp)
1047 G.got_clen = 1; /* makes it show 100% even for download of (formerly) unknown size */ 1047 G.got_clen = 1; /* makes it show 100% even for download of (formerly) unknown size */
1048 progress_meter(PROGRESS_END); 1048 progress_meter(PROGRESS_END);
1049 if (G.content_len != 0) { 1049 if (G.content_len != 0) {
1050 bb_perror_msg_and_die("connection closed prematurely"); 1050 bb_simple_perror_msg_and_die("connection closed prematurely");
1051 /* GNU wget says "DATE TIME (NN MB/s) - Connection closed at byte NNN. Retrying." */ 1051 /* GNU wget says "DATE TIME (NN MB/s) - Connection closed at byte NNN. Retrying." */
1052 } 1052 }
1053 1053
@@ -1381,7 +1381,7 @@ However, in real world it was observed that some web servers
1381 } 1381 }
1382 if (key == KEY_location && status >= 300) { 1382 if (key == KEY_location && status >= 300) {
1383 if (--redir_limit == 0) 1383 if (--redir_limit == 0)
1384 bb_error_msg_and_die("too many redirections"); 1384 bb_simple_error_msg_and_die("too many redirections");
1385 fclose(sfp); 1385 fclose(sfp);
1386 if (str[0] == '/') { 1386 if (str[0] == '/') {
1387 free(redirected_path); 1387 free(redirected_path);
diff --git a/networking/zcip.c b/networking/zcip.c
index f95b6f7fb..134dfb2df 100644
--- a/networking/zcip.c
+++ b/networking/zcip.c
@@ -276,7 +276,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
276 if (inet_aton(l_opt, &net) == 0 276 if (inet_aton(l_opt, &net) == 0
277 || (net.s_addr & htonl(IN_CLASSB_NET)) != net.s_addr 277 || (net.s_addr & htonl(IN_CLASSB_NET)) != net.s_addr
278 ) { 278 ) {
279 bb_error_msg_and_die("invalid network address"); 279 bb_simple_error_msg_and_die("invalid network address");
280 } 280 }
281 G.localnet_ip = ntohl(net.s_addr); 281 G.localnet_ip = ntohl(net.s_addr);
282 } 282 }
@@ -285,7 +285,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
285 if (inet_aton(r_opt, &ip) == 0 285 if (inet_aton(r_opt, &ip) == 0
286 || (ntohl(ip.s_addr) & IN_CLASSB_NET) != G.localnet_ip 286 || (ntohl(ip.s_addr) & IN_CLASSB_NET) != G.localnet_ip
287 ) { 287 ) {
288 bb_error_msg_and_die("invalid link address"); 288 bb_simple_error_msg_and_die("invalid link address");
289 } 289 }
290 chosen_nip = ip.s_addr; 290 chosen_nip = ip.s_addr;
291 } 291 }
@@ -473,7 +473,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
473 473
474 // Read ARP packet 474 // Read ARP packet
475 if (safe_read(sock_fd, &p, sizeof(p)) < 0) { 475 if (safe_read(sock_fd, &p, sizeof(p)) < 0) {
476 bb_perror_msg_and_die(bb_msg_read_error); 476 bb_simple_perror_msg_and_die(bb_msg_read_error);
477 } 477 }
478 478
479 if (p.eth.ether_type != htons(ETHERTYPE_ARP)) 479 if (p.eth.ether_type != htons(ETHERTYPE_ARP))
diff --git a/printutils/lpd.c b/printutils/lpd.c
index ce5944026..e48feef90 100644
--- a/printutils/lpd.c
+++ b/printutils/lpd.c
@@ -133,6 +133,8 @@ int lpd_main(int argc UNUSED_PARAM, char *argv[])
133 133
134 // read command 134 // read command
135 s = queue = xmalloc_read_stdin(); 135 s = queue = xmalloc_read_stdin();
136 if (!s) // eof?
137 return EXIT_FAILURE;
136 // we understand only "receive job" command 138 // we understand only "receive job" command
137 if (2 != *queue) { 139 if (2 != *queue) {
138 unsupported_cmd: 140 unsupported_cmd:
@@ -204,7 +206,7 @@ int lpd_main(int argc UNUSED_PARAM, char *argv[])
204 } 206 }
205 207
206 // validate input. 208 // validate input.
207 // we understand only "control file" or "data file" cmds 209 // we understand only "control file" or "data file" subcmds
208 if (2 != s[0] && 3 != s[0]) 210 if (2 != s[0] && 3 != s[0])
209 goto unsupported_cmd; 211 goto unsupported_cmd;
210 if (spooling & (1 << (s[0]-1))) { 212 if (spooling & (1 << (s[0]-1))) {
@@ -291,7 +293,7 @@ int lpd_main(int argc UNUSED_PARAM, char *argv[])
291 err_exit: 293 err_exit:
292 // don't keep corrupted files 294 // don't keep corrupted files
293 if (spooling) { 295 if (spooling) {
294#define i spooling 296 int i;
295 for (i = 2; --i >= 0; ) 297 for (i = 2; --i >= 0; )
296 if (filenames[i]) 298 if (filenames[i])
297 unlink(filenames[i]); 299 unlink(filenames[i]);
diff --git a/printutils/lpr.c b/printutils/lpr.c
index 7acb6c357..77d1a79a4 100644
--- a/printutils/lpr.c
+++ b/printutils/lpr.c
@@ -167,7 +167,7 @@ int lpqr_main(int argc UNUSED_PARAM, char *argv[])
167 // LPR ------------------------ 167 // LPR ------------------------
168 // 168 //
169 if (opts & LPR_V) 169 if (opts & LPR_V)
170 bb_error_msg("connected to server"); 170 bb_simple_error_msg("connected to server");
171 171
172 job = getpid() % 1000; 172 job = getpid() % 1000;
173 hostname = safe_gethostname(); 173 hostname = safe_gethostname();
@@ -206,7 +206,7 @@ int lpqr_main(int argc UNUSED_PARAM, char *argv[])
206 * Standard lpr works around it by refusing to send such jobs: 206 * Standard lpr works around it by refusing to send such jobs:
207 */ 207 */
208 if (st.st_size == 0) { 208 if (st.st_size == 0) {
209 bb_error_msg("nothing to print"); 209 bb_simple_error_msg("nothing to print");
210 continue; 210 continue;
211 } 211 }
212 212
@@ -246,7 +246,7 @@ int lpqr_main(int argc UNUSED_PARAM, char *argv[])
246 246
247 // send control file 247 // send control file
248 if (opts & LPR_V) 248 if (opts & LPR_V)
249 bb_error_msg("sending control file"); 249 bb_simple_error_msg("sending control file");
250 /* "Acknowledgement processing must occur as usual 250 /* "Acknowledgement processing must occur as usual
251 * after the command is sent." */ 251 * after the command is sent." */
252 cflen = (unsigned)strlen(controlfile); 252 cflen = (unsigned)strlen(controlfile);
@@ -262,12 +262,12 @@ int lpqr_main(int argc UNUSED_PARAM, char *argv[])
262 262
263 // send data file, with name "dfaXXX" 263 // send data file, with name "dfaXXX"
264 if (opts & LPR_V) 264 if (opts & LPR_V)
265 bb_error_msg("sending data file"); 265 bb_simple_error_msg("sending data file");
266 fdprintf(fd, "\x3" "%"OFF_FMT"u d%s\n", st.st_size, remote_filename); 266 fdprintf(fd, "\x3" "%"OFF_FMT"u d%s\n", st.st_size, remote_filename);
267 get_response_or_say_and_die(fd, "sending data file"); 267 get_response_or_say_and_die(fd, "sending data file");
268 if (bb_copyfd_size(dfd, fd, st.st_size) != st.st_size) { 268 if (bb_copyfd_size(dfd, fd, st.st_size) != st.st_size) {
269 // We're screwed. We sent less bytes than we advertised. 269 // We're screwed. We sent less bytes than we advertised.
270 bb_error_msg_and_die("local file changed size?!"); 270 bb_simple_error_msg_and_die("local file changed size?!");
271 } 271 }
272 write(fd, "", 1); // send ACK 272 write(fd, "", 1); // send ACK
273 get_response_or_say_and_die(fd, "sending data file"); 273 get_response_or_say_and_die(fd, "sending data file");
@@ -283,7 +283,7 @@ int lpqr_main(int argc UNUSED_PARAM, char *argv[])
283 283
284 // say job accepted 284 // say job accepted
285 if (opts & LPR_V) 285 if (opts & LPR_V)
286 bb_error_msg("job accepted"); 286 bb_simple_error_msg("job accepted");
287 287
288 // next, please! 288 // next, please!
289 job = (job + 1) % 1000; 289 job = (job + 1) % 1000;
diff --git a/procps/free.c b/procps/free.c
index 3acfc4072..1e5d36742 100644
--- a/procps/free.c
+++ b/procps/free.c
@@ -44,6 +44,7 @@ struct globals {
44#else 44#else
45# define G_unit_steps 10 45# define G_unit_steps 10
46#endif 46#endif
47 unsigned long cached_kb, available_kb, reclaimable_kb;
47}; 48};
48/* Because of NOFORK, "globals" are not in global data */ 49/* Because of NOFORK, "globals" are not in global data */
49 50
@@ -53,27 +54,30 @@ static unsigned long long scale(struct globals *g, unsigned long d)
53} 54}
54 55
55/* NOINLINE reduces main() stack usage, which makes code smaller (on x86 at least) */ 56/* NOINLINE reduces main() stack usage, which makes code smaller (on x86 at least) */
56static NOINLINE unsigned int parse_meminfo(unsigned long *cached_kb, unsigned long *available_kb) 57static NOINLINE unsigned int parse_meminfo(struct globals *g)
57{ 58{
58 char buf[60]; /* actual lines we expect are ~30 chars or less */ 59 char buf[60]; /* actual lines we expect are ~30 chars or less */
59 FILE *fp; 60 FILE *fp;
60 int seen_cached_and_available; 61 int seen_cached_and_available_and_reclaimable;
61 62
62 fp = xfopen_for_read("/proc/meminfo"); 63 fp = xfopen_for_read("/proc/meminfo");
63 *cached_kb = *available_kb = 0; 64 g->cached_kb = g->available_kb = g->reclaimable_kb = 0;
64 seen_cached_and_available = 2; 65 seen_cached_and_available_and_reclaimable = 3;
65 while (fgets(buf, sizeof(buf), fp)) { 66 while (fgets(buf, sizeof(buf), fp)) {
66 if (sscanf(buf, "Cached: %lu %*s\n", cached_kb) == 1) 67 if (sscanf(buf, "Cached: %lu %*s\n", &g->cached_kb) == 1)
67 if (--seen_cached_and_available == 0) 68 if (--seen_cached_and_available_and_reclaimable == 0)
68 break; 69 break;
69 if (sscanf(buf, "MemAvailable: %lu %*s\n", available_kb) == 1) 70 if (sscanf(buf, "MemAvailable: %lu %*s\n", &g->available_kb) == 1)
70 if (--seen_cached_and_available == 0) 71 if (--seen_cached_and_available_and_reclaimable == 0)
72 break;
73 if (sscanf(buf, "SReclaimable: %lu %*s\n", &g->reclaimable_kb) == 1)
74 if (--seen_cached_and_available_and_reclaimable == 0)
71 break; 75 break;
72 } 76 }
73 /* Have to close because of NOFORK */ 77 /* Have to close because of NOFORK */
74 fclose(fp); 78 fclose(fp);
75 79
76 return seen_cached_and_available == 0; 80 return seen_cached_and_available_and_reclaimable == 0;
77} 81}
78 82
79int free_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 83int free_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
@@ -82,7 +86,6 @@ int free_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM))
82 struct globals G; 86 struct globals G;
83 struct sysinfo info; 87 struct sysinfo info;
84 unsigned long long cached, cached_plus_free, available; 88 unsigned long long cached, cached_plus_free, available;
85 unsigned long cached_kb, available_kb;
86 int seen_available; 89 int seen_available;
87 90
88#if ENABLE_DESKTOP 91#if ENABLE_DESKTOP
@@ -118,10 +121,11 @@ int free_main(int argc UNUSED_PARAM, char **argv IF_NOT_DESKTOP(UNUSED_PARAM))
118 /* Kernels prior to 2.4.x will return info.mem_unit==0, so cope... */ 121 /* Kernels prior to 2.4.x will return info.mem_unit==0, so cope... */
119 G.mem_unit = (info.mem_unit ? info.mem_unit : 1); 122 G.mem_unit = (info.mem_unit ? info.mem_unit : 1);
120 /* Extract cached and memavailable from /proc/meminfo and convert to mem_units */ 123 /* Extract cached and memavailable from /proc/meminfo and convert to mem_units */
121 seen_available = parse_meminfo(&cached_kb, &available_kb); 124 seen_available = parse_meminfo(&G);
122 available = ((unsigned long long) available_kb * 1024) / G.mem_unit; 125 available = ((unsigned long long) G.available_kb * 1024) / G.mem_unit;
123 cached = ((unsigned long long) cached_kb * 1024) / G.mem_unit; 126 cached = ((unsigned long long) G.cached_kb * 1024) / G.mem_unit;
124 cached += info.bufferram; 127 cached += info.bufferram;
128 cached += ((unsigned long long) G.reclaimable_kb * 1024) / G.mem_unit;
125 cached_plus_free = cached + info.freeram; 129 cached_plus_free = cached + info.freeram;
126 130
127#define FIELDS_6 "%12llu %11llu %11llu %11llu %11llu %11llu\n" 131#define FIELDS_6 "%12llu %11llu %11llu %11llu %11llu %11llu\n"
diff --git a/procps/kill.c b/procps/kill.c
index 073e74332..358d8f42b 100644
--- a/procps/kill.c
+++ b/procps/kill.c
@@ -270,7 +270,7 @@ int kill_main(int argc UNUSED_PARAM, char **argv)
270#if ENABLE_KILL || ENABLE_KILLALL 270#if ENABLE_KILL || ENABLE_KILLALL
271 /* Pid or name is required for kill/killall */ 271 /* Pid or name is required for kill/killall */
272 if (!arg) { 272 if (!arg) {
273 bb_error_msg("you need to specify whom to kill"); 273 bb_simple_error_msg("you need to specify whom to kill");
274 return EXIT_FAILURE; 274 return EXIT_FAILURE;
275 } 275 }
276 276
diff --git a/procps/mpstat.c b/procps/mpstat.c
index e7dc4312a..3e07edc5c 100644
--- a/procps/mpstat.c
+++ b/procps/mpstat.c
@@ -931,7 +931,7 @@ int mpstat_main(int argc UNUSED_PARAM, char **argv)
931 /* Get CPU number */ 931 /* Get CPU number */
932 unsigned n = xatoi_positive(t); 932 unsigned n = xatoi_positive(t);
933 if (n >= G.cpu_nr) 933 if (n >= G.cpu_nr)
934 bb_error_msg_and_die("not that many processors"); 934 bb_simple_error_msg_and_die("not that many processors");
935 n++; 935 n++;
936 G.cpu_bitmap[n >> 3] |= 1 << (n & 7); 936 G.cpu_bitmap[n >> 3] |= 1 << (n & 7);
937 } 937 }
diff --git a/procps/nmeter.c b/procps/nmeter.c
index a01d19a6a..f0eb36740 100644
--- a/procps/nmeter.c
+++ b/procps/nmeter.c
@@ -351,7 +351,7 @@ static s_stat* init_cr(const char *param UNUSED_PARAM)
351enum { CPU_FIELDCNT = 7 }; 351enum { CPU_FIELDCNT = 7 };
352S_STAT(cpu_stat) 352S_STAT(cpu_stat)
353 ullong old[CPU_FIELDCNT]; 353 ullong old[CPU_FIELDCNT];
354 int bar_sz; 354 unsigned bar_sz;
355 char bar[1]; 355 char bar[1];
356S_STAT_END(cpu_stat) 356S_STAT_END(cpu_stat)
357 357
@@ -360,8 +360,8 @@ static void FAST_FUNC collect_cpu(cpu_stat *s)
360 ullong data[CPU_FIELDCNT] = { 0, 0, 0, 0, 0, 0, 0 }; 360 ullong data[CPU_FIELDCNT] = { 0, 0, 0, 0, 0, 0, 0 };
361 unsigned frac[CPU_FIELDCNT] = { 0, 0, 0, 0, 0, 0, 0 }; 361 unsigned frac[CPU_FIELDCNT] = { 0, 0, 0, 0, 0, 0, 0 };
362 ullong all = 0; 362 ullong all = 0;
363 int norm_all = 0; 363 unsigned norm_all = 0;
364 int bar_sz = s->bar_sz; 364 unsigned bar_sz = s->bar_sz;
365 char *bar = s->bar; 365 char *bar = s->bar;
366 int i; 366 int i;
367 367
@@ -420,8 +420,8 @@ static s_stat* init_cpu(const char *param)
420{ 420{
421 int sz; 421 int sz;
422 cpu_stat *s; 422 cpu_stat *s;
423 sz = strtoul(param, NULL, 0); /* param can be "" */ 423 sz = param[0] ? strtoul(param, NULL, 0) : 10;
424 if (sz < 10) sz = 10; 424 if (sz <= 0) sz = 1;
425 if (sz > 1000) sz = 1000; 425 if (sz > 1000) sz = 1000;
426 s = xzalloc(sizeof(*s) + sz); 426 s = xzalloc(sizeof(*s) + sz);
427 /*s->bar[sz] = '\0'; - xzalloc did it */ 427 /*s->bar[sz] = '\0'; - xzalloc did it */
diff --git a/procps/powertop.c b/procps/powertop.c
index e70f5433b..d508b5f78 100644
--- a/procps/powertop.c
+++ b/procps/powertop.c
@@ -657,7 +657,7 @@ static void show_timerstats(void)
657 } 657 }
658 } else { 658 } else {
659 bb_putchar('\n'); 659 bb_putchar('\n');
660 bb_error_msg("no stats available; run as root or" 660 bb_simple_error_msg("no stats available; run as root or"
661 " enable the timer_stats module"); 661 " enable the timer_stats module");
662 } 662 }
663} 663}
@@ -707,7 +707,7 @@ int powertop_main(int argc UNUSED_PARAM, char UNUSED_PARAM **argv)
707 707
708 /* Print warning when we don't have superuser privileges */ 708 /* Print warning when we don't have superuser privileges */
709 if (geteuid() != 0) 709 if (geteuid() != 0)
710 bb_error_msg("run as root to collect enough information"); 710 bb_simple_error_msg("run as root to collect enough information");
711 711
712 /* Get number of CPUs */ 712 /* Get number of CPUs */
713 G.total_cpus = get_cpu_count(); 713 G.total_cpus = get_cpu_count();
diff --git a/procps/pstree.c b/procps/pstree.c
index 1d124d2d2..67b711168 100644
--- a/procps/pstree.c
+++ b/procps/pstree.c
@@ -404,7 +404,7 @@ int pstree_main(int argc UNUSED_PARAM, char **argv)
404 else { 404 else {
405 dump_by_user(find_proc(1), uid); 405 dump_by_user(find_proc(1), uid);
406 if (!G.dumped) { 406 if (!G.dumped) {
407 bb_error_msg_and_die("no processes found"); 407 bb_simple_error_msg_and_die("no processes found");
408 } 408 }
409 } 409 }
410 410
diff --git a/procps/top.c b/procps/top.c
index 89f9d23f4..5c41e8e10 100644
--- a/procps/top.c
+++ b/procps/top.c
@@ -979,6 +979,9 @@ static unsigned handle_input(unsigned scan_mask, duration_t interval)
979 IF_FEATURE_TOPMEM(&& scan_mask != TOPMEM_MASK) 979 IF_FEATURE_TOPMEM(&& scan_mask != TOPMEM_MASK)
980 ) { 980 ) {
981 scan_mask ^= PSSCAN_TASKS; 981 scan_mask ^= PSSCAN_TASKS;
982 free(prev_hist);
983 prev_hist = NULL;
984 prev_hist_count = 0;
982 continue; 985 continue;
983 } 986 }
984# endif 987# endif
@@ -1000,10 +1003,10 @@ static unsigned handle_input(unsigned scan_mask, duration_t interval)
1000# if ENABLE_FEATURE_TOPMEM 1003# if ENABLE_FEATURE_TOPMEM
1001 if (c == 's') { 1004 if (c == 's') {
1002 scan_mask = TOPMEM_MASK; 1005 scan_mask = TOPMEM_MASK;
1006 sort_field = (sort_field + 1) % NUM_SORT_FIELD;
1003 free(prev_hist); 1007 free(prev_hist);
1004 prev_hist = NULL; 1008 prev_hist = NULL;
1005 prev_hist_count = 0; 1009 prev_hist_count = 0;
1006 sort_field = (sort_field + 1) % NUM_SORT_FIELD;
1007 continue; 1010 continue;
1008 } 1011 }
1009# endif 1012# endif
@@ -1229,7 +1232,7 @@ int top_main(int argc UNUSED_PARAM, char **argv)
1229#endif 1232#endif
1230 } /* end of "while we read /proc" */ 1233 } /* end of "while we read /proc" */
1231 if (ntop == 0) { 1234 if (ntop == 0) {
1232 bb_error_msg("no process info in /proc"); 1235 bb_simple_error_msg("no process info in /proc");
1233 break; 1236 break;
1234 } 1237 }
1235 1238
diff --git a/runit/chpst.c b/runit/chpst.c
index 5e77245f6..af777568f 100644
--- a/runit/chpst.c
+++ b/runit/chpst.c
@@ -270,7 +270,7 @@ static void limit(int what, long l)
270 else 270 else
271 r.rlim_cur = l; 271 r.rlim_cur = l;
272 if (setrlimit(what, &r) == -1) 272 if (setrlimit(what, &r) == -1)
273 bb_perror_msg_and_die("setrlimit"); 273 bb_simple_perror_msg_and_die("setrlimit");
274} 274}
275 275
276int chpst_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 276int chpst_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
@@ -467,12 +467,12 @@ int chpst_main(int argc UNUSED_PARAM, char **argv)
467 if (opt & OPT_n) { 467 if (opt & OPT_n) {
468 errno = 0; 468 errno = 0;
469 if (nice(xatoi(nicestr)) == -1) 469 if (nice(xatoi(nicestr)) == -1)
470 bb_perror_msg_and_die("nice"); 470 bb_simple_perror_msg_and_die("nice");
471 } 471 }
472 472
473 if (opt & OPT_u) { 473 if (opt & OPT_u) {
474 if (setgroups(1, &ugid.gid) == -1) 474 if (setgroups(1, &ugid.gid) == -1)
475 bb_perror_msg_and_die("setgroups"); 475 bb_simple_perror_msg_and_die("setgroups");
476 xsetgid(ugid.gid); 476 xsetgid(ugid.gid);
477 xsetuid(ugid.uid); 477 xsetuid(ugid.uid);
478 } 478 }
diff --git a/runit/svlogd.c b/runit/svlogd.c
index c9e5346d1..a250058a1 100644
--- a/runit/svlogd.c
+++ b/runit/svlogd.c
@@ -274,7 +274,7 @@ static void warnx(const char *m0, const char *m1)
274} 274}
275static void pause_nomem(void) 275static void pause_nomem(void)
276{ 276{
277 bb_error_msg(PAUSE"out of memory"); 277 bb_simple_error_msg(PAUSE"out of memory");
278 sleep(3); 278 sleep(3);
279} 279}
280static void pause1cannot(const char *m0) 280static void pause1cannot(const char *m0)
diff --git a/selinux/chcon.c b/selinux/chcon.c
index 5bf91710c..afe7f713d 100644
--- a/selinux/chcon.c
+++ b/selinux/chcon.c
@@ -107,7 +107,7 @@ static int FAST_FUNC change_filedir_context(
107 107
108 context_string = context_str(context); 108 context_string = context_str(context);
109 if (!context_string) { 109 if (!context_string) {
110 bb_error_msg("can't obtain security context in text expression"); 110 bb_simple_error_msg("can't obtain security context in text expression");
111 goto skip; 111 goto skip;
112 } 112 }
113 113
@@ -194,7 +194,7 @@ int chcon_main(int argc UNUSED_PARAM, char **argv)
194 /* specified_context is never NULL - 194 /* specified_context is never NULL -
195 * "-1" in opt_complementary prevents this. */ 195 * "-1" in opt_complementary prevents this. */
196 if (!argv[0]) 196 if (!argv[0])
197 bb_error_msg_and_die("too few arguments"); 197 bb_simple_error_msg_and_die("too few arguments");
198 } 198 }
199 199
200 for (i = 0; (fname = argv[i]) != NULL; i++) { 200 for (i = 0; (fname = argv[i]) != NULL; i++) {
diff --git a/selinux/getenforce.c b/selinux/getenforce.c
index 0286dd0be..f082ba614 100644
--- a/selinux/getenforce.c
+++ b/selinux/getenforce.c
@@ -29,12 +29,12 @@ int getenforce_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
29 29
30 rc = is_selinux_enabled(); 30 rc = is_selinux_enabled();
31 if (rc < 0) 31 if (rc < 0)
32 bb_error_msg_and_die("is_selinux_enabled() failed"); 32 bb_simple_error_msg_and_die("is_selinux_enabled() failed");
33 33
34 if (rc == 1) { 34 if (rc == 1) {
35 rc = security_getenforce(); 35 rc = security_getenforce();
36 if (rc < 0) 36 if (rc < 0)
37 bb_error_msg_and_die("getenforce() failed"); 37 bb_simple_error_msg_and_die("getenforce() failed");
38 38
39 if (rc) 39 if (rc)
40 puts("Enforcing"); 40 puts("Enforcing");
diff --git a/selinux/getsebool.c b/selinux/getsebool.c
index 6d7805c8d..36ddd45b9 100644
--- a/selinux/getsebool.c
+++ b/selinux/getsebool.c
@@ -40,7 +40,7 @@ int getsebool_main(int argc, char **argv)
40 40
41 rc = security_get_boolean_names(&names, &len); 41 rc = security_get_boolean_names(&names, &len);
42 if (rc) 42 if (rc)
43 bb_perror_msg_and_die("can't get boolean names"); 43 bb_simple_perror_msg_and_die("can't get boolean names");
44 44
45 if (!len) { 45 if (!len) {
46 puts("No booleans"); 46 puts("No booleans");
diff --git a/selinux/load_policy.c b/selinux/load_policy.c
index b7930839c..eac6ba6c1 100644
--- a/selinux/load_policy.c
+++ b/selinux/load_policy.c
@@ -31,7 +31,7 @@ int load_policy_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
31 31
32 rc = selinux_mkload_policy(1); 32 rc = selinux_mkload_policy(1);
33 if (rc < 0) { 33 if (rc < 0) {
34 bb_perror_msg_and_die("can't load policy"); 34 bb_simple_perror_msg_and_die("can't load policy");
35 } 35 }
36 36
37 return 0; 37 return 0;
diff --git a/selinux/runcon.c b/selinux/runcon.c
index a5a394427..bc4fa23e0 100644
--- a/selinux/runcon.c
+++ b/selinux/runcon.c
@@ -65,7 +65,7 @@ static context_t runcon_compute_new_context(char *user, char *role, char *type,
65 security_context_t cur_context; 65 security_context_t cur_context;
66 66
67 if (getcon(&cur_context)) 67 if (getcon(&cur_context))
68 bb_error_msg_and_die("can't get current context"); 68 bb_simple_error_msg_and_die("can't get current context");
69 69
70 if (compute_trans) { 70 if (compute_trans) {
71 security_context_t file_context, new_context; 71 security_context_t file_context, new_context;
@@ -75,7 +75,7 @@ static context_t runcon_compute_new_context(char *user, char *role, char *type,
75 command); 75 command);
76 if (security_compute_create(cur_context, file_context, 76 if (security_compute_create(cur_context, file_context,
77 SECCLASS_PROCESS, &new_context)) 77 SECCLASS_PROCESS, &new_context))
78 bb_error_msg_and_die("unable to compute a new context"); 78 bb_simple_error_msg_and_die("unable to compute a new context");
79 cur_context = new_context; 79 cur_context = new_context;
80 } 80 }
81 81
@@ -137,7 +137,7 @@ int runcon_main(int argc UNUSED_PARAM, char **argv)
137 if (!(opts & OPTS_CONTEXT_COMPONENT)) { 137 if (!(opts & OPTS_CONTEXT_COMPONENT)) {
138 context = *argv++; 138 context = *argv++;
139 if (!argv[0]) 139 if (!argv[0])
140 bb_error_msg_and_die("no command given"); 140 bb_simple_error_msg_and_die("no command given");
141 } 141 }
142 142
143 if (context) { 143 if (context) {
diff --git a/selinux/sestatus.c b/selinux/sestatus.c
index 6954aca70..098a4d189 100644
--- a/selinux/sestatus.c
+++ b/selinux/sestatus.c
@@ -216,5 +216,5 @@ int sestatus_main(int argc UNUSED_PARAM, char **argv)
216 return 0; 216 return 0;
217 217
218 error: 218 error:
219 bb_perror_msg_and_die("libselinux returns unknown state"); 219 bb_simple_perror_msg_and_die("libselinux returns unknown state");
220} 220}
diff --git a/selinux/setenforce.c b/selinux/setenforce.c
index c28de6ec5..996034f8e 100644
--- a/selinux/setenforce.c
+++ b/selinux/setenforce.c
@@ -49,7 +49,7 @@ int setenforce_main(int argc UNUSED_PARAM, char **argv)
49 continue; 49 continue;
50 rc = security_setenforce(i & 1); 50 rc = security_setenforce(i & 1);
51 if (rc < 0) 51 if (rc < 0)
52 bb_perror_msg_and_die("setenforce() failed"); 52 bb_simple_perror_msg_and_die("setenforce() failed");
53 return 0; 53 return 0;
54 } 54 }
55 55
diff --git a/selinux/setfiles.c b/selinux/setfiles.c
index 740eaf8fb..55bfb4d02 100644
--- a/selinux/setfiles.c
+++ b/selinux/setfiles.c
@@ -182,7 +182,7 @@ static void inc_err(void)
182{ 182{
183 nerr++; 183 nerr++;
184 if (nerr > 9 && !FLAG_d_debug) { 184 if (nerr > 9 && !FLAG_d_debug) {
185 bb_error_msg_and_die("exiting after 10 errors"); 185 bb_simple_error_msg_and_die("exiting after 10 errors");
186 } 186 }
187} 187}
188 188
diff --git a/selinux/setsebool.c b/selinux/setsebool.c
index 579118172..2af23acd7 100644
--- a/selinux/setsebool.c
+++ b/selinux/setsebool.c
@@ -46,7 +46,7 @@ int setsebool_main(int argc, char **argv)
46 } 46 }
47 47
48 if (security_set_boolean(argv[1], value) < 0) 48 if (security_set_boolean(argv[1], value) < 0)
49 bb_error_msg_and_die("can't set boolean"); 49 bb_simple_error_msg_and_die("can't set boolean");
50 50
51 return 0; 51 return 0;
52} 52}
diff --git a/shell/ash.c b/shell/ash.c
index b82c51029..690485a83 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -416,10 +416,18 @@ static const char *const optletters_optnames[] = {
416 "e" "errexit", 416 "e" "errexit",
417 "f" "noglob", 417 "f" "noglob",
418 "I" "ignoreeof", 418 "I" "ignoreeof",
419 "i" "interactive", 419/* The below allowed this invocation:
420 * ash -c 'set -i; echo $-; sleep 5; echo $-'
421 * to be ^C-ed and get to interactive ash prompt.
422 * bash does not support such "set -i".
423 * In our code, this is denoted by empty long name:
424 */
425 "i" "",
420 "m" "monitor", 426 "m" "monitor",
421 "n" "noexec", 427 "n" "noexec",
422 "s" "stdin", 428/* Ditto: bash has no "set -s" */
429 "s" "",
430 "c" "",
423 "x" "xtrace", 431 "x" "xtrace",
424 "v" "verbose", 432 "v" "verbose",
425 "C" "noclobber", 433 "C" "noclobber",
@@ -444,6 +452,20 @@ static const char *const optletters_optnames[] = {
444 ,"\0" "nocaseglob" 452 ,"\0" "nocaseglob"
445#endif 453#endif
446}; 454};
455//bash 4.4.23 also has these opts (with these defaults):
456//braceexpand on
457//emacs on
458//errtrace off
459//functrace off
460//hashall on
461//histexpand off
462//history on
463//interactive-comments on
464//keyword off
465//onecmd off
466//physical off
467//posix off
468//privileged off
447 469
448#define optletters(n) optletters_optnames[n][0] 470#define optletters(n) optletters_optnames[n][0]
449#define optnames(n) (optletters_optnames[n] + 1) 471#define optnames(n) (optletters_optnames[n] + 1)
@@ -517,21 +539,22 @@ struct globals_misc {
517#define mflag optlist[4] 539#define mflag optlist[4]
518#define nflag optlist[5] 540#define nflag optlist[5]
519#define sflag optlist[6] 541#define sflag optlist[6]
520#define xflag optlist[7] 542#define cflag optlist[7]
521#define vflag optlist[8] 543#define xflag optlist[8]
522#define Cflag optlist[9] 544#define vflag optlist[9]
523#define aflag optlist[10] 545#define Cflag optlist[10]
524#define bflag optlist[11] 546#define aflag optlist[11]
525#define uflag optlist[12] 547#define bflag optlist[12]
526#define viflag optlist[13] 548#define uflag optlist[13]
549#define viflag optlist[14]
527#if BASH_PIPEFAIL 550#if BASH_PIPEFAIL
528# define pipefail optlist[14] 551# define pipefail optlist[15]
529#else 552#else
530# define pipefail 0 553# define pipefail 0
531#endif 554#endif
532#if DEBUG 555#if DEBUG
533# define nolog optlist[14 + BASH_PIPEFAIL] 556# define nolog optlist[15 + BASH_PIPEFAIL]
534# define debug optlist[15 + BASH_PIPEFAIL] 557# define debug optlist[16 + BASH_PIPEFAIL]
535#endif 558#endif
536#if ENABLE_PLATFORM_MINGW32 559#if ENABLE_PLATFORM_MINGW32
537# define winxp optlist[14 + BASH_PIPEFAIL + 2*DEBUG] 560# define winxp optlist[14 + BASH_PIPEFAIL + 2*DEBUG]
@@ -10156,8 +10179,8 @@ setinteractive(int on)
10156 setsignal(SIGINT); 10179 setsignal(SIGINT);
10157 setsignal(SIGQUIT); 10180 setsignal(SIGQUIT);
10158 setsignal(SIGTERM); 10181 setsignal(SIGTERM);
10159#if !ENABLE_FEATURE_SH_EXTRA_QUIET
10160 if (is_interactive > 1) { 10182 if (is_interactive > 1) {
10183#if !ENABLE_FEATURE_SH_EXTRA_QUIET
10161 /* Looks like they want an interactive shell */ 10184 /* Looks like they want an interactive shell */
10162 static smallint did_banner; 10185 static smallint did_banner;
10163 10186
@@ -10171,8 +10194,12 @@ setinteractive(int on)
10171 ); 10194 );
10172 did_banner = 1; 10195 did_banner = 1;
10173 } 10196 }
10174 }
10175#endif 10197#endif
10198#if ENABLE_FEATURE_EDITING
10199 if (!line_input_state)
10200 line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
10201#endif
10202 }
10176} 10203}
10177 10204
10178static void 10205static void
@@ -10184,10 +10211,12 @@ optschanged(void)
10184 setinteractive(iflag); 10211 setinteractive(iflag);
10185 setjobctl(mflag); 10212 setjobctl(mflag);
10186#if ENABLE_FEATURE_EDITING_VI 10213#if ENABLE_FEATURE_EDITING_VI
10187 if (viflag) 10214 if (line_input_state) {
10188 line_input_state->flags |= VI_MODE; 10215 if (viflag)
10189 else 10216 line_input_state->flags |= VI_MODE;
10190 line_input_state->flags &= ~VI_MODE; 10217 else
10218 line_input_state->flags &= ~VI_MODE;
10219 }
10191#else 10220#else
10192 viflag = 0; /* forcibly keep the option off */ 10221 viflag = 0; /* forcibly keep the option off */
10193#endif 10222#endif
@@ -11203,13 +11232,11 @@ preadfd(void)
11203 else { 11232 else {
11204# if ENABLE_ASH_IDLE_TIMEOUT 11233# if ENABLE_ASH_IDLE_TIMEOUT
11205 int timeout = -1; 11234 int timeout = -1;
11206 if (iflag) { 11235 const char *tmout_var = lookupvar("TMOUT");
11207 const char *tmout_var = lookupvar("TMOUT"); 11236 if (tmout_var) {
11208 if (tmout_var) { 11237 timeout = atoi(tmout_var) * 1000;
11209 timeout = atoi(tmout_var) * 1000; 11238 if (timeout <= 0)
11210 if (timeout <= 0) 11239 timeout = -1;
11211 timeout = -1;
11212 }
11213 } 11240 }
11214 line_input_state->timeout = timeout; 11241 line_input_state->timeout = timeout;
11215# endif 11242# endif
@@ -11750,6 +11777,8 @@ plus_minus_o(char *name, int val)
11750 return 1; 11777 return 1;
11751 } 11778 }
11752 for (i = 0; i < NOPTS; i++) { 11779 for (i = 0; i < NOPTS; i++) {
11780 if (optnames(i)[0] == '\0')
11781 continue;
11753 if (val) { 11782 if (val) {
11754 out1fmt("%-16s%s\n", optnames(i), optlist[i] ? "on" : "off"); 11783 out1fmt("%-16s%s\n", optnames(i), optlist[i] ? "on" : "off");
11755 } else { 11784 } else {
@@ -11764,7 +11793,7 @@ setoption(int flag, int val)
11764 int i; 11793 int i;
11765 11794
11766 for (i = 0; i < NOPTS; i++) { 11795 for (i = 0; i < NOPTS; i++) {
11767 if (optletters(i) == flag) { 11796 if (optletters(i) == flag && optnames(i)[0] != '\0') {
11768 optlist[i] = val; 11797 optlist[i] = val;
11769 return; 11798 return;
11770 } 11799 }
@@ -11772,14 +11801,17 @@ setoption(int flag, int val)
11772 ash_msg_and_raise_error("illegal option %c%c", val ? '-' : '+', flag); 11801 ash_msg_and_raise_error("illegal option %c%c", val ? '-' : '+', flag);
11773 /* NOTREACHED */ 11802 /* NOTREACHED */
11774} 11803}
11804/* If login_sh is not NULL, we are called to parse command line opts,
11805 * not "set -opts"
11806 */
11775static int 11807static int
11776options(int cmdline, int *login_sh) 11808options(int *login_sh)
11777{ 11809{
11778 char *p; 11810 char *p;
11779 int val; 11811 int val;
11780 int c; 11812 int c;
11781 11813
11782 if (cmdline) { 11814 if (login_sh) {
11783 minusc = NULL; 11815 minusc = NULL;
11784#if ENABLE_PLATFORM_MINGW32 11816#if ENABLE_PLATFORM_MINGW32
11785 dirarg = NULL; 11817 dirarg = NULL;
@@ -11795,7 +11827,7 @@ options(int cmdline, int *login_sh)
11795 if (c == '-') { 11827 if (c == '-') {
11796 val = 1; 11828 val = 1;
11797 if (p[0] == '\0' || LONE_DASH(p)) { 11829 if (p[0] == '\0' || LONE_DASH(p)) {
11798 if (!cmdline) { 11830 if (!login_sh) {
11799 /* "-" means turn off -x and -v */ 11831 /* "-" means turn off -x and -v */
11800 if (p[0] == '\0') 11832 if (p[0] == '\0')
11801 xflag = vflag = 0; 11833 xflag = vflag = 0;
@@ -11808,40 +11840,58 @@ options(int cmdline, int *login_sh)
11808 } 11840 }
11809 /* first char was + or - */ 11841 /* first char was + or - */
11810 while ((c = *p++) != '\0') { 11842 while ((c = *p++) != '\0') {
11811 /* bash 3.2 indeed handles -c CMD and +c CMD the same */ 11843 if (login_sh) {
11812 if (c == 'c' && cmdline) { 11844 /* bash 3.2 indeed handles -c CMD and +c CMD the same */
11813 minusc = p; /* command is after shell args */ 11845 if (c == 'c') {
11846 minusc = p; /* command is after shell args */
11847 cflag = 1;
11848 continue;
11849 }
11814#if ENABLE_PLATFORM_MINGW32 11850#if ENABLE_PLATFORM_MINGW32
11815 /* Undocumented flags; 11851 /* Undocumented flags;
11816 * -d force current directory 11852 * -d force current directory
11817 * -t title to display in console window 11853 * -t title to display in console window
11818 * Must appear before -s or -c. */ 11854 * Must appear before -s or -c. */
11819 } else if (c == 'd' && cmdline && val == 1) { 11855 if (c == 'd' && val == 1) {
11820 if (*argptr == NULL) 11856 if (*argptr == NULL)
11821 ash_msg_and_raise_error(bb_msg_requires_arg, "-d"); 11857 ash_msg_and_raise_error(bb_msg_requires_arg, "-d");
11822 dirarg = *argptr++; 11858 dirarg = *argptr++;
11823 } else if (c == 't' && cmdline && val == 1) { 11859 continue;
11824 if (*argptr == NULL) 11860 }
11825 ash_msg_and_raise_error(bb_msg_requires_arg, "-t"); 11861 if (c == 't' && val == 1) {
11826 title = *argptr++; 11862 if (*argptr == NULL)
11827#endif 11863 ash_msg_and_raise_error(bb_msg_requires_arg, "-t");
11828 } else if (c == 'o') { 11864 title = *argptr++;
11865 continue;
11866 }
11867#endif
11868 if (c == 's') { /* -s, +s */
11869 sflag = 1;
11870 continue;
11871 }
11872 if (c == 'i') { /* -i, +i */
11873 iflag = 1;
11874 continue;
11875 }
11876 if (c == 'l') {
11877 *login_sh = 1; /* -l or +l == --login */
11878 continue;
11879 }
11880 /* bash does not accept +-login, we also won't */
11881 if (val && (c == '-')) { /* long options */
11882 if (strcmp(p, "login") == 0) {
11883 *login_sh = 1;
11884 }
11885 break;
11886 }
11887 }
11888 if (c == 'o') {
11829 if (plus_minus_o(*argptr, val)) { 11889 if (plus_minus_o(*argptr, val)) {
11830 /* it already printed err message */ 11890 /* it already printed err message */
11831 return 1; /* error */ 11891 return 1; /* error */
11832 } 11892 }
11833 if (*argptr) 11893 if (*argptr)
11834 argptr++; 11894 argptr++;
11835 } else if (cmdline && (c == 'l')) { /* -l or +l == --login */
11836 if (login_sh)
11837 *login_sh = 1;
11838 /* bash does not accept +-login, we also won't */
11839 } else if (cmdline && val && (c == '-')) { /* long options */
11840 if (strcmp(p, "login") == 0) {
11841 if (login_sh)
11842 *login_sh = 1;
11843 }
11844 break;
11845 } else { 11895 } else {
11846 setoption(c, val); 11896 setoption(c, val);
11847 } 11897 }
@@ -11932,7 +11982,7 @@ setcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
11932 return showvars(nullstr, 0, VUNSET); 11982 return showvars(nullstr, 0, VUNSET);
11933 11983
11934 INT_OFF; 11984 INT_OFF;
11935 retval = options(/*cmdline:*/ 0, NULL); 11985 retval = options(/*login_sh:*/ NULL);
11936 if (retval == 0) { /* if no parse error... */ 11986 if (retval == 0) { /* if no parse error... */
11937 optschanged(); 11987 optschanged();
11938 if (*argptr != NULL) { 11988 if (*argptr != NULL) {
@@ -13787,6 +13837,8 @@ expandstr(const char *ps, int syntax_type)
13787 if (setjmp(jmploc.loc) == 0) { 13837 if (setjmp(jmploc.loc) == 0) {
13788 exception_handler = &jmploc; 13838 exception_handler = &jmploc;
13789 expandarg(&n, NULL, EXP_QUOTED); 13839 expandarg(&n, NULL, EXP_QUOTED);
13840 } else if (exception_type == EXEXIT) {
13841 exitshell();
13790 } 13842 }
13791 exception_handler = savehandler; 13843 exception_handler = savehandler;
13792 RESTORE_INT(saveint); 13844 RESTORE_INT(saveint);
@@ -14400,7 +14452,8 @@ helpcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
14400static int FAST_FUNC 14452static int FAST_FUNC
14401historycmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) 14453historycmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
14402{ 14454{
14403 show_history(line_input_state); 14455 if (line_input_state)
14456 show_history(line_input_state);
14404 return EXIT_SUCCESS; 14457 return EXIT_SUCCESS;
14405} 14458}
14406#endif 14459#endif
@@ -14719,7 +14772,8 @@ exitshell(void)
14719 int status; 14772 int status;
14720 14773
14721#if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT 14774#if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
14722 save_history(line_input_state); 14775 if (line_input_state)
14776 save_history(line_input_state);
14723#endif 14777#endif
14724 status = exitstatus; 14778 status = exitstatus;
14725 TRACE(("pid %d, exitshell(%d)\n", getpid(), status)); 14779 TRACE(("pid %d, exitshell(%d)\n", getpid(), status));
@@ -14923,7 +14977,7 @@ procargs(char **argv)
14923 argptr = xargv; 14977 argptr = xargv;
14924 for (i = 0; i < NOPTS; i++) 14978 for (i = 0; i < NOPTS; i++)
14925 optlist[i] = 2; 14979 optlist[i] = 2;
14926 if (options(/*cmdline:*/ 1, &login_sh)) { 14980 if (options(&login_sh)) {
14927 /* it already printed err message */ 14981 /* it already printed err message */
14928 raise_exception(EXERROR); 14982 raise_exception(EXERROR);
14929 } 14983 }
@@ -14934,8 +14988,13 @@ procargs(char **argv)
14934 ash_msg_and_raise_error(bb_msg_requires_arg, "-c"); 14988 ash_msg_and_raise_error(bb_msg_requires_arg, "-c");
14935 sflag = 1; 14989 sflag = 1;
14936 } 14990 }
14937 if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1)) 14991 if (iflag == 2 /* no explicit -i given */
14992 && sflag == 1 /* -s given (or implied) */
14993 && !minusc /* bash compat: ash -sc 'echo $-' is not interactive (dash is) */
14994 && isatty(0) && isatty(1) /* we are on tty */
14995 ) {
14938 iflag = 1; 14996 iflag = 1;
14997 }
14939 if (mflag == 2) 14998 if (mflag == 2)
14940 mflag = iflag; 14999 mflag = iflag;
14941 for (i = 0; i < NOPTS; i++) 15000 for (i = 0; i < NOPTS; i++)
@@ -15055,9 +15114,6 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
15055 monitor(4, etext, profile_buf, sizeof(profile_buf), 50); 15114 monitor(4, etext, profile_buf, sizeof(profile_buf), 50);
15056#endif 15115#endif
15057 15116
15058#if ENABLE_FEATURE_EDITING
15059 line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP);
15060#endif
15061 state = 0; 15117 state = 0;
15062 if (setjmp(jmploc.loc)) { 15118 if (setjmp(jmploc.loc)) {
15063 smallint e; 15119 smallint e;
@@ -15188,10 +15244,17 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
15188 * Ensure we don't falsely claim that 0 (stdin) 15244 * Ensure we don't falsely claim that 0 (stdin)
15189 * is one of stacked source fds. 15245 * is one of stacked source fds.
15190 * Testcase: ash -c 'exec 1>&0' must not complain. */ 15246 * Testcase: ash -c 'exec 1>&0' must not complain. */
15247
15191 // if (!sflag) g_parsefile->pf_fd = -1; 15248 // if (!sflag) g_parsefile->pf_fd = -1;
15192 // ^^ not necessary since now we special-case fd 0 15249 // ^^ not necessary since now we special-case fd 0
15193 // in save_fd_on_redirect() 15250 // in save_fd_on_redirect()
15194 evalstring(minusc, sflag ? 0 : EV_EXIT); 15251
15252 // dash: evalstring(minusc, sflag ? 0 : EV_EXIT);
15253 // The above makes
15254 // ash -sc 'echo $-'
15255 // continue reading input from stdin after running 'echo'.
15256 // bash does not do this: it prints "hBcs" and exits.
15257 evalstring(minusc, EV_EXIT);
15195 } 15258 }
15196 15259
15197 if (sflag || minusc == NULL) { 15260 if (sflag || minusc == NULL) {
diff --git a/shell/hush.c b/shell/hush.c
index 4b08232a4..19b97e2a5 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -903,6 +903,7 @@ struct globals {
903# define G_x_mode 0 903# define G_x_mode 0
904#endif 904#endif
905 char opt_s; 905 char opt_s;
906 char opt_c;
906#if ENABLE_HUSH_INTERACTIVE 907#if ENABLE_HUSH_INTERACTIVE
907 smallint promptmode; /* 0: PS1, 1: PS2 */ 908 smallint promptmode; /* 0: PS1, 1: PS2 */
908#endif 909#endif
@@ -1009,7 +1010,7 @@ struct globals {
1009 int debug_indent; 1010 int debug_indent;
1010#endif 1011#endif
1011 struct sigaction sa; 1012 struct sigaction sa;
1012 char optstring_buf[sizeof("eixs")]; 1013 char optstring_buf[sizeof("eixcs")];
1013#if BASH_EPOCH_VARS 1014#if BASH_EPOCH_VARS
1014 char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3]; 1015 char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3];
1015#endif 1016#endif
@@ -1397,7 +1398,7 @@ static void syntax_error(unsigned lineno UNUSED_PARAM, const char *msg)
1397 if (msg) 1398 if (msg)
1398 bb_error_msg("syntax error: %s", msg); 1399 bb_error_msg("syntax error: %s", msg);
1399 else 1400 else
1400 bb_error_msg("syntax error"); 1401 bb_simple_error_msg("syntax error");
1401 die_if_script(); 1402 die_if_script();
1402} 1403}
1403 1404
@@ -1636,7 +1637,7 @@ static int refill_HFILE_and_getc(HFILE *fp)
1636 fp->cur = fp->buf; 1637 fp->cur = fp->buf;
1637 n = safe_read(fp->fd, fp->buf, sizeof(fp->buf)); 1638 n = safe_read(fp->fd, fp->buf, sizeof(fp->buf));
1638 if (n < 0) { 1639 if (n < 0) {
1639 bb_perror_msg("read error"); 1640 bb_simple_perror_msg("read error");
1640 n = 0; 1641 n = 0;
1641 } 1642 }
1642 fp->end = fp->buf + n; 1643 fp->end = fp->buf + n;
@@ -2281,7 +2282,7 @@ static int set_local_var(char *str, unsigned flags)
2281 2282
2282 eq_sign = strchr(str, '='); 2283 eq_sign = strchr(str, '=');
2283 if (HUSH_DEBUG && !eq_sign) 2284 if (HUSH_DEBUG && !eq_sign)
2284 bb_error_msg_and_die("BUG in setvar"); 2285 bb_simple_error_msg_and_die("BUG in setvar");
2285 2286
2286 name_len = eq_sign - str + 1; /* including '=' */ 2287 name_len = eq_sign - str + 1; /* including '=' */
2287 cur_pp = &G.top_var; 2288 cur_pp = &G.top_var;
@@ -2504,7 +2505,7 @@ static void set_vars_and_save_old(char **strings)
2504 2505
2505 eq = strchr(*s, '='); 2506 eq = strchr(*s, '=');
2506 if (HUSH_DEBUG && !eq) 2507 if (HUSH_DEBUG && !eq)
2507 bb_error_msg_and_die("BUG in varexp4"); 2508 bb_simple_error_msg_and_die("BUG in varexp4");
2508 var_pp = get_ptr_to_local_var(*s, eq - *s); 2509 var_pp = get_ptr_to_local_var(*s, eq - *s);
2509 if (var_pp) { 2510 if (var_pp) {
2510 var_p = *var_pp; 2511 var_p = *var_pp;
@@ -4245,7 +4246,7 @@ static int parse_redir_right_fd(o_string *as_string, struct in_str *input)
4245 4246
4246//TODO: this is the place to catch ">&file" bashism (redirect both fd 1 and 2) 4247//TODO: this is the place to catch ">&file" bashism (redirect both fd 1 and 2)
4247 4248
4248 bb_error_msg("ambiguous redirect"); 4249 bb_simple_error_msg("ambiguous redirect");
4249 return REDIRFD_SYNTAX_ERR; 4250 return REDIRFD_SYNTAX_ERR;
4250} 4251}
4251 4252
@@ -6414,9 +6415,10 @@ static NOINLINE int expand_one_var(o_string *output, int n,
6414 * commands read but are not executed, 6415 * commands read but are not executed,
6415 * so $- can not execute too, 'n' is never seen in $-. 6416 * so $- can not execute too, 'n' is never seen in $-.
6416 */ 6417 */
6418 if (G.opt_c)
6419 *cp++ = 'c';
6417 if (G.opt_s) 6420 if (G.opt_s)
6418 *cp++ = 's'; 6421 *cp++ = 's';
6419//TODO: show 'c' if executed via "hush -c 'CMDS'" (bash only, not ash)
6420 *cp = '\0'; 6422 *cp = '\0';
6421 break; 6423 break;
6422 } 6424 }
@@ -6954,7 +6956,7 @@ static char *expand_string_to_string(const char *str, int EXP_flags, int do_unba
6954 } else { 6956 } else {
6955 if (HUSH_DEBUG) 6957 if (HUSH_DEBUG)
6956 if (list[1]) 6958 if (list[1])
6957 bb_error_msg_and_die("BUG in varexp2"); 6959 bb_simple_error_msg_and_die("BUG in varexp2");
6958 /* actually, just move string 2*sizeof(char*) bytes back */ 6960 /* actually, just move string 2*sizeof(char*) bytes back */
6959 overlapping_strcpy((char*)list, list[0]); 6961 overlapping_strcpy((char*)list, list[0]);
6960 if (do_unbackslash) 6962 if (do_unbackslash)
@@ -7215,7 +7217,7 @@ static void re_execute_shell(char ***to_free, const char *s,
7215 if (argv[0][0] == '/') 7217 if (argv[0][0] == '/')
7216 execve(argv[0], argv, pp); 7218 execve(argv[0], argv, pp);
7217 xfunc_error_retval = 127; 7219 xfunc_error_retval = 127;
7218 bb_error_msg_and_die("can't re-execute the shell"); 7220 bb_simple_error_msg_and_die("can't re-execute the shell");
7219} 7221}
7220#endif /* !BB_MMU */ 7222#endif /* !BB_MMU */
7221 7223
@@ -7917,7 +7919,7 @@ static void leave_var_nest_level(void)
7917 G.var_nest_level--; 7919 G.var_nest_level--;
7918 debug_printf_env("var_nest_level-- %u\n", G.var_nest_level); 7920 debug_printf_env("var_nest_level-- %u\n", G.var_nest_level);
7919 if (HUSH_DEBUG && (int)G.var_nest_level < 0) 7921 if (HUSH_DEBUG && (int)G.var_nest_level < 0)
7920 bb_error_msg_and_die("BUG: nesting underflow"); 7922 bb_simple_error_msg_and_die("BUG: nesting underflow");
7921 7923
7922 remove_nested_vars(); 7924 remove_nested_vars();
7923} 7925}
@@ -8774,7 +8776,7 @@ static int checkjobs(struct pipe *fg_pipe, pid_t waitfor_pid)
8774 childpid = waitpid(-1, &status, attributes); 8776 childpid = waitpid(-1, &status, attributes);
8775 if (childpid <= 0) { 8777 if (childpid <= 0) {
8776 if (childpid && errno != ECHILD) 8778 if (childpid && errno != ECHILD)
8777 bb_perror_msg("waitpid"); 8779 bb_simple_perror_msg("waitpid");
8778#if ENABLE_HUSH_FAST 8780#if ENABLE_HUSH_FAST
8779 else { /* Until next SIGCHLD, waitpid's are useless */ 8781 else { /* Until next SIGCHLD, waitpid's are useless */
8780 G.we_have_children = (childpid == 0); 8782 G.we_have_children = (childpid == 0);
@@ -9306,7 +9308,7 @@ static NOINLINE int run_pipe(struct pipe *pi)
9306 argv_expanded = NULL; 9308 argv_expanded = NULL;
9307 if (command->pid < 0) { /* [v]fork failed */ 9309 if (command->pid < 0) { /* [v]fork failed */
9308 /* Clearly indicate, was it fork or vfork */ 9310 /* Clearly indicate, was it fork or vfork */
9309 bb_perror_msg(BB_MMU ? "vfork"+1 : "vfork"); 9311 bb_simple_perror_msg(BB_MMU ? "vfork"+1 : "vfork");
9310 } else { 9312 } else {
9311 pi->alive_cmds++; 9313 pi->alive_cmds++;
9312#if ENABLE_HUSH_JOB 9314#if ENABLE_HUSH_JOB
@@ -9859,7 +9861,6 @@ int hush_main(int argc, char **argv)
9859{ 9861{
9860 enum { 9862 enum {
9861 OPT_login = (1 << 0), 9863 OPT_login = (1 << 0),
9862 OPT_s = (1 << 1),
9863 }; 9864 };
9864 unsigned flags; 9865 unsigned flags;
9865 unsigned builtin_argc; 9866 unsigned builtin_argc;
@@ -10029,6 +10030,7 @@ int hush_main(int argc, char **argv)
10029 } 10030 }
10030 goto final_return; 10031 goto final_return;
10031 } 10032 }
10033 G.opt_c = 1;
10032 if (!G.global_argv[0]) { 10034 if (!G.global_argv[0]) {
10033 /* -c 'script' (no params): prevent empty $0 */ 10035 /* -c 'script' (no params): prevent empty $0 */
10034 G.global_argv--; /* points to argv[i] of 'script' */ 10036 G.global_argv--; /* points to argv[i] of 'script' */
@@ -10044,7 +10046,7 @@ int hush_main(int argc, char **argv)
10044 /* G_interactive_fd++; */ 10046 /* G_interactive_fd++; */
10045 break; 10047 break;
10046 case 's': 10048 case 's':
10047 flags |= OPT_s; 10049 G.opt_s = 1;
10048 break; 10050 break;
10049 case 'l': 10051 case 'l':
10050 flags |= OPT_login; 10052 flags |= OPT_login;
@@ -10154,7 +10156,7 @@ int hush_main(int argc, char **argv)
10154 } 10156 }
10155 10157
10156 /* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */ 10158 /* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */
10157 if (!(flags & OPT_s) && G.global_argv[1]) { 10159 if (!G.opt_s && G.global_argv[1]) {
10158 HFILE *input; 10160 HFILE *input;
10159 /* 10161 /*
10160 * "bash <script>" (which is never interactive (unless -i?)) 10162 * "bash <script>" (which is never interactive (unless -i?))
@@ -10178,6 +10180,7 @@ int hush_main(int argc, char **argv)
10178#endif 10180#endif
10179 goto final_return; 10181 goto final_return;
10180 } 10182 }
10183 /* "implicit" -s: bare interactive hush shows 's' in $- */
10181 G.opt_s = 1; 10184 G.opt_s = 1;
10182 10185
10183 /* Up to here, shell was non-interactive. Now it may become one. 10186 /* Up to here, shell was non-interactive. Now it may become one.
@@ -10614,7 +10617,7 @@ static int FAST_FUNC builtin_read(char **argv)
10614 } 10617 }
10615 10618
10616 if ((uintptr_t)r > 1) { 10619 if ((uintptr_t)r > 1) {
10617 bb_error_msg("%s", r); 10620 bb_simple_error_msg(r);
10618 r = (char*)(uintptr_t)1; 10621 r = (char*)(uintptr_t)1;
10619 } 10622 }
10620 10623
@@ -10859,7 +10862,7 @@ static int FAST_FUNC builtin_unset(char **argv)
10859 if (opts == (unsigned)-1) 10862 if (opts == (unsigned)-1)
10860 return EXIT_FAILURE; 10863 return EXIT_FAILURE;
10861 if (opts == 3) { 10864 if (opts == 3) {
10862 bb_error_msg("unset: -v and -f are exclusive"); 10865 bb_simple_error_msg("unset: -v and -f are exclusive");
10863 return EXIT_FAILURE; 10866 return EXIT_FAILURE;
10864 } 10867 }
10865 argv += optind; 10868 argv += optind;
@@ -11022,7 +11025,7 @@ Test that VAR is a valid variable name?
11022 11025
11023 optstring = *++argv; 11026 optstring = *++argv;
11024 if (!optstring || !(var = *++argv)) { 11027 if (!optstring || !(var = *++argv)) {
11025 bb_error_msg("usage: getopts OPTSTRING VAR [ARGS]"); 11028 bb_simple_error_msg("usage: getopts OPTSTRING VAR [ARGS]");
11026 return EXIT_FAILURE; 11029 return EXIT_FAILURE;
11027 } 11030 }
11028 11031
@@ -11251,7 +11254,7 @@ static int FAST_FUNC builtin_trap(char **argv)
11251 } 11254 }
11252 11255
11253 if (!argv[1]) { /* no second arg */ 11256 if (!argv[1]) { /* no second arg */
11254 bb_error_msg("trap: invalid arguments"); 11257 bb_simple_error_msg("trap: invalid arguments");
11255 return EXIT_FAILURE; 11258 return EXIT_FAILURE;
11256 } 11259 }
11257 11260
@@ -11292,7 +11295,7 @@ static struct pipe *parse_jobspec(const char *str)
11292 /* It is "%%", "%+" or "%" - current job */ 11295 /* It is "%%", "%+" or "%" - current job */
11293 jobnum = G.last_jobid; 11296 jobnum = G.last_jobid;
11294 if (jobnum == 0) { 11297 if (jobnum == 0) {
11295 bb_error_msg("no current job"); 11298 bb_simple_error_msg("no current job");
11296 return NULL; 11299 return NULL;
11297 } 11300 }
11298 } 11301 }
@@ -11369,7 +11372,7 @@ static int FAST_FUNC builtin_fg_bg(char **argv)
11369 delete_finished_job(pi); 11372 delete_finished_job(pi);
11370 return EXIT_SUCCESS; 11373 return EXIT_SUCCESS;
11371 } 11374 }
11372 bb_perror_msg("kill (SIGCONT)"); 11375 bb_simple_perror_msg("kill (SIGCONT)");
11373 } 11376 }
11374 11377
11375 if (argv[0][0] == 'f') { 11378 if (argv[0][0] == 'f') {
diff --git a/shell/shell_common.c b/shell/shell_common.c
index d1df5888c..06a6b6e5f 100644
--- a/shell/shell_common.c
+++ b/shell/shell_common.c
@@ -668,7 +668,7 @@ shell_builtin_ulimit(char **argv)
668 limit.rlim_cur = val; 668 limit.rlim_cur = val;
669//bb_error_msg("setrlimit(%d, %lld, %lld)", limits_tbl[i].cmd, (long long)limit.rlim_cur, (long long)limit.rlim_max); 669//bb_error_msg("setrlimit(%d, %lld, %lld)", limits_tbl[i].cmd, (long long)limit.rlim_cur, (long long)limit.rlim_max);
670 if (setrlimit(limits_tbl[i].cmd, &limit) < 0) { 670 if (setrlimit(limits_tbl[i].cmd, &limit) < 0) {
671 bb_perror_msg("error setting limit"); 671 bb_simple_perror_msg("error setting limit");
672 return EXIT_FAILURE; 672 return EXIT_FAILURE;
673 } 673 }
674 } 674 }
diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c
index 17b6ca235..bdd0b6325 100644
--- a/sysklogd/klogd.c
+++ b/sysklogd/klogd.c
@@ -244,7 +244,7 @@ int klogd_main(int argc UNUSED_PARAM, char **argv)
244 if (n < 0) { 244 if (n < 0) {
245 if (errno == EINTR) 245 if (errno == EINTR)
246 continue; 246 continue;
247 bb_perror_msg(READ_ERROR); 247 bb_simple_perror_msg(READ_ERROR);
248 break; 248 break;
249 } 249 }
250 start[n] = '\0'; 250 start[n] = '\0';
diff --git a/sysklogd/logread.c b/sysklogd/logread.c
index ea41fc0c8..1e1f1347f 100644
--- a/sysklogd/logread.c
+++ b/sysklogd/logread.c
@@ -88,7 +88,7 @@ static void error_exit(const char *str)
88} 88}
89#else 89#else
90/* On Linux, shmdt is not mandatory on exit */ 90/* On Linux, shmdt is not mandatory on exit */
91# define error_exit(str) bb_perror_msg_and_die(str) 91# define error_exit(str) bb_simple_perror_msg_and_die(str)
92#endif 92#endif
93 93
94/* 94/*
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index d0dd1bd20..0e226124a 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -572,12 +572,12 @@ static void ipcsyslog_init(void)
572 572
573 G.shmid = shmget(KEY_ID, G.shm_size, IPC_CREAT | 0644); 573 G.shmid = shmget(KEY_ID, G.shm_size, IPC_CREAT | 0644);
574 if (G.shmid == -1) { 574 if (G.shmid == -1) {
575 bb_perror_msg_and_die("shmget"); 575 bb_simple_perror_msg_and_die("shmget");
576 } 576 }
577 577
578 G.shbuf = shmat(G.shmid, NULL, 0); 578 G.shbuf = shmat(G.shmid, NULL, 0);
579 if (G.shbuf == (void*) -1L) { /* shmat has bizarre error return */ 579 if (G.shbuf == (void*) -1L) { /* shmat has bizarre error return */
580 bb_perror_msg_and_die("shmat"); 580 bb_simple_perror_msg_and_die("shmat");
581 } 581 }
582 582
583 memset(G.shbuf, 0, G.shm_size); 583 memset(G.shbuf, 0, G.shm_size);
@@ -592,7 +592,7 @@ static void ipcsyslog_init(void)
592 if (G.s_semid != -1) 592 if (G.s_semid != -1)
593 return; 593 return;
594 } 594 }
595 bb_perror_msg_and_die("semget"); 595 bb_simple_perror_msg_and_die("semget");
596 } 596 }
597} 597}
598 598
@@ -603,7 +603,7 @@ static void log_to_shmem(const char *msg)
603 int len; 603 int len;
604 604
605 if (semop(G.s_semid, G.SMwdn, 3) == -1) { 605 if (semop(G.s_semid, G.SMwdn, 3) == -1) {
606 bb_perror_msg_and_die("SMwdn"); 606 bb_simple_perror_msg_and_die("SMwdn");
607 } 607 }
608 608
609 /* Circular Buffer Algorithm: 609 /* Circular Buffer Algorithm:
@@ -631,7 +631,7 @@ static void log_to_shmem(const char *msg)
631 goto again; 631 goto again;
632 } 632 }
633 if (semop(G.s_semid, G.SMwup, 1) == -1) { 633 if (semop(G.s_semid, G.SMwup, 1) == -1) {
634 bb_perror_msg_and_die("SMwup"); 634 bb_simple_perror_msg_and_die("SMwup");
635 } 635 }
636 if (DEBUG) 636 if (DEBUG)
637 printf("tail:%d\n", G.shbuf->tail); 637 printf("tail:%d\n", G.shbuf->tail);
diff --git a/testsuite/awk.tests b/testsuite/awk.tests
index 0db6a26e4..a7a533ba0 100755
--- a/testsuite/awk.tests
+++ b/testsuite/awk.tests
@@ -347,14 +347,20 @@ testing "awk continue" \
347 "" \ 347 "" \
348 'BEGIN { if (1) continue; else a = 1 }' 348 'BEGIN { if (1) continue; else a = 1 }'
349 349
350optional FEATURE_AWK_GNU_EXTENSIONS
350testing "awk handles invalid for loop" \ 351testing "awk handles invalid for loop" \
351 "awk -e '{ for() }' 2>&1" "awk: cmd. line:1: Unexpected token\n" "" "" 352 "awk -e '{ for() }' 2>&1" "awk: cmd. line:1: Unexpected token\n" "" ""
353SKIP=
352 354
355optional FEATURE_AWK_GNU_EXTENSIONS
353testing "awk handles colon not preceded by ternary" \ 356testing "awk handles colon not preceded by ternary" \
354 "awk -e foo:bar: 2>&1" "awk: cmd. line:1: Unexpected token\n" "" "" 357 "awk -e foo:bar: 2>&1" "awk: cmd. line:1: Unexpected token\n" "" ""
358SKIP=
355 359
360optional FEATURE_AWK_GNU_EXTENSIONS
356testing "awk errors on missing delete arg" \ 361testing "awk errors on missing delete arg" \
357 "awk -e '{delete}' 2>&1" "awk: cmd. line:1: Too few arguments\n" "" "" 362 "awk -e '{delete}' 2>&1" "awk: cmd. line:1: Too few arguments\n" "" ""
363SKIP=
358 364
359# testing "description" "command" "result" "infile" "stdin" 365# testing "description" "command" "result" "infile" "stdin"
360testing 'awk negative field access' \ 366testing 'awk negative field access' \
diff --git a/testsuite/expand/expand-works-like-GNU b/testsuite/expand/expand-works-like-GNU
deleted file mode 100644
index b0278d88d..000000000
--- a/testsuite/expand/expand-works-like-GNU
+++ /dev/null
@@ -1,20 +0,0 @@
1# FEATURE: CONFIG_UNEXPAND
2
3rm -f foo bar
4$ECHO -e "\ty" | expand -t 3 ../../busybox > foo
5$ECHO -e "\ty" | busybox unexpand -t 3 ../../busybox > bar
6set +e
7test ! -f foo -a -f bar
8if [ $? = 0 ] ; then
9 set -e
10 diff -q foo bar
11fi
12rm -f foo bar
13$ECHO -e "\ty\tx" | expand -it 3 ../../busybox > foo
14$ECHO -e "\ty\tx" | busybox unexpand -it 3 ../../busybox > bar
15set +e
16test ! -f foo -a -f bar
17if [ $? = 0 ] ; then
18 set -e
19 diff -q foo bar
20fi
diff --git a/testsuite/unexpand/unexpand-works-like-GNU b/testsuite/unexpand/unexpand-works-like-GNU
deleted file mode 100644
index 111b277b5..000000000
--- a/testsuite/unexpand/unexpand-works-like-GNU
+++ /dev/null
@@ -1,56 +0,0 @@
1# coreutils 8.25 often says "input line is too long"
2# on ELF executables. In this case, do not run the test:
3unexpand ../../busybox >/dev/null || exit 0
4
5rm -f foo bar
6echo " y" | unexpand ../../busybox > foo
7echo " y" | busybox unexpand ../../busybox > bar
8set +e
9test ! -f foo -a -f bar
10if [ $? = 0 ] ; then
11 set -e
12 diff -q foo bar
13fi
14rm -f foo bar
15echo " y" | unexpand ../../busybox > foo
16echo " y" | busybox unexpand ../../busybox > bar
17set +e
18test ! -f foo -a -f bar
19if [ $? = 0 ] ; then
20 set -e
21 diff -q foo bar
22fi
23echo " y y" | unexpand ../../busybox > foo
24echo " y y" | busybox unexpand ../../busybox > bar
25set +e
26test ! -f foo -a -f bar
27if [ $? = 0 ] ; then
28 set -e
29 diff -q foo bar
30fi
31rm -f foo bar
32echo " y y" | unexpand ../../busybox > foo
33echo " y y" | busybox unexpand ../../busybox > bar
34set +e
35test ! -f foo -a -f bar
36if [ $? = 0 ] ; then
37 set -e
38 diff -q foo bar
39fi
40echo " y y" | unexpand -a ../../busybox > foo
41echo " y y" | busybox unexpand -a ../../busybox > bar
42set +e
43test ! -f foo -a -f bar
44if [ $? = 0 ] ; then
45 set -e
46 diff -q foo bar
47fi
48rm -f foo bar
49echo " y y" | unexpand -a ../../busybox > foo
50echo " y y" | busybox unexpand -a ../../busybox > bar
51set +e
52test ! -f foo -a -f bar
53if [ $? = 0 ] ; then
54 set -e
55 diff -q foo bar
56fi
diff --git a/util-linux/acpid.c b/util-linux/acpid.c
index 7274b6866..95f8150e2 100644
--- a/util-linux/acpid.c
+++ b/util-linux/acpid.c
@@ -148,7 +148,7 @@ static void process_event(const char *event)
148 const char *args[] = { "run-parts", handler, NULL }; 148 const char *args[] = { "run-parts", handler, NULL };
149 149
150 // log the event 150 // log the event
151 bb_error_msg("%s", event); 151 bb_simple_error_msg(event);
152 152
153 // spawn handler 153 // spawn handler
154 // N.B. run-parts would require scripts to have #!/bin/sh 154 // N.B. run-parts would require scripts to have #!/bin/sh
diff --git a/util-linux/blockdev.c b/util-linux/blockdev.c
index e9b5b8bf9..e60bbe609 100644
--- a/util-linux/blockdev.c
+++ b/util-linux/blockdev.c
@@ -29,7 +29,17 @@
29//usage: "\n --getsize64 Get device size in bytes" 29//usage: "\n --getsize64 Get device size in bytes"
30//usage: "\n --flushbufs Flush buffers" 30//usage: "\n --flushbufs Flush buffers"
31//usage: "\n --rereadpt Reread partition table" 31//usage: "\n --rereadpt Reread partition table"
32 32// util-linux 2.31 also has:
33// --getdiscardzeroes BLKDISCARDZEROES Get discard zeroes support status
34// --getpbsz BLKPBSZGET Get physical block (sector) size
35// --getiomin BLKIOMIN Get minimum I/O size
36// --getioopt BLKIOOPT Get optimal I/O size
37// --getalignoff BLKALIGNOFF Get alignment offset in bytes
38// --getmaxsect BLKSECTGET Get max sectors per request
39// --setra SECTORS BLKRASET Set readahead
40// --getra BLKRAGET Get readahead
41// --setfra SECTORS BLKFRASET Set filesystem readahead
42// --getfra BLKFRAGET Get filesystem readahead
33 43
34#include "libbb.h" 44#include "libbb.h"
35#include <linux/fs.h> 45#include <linux/fs.h>
diff --git a/util-linux/dmesg.c b/util-linux/dmesg.c
index b797c7b2a..a1f269142 100644
--- a/util-linux/dmesg.c
+++ b/util-linux/dmesg.c
@@ -74,7 +74,7 @@ int dmesg_main(int argc UNUSED_PARAM, char **argv)
74 opts = getopt32(argv, "cs:+n:+r", &len, &level); 74 opts = getopt32(argv, "cs:+n:+r", &len, &level);
75 if (opts & OPT_n) { 75 if (opts & OPT_n) {
76 if (klogctl(8, NULL, (long) level)) 76 if (klogctl(8, NULL, (long) level))
77 bb_perror_msg_and_die("klogctl"); 77 bb_simple_perror_msg_and_die("klogctl");
78 return EXIT_SUCCESS; 78 return EXIT_SUCCESS;
79 } 79 }
80 80
@@ -88,7 +88,7 @@ int dmesg_main(int argc UNUSED_PARAM, char **argv)
88 buf = xmalloc(len); 88 buf = xmalloc(len);
89 len = klogctl(3 + (opts & OPT_c), buf, len); /* read ring buffer */ 89 len = klogctl(3 + (opts & OPT_c), buf, len); /* read ring buffer */
90 if (len < 0) 90 if (len < 0)
91 bb_perror_msg_and_die("klogctl"); 91 bb_simple_perror_msg_and_die("klogctl");
92 if (len == 0) 92 if (len == 0)
93 return EXIT_SUCCESS; 93 return EXIT_SUCCESS;
94 94
diff --git a/util-linux/eject.c b/util-linux/eject.c
index 749e2c986..3ccb4ae89 100644
--- a/util-linux/eject.c
+++ b/util-linux/eject.c
@@ -70,7 +70,7 @@ static void eject_scsi(const char *dev)
70 sg_io_hdr_t io_hdr; 70 sg_io_hdr_t io_hdr;
71 71
72 if ((ioctl(dev_fd, SG_GET_VERSION_NUM, &i) < 0) || (i < 30000)) 72 if ((ioctl(dev_fd, SG_GET_VERSION_NUM, &i) < 0) || (i < 30000))
73 bb_error_msg_and_die("not a sg device or old sg driver"); 73 bb_simple_error_msg_and_die("not a sg device or old sg driver");
74 74
75 memset(&io_hdr, 0, sizeof(sg_io_hdr_t)); 75 memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
76 io_hdr.interface_id = 'S'; 76 io_hdr.interface_id = 'S';
diff --git a/util-linux/fdformat.c b/util-linux/fdformat.c
index ff3bc4870..e1c8561d6 100644
--- a/util-linux/fdformat.c
+++ b/util-linux/fdformat.c
@@ -117,7 +117,7 @@ int fdformat_main(int argc UNUSED_PARAM, char **argv)
117 read_bytes = safe_read(fd, data, n); 117 read_bytes = safe_read(fd, data, n);
118 if (read_bytes != n) { 118 if (read_bytes != n) {
119 if (read_bytes < 0) { 119 if (read_bytes < 0) {
120 bb_perror_msg(bb_msg_read_error); 120 bb_simple_perror_msg(bb_msg_read_error);
121 } 121 }
122 bb_error_msg_and_die("problem reading cylinder %d, " 122 bb_error_msg_and_die("problem reading cylinder %d, "
123 "expected %d, read %d", cyl, n, read_bytes); 123 "expected %d, read %d", cyl, n, read_bytes);
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c
index 58e93bb92..f28d4fdd2 100644
--- a/util-linux/fdisk.c
+++ b/util-linux/fdisk.c
@@ -511,7 +511,7 @@ static sector_t bb_BLKGETSIZE_sectors(int fd)
511 * we support can't record more than 32 bit 511 * we support can't record more than 32 bit
512 * sector counts or offsets 512 * sector counts or offsets
513 */ 513 */
514 bb_error_msg("device has more than 2^32 sectors, can't use all of them"); 514 bb_simple_error_msg("device has more than 2^32 sectors, can't use all of them");
515 v64 = (uint32_t)-1L; 515 v64 = (uint32_t)-1L;
516 } 516 }
517 return v64; 517 return v64;
diff --git a/util-linux/flock.c b/util-linux/flock.c
index 130627e93..12c16013c 100644
--- a/util-linux/flock.c
+++ b/util-linux/flock.c
@@ -73,7 +73,7 @@ int flock_main(int argc UNUSED_PARAM, char **argv)
73 ) { 73 ) {
74 argv++; 74 argv++;
75 if (argv[1]) 75 if (argv[1])
76 bb_error_msg_and_die("-c takes only one argument"); 76 bb_simple_error_msg_and_die("-c takes only one argument");
77 opt |= OPT_c; 77 opt |= OPT_c;
78 } 78 }
79 79
diff --git a/util-linux/fsck_minix.c b/util-linux/fsck_minix.c
index f523da945..40b86d01b 100644
--- a/util-linux/fsck_minix.c
+++ b/util-linux/fsck_minix.c
@@ -321,7 +321,7 @@ static void die(const char *str)
321{ 321{
322 if (termios_set) 322 if (termios_set)
323 tcsetattr_stdin_TCSANOW(&sv_termios); 323 tcsetattr_stdin_TCSANOW(&sv_termios);
324 bb_error_msg_and_die("%s", str); 324 bb_simple_error_msg_and_die(str);
325} 325}
326 326
327static void push_filename(const char *name) 327static void push_filename(const char *name)
diff --git a/util-linux/getopt.c b/util-linux/getopt.c
index 1666d3d30..db7db6ff8 100644
--- a/util-linux/getopt.c
+++ b/util-linux/getopt.c
@@ -308,7 +308,7 @@ static struct option *add_long_options(struct option *long_options, char *option
308 } 308 }
309 tokptr[tlen] = '\0'; 309 tokptr[tlen] = '\0';
310 if (tlen == 0) 310 if (tlen == 0)
311 bb_error_msg_and_die("empty long option specified"); 311 bb_simple_error_msg_and_die("empty long option specified");
312 } 312 }
313 long_options = xrealloc_vector(long_options, 4, long_nr); 313 long_options = xrealloc_vector(long_options, 4, long_nr);
314 long_options[long_nr].has_arg = arg_opt; 314 long_options[long_nr].has_arg = arg_opt;
@@ -380,7 +380,7 @@ int getopt_main(int argc, char **argv)
380 puts(" --"); 380 puts(" --");
381 return 0; 381 return 0;
382 } 382 }
383 bb_error_msg_and_die("missing optstring argument"); 383 bb_simple_error_msg_and_die("missing optstring argument");
384 } 384 }
385 385
386 if (argv[1][0] != '-' || compatible) { 386 if (argv[1][0] != '-' || compatible) {
@@ -416,7 +416,7 @@ int getopt_main(int argc, char **argv)
416 if (!optstr) { 416 if (!optstr) {
417 optstr = argv[++n]; 417 optstr = argv[++n];
418 if (!optstr) 418 if (!optstr)
419 bb_error_msg_and_die("missing optstring argument"); 419 bb_simple_error_msg_and_die("missing optstring argument");
420 } 420 }
421 421
422 argv[n] = name ? name : argv[0]; 422 argv[n] = name ? name : argv[0];
diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c
index 29f51021e..dc97d8fb4 100644
--- a/util-linux/hwclock.c
+++ b/util-linux/hwclock.c
@@ -132,7 +132,7 @@ static void to_sys_clock(const char **pp_rtcname, int utc)
132 tv.tv_sec = read_rtc(pp_rtcname, NULL, utc); 132 tv.tv_sec = read_rtc(pp_rtcname, NULL, utc);
133 tv.tv_usec = 0; 133 tv.tv_usec = 0;
134 if (settimeofday(&tv, &tz)) 134 if (settimeofday(&tv, &tz))
135 bb_perror_msg_and_die("settimeofday"); 135 bb_simple_perror_msg_and_die("settimeofday");
136} 136}
137 137
138static void from_sys_clock(const char **pp_rtcname, int utc) 138static void from_sys_clock(const char **pp_rtcname, int utc)
@@ -284,7 +284,7 @@ static void set_system_clock_timezone(int utc)
284 if (!utc) 284 if (!utc)
285 tv.tv_sec += tz.tz_minuteswest * 60; 285 tv.tv_sec += tz.tz_minuteswest * 60;
286 if (settimeofday(&tv, &tz)) 286 if (settimeofday(&tv, &tz))
287 bb_perror_msg_and_die("settimeofday"); 287 bb_simple_perror_msg_and_die("settimeofday");
288} 288}
289 289
290//usage:#define hwclock_trivial_usage 290//usage:#define hwclock_trivial_usage
diff --git a/util-linux/ipcs.c b/util-linux/ipcs.c
index 4863a5c29..df86cfb9d 100644
--- a/util-linux/ipcs.c
+++ b/util-linux/ipcs.c
@@ -467,7 +467,7 @@ static void print_shm(int shmid)
467 struct ipc_perm *ipcp = &shmds.shm_perm; 467 struct ipc_perm *ipcp = &shmds.shm_perm;
468 468
469 if (shmctl(shmid, IPC_STAT, &shmds) == -1) { 469 if (shmctl(shmid, IPC_STAT, &shmds) == -1) {
470 bb_perror_msg("shmctl"); 470 bb_simple_perror_msg("shmctl");
471 return; 471 return;
472 } 472 }
473 473
@@ -493,7 +493,7 @@ static void print_msg(int msqid)
493 struct ipc_perm *ipcp = &buf.msg_perm; 493 struct ipc_perm *ipcp = &buf.msg_perm;
494 494
495 if (msgctl(msqid, IPC_STAT, &buf) == -1) { 495 if (msgctl(msqid, IPC_STAT, &buf) == -1) {
496 bb_perror_msg("msgctl"); 496 bb_simple_perror_msg("msgctl");
497 return; 497 return;
498 } 498 }
499 499
@@ -527,7 +527,7 @@ static void print_sem(int semid)
527 527
528 arg.buf = &semds; 528 arg.buf = &semds;
529 if (semctl(semid, 0, IPC_STAT, arg)) { 529 if (semctl(semid, 0, IPC_STAT, arg)) {
530 bb_perror_msg("semctl"); 530 bb_simple_perror_msg("semctl");
531 return; 531 return;
532 } 532 }
533 533
@@ -555,7 +555,7 @@ static void print_sem(int semid)
555 zcnt = semctl(semid, i, GETZCNT, arg); 555 zcnt = semctl(semid, i, GETZCNT, arg);
556 pid = semctl(semid, i, GETPID, arg); 556 pid = semctl(semid, i, GETPID, arg);
557 if (val < 0 || ncnt < 0 || zcnt < 0 || pid < 0) { 557 if (val < 0 || ncnt < 0 || zcnt < 0 || pid < 0) {
558 bb_perror_msg_and_die("semctl"); 558 bb_simple_perror_msg_and_die("semctl");
559 } 559 }
560 printf("%-10u %-10d %-10d %-10d %-10d\n", i, val, ncnt, zcnt, pid); 560 printf("%-10u %-10d %-10d %-10d %-10d\n", i, val, ncnt, zcnt, pid);
561 } 561 }
diff --git a/util-linux/last.c b/util-linux/last.c
index 689aa7a34..24ce7a8d8 100644
--- a/util-linux/last.c
+++ b/util-linux/last.c
@@ -100,7 +100,7 @@ int last_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
100 pos = lseek(file, pos - sizeof(ut), SEEK_SET); 100 pos = lseek(file, pos - sizeof(ut), SEEK_SET);
101 while ((n = full_read(file, &ut, sizeof(ut))) > 0) { 101 while ((n = full_read(file, &ut, sizeof(ut))) > 0) {
102 if (n != sizeof(ut)) { 102 if (n != sizeof(ut)) {
103 bb_perror_msg_and_die("short read"); 103 bb_simple_perror_msg_and_die("short read");
104 } 104 }
105 n = index_in_strings(_ut_lin, ut.ut_line); 105 n = index_in_strings(_ut_lin, ut.ut_line);
106 if (n == _TILDE) { /* '~' */ 106 if (n == _TILDE) { /* '~' */
diff --git a/util-linux/losetup.c b/util-linux/losetup.c
index 2248f2cba..cc6c2b1d5 100644
--- a/util-linux/losetup.c
+++ b/util-linux/losetup.c
@@ -20,13 +20,14 @@
20//kbuild:lib-$(CONFIG_LOSETUP) += losetup.o 20//kbuild:lib-$(CONFIG_LOSETUP) += losetup.o
21 21
22//usage:#define losetup_trivial_usage 22//usage:#define losetup_trivial_usage
23//usage: "[-r] [-o OFS] {-f|LOOPDEV} FILE: associate loop devices\n" 23//usage: "[-rP] [-o OFS] {-f|LOOPDEV} FILE: associate loop devices\n"
24//usage: " losetup -c LOOPDEV: reread file size\n" 24//usage: " losetup -c LOOPDEV: reread file size\n"
25//usage: " losetup -d LOOPDEV: disassociate\n" 25//usage: " losetup -d LOOPDEV: disassociate\n"
26//usage: " losetup -a: show status\n" 26//usage: " losetup -a: show status\n"
27//usage: " losetup -f: show next free loop device" 27//usage: " losetup -f: show next free loop device"
28//usage:#define losetup_full_usage "\n\n" 28//usage:#define losetup_full_usage "\n\n"
29//usage: " -o OFS Start OFS bytes into FILE" 29//usage: " -o OFS Start OFS bytes into FILE"
30//usage: "\n -P Scan for partitions"
30//usage: "\n -r Read-only" 31//usage: "\n -r Read-only"
31//usage: "\n -f Show/use next free loop device" 32//usage: "\n -f Show/use next free loop device"
32//usage: 33//usage:
@@ -35,8 +36,9 @@
35//usage: "(if any), or disassociate it (with -d). The display shows the offset\n" 36//usage: "(if any), or disassociate it (with -d). The display shows the offset\n"
36//usage: "and filename of the file the loop device is currently bound to.\n\n" 37//usage: "and filename of the file the loop device is currently bound to.\n\n"
37//usage: "Two arguments (losetup /dev/loop1 file.img) create a new association,\n" 38//usage: "Two arguments (losetup /dev/loop1 file.img) create a new association,\n"
38//usage: "with an optional offset (-o 12345). Encryption is not yet supported.\n" 39//usage: "with optional partition scanning (creates /dev/loop1p1, /dev/loop1p2\n"
39//usage: "losetup -f will show the first loop free loop device\n\n" 40//usage: "etc. with -P) and with an optional offset (-o 12345). Encryption is\n"
41//usage: "not yet supported. losetup -f will show the first free loop device\n\n"
40 42
41#include "libbb.h" 43#include "libbb.h"
42 44
@@ -53,13 +55,14 @@ int losetup_main(int argc UNUSED_PARAM, char **argv)
53 enum { 55 enum {
54 OPT_c = (1 << 0), 56 OPT_c = (1 << 0),
55 OPT_d = (1 << 1), 57 OPT_d = (1 << 1),
56 OPT_o = (1 << 2), 58 OPT_P = (1 << 2),
57 OPT_f = (1 << 3), 59 OPT_o = (1 << 3),
58 OPT_a = (1 << 4), 60 OPT_f = (1 << 4),
59 OPT_r = (1 << 5), 61 OPT_a = (1 << 5),
62 OPT_r = (1 << 6),
60 }; 63 };
61 64
62 opt = getopt32(argv, "^" "cdo:far" "\0" "?2:d--ofar:a--ofr", &opt_o); 65 opt = getopt32(argv, "^" "cdPo:far" "\0" "?2:d--Pofar:a--Pofr", &opt_o);
63 argv += optind; 66 argv += optind;
64 67
65 /* LOOPDEV */ 68 /* LOOPDEV */
@@ -111,11 +114,17 @@ int losetup_main(int argc UNUSED_PARAM, char **argv)
111 /* contains -f */ 114 /* contains -f */
112 if (opt & OPT_f) { 115 if (opt & OPT_f) {
113 char *s; 116 char *s;
114 int n = 0; 117 int n;
115 118
119 n = get_free_loop();
120 if (n == -1)
121 bb_simple_error_msg_and_die("no free loop devices");
122 if (n < 0) /* n == -2: no /dev/loop-control, use legacy method */
123 n = 0;
124 /* or: n >= 0: the number of next free loopdev, just verify it */
116 do { 125 do {
117 if (n > MAX_LOOP_NUM) 126 if (n > MAX_LOOP_NUM)
118 bb_error_msg_and_die("no free loop devices"); 127 bb_simple_error_msg_and_die("no free loop devices");
119 sprintf(dev, LOOP_FORMAT, n++); 128 sprintf(dev, LOOP_FORMAT, n++);
120 s = query_loop(dev); 129 s = query_loop(dev);
121 free(s); 130 free(s);
@@ -127,7 +136,7 @@ int losetup_main(int argc UNUSED_PARAM, char **argv)
127 } 136 }
128 } 137 }
129 138
130 /* [-r] [-o OFS] {-f|LOOPDEV} FILE */ 139 /* [-rP] [-o OFS] {-f|LOOPDEV} FILE */
131 if (argv[0] && ((opt & OPT_f) || argv[1])) { 140 if (argv[0] && ((opt & OPT_f) || argv[1])) {
132 unsigned long long offset = 0; 141 unsigned long long offset = 0;
133 char *d = dev; 142 char *d = dev;
@@ -138,7 +147,11 @@ int losetup_main(int argc UNUSED_PARAM, char **argv)
138 d = *argv++; 147 d = *argv++;
139 148
140 if (argv[0]) { 149 if (argv[0]) {
141 if (set_loop(&d, argv[0], offset, (opt & OPT_r) ? BB_LO_FLAGS_READ_ONLY : 0) < 0) 150 unsigned flags = (opt & OPT_r) ? BB_LO_FLAGS_READ_ONLY : 0;
151 if (opt & OPT_P) {
152 flags |= BB_LO_FLAGS_PARTSCAN;
153 }
154 if (set_loop(&d, argv[0], offset, flags) < 0)
142 bb_simple_perror_msg_and_die(argv[0]); 155 bb_simple_perror_msg_and_die(argv[0]);
143 return EXIT_SUCCESS; 156 return EXIT_SUCCESS;
144 } 157 }
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index 63b55536a..207a112c1 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -64,15 +64,30 @@
64//config: These devices will request userspace look up the files in 64//config: These devices will request userspace look up the files in
65//config: /lib/firmware/ and if it exists, send it to the kernel for 65//config: /lib/firmware/ and if it exists, send it to the kernel for
66//config: loading into the hardware. 66//config: loading into the hardware.
67//config:
68//config:config FEATURE_MDEV_DAEMON
69//config: bool "Support daemon mode"
70//config: default y
71//config: depends on MDEV
72//config: help
73//config: Adds the -d option to run mdev in daemon mode handling hotplug
74//config: events from the kernel like udev. If the system generates many
75//config: hotplug events this mode of operation will consume less
76//config: resources than registering mdev as hotplug helper or using the
77//config: uevent applet.
67 78
68//applet:IF_MDEV(APPLET(mdev, BB_DIR_SBIN, BB_SUID_DROP)) 79//applet:IF_MDEV(APPLET(mdev, BB_DIR_SBIN, BB_SUID_DROP))
69 80
70//kbuild:lib-$(CONFIG_MDEV) += mdev.o 81//kbuild:lib-$(CONFIG_MDEV) += mdev.o
71 82
72//usage:#define mdev_trivial_usage 83//usage:#define mdev_trivial_usage
73//usage: "[-s]" 84//usage: "[-s]" IF_FEATURE_MDEV_DAEMON(" | [-df]")
74//usage:#define mdev_full_usage "\n\n" 85//usage:#define mdev_full_usage "\n\n"
75//usage: "mdev -s is to be run during boot to scan /sys and populate /dev.\n" 86//usage: "mdev -s is to be run during boot to scan /sys and populate /dev.\n"
87//usage: IF_FEATURE_MDEV_DAEMON(
88//usage: "mdev -d[f]: daemon, listen on netlink.\n"
89//usage: " -f: stay in foreground.\n"
90//usage: )
76//usage: "\n" 91//usage: "\n"
77//usage: "Bare mdev is a kernel hotplug helper. To activate it:\n" 92//usage: "Bare mdev is a kernel hotplug helper. To activate it:\n"
78//usage: " echo /sbin/mdev >/proc/sys/kernel/hotplug\n" 93//usage: " echo /sbin/mdev >/proc/sys/kernel/hotplug\n"
@@ -98,6 +113,7 @@
98#include "libbb.h" 113#include "libbb.h"
99#include "common_bufsiz.h" 114#include "common_bufsiz.h"
100#include "xregex.h" 115#include "xregex.h"
116#include <linux/netlink.h>
101 117
102/* "mdev -s" scans /sys/class/xxx, looking for directories which have dev 118/* "mdev -s" scans /sys/class/xxx, looking for directories which have dev
103 * file (it is of the form "M:m\n"). Example: /sys/class/tty/tty0/dev 119 * file (it is of the form "M:m\n"). Example: /sys/class/tty/tty0/dev
@@ -234,21 +250,30 @@
234 250
235#if DEBUG_LVL >= 1 251#if DEBUG_LVL >= 1
236# define dbg1(...) do { if (G.verbose) bb_error_msg(__VA_ARGS__); } while(0) 252# define dbg1(...) do { if (G.verbose) bb_error_msg(__VA_ARGS__); } while(0)
253# define dbg1s(msg) do { if (G.verbose) bb_simple_error_msg(msg); } while(0)
237#else 254#else
238# define dbg1(...) ((void)0) 255# define dbg1(...) ((void)0)
256# define dbg1s(msg) ((void)0)
239#endif 257#endif
240#if DEBUG_LVL >= 2 258#if DEBUG_LVL >= 2
241# define dbg2(...) do { if (G.verbose >= 2) bb_error_msg(__VA_ARGS__); } while(0) 259# define dbg2(...) do { if (G.verbose >= 2) bb_error_msg(__VA_ARGS__); } while(0)
260# define dbg2s(msg) do { if (G.verbose >= 2) bb_simple_error_msg(msg); } while(0)
242#else 261#else
243# define dbg2(...) ((void)0) 262# define dbg2(...) ((void)0)
263# define dbg2s(msg) ((void)0)
244#endif 264#endif
245#if DEBUG_LVL >= 3 265#if DEBUG_LVL >= 3
246# define dbg3(...) do { if (G.verbose >= 3) bb_error_msg(__VA_ARGS__); } while(0) 266# define dbg3(...) do { if (G.verbose >= 3) bb_error_msg(__VA_ARGS__); } while(0)
267# define dbg3s(msg) do { if (G.verbose >= 3) bb_simple_error_msg(msg); } while(0)
247#else 268#else
248# define dbg3(...) ((void)0) 269# define dbg3(...) ((void)0)
270# define dbg3s(msg) ((void)0)
249#endif 271#endif
250 272
251 273
274#ifndef SO_RCVBUFFORCE
275#define SO_RCVBUFFORCE 33
276#endif
252static const char keywords[] ALIGN1 = "add\0remove\0"; // "change\0" 277static const char keywords[] ALIGN1 = "add\0remove\0"; // "change\0"
253enum { OP_add, OP_remove }; 278enum { OP_add, OP_remove };
254 279
@@ -1002,7 +1027,7 @@ wait_for_seqfile(unsigned expected_seq)
1002 /* seed file: write out seq ASAP */ 1027 /* seed file: write out seq ASAP */
1003 xwrite_str(seq_fd, utoa(expected_seq)); 1028 xwrite_str(seq_fd, utoa(expected_seq));
1004 xlseek(seq_fd, 0, SEEK_SET); 1029 xlseek(seq_fd, 0, SEEK_SET);
1005 dbg2("first seq written"); 1030 dbg2s("first seq written");
1006 break; 1031 break;
1007 } 1032 }
1008 seqbufnum = atoll(seqbuf); 1033 seqbufnum = atoll(seqbuf);
@@ -1047,17 +1072,141 @@ static void signal_mdevs(unsigned my_pid)
1047 } 1072 }
1048} 1073}
1049 1074
1075static void process_action(char *temp, unsigned my_pid)
1076{
1077 char *fw;
1078 char *seq;
1079 char *action;
1080 char *env_devname;
1081 char *env_devpath;
1082 unsigned seqnum = seqnum; /* for compiler */
1083 int seq_fd;
1084 smalluint op;
1085
1086 /* Hotplug:
1087 * env ACTION=... DEVPATH=... SUBSYSTEM=... [SEQNUM=...] mdev
1088 * ACTION can be "add", "remove", "change"
1089 * DEVPATH is like "/block/sda" or "/class/input/mice"
1090 */
1091 env_devname = getenv("DEVNAME"); /* can be NULL */
1092 G.subsystem = getenv("SUBSYSTEM");
1093 action = getenv("ACTION");
1094 env_devpath = getenv("DEVPATH");
1095 if (!action || !env_devpath /*|| !G.subsystem*/)
1096 bb_show_usage();
1097 fw = getenv("FIRMWARE");
1098 seq = getenv("SEQNUM");
1099 op = index_in_strings(keywords, action);
1100
1101 if (my_pid)
1102 open_mdev_log(seq, my_pid);
1103
1104 seq_fd = -1;
1105 if (my_pid && seq) {
1106 seqnum = atoll(seq);
1107 seq_fd = wait_for_seqfile(seqnum);
1108 }
1109
1110 dbg1("%s "
1111 "ACTION:%s SEQNUM:%s SUBSYSTEM:%s DEVNAME:%s DEVPATH:%s"
1112 "%s%s",
1113 curtime(),
1114 action, seq, G.subsystem, env_devname, env_devpath,
1115 fw ? " FW:" : "", fw ? fw : ""
1116 );
1117
1118 snprintf(temp, PATH_MAX, "/sys%s", env_devpath);
1119 if (op == OP_remove) {
1120 /* Ignoring "remove firmware". It was reported
1121 * to happen and to cause erroneous deletion
1122 * of device nodes. */
1123 if (!fw)
1124 make_device(env_devname, temp, op);
1125 }
1126 else {
1127 make_device(env_devname, temp, op);
1128 if (ENABLE_FEATURE_MDEV_LOAD_FIRMWARE) {
1129 if (op == OP_add && fw)
1130 load_firmware(fw, temp);
1131 }
1132 }
1133
1134 if (seq_fd >= 0) {
1135 xwrite_str(seq_fd, utoa(seqnum + 1));
1136 signal_mdevs(my_pid);
1137 }
1138}
1139
1140static void initial_scan(char *temp)
1141{
1142 struct stat st;
1143
1144 xstat("/", &st);
1145 G.root_major = major(st.st_dev);
1146 G.root_minor = minor(st.st_dev);
1147
1148 putenv((char*)"ACTION=add");
1149
1150 /* Create all devices from /sys/dev hierarchy */
1151 recursive_action("/sys/dev",
1152 ACTION_RECURSE | ACTION_FOLLOWLINKS,
1153 fileAction, dirAction, temp, 0);
1154}
1155
1156#if ENABLE_FEATURE_MDEV_DAEMON
1157
1158/* uevent applet uses 16k buffer, and mmaps it before every read */
1159# define BUFFER_SIZE (2 * 1024)
1160# define RCVBUF (2 * 1024 * 1024)
1161# define MAX_ENV 32
1162
1163static void daemon_loop(char *temp, int fd)
1164{
1165 for (;;) {
1166 char netbuf[BUFFER_SIZE];
1167 char *env[MAX_ENV];
1168 char *s, *end;
1169 ssize_t len;
1170 int idx;
1171
1172 len = safe_read(fd, netbuf, sizeof(netbuf) - 1);
1173 if (len < 0) {
1174 bb_simple_perror_msg_and_die("read");
1175 }
1176 end = netbuf + len;
1177 *end = '\0';
1178
1179 idx = 0;
1180 s = netbuf;
1181 while (s < end && idx < MAX_ENV) {
1182 if (endofname(s)[0] == '=') {
1183 env[idx++] = s;
1184 putenv(s);
1185 }
1186 s += strlen(s) + 1;
1187 }
1188
1189 process_action(temp, 0);
1190
1191 while (idx)
1192 bb_unsetenv(env[--idx]);
1193 }
1194}
1195#endif
1196
1050int mdev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1197int mdev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1051int mdev_main(int argc UNUSED_PARAM, char **argv) 1198int mdev_main(int argc UNUSED_PARAM, char **argv)
1052{ 1199{
1200 enum {
1201 MDEV_OPT_SCAN = 1 << 0,
1202 MDEV_OPT_DAEMON = 1 << 1,
1203 MDEV_OPT_FOREGROUND = 1 << 2,
1204 };
1205 int opt;
1053 RESERVE_CONFIG_BUFFER(temp, PATH_MAX + SCRATCH_SIZE); 1206 RESERVE_CONFIG_BUFFER(temp, PATH_MAX + SCRATCH_SIZE);
1054 1207
1055 INIT_G(); 1208 INIT_G();
1056 1209
1057#if ENABLE_FEATURE_MDEV_CONF
1058 G.filename = "/etc/mdev.conf";
1059#endif
1060
1061 /* We can be called as hotplug helper */ 1210 /* We can be called as hotplug helper */
1062 /* Kernel cannot provide suitable stdio fds for us, do it ourself */ 1211 /* Kernel cannot provide suitable stdio fds for us, do it ourself */
1063 bb_sanitize_stdio(); 1212 bb_sanitize_stdio();
@@ -1067,90 +1216,55 @@ int mdev_main(int argc UNUSED_PARAM, char **argv)
1067 1216
1068 xchdir("/dev"); 1217 xchdir("/dev");
1069 1218
1070 if (argv[1] && strcmp(argv[1], "-s") == 0) { 1219 opt = getopt32(argv, "s" IF_FEATURE_MDEV_DAEMON("df"));
1071 /*
1072 * Scan: mdev -s
1073 */
1074 struct stat st;
1075 1220
1076#if ENABLE_FEATURE_MDEV_CONF 1221#if ENABLE_FEATURE_MDEV_CONF
1222 G.filename = "/etc/mdev.conf";
1223 if (opt & (MDEV_OPT_SCAN|MDEV_OPT_DAEMON)) {
1077 /* Same as xrealloc_vector(NULL, 4, 0): */ 1224 /* Same as xrealloc_vector(NULL, 4, 0): */
1078 G.rule_vec = xzalloc((1 << 4) * sizeof(*G.rule_vec)); 1225 G.rule_vec = xzalloc((1 << 4) * sizeof(*G.rule_vec));
1226 }
1079#endif 1227#endif
1080 xstat("/", &st);
1081 G.root_major = major(st.st_dev);
1082 G.root_minor = minor(st.st_dev);
1083 1228
1084 putenv((char*)"ACTION=add"); 1229#if ENABLE_FEATURE_MDEV_DAEMON
1230 if (opt & MDEV_OPT_DAEMON) {
1231 /*
1232 * Daemon mode listening on uevent netlink socket.
1233 */
1234 int fd;
1235
1236 /* Subscribe for UEVENT kernel messages */
1237 /* Without a sufficiently big RCVBUF, a ton of simultaneous events
1238 * can trigger ENOBUFS on read, which is unrecoverable.
1239 * Reproducer:
1240 * mdev -d
1241 * find /sys -name uevent -exec sh -c 'echo add >"{}"' ';'
1242 */
1243 fd = create_and_bind_to_netlink(NETLINK_KOBJECT_UEVENT, 1 << 0, RCVBUF);
1085 1244
1086 /* Create all devices from /sys/dev hierarchy */ 1245 /*
1087 recursive_action("/sys/dev", 1246 * Make inital scan after the uevent socket is alive and
1088 ACTION_RECURSE | ACTION_FOLLOWLINKS, 1247 * _before_ we fork away.
1089 fileAction, dirAction, temp, 0);
1090 } else {
1091 char *fw;
1092 char *seq;
1093 char *action;
1094 char *env_devname;
1095 char *env_devpath;
1096 unsigned my_pid;
1097 unsigned seqnum = seqnum; /* for compiler */
1098 int seq_fd;
1099 smalluint op;
1100
1101 /* Hotplug:
1102 * env ACTION=... DEVPATH=... SUBSYSTEM=... [SEQNUM=...] mdev
1103 * ACTION can be "add", "remove", "change"
1104 * DEVPATH is like "/block/sda" or "/class/input/mice"
1105 */ 1248 */
1106 env_devname = getenv("DEVNAME"); /* can be NULL */ 1249 initial_scan(temp);
1107 G.subsystem = getenv("SUBSYSTEM");
1108 action = getenv("ACTION");
1109 env_devpath = getenv("DEVPATH");
1110 if (!action || !env_devpath /*|| !G.subsystem*/)
1111 bb_show_usage();
1112 fw = getenv("FIRMWARE");
1113 seq = getenv("SEQNUM");
1114 op = index_in_strings(keywords, action);
1115
1116 my_pid = getpid();
1117 open_mdev_log(seq, my_pid);
1118 1250
1119 seq_fd = -1; 1251 if (!(opt & MDEV_OPT_FOREGROUND))
1120 if (seq) { 1252 bb_daemonize_or_rexec(0, argv);
1121 seqnum = atoll(seq);
1122 seq_fd = wait_for_seqfile(seqnum);
1123 }
1124 1253
1125 dbg1("%s " 1254 open_mdev_log(NULL, getpid());
1126 "ACTION:%s SUBSYSTEM:%s DEVNAME:%s DEVPATH:%s" 1255
1127 "%s%s", 1256 daemon_loop(temp, fd);
1128 curtime(), 1257 }
1129 action, G.subsystem, env_devname, env_devpath, 1258#endif
1130 fw ? " FW:" : "", fw ? fw : "" 1259 if (opt & MDEV_OPT_SCAN) {
1131 ); 1260 /*
1132 1261 * Scan: mdev -s
1133 snprintf(temp, PATH_MAX, "/sys%s", env_devpath); 1262 */
1134 if (op == OP_remove) { 1263 initial_scan(temp);
1135 /* Ignoring "remove firmware". It was reported 1264 } else {
1136 * to happen and to cause erroneous deletion 1265 process_action(temp, getpid());
1137 * of device nodes. */
1138 if (!fw)
1139 make_device(env_devname, temp, op);
1140 }
1141 else {
1142 make_device(env_devname, temp, op);
1143 if (ENABLE_FEATURE_MDEV_LOAD_FIRMWARE) {
1144 if (op == OP_add && fw)
1145 load_firmware(fw, temp);
1146 }
1147 }
1148 1266
1149 dbg1("%s exiting", curtime()); 1267 dbg1("%s exiting", curtime());
1150 if (seq_fd >= 0) {
1151 xwrite_str(seq_fd, utoa(seqnum + 1));
1152 signal_mdevs(my_pid);
1153 }
1154 } 1268 }
1155 1269
1156 if (ENABLE_FEATURE_CLEAN_UP) 1270 if (ENABLE_FEATURE_CLEAN_UP)
diff --git a/util-linux/mesg.c b/util-linux/mesg.c
index c7b696853..8c032555b 100644
--- a/util-linux/mesg.c
+++ b/util-linux/mesg.c
@@ -65,7 +65,7 @@ int mesg_main(int argc UNUSED_PARAM, char **argv)
65 */ 65 */
66 66
67 if (!isatty(STDIN_FILENO)) 67 if (!isatty(STDIN_FILENO))
68 bb_error_msg_and_die("not a tty"); 68 bb_simple_error_msg_and_die("not a tty");
69 69
70 xfstat(STDIN_FILENO, &sb, "stdin"); 70 xfstat(STDIN_FILENO, &sb, "stdin");
71 if (c == 0) { 71 if (c == 0) {
diff --git a/util-linux/mkfs_ext2.c b/util-linux/mkfs_ext2.c
index 845ba0a24..d568f4be5 100644
--- a/util-linux/mkfs_ext2.c
+++ b/util-linux/mkfs_ext2.c
@@ -266,7 +266,7 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
266 // N.B. what if we format a file? find_mount_point will return false negative since 266 // N.B. what if we format a file? find_mount_point will return false negative since
267 // it is loop block device which is mounted! 267 // it is loop block device which is mounted!
268 if (find_mount_point(argv[0], 0)) 268 if (find_mount_point(argv[0], 0))
269 bb_error_msg_and_die("can't format mounted filesystem"); 269 bb_simple_error_msg_and_die("can't format mounted filesystem");
270 270
271 // get size in kbytes 271 // get size in kbytes
272 kilobytes = get_volume_size_in_bytes(fd, argv[1], 1024, /*extend:*/ !(option_mask32 & OPT_n)) / 1024; 272 kilobytes = get_volume_size_in_bytes(fd, argv[1], 1024, /*extend:*/ !(option_mask32 & OPT_n)) / 1024;
@@ -326,11 +326,11 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv)
326 kilobytes >>= (blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE); 326 kilobytes >>= (blocksize_log2 - EXT2_MIN_BLOCK_LOG_SIZE);
327 nblocks = kilobytes; 327 nblocks = kilobytes;
328 if (nblocks != kilobytes) 328 if (nblocks != kilobytes)
329 bb_error_msg_and_die("block count doesn't fit in 32 bits"); 329 bb_simple_error_msg_and_die("block count doesn't fit in 32 bits");
330#define kilobytes kilobytes_unused_after_this 330#define kilobytes kilobytes_unused_after_this
331 // Experimentally, standard mke2fs won't work on images smaller than 60k 331 // Experimentally, standard mke2fs won't work on images smaller than 60k
332 if (nblocks < 60) 332 if (nblocks < 60)
333 bb_error_msg_and_die("need >= 60 blocks"); 333 bb_simple_error_msg_and_die("need >= 60 blocks");
334 334
335 // How many reserved blocks? 335 // How many reserved blocks?
336 if (reserved_percent > 50) 336 if (reserved_percent > 50)
diff --git a/util-linux/mkfs_minix.c b/util-linux/mkfs_minix.c
index e191acbd0..8f791cf66 100644
--- a/util-linux/mkfs_minix.c
+++ b/util-linux/mkfs_minix.c
@@ -262,7 +262,7 @@ static int get_free_block(void)
262 int blk; 262 int blk;
263 263
264 if (G.used_good_blocks + 1 >= MAX_GOOD_BLOCKS) 264 if (G.used_good_blocks + 1 >= MAX_GOOD_BLOCKS)
265 bb_error_msg_and_die("too many bad blocks"); 265 bb_simple_error_msg_and_die("too many bad blocks");
266 if (G.used_good_blocks) 266 if (G.used_good_blocks)
267 blk = G.good_blocks_table[G.used_good_blocks - 1] + 1; 267 blk = G.good_blocks_table[G.used_good_blocks - 1] + 1;
268 else 268 else
@@ -270,7 +270,7 @@ static int get_free_block(void)
270 while (blk < SB_ZONES && zone_in_use(blk)) 270 while (blk < SB_ZONES && zone_in_use(blk))
271 blk++; 271 blk++;
272 if (blk >= SB_ZONES) 272 if (blk >= SB_ZONES)
273 bb_error_msg_and_die("not enough good blocks"); 273 bb_simple_error_msg_and_die("not enough good blocks");
274 G.good_blocks_table[G.used_good_blocks] = blk; 274 G.good_blocks_table[G.used_good_blocks] = blk;
275 G.used_good_blocks++; 275 G.used_good_blocks++;
276 return blk; 276 return blk;
@@ -342,7 +342,7 @@ static void make_bad_inode(void)
342 goto end_bad; 342 goto end_bad;
343 } 343 }
344 } 344 }
345 bb_error_msg_and_die("too many bad blocks"); 345 bb_simple_error_msg_and_die("too many bad blocks");
346 end_bad: 346 end_bad:
347 if (ind) 347 if (ind)
348 write_block(ind, (char *) ind_block); 348 write_block(ind, (char *) ind_block);
@@ -398,7 +398,7 @@ static void make_bad_inode2(void)
398 } 398 }
399 } 399 }
400 /* Could make triple indirect block here */ 400 /* Could make triple indirect block here */
401 bb_error_msg_and_die("too many bad blocks"); 401 bb_simple_error_msg_and_die("too many bad blocks");
402 end_bad: 402 end_bad:
403 if (ind) 403 if (ind)
404 write_block(ind, (char *) ind_block); 404 write_block(ind, (char *) ind_block);
@@ -514,7 +514,7 @@ static void check_blocks(void)
514 if (got == try) 514 if (got == try)
515 continue; 515 continue;
516 if (G.currently_testing < SB_FIRSTZONE) 516 if (G.currently_testing < SB_FIRSTZONE)
517 bb_error_msg_and_die("bad blocks before data-area: cannot make fs"); 517 bb_simple_error_msg_and_die("bad blocks before data-area: cannot make fs");
518 mark_zone(G.currently_testing); 518 mark_zone(G.currently_testing);
519 G.badblocks++; 519 G.badblocks++;
520 G.currently_testing++; 520 G.currently_testing++;
@@ -588,7 +588,7 @@ static void setup_tables(void)
588 SB_ZMAPS = sb_zmaps; 588 SB_ZMAPS = sb_zmaps;
589 /* new SB_ZMAPS, need to recalc NORM_FIRSTZONE */ 589 /* new SB_ZMAPS, need to recalc NORM_FIRSTZONE */
590 } while (--i); 590 } while (--i);
591 bb_error_msg_and_die("incompatible size/inode count, try different -i N"); 591 bb_simple_error_msg_and_die("incompatible size/inode count, try different -i N");
592 got_it: 592 got_it:
593 593
594 SB_FIRSTZONE = norm_firstzone; 594 SB_FIRSTZONE = norm_firstzone;
@@ -623,10 +623,10 @@ int mkfs_minix_main(int argc UNUSED_PARAM, char **argv)
623 G.magic = MINIX1_SUPER_MAGIC2; 623 G.magic = MINIX1_SUPER_MAGIC2;
624 624
625 if (INODE_SIZE1 * MINIX1_INODES_PER_BLOCK != BLOCK_SIZE) 625 if (INODE_SIZE1 * MINIX1_INODES_PER_BLOCK != BLOCK_SIZE)
626 bb_error_msg_and_die("bad inode size"); 626 bb_simple_error_msg_and_die("bad inode size");
627#if ENABLE_FEATURE_MINIX2 627#if ENABLE_FEATURE_MINIX2
628 if (INODE_SIZE2 * MINIX2_INODES_PER_BLOCK != BLOCK_SIZE) 628 if (INODE_SIZE2 * MINIX2_INODES_PER_BLOCK != BLOCK_SIZE)
629 bb_error_msg_and_die("bad inode size"); 629 bb_simple_error_msg_and_die("bad inode size");
630#endif 630#endif
631 631
632 opt = getopt32(argv, "ci:l:n:+v", &str_i, &listfile, &G.namelen); 632 opt = getopt32(argv, "ci:l:n:+v", &str_i, &listfile, &G.namelen);
@@ -644,7 +644,7 @@ int mkfs_minix_main(int argc UNUSED_PARAM, char **argv)
644#if ENABLE_FEATURE_MINIX2 644#if ENABLE_FEATURE_MINIX2
645 version2 = 1; 645 version2 = 1;
646#else 646#else
647 bb_error_msg_and_die("not compiled with minix v2 support"); 647 bb_simple_error_msg_and_die("not compiled with minix v2 support");
648#endif 648#endif
649 } 649 }
650 650
@@ -654,14 +654,14 @@ int mkfs_minix_main(int argc UNUSED_PARAM, char **argv)
654 654
655 /* Check if it is mounted */ 655 /* Check if it is mounted */
656 if (find_mount_point(G.device_name, 0)) 656 if (find_mount_point(G.device_name, 0))
657 bb_error_msg_and_die("can't format mounted filesystem"); 657 bb_simple_error_msg_and_die("can't format mounted filesystem");
658 658
659 xmove_fd(xopen(G.device_name, O_RDWR), dev_fd); 659 xmove_fd(xopen(G.device_name, O_RDWR), dev_fd);
660 660
661 G.total_blocks = get_volume_size_in_bytes(dev_fd, argv[1], 1024, /*extend:*/ 1) / 1024; 661 G.total_blocks = get_volume_size_in_bytes(dev_fd, argv[1], 1024, /*extend:*/ 1) / 1024;
662 662
663 if (G.total_blocks < 10) 663 if (G.total_blocks < 10)
664 bb_error_msg_and_die("must have at least 10 blocks"); 664 bb_simple_error_msg_and_die("must have at least 10 blocks");
665 665
666 if (version2) { 666 if (version2) {
667 G.magic = MINIX2_SUPER_MAGIC2; 667 G.magic = MINIX2_SUPER_MAGIC2;
diff --git a/util-linux/mkfs_reiser.c b/util-linux/mkfs_reiser.c
index b4c8dda6f..d2eaf5f94 100644
--- a/util-linux/mkfs_reiser.c
+++ b/util-linux/mkfs_reiser.c
@@ -178,7 +178,7 @@ int mkfs_reiser_main(int argc UNUSED_PARAM, char **argv)
178 // N.B. what if we format a file? find_mount_point will return false negative since 178 // N.B. what if we format a file? find_mount_point will return false negative since
179 // it is loop block device which is mounted! 179 // it is loop block device which is mounted!
180 if (find_mount_point(argv[0], 0)) 180 if (find_mount_point(argv[0], 0))
181 bb_error_msg_and_die("can't format mounted filesystem"); 181 bb_simple_error_msg_and_die("can't format mounted filesystem");
182 182
183 // open the device, get size in blocks 183 // open the device, get size in blocks
184 blocks = get_volume_size_in_bytes(fd, argv[1], blocksize, /*extend:*/ 1) / blocksize; 184 blocks = get_volume_size_in_bytes(fd, argv[1], blocksize, /*extend:*/ 1) / blocksize;
diff --git a/util-linux/mkfs_vfat.c b/util-linux/mkfs_vfat.c
index b760fb2aa..16c1fac00 100644
--- a/util-linux/mkfs_vfat.c
+++ b/util-linux/mkfs_vfat.c
@@ -278,7 +278,7 @@ int mkfs_vfat_main(int argc UNUSED_PARAM, char **argv)
278 if (!S_ISBLK(st.st_mode)) { 278 if (!S_ISBLK(st.st_mode)) {
279 if (!S_ISREG(st.st_mode)) { 279 if (!S_ISREG(st.st_mode)) {
280 if (!argv[1]) 280 if (!argv[1])
281 bb_error_msg_and_die("image size must be specified"); 281 bb_simple_error_msg_and_die("image size must be specified");
282 } 282 }
283 // not a block device, skip bad sectors check 283 // not a block device, skip bad sectors check
284 opts &= ~OPT_c; 284 opts &= ~OPT_c;
@@ -399,7 +399,7 @@ int mkfs_vfat_main(int argc UNUSED_PARAM, char **argv)
399 // "mkdosfs -v -F 32 image5k 5" is the minimum: 399 // "mkdosfs -v -F 32 image5k 5" is the minimum:
400 // 2 sectors for FATs and 2 data sectors 400 // 2 sectors for FATs and 2 data sectors
401 if ((off_t)(volume_size_sect - reserved_sect) < 4) 401 if ((off_t)(volume_size_sect - reserved_sect) < 4)
402 bb_error_msg_and_die("the image is too small for FAT32"); 402 bb_simple_error_msg_and_die("the image is too small for FAT32");
403 sect_per_fat = 1; 403 sect_per_fat = 1;
404 while (1) { 404 while (1) {
405 while (1) { 405 while (1) {
@@ -439,7 +439,7 @@ int mkfs_vfat_main(int argc UNUSED_PARAM, char **argv)
439 } 439 }
440 next: 440 next:
441 if (sect_per_clust == 128) 441 if (sect_per_clust == 128)
442 bb_error_msg_and_die("can't make FAT32 with >128 sectors/cluster"); 442 bb_simple_error_msg_and_die("can't make FAT32 with >128 sectors/cluster");
443 sect_per_clust *= 2; 443 sect_per_clust *= 2;
444 sect_per_fat = (sect_per_fat / 2) | 1; 444 sect_per_fat = (sect_per_fat / 2) | 1;
445 } 445 }
diff --git a/util-linux/mkswap.c b/util-linux/mkswap.c
index 38413606d..9e51a1dcc 100644
--- a/util-linux/mkswap.c
+++ b/util-linux/mkswap.c
@@ -75,7 +75,7 @@ static void mkswap_selinux_setcontext(int fd, const char *path)
75 } 75 }
76 return; 76 return;
77 error: 77 error:
78 bb_perror_msg_and_die("SELinux relabeling failed"); 78 bb_simple_perror_msg_and_die("SELinux relabeling failed");
79} 79}
80#else 80#else
81# define mkswap_selinux_setcontext(fd, path) ((void)0) 81# define mkswap_selinux_setcontext(fd, path) ((void)0)
diff --git a/util-linux/mount.c b/util-linux/mount.c
index e6bad7c2c..84c85c057 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -483,7 +483,7 @@ static void FAST_FUNC update_mtab_entry_on_move(const struct mntent *mp)
483 483
484 mountTable = setmntent(bb_path_mtab_file, "r"); 484 mountTable = setmntent(bb_path_mtab_file, "r");
485 if (!mountTable) { 485 if (!mountTable) {
486 bb_perror_msg(bb_path_mtab_file); 486 bb_simple_perror_msg(bb_path_mtab_file);
487 return; 487 return;
488 } 488 }
489 489
@@ -511,7 +511,7 @@ static void FAST_FUNC update_mtab_entry_on_move(const struct mntent *mp)
511 } 511 }
512 endmntent(mountTable); 512 endmntent(mountTable);
513 } else if (errno != EROFS) 513 } else if (errno != EROFS)
514 bb_perror_msg(bb_path_mtab_file); 514 bb_simple_perror_msg(bb_path_mtab_file);
515 515
516 if (ENABLE_FEATURE_CLEAN_UP) { 516 if (ENABLE_FEATURE_CLEAN_UP) {
517 for (i = 0; i < count; i++) { 517 for (i = 0; i < count; i++) {
@@ -739,7 +739,7 @@ static int mount_it_now(struct mntent *mp, unsigned long vfsflags, char *filtero
739 // Abort entirely if permission denied. 739 // Abort entirely if permission denied.
740 740
741 if (rc && errno == EPERM) 741 if (rc && errno == EPERM)
742 bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); 742 bb_simple_error_msg_and_die(bb_msg_perm_denied_are_you_root);
743 743
744 // If the mount was successful, and we're maintaining an old-style 744 // If the mount was successful, and we're maintaining an old-style
745 // mtab file by hand, add the new entry to it now. 745 // mtab file by hand, add the new entry to it now.
@@ -751,7 +751,7 @@ static int mount_it_now(struct mntent *mp, unsigned long vfsflags, char *filtero
751 int i; 751 int i;
752 752
753 if (!mountTable) { 753 if (!mountTable) {
754 bb_perror_msg(bb_path_mtab_file); 754 bb_simple_perror_msg(bb_path_mtab_file);
755 goto ret; 755 goto ret;
756 } 756 }
757 757
@@ -1288,18 +1288,18 @@ static NOINLINE int nfsmount(struct mntent *mp, unsigned long vfsflags, char *fi
1288 s = strchr(hostname, ','); 1288 s = strchr(hostname, ',');
1289 if (s) { 1289 if (s) {
1290 *s = '\0'; 1290 *s = '\0';
1291 bb_error_msg("warning: multiple hostnames not supported"); 1291 bb_simple_error_msg("warning: multiple hostnames not supported");
1292 } 1292 }
1293 1293
1294 server_addr.sin_family = AF_INET; 1294 server_addr.sin_family = AF_INET;
1295 if (!inet_aton(hostname, &server_addr.sin_addr)) { 1295 if (!inet_aton(hostname, &server_addr.sin_addr)) {
1296 hp = gethostbyname(hostname); 1296 hp = gethostbyname(hostname);
1297 if (hp == NULL) { 1297 if (hp == NULL) {
1298 bb_herror_msg("%s", hostname); 1298 bb_simple_herror_msg(hostname);
1299 goto fail; 1299 goto fail;
1300 } 1300 }
1301 if (hp->h_length != (int)sizeof(struct in_addr)) { 1301 if (hp->h_length != (int)sizeof(struct in_addr)) {
1302 bb_error_msg_and_die("only IPv4 is supported"); 1302 bb_simple_error_msg_and_die("only IPv4 is supported");
1303 } 1303 }
1304 memcpy(&server_addr.sin_addr, hp->h_addr_list[0], sizeof(struct in_addr)); 1304 memcpy(&server_addr.sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
1305 } 1305 }
@@ -1389,7 +1389,7 @@ static NOINLINE int nfsmount(struct mntent *mp, unsigned long vfsflags, char *fi
1389 else if (is_prefixed_with(opteq, "udp")) 1389 else if (is_prefixed_with(opteq, "udp"))
1390 tcp = 0; 1390 tcp = 0;
1391 else 1391 else
1392 bb_error_msg("warning: unrecognized proto= option"); 1392 bb_simple_error_msg("warning: unrecognized proto= option");
1393 continue; 1393 continue;
1394 case 20: // "addr" - ignore 1394 case 20: // "addr" - ignore
1395 continue; 1395 continue;
@@ -1522,7 +1522,7 @@ static NOINLINE int nfsmount(struct mntent *mp, unsigned long vfsflags, char *fi
1522 if (nfs_mount_version >= 3) 1522 if (nfs_mount_version >= 3)
1523 nolock = !val; 1523 nolock = !val;
1524 else 1524 else
1525 bb_error_msg("warning: option nolock is not supported"); 1525 bb_simple_error_msg("warning: option nolock is not supported");
1526 break; 1526 break;
1527 case 11: //rdirplus 1527 case 11: //rdirplus
1528 nordirplus = !val; 1528 nordirplus = !val;
@@ -1590,11 +1590,11 @@ static NOINLINE int nfsmount(struct mntent *mp, unsigned long vfsflags, char *fi
1590 } else { 1590 } else {
1591 hp = gethostbyname(mounthost); 1591 hp = gethostbyname(mounthost);
1592 if (hp == NULL) { 1592 if (hp == NULL) {
1593 bb_herror_msg("%s", mounthost); 1593 bb_simple_herror_msg(mounthost);
1594 goto fail; 1594 goto fail;
1595 } 1595 }
1596 if (hp->h_length != (int)sizeof(struct in_addr)) { 1596 if (hp->h_length != (int)sizeof(struct in_addr)) {
1597 bb_error_msg_and_die("only IPv4 is supported"); 1597 bb_simple_error_msg_and_die("only IPv4 is supported");
1598 } 1598 }
1599 mount_server_addr.sin_family = AF_INET; 1599 mount_server_addr.sin_family = AF_INET;
1600 memcpy(&mount_server_addr.sin_addr, hp->h_addr_list[0], sizeof(struct in_addr)); 1600 memcpy(&mount_server_addr.sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
@@ -1767,18 +1767,18 @@ static NOINLINE int nfsmount(struct mntent *mp, unsigned long vfsflags, char *fi
1767 /* Create nfs socket for kernel */ 1767 /* Create nfs socket for kernel */
1768 if (tcp) { 1768 if (tcp) {
1769 if (nfs_mount_version < 3) { 1769 if (nfs_mount_version < 3) {
1770 bb_error_msg("NFS over TCP is not supported"); 1770 bb_simple_error_msg("NFS over TCP is not supported");
1771 goto fail; 1771 goto fail;
1772 } 1772 }
1773 fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 1773 fsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1774 } else 1774 } else
1775 fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 1775 fsock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
1776 if (fsock < 0) { 1776 if (fsock < 0) {
1777 bb_perror_msg("nfs socket"); 1777 bb_simple_perror_msg("nfs socket");
1778 goto fail; 1778 goto fail;
1779 } 1779 }
1780 if (bindresvport(fsock, 0) < 0) { 1780 if (bindresvport(fsock, 0) < 0) {
1781 bb_perror_msg("nfs bindresvport"); 1781 bb_simple_perror_msg("nfs bindresvport");
1782 goto fail; 1782 goto fail;
1783 } 1783 }
1784 if (port == 0) { 1784 if (port == 0) {
@@ -2047,9 +2047,9 @@ static int singlemount(struct mntent *mp, int ignore_busy)
2047 ); 2047 );
2048 if (loopfd < 0) { 2048 if (loopfd < 0) {
2049 if (errno == EPERM || errno == EACCES) 2049 if (errno == EPERM || errno == EACCES)
2050 bb_error_msg(bb_msg_perm_denied_are_you_root); 2050 bb_simple_error_msg(bb_msg_perm_denied_are_you_root);
2051 else 2051 else
2052 bb_perror_msg("can't setup loop device"); 2052 bb_simple_perror_msg("can't setup loop device");
2053 return errno; 2053 return errno;
2054 } 2054 }
2055 2055
@@ -2255,7 +2255,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
2255 // argument when we get it. 2255 // argument when we get it.
2256 if (argv[1]) { 2256 if (argv[1]) {
2257 if (nonroot) 2257 if (nonroot)
2258 bb_error_msg_and_die(bb_msg_you_must_be_root); 2258 bb_simple_error_msg_and_die(bb_msg_you_must_be_root);
2259 mtpair->mnt_fsname = argv[0]; 2259 mtpair->mnt_fsname = argv[0];
2260 mtpair->mnt_dir = argv[1]; 2260 mtpair->mnt_dir = argv[1];
2261 mtpair->mnt_type = fstype; 2261 mtpair->mnt_type = fstype;
@@ -2272,7 +2272,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
2272 2272
2273 cmdopt_flags = parse_mount_options(cmdopts, NULL); 2273 cmdopt_flags = parse_mount_options(cmdopts, NULL);
2274 if (nonroot && (cmdopt_flags & ~MS_SILENT)) // Non-root users cannot specify flags 2274 if (nonroot && (cmdopt_flags & ~MS_SILENT)) // Non-root users cannot specify flags
2275 bb_error_msg_and_die(bb_msg_you_must_be_root); 2275 bb_simple_error_msg_and_die(bb_msg_you_must_be_root);
2276 2276
2277 // If we have a shared subtree flag, don't worry about fstab or mtab. 2277 // If we have a shared subtree flag, don't worry about fstab or mtab.
2278 if (ENABLE_FEATURE_MOUNT_FLAGS 2278 if (ENABLE_FEATURE_MOUNT_FLAGS
@@ -2337,7 +2337,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
2337 // No, mount -a won't mount anything, 2337 // No, mount -a won't mount anything,
2338 // even user mounts, for mere humans 2338 // even user mounts, for mere humans
2339 if (nonroot) 2339 if (nonroot)
2340 bb_error_msg_and_die(bb_msg_you_must_be_root); 2340 bb_simple_error_msg_and_die(bb_msg_you_must_be_root);
2341 2341
2342 // Does type match? (NULL matches always) 2342 // Does type match? (NULL matches always)
2343 if (!fstype_matches(mtcur->mnt_type, fstype)) 2343 if (!fstype_matches(mtcur->mnt_type, fstype))
@@ -2417,7 +2417,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv)
2417 // fstab must have "users" or "user" 2417 // fstab must have "users" or "user"
2418 l = parse_mount_options(mtcur->mnt_opts, NULL); 2418 l = parse_mount_options(mtcur->mnt_opts, NULL);
2419 if (!(l & MOUNT_USERS)) 2419 if (!(l & MOUNT_USERS))
2420 bb_error_msg_and_die(bb_msg_you_must_be_root); 2420 bb_simple_error_msg_and_die(bb_msg_you_must_be_root);
2421 } 2421 }
2422 2422
2423 //util-linux-2.12 does not do this check. 2423 //util-linux-2.12 does not do this check.
diff --git a/util-linux/nsenter.c b/util-linux/nsenter.c
index 4eeaa9f3e..304f2d748 100644
--- a/util-linux/nsenter.c
+++ b/util-linux/nsenter.c
@@ -257,7 +257,7 @@ int nsenter_main(int argc UNUSED_PARAM, char **argv)
257 257
258 if (opts & OPT_setgid) { 258 if (opts & OPT_setgid) {
259 if (setgroups(0, NULL) < 0 && setgroups_failed) 259 if (setgroups(0, NULL) < 0 && setgroups_failed)
260 bb_perror_msg_and_die("setgroups"); 260 bb_simple_perror_msg_and_die("setgroups");
261 xsetgid(gid); 261 xsetgid(gid);
262 } 262 }
263 if (opts & OPT_setuid) 263 if (opts & OPT_setuid)
diff --git a/util-linux/rdate.c b/util-linux/rdate.c
index 70f829e7f..41aade5ea 100644
--- a/util-linux/rdate.c
+++ b/util-linux/rdate.c
@@ -33,7 +33,7 @@ enum { RFC_868_BIAS = 2208988800UL };
33 33
34static void socket_timeout(int sig UNUSED_PARAM) 34static void socket_timeout(int sig UNUSED_PARAM)
35{ 35{
36 bb_error_msg_and_die("timeout connecting to time server"); 36 bb_simple_error_msg_and_die("timeout connecting to time server");
37} 37}
38 38
39static time_t askremotedate(const char *host) 39static time_t askremotedate(const char *host)
@@ -94,10 +94,10 @@ int rdate_main(int argc UNUSED_PARAM, char **argv)
94 94
95 if (!(flags & 2)) { /* no -p (-s may be present) */ 95 if (!(flags & 2)) { /* no -p (-s may be present) */
96 if (time(NULL) == remote_time) 96 if (time(NULL) == remote_time)
97 bb_error_msg("current time matches remote time"); 97 bb_simple_error_msg("current time matches remote time");
98 else 98 else
99 if (stime(&remote_time) < 0) 99 if (stime(&remote_time) < 0)
100 bb_perror_msg_and_die("can't set time of day"); 100 bb_simple_perror_msg_and_die("can't set time of day");
101 } 101 }
102 102
103 if (flags != 1) /* not lone -s */ 103 if (flags != 1) /* not lone -s */
diff --git a/util-linux/readprofile.c b/util-linux/readprofile.c
index cab2c4319..c4ea374be 100644
--- a/util-linux/readprofile.c
+++ b/util-linux/readprofile.c
@@ -142,7 +142,7 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv)
142 small++; 142 small++;
143 } 143 }
144 if (big > small) { 144 if (big > small) {
145 bb_error_msg("assuming reversed byte order, " 145 bb_simple_error_msg("assuming reversed byte order, "
146 "use -n to force native byte order"); 146 "use -n to force native byte order");
147 BUILD_BUG_ON(sizeof(*p) > 8); 147 BUILD_BUG_ON(sizeof(*p) > 8);
148 for (p = buf; p < buf+len; p++) { 148 for (p = buf; p < buf+len; p++) {
@@ -204,7 +204,7 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv)
204 } 204 }
205 205
206 if (indx >= len) 206 if (indx >= len)
207 bb_error_msg_and_die("profile address out of range. " 207 bb_simple_error_msg_and_die("profile address out of range. "
208 "Wrong map file?"); 208 "Wrong map file?");
209 209
210 this = 0; 210 this = 0;
diff --git a/util-linux/rtcwake.c b/util-linux/rtcwake.c
index 29c440b82..cad0f9d64 100644
--- a/util-linux/rtcwake.c
+++ b/util-linux/rtcwake.c
@@ -230,7 +230,7 @@ int rtcwake_main(int argc UNUSED_PARAM, char **argv)
230 do { 230 do {
231 ssize_t ret = safe_read(fd, &data, sizeof(data)); 231 ssize_t ret = safe_read(fd, &data, sizeof(data));
232 if (ret < 0) { 232 if (ret < 0) {
233 bb_perror_msg("rtc read"); 233 bb_simple_perror_msg("rtc read");
234 break; 234 break;
235 } 235 }
236 } while (!(data & RTC_AF)); 236 } while (!(data & RTC_AF));
diff --git a/util-linux/setpriv.c b/util-linux/setpriv.c
index b69b8cbb6..e5cf96957 100644
--- a/util-linux/setpriv.c
+++ b/util-linux/setpriv.c
@@ -164,7 +164,7 @@ static void set_inh_caps(char *capstring)
164 } 164 }
165 165
166 if (capset(&caps.header, caps.data) != 0) 166 if (capset(&caps.header, caps.data) != 0)
167 bb_perror_msg_and_die("capset"); 167 bb_simple_perror_msg_and_die("capset");
168} 168}
169 169
170static void set_ambient_caps(char *string) 170static void set_ambient_caps(char *string)
@@ -178,10 +178,10 @@ static void set_ambient_caps(char *string)
178 idx = parse_cap(cap); 178 idx = parse_cap(cap);
179 if (cap[0] == '+') { 179 if (cap[0] == '+') {
180 if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, idx, 0, 0) < 0) 180 if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, idx, 0, 0) < 0)
181 bb_perror_msg("cap_ambient_raise"); 181 bb_simple_perror_msg("cap_ambient_raise");
182 } else { 182 } else {
183 if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, idx, 0, 0) < 0) 183 if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, idx, 0, 0) < 0)
184 bb_perror_msg("cap_ambient_lower"); 184 bb_simple_perror_msg("cap_ambient_lower");
185 } 185 }
186 cap = strtok(NULL, ","); 186 cap = strtok(NULL, ",");
187 } 187 }
@@ -236,7 +236,7 @@ static int dump(void)
236 unsigned idx = CAP_TO_INDEX(i); 236 unsigned idx = CAP_TO_INDEX(i);
237 if (idx >= caps.u32s) { 237 if (idx >= caps.u32s) {
238 printf("\nindex: %u u32s: %u capability: %u\n", idx, caps.u32s, i); 238 printf("\nindex: %u u32s: %u capability: %u\n", idx, caps.u32s, i);
239 bb_error_msg_and_die("unsupported capability"); 239 bb_simple_error_msg_and_die("unsupported capability");
240 } 240 }
241 if (caps.data[idx].inheritable & CAP_TO_MASK(i)) { 241 if (caps.data[idx].inheritable & CAP_TO_MASK(i)) {
242 printf_cap(fmt, i); 242 printf_cap(fmt, i);
diff --git a/util-linux/switch_root.c b/util-linux/switch_root.c
index ae9d412d1..a483893ed 100644
--- a/util-linux/switch_root.c
+++ b/util-linux/switch_root.c
@@ -117,7 +117,7 @@ static void drop_capset(int cap_idx)
117 getcaps(&caps); 117 getcaps(&caps);
118 caps.data[CAP_TO_INDEX(cap_idx)].inheritable &= ~CAP_TO_MASK(cap_idx); 118 caps.data[CAP_TO_INDEX(cap_idx)].inheritable &= ~CAP_TO_MASK(cap_idx);
119 if (capset(&caps.header, caps.data) != 0) 119 if (capset(&caps.header, caps.data) != 0)
120 bb_perror_msg_and_die("capset"); 120 bb_simple_perror_msg_and_die("capset");
121} 121}
122 122
123static void drop_bounding_set(int cap_idx) 123static void drop_bounding_set(int cap_idx)
@@ -253,7 +253,7 @@ int switch_root_main(int argc UNUSED_PARAM, char **argv)
253 if ((unsigned)stfs.f_type != RAMFS_MAGIC 253 if ((unsigned)stfs.f_type != RAMFS_MAGIC
254 && (unsigned)stfs.f_type != TMPFS_MAGIC 254 && (unsigned)stfs.f_type != TMPFS_MAGIC
255 ) { 255 ) {
256 bb_error_msg_and_die("root filesystem is not ramfs/tmpfs"); 256 bb_simple_error_msg_and_die("root filesystem is not ramfs/tmpfs");
257 } 257 }
258 258
259 if (!dry_run) { 259 if (!dry_run) {
@@ -263,7 +263,7 @@ int switch_root_main(int argc UNUSED_PARAM, char **argv)
263 // Overmount / with newdir and chroot into it 263 // Overmount / with newdir and chroot into it
264 if (mount(".", "/", NULL, MS_MOVE, NULL)) { 264 if (mount(".", "/", NULL, MS_MOVE, NULL)) {
265 // For example, fails when newroot is not a mountpoint 265 // For example, fails when newroot is not a mountpoint
266 bb_perror_msg_and_die("error moving root"); 266 bb_simple_perror_msg_and_die("error moving root");
267 } 267 }
268 } 268 }
269 xchroot("."); 269 xchroot(".");
diff --git a/util-linux/uevent.c b/util-linux/uevent.c
index 761743f45..7a1d7d4a7 100644
--- a/util-linux/uevent.c
+++ b/util-linux/uevent.c
@@ -46,37 +46,19 @@ enum { RCVBUF = 2 * 1024 * 1024 };
46int uevent_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 46int uevent_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
47int uevent_main(int argc UNUSED_PARAM, char **argv) 47int uevent_main(int argc UNUSED_PARAM, char **argv)
48{ 48{
49 struct sockaddr_nl sa;
50 int fd; 49 int fd;
51 50
52 INIT_G(); 51 INIT_G();
53 52
54 argv++; 53 argv++;
55 54
56 // Subscribe for UEVENT kernel messages 55 // Subscribe for UEVENT kernel messages.
57 sa.nl_family = AF_NETLINK;
58 sa.nl_pad = 0;
59 sa.nl_pid = getpid();
60 sa.nl_groups = 1 << 0;
61 fd = xsocket(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
62 xbind(fd, (struct sockaddr *) &sa, sizeof(sa));
63 close_on_exec_on(fd);
64
65 // Without a sufficiently big RCVBUF, a ton of simultaneous events 56 // Without a sufficiently big RCVBUF, a ton of simultaneous events
66 // can trigger ENOBUFS on read, which is unrecoverable. 57 // can trigger ENOBUFS on read, which is unrecoverable.
67 // Reproducer: 58 // Reproducer:
68 // uevent mdev & 59 // uevent mdev &
69 // find /sys -name uevent -exec sh -c 'echo add >"{}"' ';' 60 // find /sys -name uevent -exec sh -c 'echo add >"{}"' ';'
70 // 61 fd = create_and_bind_to_netlink(NETLINK_KOBJECT_UEVENT, /*groups:*/ 1 << 0, RCVBUF);
71 // SO_RCVBUFFORCE (root only) can go above net.core.rmem_max sysctl
72 setsockopt_SOL_SOCKET_int(fd, SO_RCVBUF, RCVBUF);
73 setsockopt_SOL_SOCKET_int(fd, SO_RCVBUFFORCE, RCVBUF);
74 if (0) {
75 int z;
76 socklen_t zl = sizeof(z);
77 getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &z, &zl);
78 bb_error_msg("SO_RCVBUF:%d", z);
79 }
80 62
81 for (;;) { 63 for (;;) {
82 char *netbuf; 64 char *netbuf;
@@ -93,12 +75,12 @@ int uevent_main(int argc UNUSED_PARAM, char **argv)
93 MAP_PRIVATE | MAP_ANON, 75 MAP_PRIVATE | MAP_ANON,
94 /* ignored: */ -1, 0); 76 /* ignored: */ -1, 0);
95 if (netbuf == MAP_FAILED) 77 if (netbuf == MAP_FAILED)
96 bb_perror_msg_and_die("mmap"); 78 bb_simple_perror_msg_and_die("mmap");
97 79
98 // Here we block, possibly for a very long time 80 // Here we block, possibly for a very long time
99 len = safe_read(fd, netbuf, BUFFER_SIZE - 1); 81 len = safe_read(fd, netbuf, BUFFER_SIZE - 1);
100 if (len < 0) 82 if (len < 0)
101 bb_perror_msg_and_die("read"); 83 bb_simple_perror_msg_and_die("read");
102 end = netbuf + len; 84 end = netbuf + len;
103 *end = '\0'; 85 *end = '\0';
104 86
@@ -118,14 +100,15 @@ int uevent_main(int argc UNUSED_PARAM, char **argv)
118 } 100 }
119 env[idx] = NULL; 101 env[idx] = NULL;
120 102
121 idx = 0; 103 if (argv[0]) {
122 while (env[idx]) 104 idx = 0;
123 putenv(env[idx++]); 105 while (env[idx])
124 if (argv[0]) 106 putenv(env[idx++]);
125 spawn_and_wait(argv); 107 spawn_and_wait(argv);
126 idx = 0; 108 idx = 0;
127 while (env[idx]) 109 while (env[idx])
128 bb_unsetenv(env[idx++]); 110 bb_unsetenv(env[idx++]);
111 }
129 munmap(netbuf, BUFFER_SIZE); 112 munmap(netbuf, BUFFER_SIZE);
130 } 113 }
131 114
diff --git a/util-linux/unshare.c b/util-linux/unshare.c
index 61fc71197..a943e7b03 100644
--- a/util-linux/unshare.c
+++ b/util-linux/unshare.c
@@ -239,7 +239,7 @@ int unshare_main(int argc UNUSED_PARAM, char **argv)
239 if (setgrp_str) { 239 if (setgrp_str) {
240 if (strcmp(setgrp_str, "allow") == 0) { 240 if (strcmp(setgrp_str, "allow") == 0) {
241 if (opts & OPT_map_root) { 241 if (opts & OPT_map_root) {
242 bb_error_msg_and_die( 242 bb_simple_error_msg_and_die(
243 "--setgroups=allow and --map-root-user " 243 "--setgroups=allow and --map-root-user "
244 "are mutually exclusive" 244 "are mutually exclusive"
245 ); 245 );